Backtrader Community

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

    Jeff Vahue

    @Jeff Vahue

    0
    Reputation
    102
    Profile views
    4
    Posts
    0
    Followers
    0
    Following
    Joined Last Online

    Jeff Vahue Unfollow Follow

    Latest posts made by Jeff Vahue

    • RE: how to sum total size of buy/sell action. then displayed total size.

      If I understand what you want, you could:

      in ___init__() for the strategy initialize the total size attribute:

      self.totalSize = 0

      Then in notify_order() something like:

      if order.status in [order.Completed]:
          self.totalSize += abs(order.executed.size)
      

      abs() in case your going short as well

      posted in General Discussion
      Jeff Vahue
      Jeff Vahue
    • Strange behavior with cheat_on_open – or that might have nothing to do with it

      Implementing a simple strategy that looks at the ROC(10) of SPY monthly data. If ROC xAbove 0 go long at the open of the next month (via daily data), otherwise if ROC xBelow 0 go short at the open of the next month (via daily data).
      Monthly data from Yahoo is tagged against the first of the month, not the last day. To achieve what I want I provide two data feeds, daily SPY (to do the trades against) and Monthly SPY to trigger the trades. I have set cheat_on_open to true and configured the broker as well. In <strategy>.next_open I determine if the month is different from the last month (i.e., the first trading day of a new month). At this point I look at the current and previous value of ROC(10, monthly) to determine if any trade needs to be done.
      The weird thing is the values that are being served up for ROC. Sometimes they match my calculated values, and sometimes they repeat or skip forward. I can’t understand what is happening. The blue heading indicates data that came out of Backtrader versus the Yahoo data and my calculated ROC value in grey/orange.

      Any ideas?

      0_1561842707453_rocData.JPG

      Here is the main setup

              print('---------- Start: %s - End: %s ----------' % (fromdate.date(), todate.date()))
      
              # Create a cerebro entity, runonce handle mixed timeBase indicators
              # cerebro0 is strategy, cerebro_bnh is Buy and hold to compare against
              cerebro0 = CerebroAnalyzer.CerebroAnalyzer(runonce=False, cheat_on_open=True)
              cerebro_bnh = CerebroAnalyzer.CerebroAnalyzer(runonce=False, cheat_on_open=True)
              cerebros = (cerebro0, cerebro_bnh)
      
              # Add a strategy
              if 1:
                  cerebro0.addstrategy(sRocSpx.RocCross, rocPeriod=10, emaRocPeriod=1, eLim=0.0)
              else:
                  cerebro0.optstrategy(sRocSpx.RocCross, rocPeriod=range(4, 20, 2))
      
              # Create a Data Feed
              data = bt.feeds.YahooFinanceCSVData(
                  dataname=os.path.join(datapath, 'SPY-1D.csv'),
                  fromdate=fromdate,        # Do not pass values before this date
                  todate=todate,            # Do not pass values after this date
                  reverse=False,            #
              )
      
              data1 = bt.feeds.YahooFinanceCSVData(
                  dataname=os.path.join(datapath, 'SPY-1M.csv'),
                  fromdate=fromdate,        # Do not pass values before this date
                  todate=todate,            # Do not pass values after this date
                  reverse=False,            #
                  timeframe=bt.TimeFrame.Months,
              )
      
              stake = 100
              comm = 5.0/stake
              for c in cerebros:
                  # Add the Data Feed to Cerebro
                  c.adddata(data)
                  c.adddata(data1)
                  # Set our desired cash start
                  c.broker.setcash(100000.0)
                  c.broker.set_coo(True)
      

      Here is the strategy

          params = {
              ('emaRocPeriod', 19),
              ('eLim', 0.003),
              ('rocPeriod', 10),
          }
      
          def __init__(self, *args, **kwArgs):
              super().__init__(*args, **kwArgs)
      
              self.dailyClose = self.datas[0].close
              self.monthClose = self.datas[1].close
      
              self.roc = bt.ind.ROC(self.monthClose, period=self.p.rocPeriod)
              #self.roc1 = self.roc(-1)
      
              # To keep track of pending orders and buy price/commission
              self.order = None
              self.buyprice = None
              self.buycomm = None
              self.tradeOpen = False
      
              self.rocCurrent = None
              bt.Indicator.csv = True
      
              self.lastMonth = None  # what was the last month that we looked at the close
              self.monthEnd = None   # what day 1-31 is the last trading day of the month
      
          #------------------------------------------------------------------------
          def next_open(self):
              """ We decide on the 1st day of the month if we need to trade based on how the monthly ROC
              finsihed
              """
              nowIs = self.datas[0].datetime.date(0)
              if self.lastMonth != nowIs.month:
                  self.lastMonth = nowIs.month
      
                  rocCurrent = self.roc.roc[0]
                  self.rocCurrent = rocCurrent
      
                  rocLast = self.roc.roc[-1] #self.roc1[0]
                  #value1 = self.ema_roc1.ema[0]
      
                  xa = rocCurrent > 0 and rocLast <= 0
                  xb = rocCurrent < 0 and rocLast >= 0
      
                  # Check if an order is pending ... if yes, we cannot send a 2nd one
                  if self.order:
                      return
      
                  self.log('>>> %7.3f,%7.4f,%7.4f,%5s,%5s' % (self.monthClose[0],
                                                              rocCurrent, rocLast, xa, xb))
      
                  # Check if we are not in the market (no open)
                  if self.tradeSize <= 0 and xa:
                      # Not yet ... we MIGHT BUY if ...
                      #if xa: # and (emaRoc0 <= -self.p.eLim or self.p.eLim == 0.0):
      
                      # BUY, BUY, BUY!!! (with all possible default parameters)
                      self.log('BUY CREATE, %.2f' % self.dailyClose[0])
      
                      # Simply log the closing price of the series from the reference
                      self.log('Close, %.2f, %.2f, %.2f, xa:%5s xb:%5s' % (
                          self.monthClose[-1], rocCurrent, rocLast, xa, xb))
      
                      # Keep track of the created order to avoid a 2nd order
                      size = 100 if self.tradeSize == 0 else 200
                      self.order = self.buy(size=size)
      
                  elif self.tradeSize >= 0 and xb:
                      #if xb: # and (emaRoc0 >= self.p.eLim or self.p.eLim == 0.0):
                      #if self.dataclose[0] < self.sma[0]:
                          # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % self.dailyClose[0])
      
                      # Simply log the closing price of the series from the reference
                      self.log('Close, %.2f, %.2f, %.2f, xa:%s xb:%s' % (
                          self.monthClose[0], rocCurrent, rocLast, xa, xb))
      
                      # Keep track of the created order to avoid a 2nd order
                      size = 100 if self.tradeSize == 0 else 200
                      # go short
                      self.order = self.sell(size=size)
      
      posted in General Code/Help
      Jeff Vahue
      Jeff Vahue
    • RE: Why YahooFinanceCSVData reports the data is broken?

      Make sure you don't open and SAVE a Yahoo data feed from excel as it will change the date format from:

      1950-01-01 to 1/1/1950

      and that will not work with YahooFinanceCSVData

      posted in General Code/Help
      Jeff Vahue
      Jeff Vahue
    • Why YahooFinanceCSVData reports the data is broken?

      I was using YahooFinanceCSVData and things worked great. Then I tried to subclass GenericCSVData with a new date format and Yahoo stopped working. To isolate the problem I commented out the original Yahoo data and got my new format working. When I re-introduced Yahoo it keeps crashing on the date processing becuase it expects a date string format of 'YYYYMMDD' but the file I just downloaded from Yahoo has the date a like '1/1/1950' as the first entry. I delete my new data type and cannot get Yahoo to parse any more. I can go into the code _loadline at line 129 <dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10]))> and change it but what happened.

      Any ideas would be appreciated.

      posted in General Code/Help
      Jeff Vahue
      Jeff Vahue