Skip to content
This repository has been archived by the owner on Feb 15, 2022. It is now read-only.

Improvement/typescript refactor #1656

Merged
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -39,3 +39,4 @@ gen.*.bat
gen.*.sh
.env
scripts/auto_backtester/backtesting_*.csv
.vscode
Copy link
Owner

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't mind, but you could also add this to your global gitignore locally.

255 changes: 255 additions & 0 deletions opts.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,255 @@
{
"options": {
"period": "5m",
"strategy": "ta_macd",
"sell_stop_pct": 0,
"buy_stop_pct": 0,
"profit_stop_enable_pct": 0,
"profit_stop_pct": 1,
"max_slippage_pct": 5,
"buy_pct": 100,
"sell_pct": 100,
"order_adjust_time": 500,
"max_sell_loss_pct": 25,
"order_poll_time": 500,
"markdown_buy_pct": 0,
"markup_sell_pct": 0,
"order_type": "taker",
"poll_trades": 300,
"currency_capital": 1000,
"asset_capital": 0,
"rsi_periods": 25,
"avg_slippage_pct": 0.045,
"max_buy_loss_pct": 99,
"keep_lookback_periods": 50000,
"min_prev_trades": 0,
"currency_increment": null,
"use_prev_trades": false,
"stats": true,
"mode": "live",
"selector": {
"exchange_id": "gdax",
"product_id": "BTC-USD",
"asset": "BTC",
"currency": "USD",
"normalized": "gdax.BTC-USD"
},
"period_length": "5m",
"min_periods": 52,
"ema_short_period": 12,
"ema_long_period": 26,
"signal_period": 9,
"up_trend_threshold": 0,
"down_trend_threshold": 0,
"overbought_rsi_periods": 25,
"overbought_rsi": 70
},
"exchange": {
"name": "gdax",
"historyScan": "backward",
"makerFee": 0,
"takerFee": 0.3,
"backfillRateLimit": 335
},
"product_id": "BTC-USD",
"asset": "BTC",
"currency": "USD",
"asset_capital": 0.0000041860065000000005,
"product": {
"asset": "BTC",
"currency": "USD",
"min_size": "0.001",
"max_size": "70",
"increment": "0.01",
"label": "BTC/USD"
},
"balance": {
"asset": "0.0000000006500000",
"currency": "1288.1592151305950000",
"currency_hold": "0.0000000000000000",
"asset_hold": "0.0000000000000000",
"deposit": 1288.159215130595
},
"ctx": {},
"lookback": [
{
"period_id": "5m5102239",
"size": "5m",
"time": 1530671700000,
"open": 6452,
"high": 6452,
"low": 6442.1,
"close": 6442.11,
"volume": 8.874228370000003,
"close_time": 1530671999999,
"latest_trade_time": 1530671989053,
"overbought_rsi_avg_gain": 2.140148595902717,
"overbought_rsi_avg_loss": 3.8784808313309873,
"overbought_rsi": 35.56,
"id": "c153ae18",
"selector": "gdax.BTC-USD",
"session_id": "b9ef83c8",
"_id": "c153ae18",
"macd": -7.32374154639092,
"macd_histogram": 2.0933382026203873,
"macd_signal": -9.417079749011307,
"rsi_avg_gain": 2.140148595902717,
"rsi_avg_loss": 3.8784808313309873,
"rsi": 35.56
}
],
"day_count": 1,
"my_trades": [],
"my_prev_trades": [],
"vol_since_last_blink": 0,
"boot_time": 1530671884432,
"tz_offset": 240,
"last_trade_id": 45775894,
"trades": [
{
"_id": "gdax.BTC-USD-45756216",
"trade_id": 45756216,
"time": 1530640508194,
"size": 0.01717321,
"price": 6576.52,
"side": "buy",
"id": "gdax.BTC-USD-45756216",
"selector": "gdax.BTC-USD"
}
],
"strategy": {
"name": "ta_macd",
"description": "Buy when (MACD - Signal > 0) and sell when (MACD - Signal < 0).",
"phenotypes": {
"period_length": {
"type": "period_length",
"min": 1,
"max": 120,
"period_length": "m"
},
"min_periods": {
"type": "int",
"min": 1,
"max": 200
},
"markdown_buy_pct": {
"type": "float",
"min": -1,
"max": 5
},
"markup_sell_pct": {
"type": "float",
"min": -1,
"max": 5
},
"order_type": {
"type": "listOption",
"options": ["maker", "taker"]
},
"sell_stop_pct": {
"type": "int0",
"min": 1,
"max": 50
},
"buy_stop_pct": {
"type": "int0",
"min": 1,
"max": 50
},
"profit_stop_enable_pct": {
"type": "int0",
"min": 1,
"max": 20
},
"profit_stop_pct": {
"type": "int",
"min": 1,
"max": 20
},
"ema_short_period": {
"type": "int",
"min": 2,
"max": 20
},
"ema_long_period": {
"type": "int",
"min": 20,
"max": 100
},
"signal_period": {
"type": "int",
"min": 1,
"max": 20
},
"up_trend_threshold": {
"type": "int",
"min": 0,
"max": 50
},
"down_trend_threshold": {
"type": "int",
"min": 0,
"max": 50
},
"overbought_rsi_periods": {
"type": "int",
"min": 1,
"max": 50
},
"overbought_rsi": {
"type": "int",
"min": 20,
"max": 100
}
}
},
"last_day": 3,
"period": {
"period_id": "5m5102240",
"size": "5m",
"time": 1530672000000,
"open": 6442.1,
"high": 6442.1,
"low": 6440,
"close": 6440,
"volume": 0.15711989,
"close_time": 1530672299999,
"latest_trade_time": 1530672012310,
"overbought_rsi_avg_gain": 2.054542652066608,
"overbought_rsi_avg_loss": 3.8077415980777345,
"overbought_rsi": 35.05,
"rsi_avg_gain": 2.054542652066608,
"rsi_avg_loss": 3.8077415980777345,
"rsi": 35.05
},
"marketData": {
"open": [],
"close": [],
"high": [],
"low": [],
"volume": []
},
"acted_on_stop": false,
"action": null,
"signal": null,
"port": 20007,
"url": "192.168.0.7:20007/",
"quote": {
"bid": "6440",
"ask": "6440.01"
},
"start_price": 6440.01,
"start_capital": 1288.1592193166016,
"real_capital": 1288.1592193166016,
"net_currency": 1288.159215130595,
"orig_capital": 1288.1592194139587,
"orig_price": 6589.79,
"stats": {
"profit": "0.00%",
"tmp_balance": "1288.15921931",
"buy_hold": "1288.15721907",
"buy_hold_profit": "-0.01%",
"day_count": 1,
"trade_per_day": "0.00"
}
}
8 changes: 6 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
"precommit": "lint-staged",
"test": "jasmine test/**/**.test.js",
"test-one": "jasmine $PATH_TO_TEST",
"postinstall": "node post_install.js"
"_postinstall": "node post_install.js"
},
"lint-staged": {
"*.js": [
Expand Down Expand Up @@ -98,10 +98,12 @@
"stats-lite": "2.1.1",
"style-loader": "^0.21.0",
"superagent": "^3.8.2",
"talib": "^1.0.4",
"talib": "^1.0.5",
"timebucket": "^0.4.0",
"trend": "0.3.0",
"ts-node": "^7.0.0",
"tulind": "^0.8.10",
"typescript": "^2.9.2",
"url-loader": "^1.0.1",
"uuid": "^3.1.0",
"waypoints": "^4.0.1",
Expand All @@ -112,6 +114,8 @@
"zero-fill": "^2.2.3"
},
"devDependencies": {
"@types/moment": "^2.13.0",
"@types/mongodb": "^3.1.0",
"eslint": "^4.19.1",
"geneticalgorithm": "^0.3.4",
"json2csv": "^4.0.2",
Expand Down
45 changes: 45 additions & 0 deletions src/analysis/adx.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// ADX + DI
export default (s, key, length) => {
if (s.lookback[0] != undefined) {
let TrueRange = Math.max(
Math.max(s.period.high - s.period.low, Math.abs(s.period.high - s.lookback[0].close)),
Math.abs(s.period.low - s.lookback[0].close)
)
let DirectionalMovementPlus =
s.period.high - s.lookback[0].high > s.lookback[0].low - s.period.low
? Math.max(s.period.high - s.lookback[0].high, 0)
: 0
let DirectionalMovementMinus =
s.lookback[0].low - s.period.low > s.period.high - s.lookback[0].high
? Math.max(s.lookback[0].low - s.period.low, 0)
: 0

s.period['SmoothedTrueRange'] =
s.lookback[0]['SmoothedTrueRange'] == undefined
? TrueRange
: s.lookback[0]['SmoothedTrueRange'] - s.lookback[0]['SmoothedTrueRange'] / length + TrueRange
s.period['SmoothedDirectionalMovementPlus'] =
s.lookback[0]['SmoothedDirectionalMovementPlus'] == undefined
? DirectionalMovementPlus
: s.lookback[0]['SmoothedDirectionalMovementPlus'] -
s.lookback[0]['SmoothedDirectionalMovementPlus'] / length +
DirectionalMovementPlus
s.period['SmoothedDirectionalMovementMinus'] =
s.lookback[0]['SmoothedDirectionalMovementMinus'] == undefined
? DirectionalMovementMinus
: s.lookback[0]['SmoothedDirectionalMovementMinus'] -
s.lookback[0]['SmoothedDirectionalMovementMinus'] / length +
DirectionalMovementMinus

s.period['DIPlus'] = (s.period['SmoothedDirectionalMovementPlus'] / s.period['SmoothedTrueRange']) * 100
s.period['DIMinus'] = (s.period['SmoothedDirectionalMovementMinus'] / s.period['SmoothedTrueRange']) * 100
}
if (s.lookback.length > length) {
let ADX = s.lookback.slice(0, length).reduce((sum, cur) => {
let DX = (Math.abs(cur['DIPlus'] - cur['DIMinus']) / (cur['DIPlus'] + cur['DIMinus'])) * 100
return sum + DX
}, 0)

s.period[key] = ADX / length
}
}
14 changes: 14 additions & 0 deletions src/analysis/bollinger.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
// Bollinger Bands
import bollingerbands from 'bollinger-bands'

export default (s, key, length, source_key?) => {
if (!source_key) source_key = 'close'
if (s.lookback.length > length) {
let data = []
for (var i = length - 1; i >= 0; i--) {
data.push(s.lookback[i][source_key])
}
let result = bollingerbands(data, length, s.options.bollinger_time)
s.period[key] = result
}
}
28 changes: 28 additions & 0 deletions src/analysis/cci.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
export default (s, key, length, c) => {
s.period['TP'] = (s.period.high + s.period.low + s.period.close) / 3
if (s.lookback.length >= length) {
let avg_TP = s.lookback.slice(0, length).reduce((sum, tp) => {
return sum + tp.TP
}, 0)
s.period['avg_TP'] = avg_TP / length
let meanDev = s.lookback.slice(0, length).reduce((sum, cur) => {
cur = Math.abs(cur.TP - s.period.avg_TP)
return sum + cur
}, 0)
meanDev = meanDev / length
let CCI = (s.period.TP - s.period.avg_TP) / (c * meanDev)
s.period[key] = CCI
}
}

/*
CCI = (Typical Price - 20-period SMA of TP) / (.015 x Mean Deviation)

Typical Price (TP) = (High + Low + Close)/3

Constant = .015

There are four steps to calculating the Mean Deviation. First, subtract the most recent 20-period average of the typical price from each period's
typical price. Second, take the absolute values of these numbers. Third,
sum the absolute values. Fourth, divide by the total number of periods (20).
*/
12 changes: 12 additions & 0 deletions src/analysis/cmf.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Chaikin Money Flow
export default (s, key, length) => {
if (s.lookback.length >= length) {
let MFV = 0,
SOV = 0
s.lookback.slice(0, length).forEach(function(cur) {
MFV += (cur.volume * (cur.close - cur.low - (cur.high - cur.close))) / (cur.high - cur.low)
SOV += cur.volume
})
s.period[key] = MFV / SOV
}
}
Loading