diff --git a/extensions/strategies/ta_ema/strategy.js b/extensions/strategies/ta_ema/strategy.js index 92de028c2b..70c9d08148 100644 --- a/extensions/strategies/ta_ema/strategy.js +++ b/extensions/strategies/ta_ema/strategy.js @@ -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 @@ -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') } @@ -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') { diff --git a/extensions/strategies/ta_macd/strategy.js b/extensions/strategies/ta_macd/strategy.js index 0262fe899b..9bc98520de 100644 --- a/extensions/strategies/ta_macd/strategy.js +++ b/extensions/strategies/ta_macd/strategy.js @@ -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) { @@ -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) { diff --git a/lib/ta_ema.js b/lib/ta_ema.js index 2e6a48afd9..f33970234d 100644 --- a/lib/ta_ema.js +++ b/lib/ta_ema.js @@ -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() } } - } + }) } diff --git a/lib/ta_macd.js b/lib/ta_macd.js index b1949c942b..274080884c 100644 --- a/lib/ta_macd.js +++ b/lib/ta_macd.js @@ -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() + } + }) +} diff --git a/lib/ta_macd_ext.js b/lib/ta_macd_ext.js index 9b9721afa1..cc1a3c30d7 100644 --- a/lib/ta_macd_ext.js +++ b/lib/ta_macd_ext.js @@ -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) diff --git a/lib/ta_ppo.js b/lib/ta_ppo.js index 5ae6610858..0d1804cb93 100644 --- a/lib/ta_ppo.js +++ b/lib/ta_ppo.js @@ -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) diff --git a/lib/ta_trix.js b/lib/ta_trix.js index edf45eb1f1..e79ab5315d 100644 --- a/lib/ta_trix.js +++ b/lib/ta_trix.js @@ -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) diff --git a/lib/ta_ultosc.js b/lib/ta_ultosc.js index d85f7c32bb..afbf1b8ac3 100644 --- a/lib/ta_ultosc.js +++ b/lib/ta_ultosc.js @@ -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({