Navigation

    Backtrader Community

    • Register
    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    1. Home
    2. ElliotP
    For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
    E
    • Profile
    • Following 0
    • Followers 1
    • Topics 12
    • Posts 31
    • Best 1
    • Groups 0

    ElliotP

    @ElliotP

    1
    Reputation
    515
    Profile views
    31
    Posts
    1
    Followers
    0
    Following
    Joined Last Online

    ElliotP Unfollow Follow

    Best posts made by ElliotP

    • RE: Live Trading Referencing Static Value

      After some more working on it, I feel I am close to working through the problem (just have to wait for markets to open again on sunday night). When I run my latest script, I receive this error:

      TWS Time at connection:20190111 15:00:43 EST
      Traceback (most recent call last):
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 222, in <module>
          run()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 219, in run
          cerebro.run()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
      2018-12-12 AAPL-STK-SMART-USD
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1298, in runstrategies
      not pos
          self._runnext(runstrats)
      tradetoday finish
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1630, in _runnext
          strat._next()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\strategy.py", line 325, in _next
          super(Strategy, self)._next()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\lineiterator.py", line 270, in _next
          self.prenext()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 110, in prenext
          self.next()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 116, in next
          pos = self.getposition(d).size
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\strategy.py", line 1366, in getposition
          return broker.getposition(data)
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\brokers\ibbroker.py", line 306, in getposition
          return self.ib.getposition(data.tradecontract, clone=clone)
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\lineseries.py", line 461, in __getattr__
          return getattr(self.lines, name)
      AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'tradecontract'
      

      So it is able to recognise the first datafeed, but is unable to recognize the second datafeed's name and date, this I am not sure how to solve. I might try cleaning up that file as so it only has one of each date, sorted, etc.

      My latest script:

      import datetime
      import backtrader as bt
      from http.cookiejar import _debug
      from Functions.PandasData_Extend import PandasData_Extend
      import pandas as pd
      import pytz
      
      # Create a Stratey
      class ADRLeader(bt.Strategy):
          StrategyInformation = dict(
              StrategyName='NextDayStrategyBinsS',
              Notes='US Leads AUS, BHP, Bin 0, Short| Freebandz',
              OrderExecutionType='Market',
              BuyLogic='%Bracket',
              SellLogic='%Bracket',
              DateRun=datetime.datetime.now(),
              DataGranularity='Day'
          )
      
          params = dict(
              ma=bt.ind.SMA,
              p1=5,
              p2=15,
              limit=0.005,
              limdays=1,
              limdays2=1,
              hold=1,
              usebracket=False,  # use order_target_size
              switchp1p2=False,  # switch prices of order1 and order2
              limu=0.005,
              limd=0.01,
              valid=1,
              when=bt.timer.SESSION_START,
              bin=0,
      
          )
      
          def __init__(self):
              self.add_timer(when=self.p.when)
              self.orefs = list()
              self.order = None
              self.o = dict()
              self.signal = self.datas[1].PercentileDailyPctChange
              self.tradetoday = 0
      
      
          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)
              return
      
          def notify_order(self, order):
              if order.status == order.Completed:
                  # self.holdstart = len(self)
                  # print('Order Completed')
                  # print(self.datas[0].datetime.datetime())
                  # print(order.price)
                  return
              if order.status == order.Accepted:
                  # print('Order Accepted')
                  return
              if not order.alive() and order.ref in self.orefs:
                  self.orefs.remove(order.ref)
              if order.isbuy():
                  if order.status == order.Submitted:
                      # print('Order Submitted BUY')
                      # print(order.price)
                      # print(str(order.price) + 'Order Buy Price')
                      return
              if order.issell():
                  if order.status == order.Submitted:
                      # print('Order Submitted SELL')
                      # print(order.price)
                      return
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  # print('tradeclosed')
                  # date = self.datas[0].datetime.datetime()
                  # print(self.datas[0].datetime.datetime())
                  # print(date, trade.pnl, trade.pnlcomm)
                  # tradetoday = (bt.num2date(trade.dtopen)).date()
                  # print(trade.ref)
                  # self.listforall.append(tradetoday)
                  # print('tradetoday')
                  # print(tradetoday)
                  self.tradetoday = 1
              if trade.isopen:
                  # print('tradeopen')
                  # date = self.datas[0].datetime.datetime()
                  # time = self.datas[0].datetime.time(0)
                  # print(date, trade.price)
                  return
      
          def notify_timer(self, timer, when):
              # print(str(when.time()) +' '+' juice')
              if when.time() == datetime.time(0,0):
                  # print('Its a new day')
                  # print(self.datas[0].datetime.datetime())
                  self.tradetoday = 0
              else:
                  # print('does not')
                  return
      
          def prenext(self):
              self.next()
      
          def next(self):
      
              for i, d in enumerate(self.datas):
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # print(AAPL-STK-SMART-USD)
                  print('{} {}'.format(dt, dn))
                  # print(i[0])
                  #Setting up the Not in Position
                  if i == 0:
                      pos = self.getposition(d).size
                      # print('position size start')
                      # print(pos)
                      # print('position size finish')
                  else:
                      pass
                  if pos == 0:
                      print('not pos')
                      #Setting up the If Not traded today
                      if not self.tradetoday == 1:
                          # print('tradetoday start')
                          # print(self.tradetoday)
                          print('tradetoday finish')
                          if (len(self.datas[i]) > 0):
                              # print(self.datetime.date())
                              #print(self.signal)
                              print('top')
                              # print(self.data0.Close)
                              print('bottom')
                              # print (self.data0.l.close[-1])
                              if d._dataname.PercentileDailyPctChange[+1] == 12:
                                  print('PercentileValue')
                                  print(d.datetime.datetime().isoformat())
                                  print(d._dataname.PercentileDailyPctChange[+1])
                                  print('PercentileValueFinish')
                                  if i == 0:
                                      print(d.close[0])
                                  # self.buy(data=d, )
      
                              elif i == 0:
                                  print('0')
                                  print('Currency Latest Close')
                                  print(self.datas[0].datetime.datetime().isoformat())
                                  print(d.close[0])
                                  print('Currency Latest Finish')
                              else:
                                  print('nope')
                                  return
      
      
      
                  else:
                      print('In Position')
                      return
              else:
                  print('no datasets coming in')
                  return
          def start(self):
              if self.data0.contractdetails is not None:
                  # print('yo')
                  # print('Timezone from ContractDetails: {}'.format(
                  #     self.data0.contractdetails.m_timeZoneId))
                  return
              header = ['Datetime', 'Open', 'High', 'Low', 'Close']
              # print(', '.join(header))
      
              self.done = False
      
      def run(args=None):
          cerebro = bt.Cerebro()
      
          storekwargs = dict(
              host='127.0.0.1', port=7496,
              clientId=None, reconnect=100, timeout=10.0, _debug=False)
          ibstore = bt.stores.IBStore(**storekwargs)
          broker = ibstore.getbroker()
          cerebro.setbroker(broker)
          # 'EUR.USD-CASH-IDEALPRO'
          # AAPL-STK-SMART-USD
          # , tradename='AAPL-CFD-SMART-USD'
          # , tradename = 'BHP-CFD-SMART-AUD'
          # BHP-STK-SMART-AUD
          data0 = ibstore.getdata(reqRealTimeBars=True, dataname='AAPL-STK-SMART-USD', rtbar=False,
                                  timeframe=bt.TimeFrame.Seconds, compression=1)
          # cerebro.resampledata(data0, timeframe=bt.TimeFrame.Seconds,
          #                      compression=3)
          cerebro.adddata(data0)
          # print('remix')
          # print(data0)
      
          # cerebro.adddata(data0, name='d0')
      
          StockPercentile = pd.read_csv(r'D:\Dropbox\Parker Magic Dropbox\Elliot Parker\Drums\QuantStrategyResults\AUSLeadsUSPercentile.csv',
                                        header=0, index_col=0, parse_dates=True)
          StockPercentile = StockPercentile[~StockPercentile.index.duplicated(keep='first')]
          StockPercentile = StockPercentile.sort_index(ascending=False)
          StockPercentile = pd.DataFrame(StockPercentile.iloc[:, :])
          # print(StockPercentile)
          data1 = PandasData_Extend(dataname=StockPercentile, timeframe=bt.TimeFrame.Days, compression=1)
          # cerebro.resampledata(data1)
          # cerebro.replaydata(data1)
          cerebro.adddata(data1)
      
          cerebro.addstrategy(ADRLeader)
          cerebro.run()
      
      if __name__ == '__main__':
          run()
      
      posted in General Code/Help
      E
      ElliotP

    Latest posts made by ElliotP

    • Struggling to consistently backfill

      Evening,

      I have read the documentation and the forums exhaustively but I'm struggling to come up with an answer. When I start some of the strategies they permanently hang on "Data Delayed" after the initial successful connection to IB live servers. So it will receive the TWS Successfull connection and then print a "Data Delayed" which I have in the Notify Order function; but it won't progress onto the next function.

      data0 = ibstore.getdata(reqRealTimeBars=True, dataname='BHP-STK-SMART-AUD', rtbar=False,
                                  timeframe=bt.TimeFrame.Seconds, compression=1, tradename ='BHP-CFD-SMART-AUD',
                                  useRTH=True, fromdate=datetime.datetime.now(pytz.timezone('Australia/Sydney')).date(),
                                  backfill=False)
          cerebro.resampledata(data0, timeframe=bt.TimeFrame.Seconds,
                               compression=5)
      

      The asx commences trading in rolling window periods by the alphabetical first letter of the stock's symbol, so some stocks will begin trading at 9.59am while some will not begin trading until 10.09am. With the larger securities, it seems to be much more consistent as I suspect there is a trade to hook in-to.

      Some slightly smaller companies but still very liquid are often the ones to cause problems. So if the Stock were to open at 10.04am, I set the script to begin at 10.04am or 10.04.15am or 10.04.30am sometimes it will work, sometimes it won't.

      I understand Data Delayed is backfilling in progress, but when multiple different stocks will just sit at the initial connection text with the status "Data Delayed" i feel it isn't stuck on backfilling. This also makes it hard to debug as I'm unable to see any of the "debug=True" text, but in the past this hasn't indicated any issues.

      I have tried varying the qcheck value and my only other remaining ideas are to begin the start of the script later and hope to catch a trade or perhaps change the compression to a minute?

      posted in General Code/Help
      E
      ElliotP
    • Debugging Live IB Trading

      Morning everyone,

      I am in the process of debugging some strategies on a paper account with Interactive Brokers and I keep hitting a snag.

      For some reason when I start the script, it will stay permanently at "Data Delayed". The docs indicate this is when the backfilling occurs and since I'm asking for Realtimebars I realize there are 5 seconds worth of data which need to be filled. The securities I'm trading are quite liquid and I can see trades being executed in the order book.

      I have read about qcheck but as I have played with that I haven't been able to find a working solution. At the moment the best solution I have found is to start the script as the market opens or a few seconds after which isn't ideal for this strategy.

      If someone could point me in the right direction, I'm a little out of ideas after reading the docs & threads.

      https://www.backtrader.com/blog/posts/2016-06-21-livedata-feed/live-data-feed.html

      I will post some debug logs, etc later when it occurs again.

      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      After some more working on it, I feel I am close to working through the problem (just have to wait for markets to open again on sunday night). When I run my latest script, I receive this error:

      TWS Time at connection:20190111 15:00:43 EST
      Traceback (most recent call last):
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 222, in <module>
          run()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 219, in run
          cerebro.run()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
      2018-12-12 AAPL-STK-SMART-USD
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1298, in runstrategies
      not pos
          self._runnext(runstrats)
      tradetoday finish
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\cerebro.py", line 1630, in _runnext
          strat._next()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\strategy.py", line 325, in _next
          super(Strategy, self)._next()
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\lineiterator.py", line 270, in _next
          self.prenext()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 110, in prenext
          self.next()
        File "D:/Dropbox/Parker Magic Dropbox/Elliot Parker/Drums/QuantStrategyProjectFiles/__init__ (1) (1) (1).py", line 116, in next
          pos = self.getposition(d).size
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\strategy.py", line 1366, in getposition
          return broker.getposition(data)
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\brokers\ibbroker.py", line 306, in getposition
          return self.ib.getposition(data.tradecontract, clone=clone)
        File "C:\Users\Elliot Parker\Anaconda3\lib\site-packages\backtrader\lineseries.py", line 461, in __getattr__
          return getattr(self.lines, name)
      AttributeError: 'Lines_LineSeries_DataSeries_OHLC_OHLCDateTime_Abst' object has no attribute 'tradecontract'
      

      So it is able to recognise the first datafeed, but is unable to recognize the second datafeed's name and date, this I am not sure how to solve. I might try cleaning up that file as so it only has one of each date, sorted, etc.

      My latest script:

      import datetime
      import backtrader as bt
      from http.cookiejar import _debug
      from Functions.PandasData_Extend import PandasData_Extend
      import pandas as pd
      import pytz
      
      # Create a Stratey
      class ADRLeader(bt.Strategy):
          StrategyInformation = dict(
              StrategyName='NextDayStrategyBinsS',
              Notes='US Leads AUS, BHP, Bin 0, Short| Freebandz',
              OrderExecutionType='Market',
              BuyLogic='%Bracket',
              SellLogic='%Bracket',
              DateRun=datetime.datetime.now(),
              DataGranularity='Day'
          )
      
          params = dict(
              ma=bt.ind.SMA,
              p1=5,
              p2=15,
              limit=0.005,
              limdays=1,
              limdays2=1,
              hold=1,
              usebracket=False,  # use order_target_size
              switchp1p2=False,  # switch prices of order1 and order2
              limu=0.005,
              limd=0.01,
              valid=1,
              when=bt.timer.SESSION_START,
              bin=0,
      
          )
      
          def __init__(self):
              self.add_timer(when=self.p.when)
              self.orefs = list()
              self.order = None
              self.o = dict()
              self.signal = self.datas[1].PercentileDailyPctChange
              self.tradetoday = 0
      
      
          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)
              return
      
          def notify_order(self, order):
              if order.status == order.Completed:
                  # self.holdstart = len(self)
                  # print('Order Completed')
                  # print(self.datas[0].datetime.datetime())
                  # print(order.price)
                  return
              if order.status == order.Accepted:
                  # print('Order Accepted')
                  return
              if not order.alive() and order.ref in self.orefs:
                  self.orefs.remove(order.ref)
              if order.isbuy():
                  if order.status == order.Submitted:
                      # print('Order Submitted BUY')
                      # print(order.price)
                      # print(str(order.price) + 'Order Buy Price')
                      return
              if order.issell():
                  if order.status == order.Submitted:
                      # print('Order Submitted SELL')
                      # print(order.price)
                      return
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  # print('tradeclosed')
                  # date = self.datas[0].datetime.datetime()
                  # print(self.datas[0].datetime.datetime())
                  # print(date, trade.pnl, trade.pnlcomm)
                  # tradetoday = (bt.num2date(trade.dtopen)).date()
                  # print(trade.ref)
                  # self.listforall.append(tradetoday)
                  # print('tradetoday')
                  # print(tradetoday)
                  self.tradetoday = 1
              if trade.isopen:
                  # print('tradeopen')
                  # date = self.datas[0].datetime.datetime()
                  # time = self.datas[0].datetime.time(0)
                  # print(date, trade.price)
                  return
      
          def notify_timer(self, timer, when):
              # print(str(when.time()) +' '+' juice')
              if when.time() == datetime.time(0,0):
                  # print('Its a new day')
                  # print(self.datas[0].datetime.datetime())
                  self.tradetoday = 0
              else:
                  # print('does not')
                  return
      
          def prenext(self):
              self.next()
      
          def next(self):
      
              for i, d in enumerate(self.datas):
                  dt, dn = self.datetime.date(), d._name
                  pos = self.getposition(d).size
                  # print(AAPL-STK-SMART-USD)
                  print('{} {}'.format(dt, dn))
                  # print(i[0])
                  #Setting up the Not in Position
                  if i == 0:
                      pos = self.getposition(d).size
                      # print('position size start')
                      # print(pos)
                      # print('position size finish')
                  else:
                      pass
                  if pos == 0:
                      print('not pos')
                      #Setting up the If Not traded today
                      if not self.tradetoday == 1:
                          # print('tradetoday start')
                          # print(self.tradetoday)
                          print('tradetoday finish')
                          if (len(self.datas[i]) > 0):
                              # print(self.datetime.date())
                              #print(self.signal)
                              print('top')
                              # print(self.data0.Close)
                              print('bottom')
                              # print (self.data0.l.close[-1])
                              if d._dataname.PercentileDailyPctChange[+1] == 12:
                                  print('PercentileValue')
                                  print(d.datetime.datetime().isoformat())
                                  print(d._dataname.PercentileDailyPctChange[+1])
                                  print('PercentileValueFinish')
                                  if i == 0:
                                      print(d.close[0])
                                  # self.buy(data=d, )
      
                              elif i == 0:
                                  print('0')
                                  print('Currency Latest Close')
                                  print(self.datas[0].datetime.datetime().isoformat())
                                  print(d.close[0])
                                  print('Currency Latest Finish')
                              else:
                                  print('nope')
                                  return
      
      
      
                  else:
                      print('In Position')
                      return
              else:
                  print('no datasets coming in')
                  return
          def start(self):
              if self.data0.contractdetails is not None:
                  # print('yo')
                  # print('Timezone from ContractDetails: {}'.format(
                  #     self.data0.contractdetails.m_timeZoneId))
                  return
              header = ['Datetime', 'Open', 'High', 'Low', 'Close']
              # print(', '.join(header))
      
              self.done = False
      
      def run(args=None):
          cerebro = bt.Cerebro()
      
          storekwargs = dict(
              host='127.0.0.1', port=7496,
              clientId=None, reconnect=100, timeout=10.0, _debug=False)
          ibstore = bt.stores.IBStore(**storekwargs)
          broker = ibstore.getbroker()
          cerebro.setbroker(broker)
          # 'EUR.USD-CASH-IDEALPRO'
          # AAPL-STK-SMART-USD
          # , tradename='AAPL-CFD-SMART-USD'
          # , tradename = 'BHP-CFD-SMART-AUD'
          # BHP-STK-SMART-AUD
          data0 = ibstore.getdata(reqRealTimeBars=True, dataname='AAPL-STK-SMART-USD', rtbar=False,
                                  timeframe=bt.TimeFrame.Seconds, compression=1)
          # cerebro.resampledata(data0, timeframe=bt.TimeFrame.Seconds,
          #                      compression=3)
          cerebro.adddata(data0)
          # print('remix')
          # print(data0)
      
          # cerebro.adddata(data0, name='d0')
      
          StockPercentile = pd.read_csv(r'D:\Dropbox\Parker Magic Dropbox\Elliot Parker\Drums\QuantStrategyResults\AUSLeadsUSPercentile.csv',
                                        header=0, index_col=0, parse_dates=True)
          StockPercentile = StockPercentile[~StockPercentile.index.duplicated(keep='first')]
          StockPercentile = StockPercentile.sort_index(ascending=False)
          StockPercentile = pd.DataFrame(StockPercentile.iloc[:, :])
          # print(StockPercentile)
          data1 = PandasData_Extend(dataname=StockPercentile, timeframe=bt.TimeFrame.Days, compression=1)
          # cerebro.resampledata(data1)
          # cerebro.replaydata(data1)
          cerebro.adddata(data1)
      
          cerebro.addstrategy(ADRLeader)
          cerebro.run()
      
      if __name__ == '__main__':
          run()
      
      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      I have made some progress, but I have hit a new snag.

      I am adding into the strategy the signals/etc, as in I would like to do

      if self.datas[1].PercentilePctChange[+1] == 12:
      
      os = self.buy_bracket(data=d, size=200, limitprice=limuLMT, limitargs=dict(valid=0),
                  price=closeslip, valid=0,
                  stopprice=limdSTP, stopargs=dict(valid=0),
                  )
                  self.orefs = [o.ref for o in os]
      

      [tried to do the above in the code block but it didn't seem to want to work]

      But at the moment I am unable to access the values from the two different data feeds. I have tried quite a few combinations, read the forums, the documentation and googled and I can't seem to work out to access a value from data1, but trade the values from data0.

      I have seen in the examples that you are just able to reference d, but I am not sure how it knows which data feed specifically to trade off. For the moment I am stuck in that I am able to retrieve the value when I specify an if function and i==1, but form here I am unable to access the values from data0.

      Here is a link to my latest bit of code:

      import datetime
      import backtrader as bt
      from http.cookiejar import _debug
      from Functions.PandasData_Extend import PandasData_Extend
      import pandas as pd
      import pytz
      
      # Create a Stratey
      class ADRLeader(bt.Strategy):
          StrategyInformation = dict(
              StrategyName='NextDayStrategyBinsS',
              Notes='US Leads AUS, BHP, Bin 0, Short| Freebandz',
              OrderExecutionType='Market',
              BuyLogic='%Bracket',
              SellLogic='%Bracket',
              DateRun=datetime.datetime.now(),
              DataGranularity='Day'
          )
      
          params = dict(
              ma=bt.ind.SMA,
              p1=5,
              p2=15,
              limit=0.005,
              limdays=1,
              limdays2=1,
              hold=1,
              usebracket=False,  # use order_target_size
              switchp1p2=False,  # switch prices of order1 and order2
              limu=0.005,
              limd=0.01,
              valid=1,
              when=bt.timer.SESSION_START,
              bin=0,
      
          )
      
          def __init__(self):
              self.add_timer(when=self.p.when)
              self.orefs = list()
              self.order = None
              self.o = dict()
              self.signal = self.datas[1].PercentileDailyPctChange
      
      
          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)
              return
      
          def notify_order(self, order):
              if order.status == order.Completed:
                  # self.holdstart = len(self)
                  # print('Order Completed')
                  # print(self.datas[0].datetime.datetime())
                  # print(order.price)
                  return
              if order.status == order.Accepted:
                  # print('Order Accepted')
                  return
              if not order.alive() and order.ref in self.orefs:
                  self.orefs.remove(order.ref)
              if order.isbuy():
                  if order.status == order.Submitted:
                      # print('Order Submitted BUY')
                      # print(order.price)
                      # print(str(order.price) + 'Order Buy Price')
                      return
              if order.issell():
                  if order.status == order.Submitted:
                      # print('Order Submitted SELL')
                      # print(order.price)
                      return
      
          def notify_trade(self, trade):
              if trade.isclosed:
                  # print('tradeclosed')
                  # date = self.datas[0].datetime.datetime()
                  # print(self.datas[0].datetime.datetime())
                  # print(date, trade.pnl, trade.pnlcomm)
                  # tradetoday = (bt.num2date(trade.dtopen)).date()
                  # print(trade.ref)
                  # self.listforall.append(tradetoday)
                  # print('tradetoday')
                  # print(tradetoday)
                  self.tradetoday = 1
              if trade.isopen:
                  # print('tradeopen')
                  # date = self.datas[0].datetime.datetime()
                  # time = self.datas[0].datetime.time(0)
                  # print(date, trade.price)
                  return
      
          def notify_timer(self, timer, when):
              # print(str(when.time()) +' '+' juice')
              if when.time() == datetime.time(0,0):
                  # print('Its a new day')
                  # print(self.datas[0].datetime.datetime())
                  self.tradetoday = 0
              else:
                  # print('does not')
                  return
      
          def prenext(self):
              self.next()
      
          def next(self):
      
              for i, d in enumerate(self.datas):
                  #Setting up the Not in Position
                  if i == 0:
                      pos = self.getposition(d).size
                      # print('position size start')
                      # print(pos)
                      # print('position size finish')
                  else:
                      pass
                  if pos == 0:
                      # print('not pos')
                      #Setting up the If Not traded today
                      if not self.tradetoday == 1:
                          # print('tradetoday start')
                          # print(self.tradetoday)
                          # print('tradetoday finish')
                          if (len(self.datas[i]) > 0):
                              # print(self.datetime.date())
                              print(self.signal[+1])
                              if d._dataname.PercentileDailyPctChange[+1] == 12:
                                  # print('1')
                                  print('PercentileValue')
                                  print(d.datetime.datetime().isoformat())
                                  print(d._dataname.PercentileDailyPctChange[+1])
                                  print('PercentileValueFinish')
      
                                  # self.buy(data=d, )
      
                              elif i == 0:
                                  print('0')
                                  print('Currency Latest Close')
                                  print(self.datas[0].datetime.datetime().isoformat())
                                  print(d.close[0])
                                  print('Currency Latest Finish')
                              else:
                                  print('nope')
                                  pass
                  else:
                      print('In Position')
                      pass
              else:
                  print('no datasets coming in')
                  pass
          def start(self):
              if self.data0.contractdetails is not None:
                  # print('Timezone from ContractDetails: {}'.format(
                  #     self.data0.contractdetails.m_timeZoneId))
                  return
              header = ['Datetime', 'Open', 'High', 'Low', 'Close']
              # print(', '.join(header))
      
              self.done = False
      
      def run(args=None):
          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)
          # 'EUR.USD-CASH-IDEALPRO'
          # AAPL - STK - SMART - USD
          # , tradename='AAPL-CFD-SMART-USD'
          # , tradename = 'BHP-CFD-SMART-AUD'
          # BHP-STK-SMART-AUD
          data0 = ibstore.getdata(reqRealTimeBars=True, dataname='AMP-STK-SMART-AUD', rtbar=False,
                                  timeframe=bt.TimeFrame.Seconds, compression=1)
          cerebro.resampledata(data0, timeframe=bt.TimeFrame.Seconds,
                               compression=3)
          # cerebro.adddata(data0)
          # print('remix')
          # print(data0)
      
          # cerebro.adddata(data0, name='d0')
      
          StockPercentile = pd.read_csv(r'removed',
                                        header=0, index_col=0, parse_dates=True)
          StockPercentile = StockPercentile[~StockPercentile.index.duplicated(keep='first')]
          StockPercentile = StockPercentile.sort_index(ascending=False)
          StockPercentile = pd.DataFrame(StockPercentile.iloc[:, :])
          # print(StockPercentile)
          data1 = PandasData_Extend(dataname=StockPercentile, timeframe=bt.TimeFrame.Days, compression=1)
          cerebro.resampledata(data1)
          # cerebro.replaydata(data1)
          cerebro.adddata(data1)
      
          cerebro.addstrategy(ADRLeader)
          cerebro.run()
      
      if __name__ == '__main__':
          run()
      
      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      @kdulep messaged, thank you, will test.

      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      @backtrader Thanks for the response; sorry for the delay.

      The csv file was populated with values from a python script. The dates are in the australian format in case the error is you are concerned 15 might not be a valid month.

      An idea would be to include 00:00:00 after each date, I will try that.

      I was going to remove the repeated dates from the csv when it was referenced by the live strategy, but I can easily ensure that the file always only has unique date values.

      The idea was to reference values from the past from the live strategy, as so the live data would reference the value from the day before, as such dates in the past.

      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      Any ideas I am still a little bit lost?

      posted in General Code/Help
      E
      ElliotP
    • RE: Live Trading Referencing Static Value

      I have gone through and worked out that I needed to add a second data feed.

      def run(args=None):
          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)
      
          data0 = ibstore.getdata(reqRealTimeBars=True, dataname='AAPL-STK-SMART-USD', rtbar=False, what='BID',
                                  timeframe=bt.TimeFrame.Seconds, compression=1, tradename='AAPL-CFD-SMART-USD')
          cerebro.resampledata(data0, timeframe=bt.TimeFrame.Seconds,
                               compression=10)
          # print('remix')
          # print(data0)
      
          # cerebro.adddata(data0, name='d0')
      
          StockPercentile = pd.read_csv(r'C:\Users\Elliot Parker\Dropbox\Drums\QuantStrategyResults\AUSLeadsUSPercentile.csv',
                                        header=0, index_col=0, parse_dates=True)
          StockPercentile = StockPercentile[~StockPercentile.index.duplicated(keep='first')]
          StockPercentile = StockPercentile.sort_index(ascending=False)
          StockPercentile = pd.DataFrame(StockPercentile.iloc[:, :])
          data1 = PandasData_Extend(dataname=StockPercentile, timeframe=bt.TimeFrame.Days, compression=1)
          cerebro.resampledata(data1)
      

      So, I now have two data feeds. The live data feed "data0" and the daily data from my csv "data1".

      When I attempt to run:

      class IBFwkLive(bt.Strategy):
      
          def __init__(self):
              self.datastatus = 0
              self.orderid = list()
              self.data_minute = self.data0
              self.data_daily = self.data1
              # self.close0 = self.datas[0].close
              # self.close1 = self.datas[1].close
              # self.PercentileDailyPctChange = self.datas[1].PercentileDailyPctChange
              # self.open = self.datas[1].open
      
          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)
              return
          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')
              return
          def prenext(self):
              self.next(frompre=False)
      
          def next(self, frompre=False):
              for i, d in enumerate(self.datas):
                  txt = []
                  txt.append('%04d' % len(d))
                  txt.append('Data_%d' % i)
                  print(len(self.data_minute))
                  # txt.append(d.PercentileDailyPctChange[0])
                  if i == 1:
                      txt.append(d.datetime.datetime().isoformat())
                      # txt.append(str(d.PercentileDailyPctChange[0]))
                      # txt.append(str(d.open[0]))
                      # txt.append(str(d.high[0]))
                      # txt.append(str(d.low[0]))
                      # txt.append(str(self.close1[0]))
                      # txt.append(str(d.volume[0]))
                      # txt.append(str(d.openinterest[0]))
                      # txt.append(str(d.PercentileDailyPctChange[0]))
                  else:
                      txt.append(d.datetime.datetime().isoformat())
                      txt.append(str(d.high[0]) + str('movingapack'))
                  # txt.append(d.datetime.datetime().isoformat())
                  # txt.append('%.4f' % d.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))
                  return
              header = ['Datetime', 'Open', 'High', 'Low', 'Close']
              # print(', '.join(header))
      
              self.done = False
      

      The "PercentileDailyPctChange" column is a column from "data1" which I added to the lines using:

      import backtrader as bt
      
      class PandasData_Extend(bt.feeds.PandasData):
          lines = ('SPIPctChange',
                   'IndexPctChange',
                   'PctChange',
                   'PercentileDPR',
                   'DailyPctChange',
                   'PercentileDailyPctChange',)
          params = (
              ('SPIPctChange', -1),
              ('IndexPctChange', -1),
              ('PctChange', -1),
              ('PercentileDPR', -1),
              ('DailyPctChange', -1),
              ('PercentileDailyPctChange', -1)
          )
          bt.feeds.PandasData.datafields = bt.feeds.PandasData.datafields + [u'SPIPctChange'] + [u'N225PctChange'] + [u'PctChange'] + [u'PercentileDPR'] + [u'DailyPctChange'] \
                                                                          + [u'PercentileDailyPctChange']
      

      I am attempting to find the latest value of PercentileDailyPctChange.

      I have tried adding it under init as self.PercentileDailyPctChange = self.datas[1].PercentileDailyPctChange and then accessing it under next(self) as d.PercentileDailyPctChange[0] wherein I get the error: ValueError: len() should return >= 0

      If I try to access it alternately as self.PercentileDailyPctChange[0] I receive "IndexError: array index out of range"

      I best like the first option as that feels like it should be correct. I am a little bit lost. To recap:

      I have added my local csv as the second datafeed and I am able to access other values from it (such as close, but it's a bit funny).

      I am unsure how to workout how to access values from PercentileDailyPctChange column of the "data1" data feed. I read that there might be an issue with backtrader being unable to recognize the date. As when i run the code it is unable to count more than 1 in regards to the len(d). When I run any variation of d.close or self.close1 or variations with [0] or [-1] I receive an index error IndexError: array index out of range

      When I attempt to run:

          def next(self, frompre=False):
              for i, d in enumerate(self.datas):
                  txt = []
                  txt.append('%04d' % len(d))
                  txt.append('Data_%d' % i)
                  # print(len(self.data_minute))
                  # txt.append(d.PercentileDailyPctChange[0])
                  if i == 1:
                      print('1')
                      txt.append(d.datetime.datetime().isoformat())
                      txt.append(str(d.close[0]))
                      # txt.append(str(d.PercentileDailyPctChange))
                      # print(txt)
                      # return
                  else:
                      print('0')
                      txt.append(d.datetime.datetime().isoformat())
                      # txt.append(str(d.high[0]) + str('movingapack'))
                      txt.append('%.4f' % d.close[0])
                      print(txt)
                      # return
                  print(','.join(txt))
      

      I receive return:

      1
      0001,Data_1,2018-12-12T23:59:59.999989,-22.0
      

      -22 corresponds to the value of close from data1 on the 3/12/2018 as opposed to the latest 12/12/2018 or the earliest 15/11/2018.

      But when I change d.close[0] to d.PercentileDailyPctChange[0] it returns nan despite there being a value for that date (7).

      Here is a link to the csv for data1 I am working with: https://www.dropbox.com/s/5h3h14bpxuvzmik/AUSLeadsUSPercentile.csv?dl=0

      These were some incredibly helpful resources along the way:
      https://community.backtrader.com/topic/26/example-of-adding-live-data-to-static-in-strategy/51?page=3
      https://community.backtrader.com/topic/26/example-of-adding-live-data-to-static-in-strategy/51?page=3
      https://community.backtrader.com/topic/133/unable-to-get-closing-daily-values-for-spy/91?page=5

      posted in General Code/Help
      E
      ElliotP
    • Live Trading Referencing Static Value

      Evening,

      I am trying to transition a strategy idea from being set up for backtesting to one setup for live trading. Ideally I would like to be able to receive the live data feed and reference a static value which could be an indicator or a signal. I have calculated this static value outside of the backtrader environment (easier/faster/etc).

      So far, I have tried adding it as a second data feed but I haven't been able to access any values from the datafeed. I was curious if you were able to cerebro.adddata() to a live strategy? I feel you can.

      I am not sure how to add this new datafeed. For example, if I wanted to pull from a pandas dataframe I would use the pandas method, pass it to cerebro.adddata(). For this next part I'm unsure, how would I construct a dataframe that was solely the date as an index column and another column 'b'.

      posted in General Code/Help
      E
      ElliotP
    • RE: Only one trade per day, how?

      What an adventure. A lot of time spent and the solution is quite elegant. @backtrader was right of course; notify_timer was the key.

      Send me a PM if you would like the solution. It's rather simple, but ya, learned from reading the documentation more, reading what backtrader said and then some furthering of my python ability.

      posted in General Code/Help
      E
      ElliotP