Multiple Time Frames with TALIB and Tulip
#4
(01-10-2019, 11:35 AM)mark.sch Wrote: Yes it is possible, but you will need to add some gekko core modifications. The problem is, that talib und tulip work async with their indicator calculations. So these calculations will either need proper callbacks or async/await patterns to work with the core without running into candle timing and race conditions.

I made some pull requests to target exactly this issue. You may have a look and pick what you need. You may also play with the Green Gekko fork, which has implemented this feature ready to go. In my own strategies I run 5 different candle sizes within one strategy on many different talib indicators for example.

Thanks Mark . i found your Green Geeko and it looks great indeed . i tried to make a simple strat just to console log macd,rsi,mfi  showing 3 time frames ( 5,15,240)

but it was not working 

Code:
const _ = require('lodash');
const util = require('util');
const log = require('../core/log.js');
const config = require ('../core/util.js').getConfig();
const candleBatcher = require('../core/candleBatcher');
const TULIPASYNC = require('../strategies/indicators/TulipAsync.js');
const TALIBASYNC = require('../strategies/indicators/TalibAsync.js');
var obj;

var stratMain = {};


stratMain.init = function (context) {
   if(context === undefined) {
       this.context = this;
   } else {
       this.context = context;
   }

   obj = this;
   this.name = 'SobhV5';
   
   this.context.exposedMain = false;
   this.context.trendMain = {
       direction: 'none',
       duration: 0,
       persisted: false,
       adviced: false
   };

   this.cb5 = new candleBatcher(5);
   this.cb5.on('candle', this.onCandle5M);

   this.cb15 = new candleBatcher(15);
   this.cb15.on('candle', this.onCandle15M);

   this.cb240 = new candleBatcher(240);
   this.cb240.on('candle', this.onCandle240M);


   this.requiredHistory = this.context.tradingAdvisor.historySize;
   //this.intCandleSize = this.context.tradingAdvisor.candleSize;



   const MACDSettings = this.context.settings.MACD;
   const STOCHSettings = this.context.settings.STOCH;
   const RSISettings = this.context.settings.RSI;
   const MFISettings = this.context.settings.MFI;
 

   this.macd5M = new TULIPASYNC({ indicator: 'macd', length: 14, candleinput: 'close', options:[ MACDSettings.optInFastPeriod, MACDSettings.optInSlowPeriod, MACDSettings.optInSignalPeriod ] });
   this.mfi5M = new TULIPASYNC({ indicator: 'mfi', length: 14, candleinput: 'close', options:[ MFISettings.optInTimePeriod ] });
   this.rsi5M = new TULIPASYNC({ indicator: 'rsi', length: 14, candleinput: 'close', options:[ RSISettings.optInTimePeriod ] });


   this.macd15M = new TULIPASYNC({ indicator: 'macd', length: 14, candleinput: 'close', options:[ MACDSettings.optInFastPeriod, MACDSettings.optInSlowPeriod, MACDSettings.optInSignalPeriod ] });
   this.mfi15M = new TULIPASYNC({ indicator: 'mfi', length: 14, candleinput: 'close', options:[ MFISettings.optInTimePeriod ] });
   this.rsi15M = new TULIPASYNC({ indicator: 'rsi', length: 14, candleinput: 'close', options:[ RSISettings.optInTimePeriod ] });

   this.macd240M = new TULIPASYNC({ indicator: 'macd', length: 14, candleinput: 'close', options:[ MACDSettings.optInFastPeriod, MACDSettings.optInSlowPeriod, MACDSettings.optInSignalPeriod ] });
   this.mfi240M = new TULIPASYNC({ indicator: 'mfi', length: 14, candleinput: 'close', options:[ MFISettings.optInTimePeriod ] });
   this.rsi240M = new TULIPASYNC({ indicator: 'rsi', length: 14, candleinput: 'close', options:[ RSISettings.optInTimePeriod ] });


}


// ***************************************************************************
// * 1 Min candles - candle batching
stratMain.onCandle = async function (candle) {
    this.cb5.write([candle]);
    this.cb5.flush();

    this.cb15.write([candle]);
    this.cb15.flush();

    this.cb240.write([candle]);
    this.cb240.flush();
}


// ***************************************************************************
// * 60 Min candles - strong market strat
stratMain.onCandle5M = async function (candle) {
       await obj.update5M(candle);
       obj.check5M(candle);      
}
stratMain.onCandle15M = async function (candle) {
       await obj.update15M(candle);
       obj.check15M(candle);
}
stratMain.onCandle240M = async function (candle) {
       await obj.update240M(candle);
       obj.check240M(candle);
}

// ***************************************************************************
// * 60 Min candles - update
stratMain.update5M = async function (candle) {
   this.macd5M.result = await this.macd5M.update(candle);
   this.macd5M.macd = this.macd5M.result[0];
   this.mfi5M.result = (await this.mfi5M.update(candle))[0];
   this.rsi5M.result = (await this.rsi5M.update(candle))[0];
}
stratMain.update15M = async function (candle) {
   this.macd15M.result = await this.macd15M.update(candle);
   this.macd15M.macd = this.macd15M.result[0];
   this.mfi15M.result = (await this.mfi15M.update(candle))[0];
}
stratMain.update240M = async function (candle) {
   this.macd240M.result = await this.macd240M.update(candle);
   this.macd240M.macd = this.macd240M.result[0];
   this.mfi240M.result = (await this.mfi240M.update(candle))[0];
}


//*5,15,240 Min candles - check
stratMain.check5M = function(candle) {
   console.log ('5M CANDLES:','macd',this.macd5M.macd,"MFINew",this.mfi5M.result,"RSINew",this.rsi5M.result);
}
stratMain.check15M = function(candle) {
   console.log ('15M CANDLES:','macd',this.macd15M.macd,"MFINew",this.mfi15M.result,"RSINew",this.rsi15M.result);
}
stratMain.check240M = function(candle) {
   console.log ('240M CANDLES:','macd',this.macd240M.macd,"MFINew",this.mfi240M.resul,"RSINew",this.rsi240M.resultt);
}




stratMain.log = function () {
}


stratMain.update = function (candle) {
   //no need for strat update, we work with onCandle custom batching
}


stratMain.check = function (candle) {
  //no need for strat check, we work with onCandle custom batching and strat execution
}


module.exports = stratMain;

my config regarding this strat is 
Code:
config.tradingAdvisor = {
 enabled: true,
 method: 'SobhV5',
 candleSize: 1,
 historySize: 14,
}



config.SobhV5=
{
MACD: {
   optInFastPeriod: 12,
   optInSlowPeriod: 26,
   optInSignalPeriod: 9
 },
 RSI: {
   optInTimePeriod:14,
 },
  MFI: {
   optInTimePeriod:14,
 },
 };

but it is getting this err
Code:
    (node:3012) UnhandledPromiseRejectionWarning: Unhandled promise rejection. This error originated either by throwing inside of an async function without a catch block, or by rejecting a promise which was not handled with .catch(). (rejection id: 515)
(node:3012) UnhandledPromiseRejectionWarning: TypeError: Cannot destructure property `id` of 'undefined' or 'null'.
   at CandleBatcher.calculate (/root/gekko/core/candleBatcher.js:112:44)
   at CandleBatcher.bound [as calculate] (/root/gekko/node_modules/lodash/dist/lodash.js:729:21)
   at CandleBatcher.check (/root/gekko/core/candleBatcher.js:84:36)
   at <anonymous>
   at process._tickCallback (internal/process/next_tick.js:189:7)



so can you please give example of having 2 time frames to show MFI , RSI Tulip . for 5 and 15 mins frames . 

Thanks in advance
  Reply


Messages In This Thread
RE: Multiple Time Frames with TALIB and Tulip - by batssmasher - 01-10-2019, 12:00 PM

Forum Jump:


Users browsing this thread: