Multiple Time Frames with TALIB and Tulip
#1
I know i can use Multiple Time Frames with builtin indicators like MACD and RSI in ZAPPRA . but i want to use same trick with TALIB and Tulip lib
  Reply
#2
anyone?
  Reply
#3
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.
  Reply
#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
#5
Ok, can you upload whole console output, e.g. to pastebin and/or your strat, I will give it a test run.
  Reply
#6
(01-10-2019, 12:09 PM)mark.sch Wrote: Ok, can you upload whole console output, e.g. to pastebin and/or your strat, I will give it a test run.

Sure here you go

sample config
https://pastebin.com/UajNLQUE

StratV5
https://pastebin.com/3BEeRyTs

FullLogs
https://file.io/38GWN6

https://www.mediafire.com/file/du61ebb56...s.txt/file

also how can i hide the candle info . it shows to the console even when i set debug to false and also when i removed it from the console.log(), func
  Reply
#7
You want your strategy to make a console output like this?


Attached Files
.png   Bildschirmfoto_2019-01-10_14-26-26.png (Size: 257.21 KB / Downloads: 37)
  Reply
#8
yes exactly with mfi indicator from tulip or talib as well
  Reply
#9
Ok, some changes have been necessary for your strat to work, I tweaked the necessary things. Have a look both the config and strat changes:

Config: https://pastebin.com/j7dB6K6n
Strat: https://pastebin.com/491Bvjs7

I added some code for proper candle warmup handling, otherwise you will get undefined indicator values during the first minutes/hours. Just match the history size in your config with the necessary history size of your indicators if you make any further changes.

You can use this strat now as a bare skelleton to start implementing any multi timeframe candle logic now. With the open source T5mainasync and T5multimarket strategies you have further examples how to use other tulip and talib async indicators. I removed the MFI indicator temporarily because it had a wrong syntax in your strat. You need to look into the tulip documentation which params it expects and what it returns. Good look with your coding.

=> apply your binance settings to the config again, I tested with kraken ETH EUR data because I had it locally available.
  Reply
#10
Thanks a lot . i will test it now .
  Reply


Forum Jump:


Users browsing this thread: