IB - Switch between Multiple (Near) Online Datafeeds
-
In trying to understand the code and the used objects better I started with the Medium Example from Daniel
Description: https://medium.com/@danjrod/interactive-brokers-in-python-with-backtrader-23dea376b2fc
Having extracted and modified the code:
https://gist.github.com/backtrader/456cf0891a7a62ceb2bbb5e4234c01e7
Right now the strategy (as shown and reproduced from the example) with automated trading is not that important.
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import datetime #import matplotlib import time import pytz class St(bt.Strategy): #pr_St__class = St() #NameError: name 'St' is not defined #print('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pr_St__class', pr_St__class) #here he defines the structure of one record D-OHLC-V def logdata(self): txt = [] txt.append('{}'.format(len(self))) #current object lenght of data, number of records for pricing txt.append('{}'.format(self.data.datetime.datetime(0).isoformat())) txt.append('{:.2f}'.format(self.data.open[0])) txt.append('{:.2f}'.format(self.data.high[0])) txt.append('{:.2f}'.format(self.data.low[0])) txt.append('{:.2f}'.format(self.data.close[0])) txt.append('{:.2f}'.format(self.data.volume[0])) print(','.join(txt)) def next(self): self.logdata() def run(args=None): cerebro = bt.Cerebro(stdstats=False) #with this i get clean data, no history. A clean structure store = bt.stores.IBStore(port=7496, clientId=1001) #20200701 with TWS THIS finally worked well data_s = store.getdata(dataname='EUR.USD-CASH-IDEALPRO', timeframe=bt.TimeFrame.Ticks, stopafter=10, #stopafter backfill_start=False, backfill=False, latethrough=True, tz='CET' ) cerebro.resampledata(data_s, timeframe=bt.TimeFrame.Seconds, compression=1) data_c = store.getdata(dataname='CHF.USD-CASH-IDEALPRO', timeframe=bt.TimeFrame.Ticks, stopafter=10, #stopafter backfill_start=False, backfill=False, latethrough=True, tz='CET' ) cerebro.resampledata(data_c, timeframe=bt.TimeFrame.Seconds, compression=1) cerebro.addstrategy(St) cerebro.run() #this will not stop, # cerebro.plot(plotter=None, iplot=True) #Unfortunately I always get a lot of unneeded nformatio like platform Darwin, V 3.1.3, loaded modules, fonts if __name__ == '__main__': run()
For testing purposes, if necessary, change port to 7497.
Even with the most recent IB Gateway 978.2C the behavior is much different, compared to the well working TWS FAT Client SV: 979.4x TWS can be used, so its not an issue.Having used CSV samples multiple data feeds can be used.
Unfortunately, even with the now added parameters in the code above
(and even with testing the live data (which is not recommended)
#DO NOT USE AS NOT RECOMMENDED data_s = bt.feeds.IBData(dataname='EUR.USD-CASH-IDEALPRO', host='127.0.0.1', port=7496, clientId=1002, #stopafter=10, backfill_start=False, backfill=False, latethrough=True, tz='CET' ) cerebro.resampledata(data_s, timeframe=bt.TimeFrame.Seconds, compression=1)
I never managed to switch between the data feeds. That the question?
Even when the 1st feed is up to date it seems cerebro is not letting it go and switching to the 2nd feed.
Is there a solution oer where can i find some hints? Having two different programs running does not make sense as calculationsbetween the retrieved data should take place.
When this is done, questions on
- having an additional column for the stock name qith the records will come.
- Also a question on whats possible with near online plotting the data.
Regards, Klaus
-
@zkl said in IB - Switch between Multiple (Near) Online Datafeeds:
Even when the 1st feed is up to date it seems cerebro is not letting it go and switching to the 2nd feed
What do you mean by switching to the 2nd feed? Do you want to print the 2nd feed bars in next ? Or trading on 2nd feed?
Basically both feeds are available in the
next
method. Currently you are logging only the firstdata
. In order to log the second one the following code could probably be used:print(f'{self.datas[1].datetime.datetime(0).isoformat}:{self.datas[1].open[0] ....')
-
@vladisld said in IB - Switch between Multiple (Near) Online Datafeeds:
print(f'{self.datas[1].datetime.datetime(0).isoformat}:{self.datas[1].open[0] ....')
Re: "what do you mean..?" I had the impression that cerebro (ES: brain) did not collect the data for the 2nd feed.
Your answer and your short example-hint helped a lot. I was wrong.
from __future__ import (absolute_import, division, print_function, unicode_literals) import backtrader as bt import datetime #import matplotlib import time import pytz class St(bt.Strategy): #pr_St__class = St() #NameError: name 'St' is not defined #print('^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ pr_St__class', pr_St__class) #here he defines the structure of one record D-OHLC-V def logdata(self): txt = [] txt.append('{}'.format(len(self))) #current object lenght of data, number of records for pricing txt.append(' data_s') #1st datafeed txt.append('{}'.format(self.data.datetime.datetime(0).isoformat())) txt.append('{:.2f}'.format(self.data.open[0])) txt.append('{:.2f}'.format(self.data.high[0])) txt.append('{:.2f}'.format(self.data.low[0])) txt.append('{:.2f}'.format(self.data.close[0])) txt.append('{:.2f}'.format(self.data.volume[0])) txt.append(' data_c') #2nd datafeed txt.append('{}'.format(self.datas[1].datetime.datetime(0).isoformat())) txt.append('{:.2f}'.format(self.datas[1].open[0])) txt.append('{:.2f}'.format(self.datas[1].high[0])) txt.append('{:.2f}'.format(self.datas[1].low[0])) txt.append('{:.2f}'.format(self.datas[1].close[0])) txt.append('{:.2f}'.format(self.datas[1].volume[0])) print(','.join(txt)) def next(self): self.logdata() def run(args=None): cerebro = bt.Cerebro(stdstats=False) #with this i get clean data, no history. A clean structure store = bt.stores.IBStore(port=7496, clientId=1001) #20200701 with TWS THIS finally worked well data_s = store.getdata(dataname='EUR.USD-CASH-IDEALPRO', timeframe=bt.TimeFrame.Ticks, stopafter=10, #stopafter backfill_start=False, backfill=False, latethrough=True, tz='CET' ) cerebro.resampledata(data_s, timeframe=bt.TimeFrame.Seconds, compression=1) data_c = store.getdata(dataname='CHF.USD-CASH-IDEALPRO', timeframe=bt.TimeFrame.Ticks, stopafter=10, #stopafter backfill_start=False, backfill=False, latethrough=True, tz='CET' ) cerebro.resampledata(data_c, timeframe=bt.TimeFrame.Seconds, compression=1) cerebro.addstrategy(St) cerebro.run() # cerebro.plot(plotter=None, iplot=True) #Unfortunately I always get a lot of unneeded nformatio like platform Darwin, V 3.1.3, loaded modules, fonts if __name__ == '__main__': run()
Having changed the code above (based on your recommendation) now I see what data is there:
Server Version: 76 TWS Time at connection:20200702 22:27:13 CET 1, data_s,2020-07-02T22:27:14,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:27:14,1.06,1.06,1.06,1.06,0.00 2, data_s,2020-07-02T22:27:14,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:27:22,1.06,1.06,1.06,1.06,0.00 3, data_s,2020-07-02T22:27:31,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:27:22,1.06,1.06,1.06,1.06,0.00 4, data_s,2020-07-02T22:27:31,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:28:57,1.06,1.06,1.06,1.06,0.00 5, data_s,2020-07-02T22:28:58,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:28:57,1.06,1.06,1.06,1.06,0.00 6, data_s,2020-07-02T22:29:01,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:01,1.06,1.06,1.06,1.06,0.00 7, data_s,2020-07-02T22:29:01,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:08,1.06,1.06,1.06,1.06,0.00 8, data_s,2020-07-02T22:29:01,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:10,1.06,1.06,1.06,1.06,0.00 9, data_s,2020-07-02T22:29:01,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:14,1.06,1.06,1.06,1.06,0.00 10, data_s,2020-07-02T22:29:21,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:14,1.06,1.06,1.06,1.06,0.00 11, data_s,2020-07-02T22:29:21,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:25,1.06,1.06,1.06,1.06,0.00 12, data_s,2020-07-02T22:29:29,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:25,1.06,1.06,1.06,1.06,0.00 13, data_s,2020-07-02T22:29:37,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:29:25,1.06,1.06,1.06,1.06,0.00 14, data_s,2020-07-02T22:30:02,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:30:02,1.06,1.06,1.06,1.06,0.00 15, data_s,2020-07-02T22:30:02,1.12,1.12,1.12,1.12,0.00, data_c,2020-07-02T22:30:07,1.06,1.06,1.06,1.06,0.00
data_s is the 1st feed EUR.USD
data_c is the 2nd feed CHF.USDAs an outlook this is getting more interesting when displaying a stock and the corresponding option(s).
It needs to be improved as I am using for the resampling the compression=1. Not always there is data. Increasing the compression to 10 could be a workaround. Even better when i leav it empty For now I can go ahead.
My question is answered and solved so that i can go ahead. Thank you very much vladisld.