Skip to content

Commit

Permalink
Updated for Alpaca V2 bars / market data
Browse files Browse the repository at this point in the history
still need to update methods for Alpaca data_stream_v2 web socket
  • Loading branch information
michaeljwright committed Jun 4, 2021
1 parent 4a4d03d commit 9aec3aa
Show file tree
Hide file tree
Showing 7 changed files with 245 additions and 51 deletions.
26 changes: 26 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

16 changes: 9 additions & 7 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@kendelchopp/alpaca-js-backtesting",
"version": "1.1.3",
"name": "@michaeljwright/alpaca-js-backtesting",
"version": "2.0.0",
"description": "",
"main": "src/index.js",
"scripts": {
Expand All @@ -9,23 +9,25 @@
},
"repository": {
"type": "git",
"url": "git+https://github.com/KendelChopp/alpaca-js-backtesting.git"
"url": "git+https://github.com/michaeljwright/alpaca-js-backtesting.git"
},
"author": "Kendel Chopp",
"author": "Kendel Chopp (V2 update by Mike)",
"license": "MIT",
"keywords": [
"alpaca",
"backtesting"
],
"bugs": {
"url": "https://github.com/KendelChopp/alpaca-js-backtesting/issues"
"url": "https://github.com/michaeljwright/alpaca-js-backtesting/issues"
},
"homepage": "https://github.com/KendelChopp/alpaca-js-backtesting#readme",
"homepage": "https://github.com/michaeljwright/alpaca-js-backtesting#readme",
"devDependencies": {
"jest": "^26.4.2",
"q": "^1.5.1"
},
"dependencies": {
"lodash": "^4.17.20"
"axios": "^0.21.1",
"lodash": "^4.17.20",
"moment-timezone": "^0.5.33"
}
}
12 changes: 7 additions & 5 deletions src/MarketData/MarketData.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const _ = require('lodash');
const _ = require("lodash");

const Security = require('../Security/Security.js');
const Security = require("../Security/Security.js");

/**
* Class tracking market data and time for all relevant securities
Expand Down Expand Up @@ -34,14 +34,16 @@ class MarketData {
* @returns {Object[]} object containing subjects and data
*/
simulateMinute() {
const validSecurities = _.filter(this.securities, (security) => Boolean(security.data[this.time]));
const dataMap = _.map(validSecurities, (security) => {
const validSecurities = _.filter(this.securities, security =>
Boolean(security.data[this.time])
);
const dataMap = _.map(validSecurities, security => {
security.price = security.data[this.time].closePrice;
return {
subject: `AM.${security.symbol}`,
data: {
...security.data[this.time],
ev: 'AM',
ev: "AM",
symbol: security.symbol
}
};
Expand Down
28 changes: 14 additions & 14 deletions src/Portfolio/Portfolio.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const _ = require('lodash');
const _ = require("lodash");

const Position = require('../Position/Position.js');
const Position = require("../Position/Position.js");

/**
* A class representing cash and all of the positions taken
Expand All @@ -26,7 +26,7 @@ class Portfolio {
* @returns {Position} The position represented by the symbol if it exists
*/
getPosition(symbol) {
return _.find(this.positions, (position) => (position.symbol === symbol));
return _.find(this.positions, position => position.symbol === symbol);
}

/**
Expand Down Expand Up @@ -58,34 +58,34 @@ class Portfolio {
*/
createOrder(options) {
if (!options.symbol) {
throw new Error('No symbol provided for order.');
throw new Error("No symbol provided for order.");
}
if (!options.qty || options.qty < 1) {
throw new Error('Quantity must be >= 1 to create an order.');
throw new Error("Quantity must be >= 1 to create an order.");
}
if (!options.side || (options.side !== 'sell' && options.side !== 'buy')) {
throw new Error('Side not provided correctly. Must be buy or sell.');
if (!options.side || (options.side !== "sell" && options.side !== "buy")) {
throw new Error("Side not provided correctly. Must be buy or sell.");
}

const currentPrice = this.marketData.getPrice(options.symbol);

if (options.side === 'sell') {
if (options.side === "sell") {
const position = this.getPosition(options.symbol);
if (position && position.quantity >= options.qty) {
this.cash += options.qty * currentPrice;
position.quantity -= options.qty;

if (position.quantity == 0) {
_.remove(this.positions, (position) => (position.quantity == 0));
_.remove(this.positions, position => position.quantity == 0);
}
} else {
// TODO: improve warning handling here
console.warn('Attempted to sell more of a position than in portfolio');
console.warn("Attempted to sell more of a position than in portfolio");
}
} else {
if (this.cash < options.qty * currentPrice) {
// TODO: improve warning handling here
console.warn('Order not executed, not enough cash');
console.warn("Order not executed, not enough cash");
} else {
const position = this.findOrCreatePosition(options.symbol);
this.cash -= options.qty * currentPrice;
Expand All @@ -100,7 +100,7 @@ class Portfolio {
* @returns {number} The total value of the Portfolio
*/
getValue() {
const positionValue = _.sumBy(this.positions, (position) => {
const positionValue = _.sumBy(this.positions, position => {
const price = this.marketData.getPrice(position.symbol);

return price * position.quantity;
Expand All @@ -116,13 +116,13 @@ class Portfolio {
*/
getStats() {
const endValue = this.getValue();
const roi = (endValue / this.startValue) - 1;
const roi = endValue / this.startValue - 1;

return {
startValue: this.startValue,
endValue,
roi
}
};
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/Position/Position.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class Position {
* @param {string} symbol - The symbol for the position
* @param {number} quantity - The number open
*/
constructor(symbol, quantity=0) {
constructor(symbol, quantity = 0) {
this.symbol = symbol;
this.quantity = quantity;
}
Expand Down
Loading

0 comments on commit 9aec3aa

Please sign in to comment.