Backtrader Community

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

    How to process data on CFD (Live IB)

    General Code/Help
    2
    12
    3828
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • ealvarpe
      ealvarpe last edited by

      I´m trying to process data from IB on CFD products, but I can´t get it done.
      Basically, the same code if I try to process "SPY-STK-SMART-USD" works correctly. But when I set the security to "IBUS500-CFD-SMART" doesn´t get any data processed.
      Any ideas? (I have the last version of backtrader - 1.9.40.116 - that I think has the support for CFD´s)

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import datetime
      import backtrader as bt
      from http.cookiejar import _debug
      
      
      # Create a Stratey
      class IBFwkLive(bt.Strategy):
      
          def __init__(self):
              self.datastatus = 0
              self.orderid = list()
              
          def notify_data(self, data, status, *args, **kwargs):
              print('*' * 5, 'DATA NOTIF:', data._getstatusname(status), *args)
              if status == data.LIVE:
                  self.datastatus = 1
      
          def notify_store(self, msg, *args, **kwargs):
              print('*' * 5, 'STORE NOTIF:', msg)
      
          def notify_order(self, order):
              if order.status in [order.Completed, order.Cancelled, order.Rejected]:
                  self.order = None
      
              print('-' * 50, 'ORDER BEGIN', datetime.datetime.now())
              print(order)
              print('-' * 50, 'ORDER END')
      
          def notify_trade(self, trade):
              print('-' * 50, 'TRADE BEGIN', datetime.datetime.now())
              print(trade)
              print('-' * 50, 'TRADE END')
      
          def prenext(self):
              self.next(frompre=True)               
              
              
          def next(self, frompre=False):
              
              txt = list()
              txt.append('Data0')
              txt.append('%04d' % len(self.data0))
              dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
              txt.append('{}'.format(self.data.datetime[0]))
              txt.append('%s' % self.data.datetime.datetime(0).strftime(dtfmt))
              txt.append('{}'.format(self.data.open[0]))
              txt.append('{}'.format(self.data.high[0]))
              txt.append('{}'.format(self.data.low[0]))
              txt.append('{}'.format(self.data.close[0]))
              print(', '.join(txt))
      
              if len(self.datas) > 1 and len(self.data1):
                  txt = list()
                  txt.append('Data1')
                  txt.append('%04d' % len(self.data1))
                  dtfmt = '%Y-%m-%dT%H:%M:%S.%f'
                  txt.append('{}'.format(self.data1.datetime[0]))
                  txt.append('%s' % self.data1.datetime.datetime(0).strftime(dtfmt))
                  txt.append('{}'.format(self.data1.open[0]))
                  txt.append('{}'.format(self.data1.high[0]))
                  txt.append('{}'.format(self.data1.low[0]))
                  txt.append('{}'.format(self.data1.close[0]))
                  print(', '.join(txt)) 
      
          def start(self):
              if self.data0.contractdetails is not None:
                  print('Timezone from ContractDetails: {}'.format(
                        self.data0.contractdetails.m_timeZoneId))
      
              header = ['Datetime', 'Open', 'High', 'Low', 'Close']
              print(', '.join(header))
      
              self.done = False
              
      if __name__ == '__main__':
      
          cerebro = bt.Cerebro()
          
          storekwargs = dict(
              host='127.0.0.1', port=7496,
              clientId=None, reconnect=100, timeout=3.0, _debug=False)
          ibstore = bt.stores.IBStore(**storekwargs)
          broker = ibstore.getbroker()
          cerebro.setbroker(broker)
          
          
          datakwargs = dict(
              timeframe=bt.TimeFrame.Ticks, compression=1,
              rtbar=False,
              what='BID')
          #data0 = ibstore.getdata(dataname='SPY-STK-SMART-USD', **datakwargs)
          data0 = ibstore.getdata(dataname='IBUS500-CFD-SMART', **datakwargs)
          cerebro.replaydata(data0, timeframe=bt.TimeFrame.Days, compression=1)
      
          cerebro.addstrategy(IBFwkLive)
          cerebro.run(exactbars=1)
      
      
      1 Reply Last reply Reply Quote 0
      • B
        backtrader administrators last edited by

        The code contains notify_store and notify_data, both of which produce a print out. It might be helpful to understand why that data isn't coming through.

        Giving the same symbol to the ibtestsample in the source can also help. For example:

        $ ./ibtest.py --data0 IBUS500-CFD-SMART --resample --timeframe Seconds --compression 5 --debug
        
        1 Reply Last reply Reply Quote 0
        • ealvarpe
          ealvarpe last edited by

          I´ve tried to do a debug an the only thing I receive is

          ***** STORE NOTIF: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
          ***** DATA NOTIF: DELAYED
          <tickPrice tickerId=16777217, field=9, price=2357.0, canAutoExecute=0>
          <tickPrice tickerId=16777217, field=1, price=-1.0, canAutoExecute=1>
          <tickSize tickerId=16777217, field=0, size=0>
          <tickPrice tickerId=16777217, field=2, price=-1.0, canAutoExecute=1>
          <tickSize tickerId=16777217, field=3, size=0>
          

          but the data never get processed. Is like if the next() method never gets called. Also it seems like with CFD I cannot backfill data, is it like this?
          Instead, when I try to use the same code for SPY it works and receive backfill data and gets Live.

          1 Reply Last reply Reply Quote 0
          • B
            backtrader administrators last edited by backtrader

            You may still run the sample as pointed out above and post the output from the beginning, (obviously you would want to blank your account number) where things like the actually retrieved contract (if any) is shown in the debug messages.

            1 Reply Last reply Reply Quote 0
            • ealvarpe
              ealvarpe last edited by

              I´ve run the example with this output

              Server Version: 76
              TWS Time at connection:20170411 01:17:04 Greenwich Mean Time
              <managedAccounts accountsList=XXXXX>
              <nextValidId orderId=1>
              <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm>
              <currentTime time=1491869824>
              <contractDetails reqId=16711216, contractDetails=<ib.ext.ContractDetails.ContractDetails object at 0x000001CA8F005630>>
              <contractDetailsEnd reqId=16711216>
              --------------------------------------------------
              Strategy Created
              --------------------------------------------------
              Timezone from ContractDetails: GB
              Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA
              ***** STORE NOTIF: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:usfarm>
              ***** DATA NOTIF: DELAYED
              <error id=-1, errorCode=2119, errorMsg=Market data farm is connecting:eufarm>
              ***** STORE NOTIF: <error id=-1, errorCode=2119, errorMsg=Market data farm is connecting:eufarm>
              <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
              ***** STORE NOTIF: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
              <tickPrice tickerId=16777217, field=9, price=2357.0, canAutoExecute=0>
              <tickPrice tickerId=16777217, field=1, price=-1.0, canAutoExecute=1>
              <tickSize tickerId=16777217, field=0, size=0>
              <tickPrice tickerId=16777217, field=2, price=-1.0, canAutoExecute=1>
              <tickSize tickerId=16777217, field=3, size=0>
              

              But as the market is now close for the CFD´s, not sure if I can expect something else. I´ll try again tomorrow during the open market.

              1 Reply Last reply Reply Quote 0
              • ealvarpe
                ealvarpe last edited by

                I can see the tick prices are coming, but next() is never called within the strategy
                Nether the autofilling seems to work
                But when trying with, for example "SPY-STK-SMART-USD" works perfectly...

                Server Version: 76
                TWS Time at connection:20170411 19:30:55 Greenwich Mean Time
                <managedAccounts accountsList=XXXXXX>
                <nextValidId orderId=1>
                <currentTime time=1491935455>
                <contractDetails reqId=16777216, contractDetails=<ib.ext.ContractDetails.ContractDetails object at 0x00000280E3ED55F8>>
                <contractDetailsEnd reqId=16777216>
                --------------------------------------------------
                Strategy Created
                --------------------------------------------------
                Timezone from ContractDetails: GB
                Datetime, Open, High, Low, Close, Volume, OpenInterest, SMA
                ***** DATA NOTIF: DELAYED
                <error id=-1, errorCode=2119, errorMsg=Market data farm is connecting:eufarm>
                ***** STORE NOTIF: <error id=-1, errorCode=2119, errorMsg=Market data farm is connecting:eufarm>
                <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
                ***** STORE NOTIF: <error id=-1, errorCode=2104, errorMsg=Market data farm connection is OK:eufarm>
                <tickPrice tickerId=16777217, field=9, price=2357.13, canAutoExecute=0>
                <tickPrice tickerId=16777217, field=1, price=2350.23, canAutoExecute=1>
                <tickSize tickerId=16777217, field=0, size=300>
                <tickPrice tickerId=16777217, field=2, price=2350.48, canAutoExecute=1>
                <tickSize tickerId=16777217, field=3, size=300>
                <tickSize tickerId=16777217, field=0, size=300>
                <tickSize tickerId=16777217, field=3, size=300>
                <tickPrice tickerId=16777217, field=1, price=2349.98, canAutoExecute=1>
                <tickSize tickerId=16777217, field=0, size=300>
                <tickPrice tickerId=16777217, field=2, price=2350.23, canAutoExecute=1>
                <tickSize tickerId=16777217, field=3, size=300>
                <tickPrice tickerId=16777217, field=1, price=2350.23, canAutoExecute=1>
                <tickSize tickerId=16777217, field=0, size=300>
                <tickPrice tickerId=16777217, field=2, price=2350.48, canAutoExecute=1>
                <tickSize tickerId=16777217, field=3, size=300>
                <tickPrice tickerId=16777217, field=1, price=2349.98, canAutoExecute=1>
                <tickSize tickerId=16777217, field=0, size=300>
                <tickPrice tickerId=16777217, field=2, price=2350.23, canAutoExecute=1>
                <tickSize tickerId=16777217, field=3, size=300>
                1 Reply Last reply Reply Quote 0
                • B
                  backtrader administrators last edited by

                  STK and CFD are two different type of assets. How to handle requests for STK is well known with several examples and samples.

                  CFD is in comparison a recent addition to the Interactive Brokers product line and there is no indication (at least not one that has been found) as to how to manage the assets (No, IB API Reference doesn't help either).

                  @skytrading54 reported (Community - Anyone using Backtrader for live trading) the lack of support and some code was added to 1st parse the contract specification and 2nd to try to request the prices, which according to the input in the thread had to be handled as a CASH asset.

                  There were no further reports about it not working. But further inspection of the code could have the CFD processing missing in one point.

                  In any case and because the OandaBroker also needed a patch, release 1.9.41.116 contains a commit to also managed CFD as cash during rqmMktData.

                  You can install this release and give it a try.

                  1 Reply Last reply Reply Quote 0
                  • ealvarpe
                    ealvarpe last edited by

                    Unfortunately no luck with the last version. Same behaviour: it receive the ticks, but next() is never called.
                    I´ll update the thread if I found the reason.

                    1 Reply Last reply Reply Quote 0
                    • ealvarpe
                      ealvarpe last edited by

                      ok, it works. Seems that I was not working with the last version as I thought.
                      The problem I see with CFD's is that for Index CFD's (like IBUS500) works as IB is providing market data.

                      But with stock CFD's (like SPY-CFD-SMART) doesn't. The IB system defers to the underlying (SPY-STK-SMART-USD).
                      One tricky way to make it work is to add the datafeed from the underlying and only before buying or selling any amount, change the contract by the CFD one. With this, all your algorithm can relay on the STK and have the leverage power of CFD's when really accessing the market.

                      1 Reply Last reply Reply Quote 0
                      • B
                        backtrader administrators last edited by backtrader

                        Good to know. The Visual Chart data feed meant for trading has the following parameter

                              - ``tradename`` (default: ``None``)
                                Continous futures cannot be traded but are ideal for data tracking. If
                                this parameter is supplied it will be the name of the current future
                                which will be the trading asset. Example:
                        
                                - 001ES -> ES-Mini continuous supplied as ``dataname``
                        
                                - ESU16 -> ES-Mini 2016-09. If this is supplied in ``tradename`` it
                                  will be the trading asset.
                        

                        A similar approach could be thought of for the CFD case described above. Let's confirm the use case:

                        • dataname would be SPY-STK-SMART-USD, which is used for data tracking

                        • tradename would be SPY-CFD-SMART, which is used for trading operations

                        Hopefully this is what you described above

                        1 Reply Last reply Reply Quote 1
                        • ealvarpe
                          ealvarpe last edited by

                          yes, it´s exactly that.

                          1 Reply Last reply Reply Quote 0
                          • B
                            backtrader administrators last edited by

                            Available with this commit in the development branch: https://github.com/mementum/backtrader/commit/aba90a3ff4e115e3373ea15389410adf10f2b4cf

                            The regular IB functionality doesn't seem broken by these changes.

                            1 Reply Last reply Reply Quote 0
                            • 1 / 1
                            • First post
                              Last post
                            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors