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

Commit

Permalink
move all tablib indicators to a promise and replace calculation usage…
Browse files Browse the repository at this point in the history
… in strategies as this function does not handle async behavior (#1383)
  • Loading branch information
Haehnchen authored and DeviaVir committed Feb 20, 2018
1 parent c67b596 commit 8bcd969
Show file tree
Hide file tree
Showing 8 changed files with 153 additions and 122 deletions.
18 changes: 14 additions & 4 deletions extensions/strategies/ta_ema/strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@ module.exports = {
},

calculate: function (s) {
ta_ema(s, 'trend_ema', s.options.trend_ema)
if (s.options.oversold_rsi) {
// sync RSI display with oversold RSI periods
s.options.rsi_periods = s.options.oversold_rsi_periods
Expand All @@ -29,9 +28,6 @@ module.exports = {
if (s.options.mode !== 'sim' || s.options.verbose) console.log(('\noversold at ' + s.period.oversold_rsi + ' RSI, preparing to buy\n').cyan)
}
}
if (s.period.trend_ema && s.lookback[0] && s.lookback[0].trend_ema) {
s.period.trend_ema_rate = (s.period.trend_ema - s.lookback[0].trend_ema) / s.lookback[0].trend_ema * 100
}
if (s.options.neutral_rate === 'auto') {
stddev(s, 'trend_ema_stddev', Math.floor(s.options.trend_ema / 2), 'trend_ema_rate')
}
Expand All @@ -50,6 +46,20 @@ module.exports = {
return cb()
}
}

// wait for promise to be resolved
// we add all maybe we need more indicators
Promise.all([ta_ema(s, s.options.trend_ema)]).then(result => {
if(result && result.outReal) {
s.period.trend_ema = result.outReal;
}
});

// calculate ema rate
if (s.period.trend_ema && s.lookback[0] && s.lookback[0].trend_ema) {
s.period.trend_ema_rate = (s.period.trend_ema - s.lookback[0].trend_ema) / s.lookback[0].trend_ema * 100
}

if (typeof s.period.trend_ema_stddev === 'number') {
if (s.period.trend_ema_rate > s.period.trend_ema_stddev) {
if (s.trend !== 'up') {
Expand Down
46 changes: 25 additions & 21 deletions extensions/strategies/ta_macd/strategy.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,18 +30,6 @@ module.exports = {
if (s.options.mode === 'sim' && s.options.verbose) console.log(('\noverbought at ' + s.period.overbought_rsi + ' RSI, preparing to sold\n').cyan)
}
}

// compture MACD
/*get('lib.ema')(s, 'ema_short', s.options.ema_short_period)
get('lib.ema')(s, 'ema_long', s.options.ema_long_period)
if (s.period.ema_short && s.period.ema_long) {
s.period.macd = (s.period.ema_short - s.period.ema_long)
get('lib.ema')(s, 'signal', s.options.signal_period, 'macd')
if (s.period.signal) {
s.period.macd_histogram = s.period.macd - s.period.signal
}
}*/
ta_macd(s,'macd','macd_histogram','macd_signal',s.options.ema_long_period,s.options.ema_short_period,s.options.signal_period)
},

onPeriod: function (s, cb) {
Expand All @@ -54,16 +42,32 @@ module.exports = {
}
}

if (typeof s.period.macd_histogram === 'number' && typeof s.lookback[0].macd_histogram === 'number') {
if ((s.period.macd_histogram - s.options.up_trend_threshold) > 0 && (s.lookback[0].macd_histogram - s.options.up_trend_threshold) <= 0) {
s.signal = 'buy'
} else if ((s.period.macd_histogram + s.options.down_trend_threshold) < 0 && (s.lookback[0].macd_histogram + s.options.down_trend_threshold) >= 0) {
s.signal = 'sell'
} else {
s.signal = null // hold
ta_macd(s, s.options.ema_long_period, s.options.ema_short_period, s.options.signal_period).then(function(signal) {
if(!signal) {
cb()
return
}
}
cb()

s.period['macd'] = signal.macd
s.period['macd_histogram'] = signal.macd_histogram
s.period['macd_signal'] = signal.macd_signal

if (typeof s.period.macd_histogram === 'number' && typeof s.lookback[0].macd_histogram === 'number') {
if ((s.period.macd_histogram - s.options.up_trend_threshold) > 0 && (s.lookback[0].macd_histogram - s.options.up_trend_threshold) <= 0) {
s.signal = 'buy'
} else if ((s.period.macd_histogram + s.options.down_trend_threshold) < 0 && (s.lookback[0].macd_histogram + s.options.down_trend_threshold) >= 0) {
s.signal = 'sell'
} else {
s.signal = null // hold
}
}

cb()
}).catch(function(error) {
console.log(error)
cb()
})

},

onReport: function (s) {
Expand Down
94 changes: 52 additions & 42 deletions lib/ta_ema.js
Original file line number Diff line number Diff line change
@@ -1,49 +1,59 @@
var talib = require('talib')

module.exports = function ta_ema (s, key, length) {
//create object for talib. only close is used for now but rest might come in handy
if (!s.marketData) {
s.marketData = { open: [], close: [], high: [], low: [], volume: [] }
}
if (s.lookback.length > s.marketData.close.length) {
for (var i = (s.lookback.length - s.marketData.close.length) - 1; i >= 0; i--) {
//console.log('add data')
s.marketData.close.push(s.lookback[i].close)
module.exports = function ta_ema (s, length) {
return new Promise(function(resolve, reject) {
// create object for talib. only close is used for now but rest might come in handy
if (!s.marketData) {
s.marketData = { open: [], close: [], high: [], low: [], volume: [] }
}
//dont calculate until we have enough data
if (s.marketData.close.length >= length) {
//fillup marketData for talib.
//this might need improvment for performance.
//for (var i = 0; i < length; i++) {
// s.marketData.close.push(s.lookback[i].close);
//}
//fillup marketData for talib.
var tmpMarket = JSON.parse(JSON.stringify(s.marketData.close))
//add current period
tmpMarket.push(s.period.close)

//doublecheck length.
if (tmpMarket.length >= length) {
talib.execute({
name: 'EMA',
startIdx: 0,
endIdx: tmpMarket.length -1,
inReal: tmpMarket,
optInTimePeriod: length
}, function (err, result) {
if (err) {
console.log(err)
return
}
//Result format: (note: outReal can have multiple items in the array)
// {
// begIndex: 8,
// nbElement: 1,
// result: { outReal: [ 1820.8621111111108 ] }
// }
s.period[key] = result.result.outReal[(result.nbElement - 1)]
})
if (s.lookback.length > s.marketData.close.length) {
for (var i = (s.lookback.length - s.marketData.close.length) - 1; i >= 0; i--) {
s.marketData.close.push(s.lookback[i].close)
}

//dont calculate until we have enough data
if (s.marketData.close.length >= length) {
//fillup marketData for talib.
//this might need improvment for performance.
//for (var i = 0; i < length; i++) {
// s.marketData.close.push(s.lookback[i].close);
//}
//fillup marketData for talib.
let tmpMarket = s.marketData.close.slice()

//add current period
tmpMarket.push(s.period.close)

//doublecheck length.
if (tmpMarket.length >= length) {
talib.execute({
name: 'EMA',
startIdx: 0,
endIdx: tmpMarket.length -1,
inReal: tmpMarket,
optInTimePeriod: length
}, function (err, result) {
if (err) {
console.log(err)
reject(err, result)
return
}

//Result format: (note: outReal can have multiple items in the array)
// {
// begIndex: 8,
// nbElement: 1,
// result: { outReal: [ 1820.8621111111108 ] }
// }
resolve({
'outReal': result.result.outReal[(result.nbElement - 1)],
})
})
}
} else {
resolve()
}
}
}
})
}
104 changes: 55 additions & 49 deletions lib/ta_macd.js
Original file line number Diff line number Diff line change
@@ -1,55 +1,61 @@
var talib = require('talib')

module.exports = function macd (s, macd_key,hist_key,sig_key, slow_period,fast_period,signal_period) {
//check parameters
// if (fast_period > slow_period) {
// console.log('incorrect parameters MACD. (fast_period < slow_period || signal_period > fast_period)')
// return;
// }
//create object for talib. only close is used for now but rest might come in handy
if (!s.marketData) {
s.marketData = { open: [], close: [], high: [], low: [], volume: [] }
}
if (s.lookback.length > s.marketData.close.length) {
for (var i = (s.lookback.length - s.marketData.close.length) - 1; i >= 0; i--) {
//console.log('add data')
s.marketData.close.push(s.lookback[i].close)
}
}
var periods_necessary = slow_period + signal_period - 1
//dont calculate until we have enough data
if (s.marketData.close.length >= periods_necessary) {
//fillup marketData for talib.
var tmpMarket = JSON.parse(JSON.stringify(s.marketData.close))
//add current period
tmpMarket.push(s.period.close)
module.exports = function macd (s, slow_period, fast_period, signal_period) {
return new Promise(function(resolve, reject) {
// check parameters
// if (fast_period > slow_period) {
// console.log('incorrect parameters MACD. (fast_period < slow_period || signal_period > fast_period)')
// return;
// }

talib.execute({
name: 'MACD',
startIdx: 0,
endIdx: tmpMarket.length -1,
inReal: tmpMarket,
optInFastPeriod: fast_period,
optInSlowPeriod: slow_period,
optInSignalPeriod: signal_period
}, function (err, result) {
if (err) {
console.log(err)
return
//create object for talib. only close is used for now but rest might come in handy
if (!s.marketData) {
s.marketData = { open: [], close: [], high: [], low: [], volume: [] }
}
if (s.lookback.length > s.marketData.close.length) {
for (var i = (s.lookback.length - s.marketData.close.length) - 1; i >= 0; i--) {
s.marketData.close.push(s.lookback[i].close)
}
//Result format: (note: outReal can have multiple items in the array)
// {
// begIndex: 8,
// nbElement: 1,
// result: { outReal: [ 1820.8621111111108 ] }
// }
// console.log(JSON.stringify(marketData))
// console.log(JSON.stringify(result.result))
s.period[macd_key] = result.result.outMACD[(result.nbElement - 1)]
s.period[hist_key] = result.result.outMACDHist[(result.nbElement - 1)]
s.period[sig_key] = result.result.outMACDSignal[(result.nbElement - 1)]
})
}

}
}
let periods_necessary = slow_period + signal_period - 1
//dont calculate until we have enough data

if (s.marketData.close.length >= periods_necessary) {
// fillup marketData for talib.
let tmpMarket = s.marketData.close.slice()

// add current period
tmpMarket.push(s.period.close)

talib.execute({
name: 'MACD',
startIdx: 0,
endIdx: tmpMarket.length - 1,
inReal: tmpMarket,
optInFastPeriod: fast_period,
optInSlowPeriod: slow_period,
optInSignalPeriod: signal_period
}, function (err, result) {
if (err) {
reject(err)
console.log(err)
return
}
//Result format: (note: outReal can have multiple items in the array)
// {
// begIndex: 8,
// nbElement: 1,
// result: { outReal: [ 1820.8621111111108 ] }
// }
resolve({
'macd': result.result.outMACD[(result.nbElement - 1)],
'macd_histogram': result.result.outMACDHist[(result.nbElement - 1)],
'macd_signal': result.result.outMACDSignal[(result.nbElement - 1)],
})
})
} else {
resolve()
}
})
}
3 changes: 2 additions & 1 deletion lib/ta_macd_ext.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,8 @@ module.exports = function ta_macd_ext (s, slow_period, fast_period, signal_perio

if (s.marketData.close.length >= periods_necessary) {
//fillup marketData for talib.
var tmpMarket = JSON.parse(JSON.stringify(s.marketData.close))
var tmpMarket = s.marketData.close.slice()

//add current period
tmpMarket.push(s.period.close)

Expand Down
2 changes: 1 addition & 1 deletion lib/ta_ppo.js
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ module.exports = function ppo(s, slow_period, fast_period, signal_period, ma_typ
return
}

let tmpMarket = JSON.parse(JSON.stringify(s.marketData.close))
let tmpMarket = s.marketData.close.slice()

// add current period
tmpMarket.push(s.period.close)
Expand Down
2 changes: 1 addition & 1 deletion lib/ta_trix.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ module.exports = function trix(s, timeperiod) {
return
}

let tmpMarket = JSON.parse(JSON.stringify(s.marketData.close))
let tmpMarket = s.marketData.close.slice()

// add current period
tmpMarket.push(s.period.close)
Expand Down
6 changes: 3 additions & 3 deletions lib/ta_ultosc.js
Original file line number Diff line number Diff line change
Expand Up @@ -20,13 +20,13 @@ module.exports = function ultosc(s, min_periods, timeperiod1, timeperiod2, timep
return
}

let tmpHigh = JSON.parse(JSON.stringify(s.marketData.high))
let tmpHigh = s.marketData.high.slice()
tmpHigh.push(s.period.high)

let tmpLow = JSON.parse(JSON.stringify(s.marketData.low))
let tmpLow = s.marketData.low.slice()
tmpLow.push(s.period.low)

let tmpClose = JSON.parse(JSON.stringify(s.marketData.close))
let tmpClose = s.marketData.close.slice()
tmpClose.push(s.period.close)

talib.execute({
Expand Down

0 comments on commit 8bcd969

Please sign in to comment.