Navigation

    Backtrader Community

    • Register
    • 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/

    PAIR TRADING IMPLEMENTATION WITH BACKTRADER

    General Code/Help
    3
    9
    56
    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.
    • H
      houba last edited by

      Hi guys ,

      I'm new here.

      I discovered BACKTRADER and I'm struggling with PAIR TRADING even if I found out a GitHub repository where we have the full access...but It doesn't work.

      Anyway , I tried to apply the code to my .csv files but I get this error :

      Traceback (most recent call last):
      File "PairTradingStrategy.py", line 174, in <module>
      cerebro.run()
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1127, in run
      runstrat = self.runstrategies(iterstrat)
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1212, in runstrategies
      data.preload()
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 688, in preload
      while self.load():
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 479, in load
      _loadret = self._load()
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 710, in _load
      return self._loadline(linetokens)
      File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feeds/yahoo.py", line 134, in _loadline
      h = float(linetokens[next(i)])
      IndexError: list index out of range

      and the code is as following :

      """

      import backtrader as bt
      import backtrader.analyzers as btanalyzers
      import backtrader.indicators as btind
      import datetime
      """
      """
      class PairTradingStrategy(bt.Strategy):
      params = dict(
      period=10,
      stake=10,
      qty1=0,
      qty2=0,
      printout=True,
      upper=2.1,
      lower=-2.1,
      up_medium=0.5,
      low_medium=-0.5,
      status=0,
      portfolio_value=10000,
      )

      def log(self, txt, dt=None):
          if self.p.printout:
              dt = dt or self.data.datetime[0]
              dt = bt.num2date(dt)
              print('%s, %s' % (dt.isoformat(), txt))
      
      def __init__(self):
         # To control operation entries
          self.orderid = None
          self.qty1 = self.p.qty1
          self.qty2 = self.p.qty2
          self.upper_limit = self.p.upper
          self.lower_limit = self.p.lower
          self.up_medium = self.p.up_medium
          self.low_medium = self.p.low_medium
          self.status = self.p.status
          self.portfolio_value = self.p.portfolio_value
      
      # Signals performed with PD.OLS :
          self.transform = btind.OLS_TransformationN(self.data1, self.data2,
                                                     period=self.p.period)
          self.zscore = self.transform.zscore
      
          # Checking signals built with StatsModel.API :
          # self.ols_transfo = btind.OLS_Transformation(self.data1, self.data2,
          #                                             period=self.p.period,
          #                                             plot=True)
      

      """"
      def next(self):
      if self.orderid:
      return # if an order is active, no new orders are allowed

          if self.p.printout:
              print('Self  len:', len(self))
              print('Data1 len:', len(self.data1))
              print('Data2 len:', len(self.data2))
              print('Data1 len == Data2 len:',
                    len(self.data1) == len(self.data2))
      
              print('Data1 dt:', self.data1.datetime.datetime())
              print('Data2 dt:', self.data2.datetime.datetime())
      
          print('status is', self.status)
          print('zscore is', self.zscore[0])
      
      
          # Step 2: Check conditions for SHORT & place the order
          # Checking the condition for SHORT
          if (self.zscore[0] > self.upper_limit) and (self.status != 1):
      
              # Calculating the number of shares for each stock
              value = 0.5 * self.portfolio_value  # Divide the cash equally
              x = int(value / (self.data1.close))  # Find the number of shares for Stock1
              y = int(value / (self.data2.close))  # Find the number of shares for Stock2
              print('x + self.qty1 is', x + self.qty1)
              print('y + self.qty2 is', y + self.qty2)
      
              # Placing the order
              self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1))
              self.sell(data=self.data1, size=(x + self.qty1))  # Place an order for buying y + qty2 shares
              self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("KO", self.data2.close[0], y + self.qty2))
              self.buy(data=self.data2, size=(y + self.qty2))  # Place an order for selling x + qty1 shares
      
              # Updating the counters with new value
              self.qty1 = x  # The new open position quantity for Stock1 is x shares
              self.qty2 = y  # The new open position quantity for Stock2 is y shares
      
              self.status = 1  # The current status is "short the spread"
      
              # Step 3: Check conditions for LONG & place the order
              # Checking the condition for LONG
          elif (self.zscore[0] < self.lower_limit) and (self.status != 2):
      
              # Calculating the number of shares for each stock
              value = 0.5 * self.portfolio_value  # Divide the cash equally
              x = int(value / (self.data1.close))  # Find the number of shares for Stock1
              y = int(value / (self.data2.close))  # Find the number of shares for Stock2
              print('x + self.qty1 is', x + self.qty1)
              print('y + self.qty2 is', y + self.qty2)
      
              # Place the order
              self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1))
              self.buy(data=self.data1, size=(x + self.qty1))  # Place an order for buying x + qty1 shares
              self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data2.close[0], y + self.qty2))
              self.sell(data=self.data2, size=(y + self.qty2))  # Place an order for selling y + qty2 shares
      
              # Updating the counters with new value
              self.qty1 = x  # The new open position quantity for Stock1 is x shares
              self.qty2 = y  # The new open position quantity for Stock2 is y shares
              self.status = 2  # The current status is "long the spread"
      
      
              # Step 4: Check conditions for No Trade
              # If the z-score is within the two bounds, close all
      
          elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium):
              self.log('CLOSE LONG %s, price = %.2f' % ("PEP", self.data1.close[0]))
              self.close(self.data1)
              self.log('CLOSE LONG %s, price = %.2f' % ("KO", self.data2.close[0]))
              self.close(self.data2)
      

      """

      def stop(self):
              print('==================================================')
              print('Starting Value - %.2f' % self.broker.startingcash)
              print('Ending   Value - %.2f' % self.broker.getvalue())
              print('==================================================')
      

      """
      """
      #Instantiate Cerebro engine
      cerebro = bt.Cerebro()

      #Add data feed to Cerebro
      data1 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AACQW.csv',
      dtformat=('%Y.%m.%d'),
      fromdate = datetime.datetime(2018,1,2),
      todate = datetime.datetime(2021,1,15),
      datetime=0,
      time=-1,
      high=-1,
      low=-1,
      open=-1,
      close=1,
      volume=-1,
      openinterest=-1)
      cerebro.adddata(data1)

      data2 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AAME.csv',
      dtformat=('%Y.%m.%d'),
      fromdate = datetime.datetime(2018,1,2),
      todate = datetime.datetime(2021,1,15),
      datetime=0,
      time=-1,
      high=-1,
      low=-1,
      open=-1,
      close=1,
      volume=-1,
      openinterest=-1)
      cerebro.adddata(data2)
      """
      """
      #Add strategy to Cerebro
      cerebro.addstrategy(PairTradingStrategy)

      """
      """
      if name == 'main':
      # Run Cerebro Engine
      start_portfolio_value = cerebro.broker.getvalue()

      cerebro.run()
      
      end_portfolio_value = cerebro.broker.getvalue()
      
      pnl = end_portfolio_value - start_portfolio_value
      print(f'Starting Portfolio Value: {start_portfolio_value:2f}')
      print(f'Final Portfolio Value: {end_portfolio_value:2f}')
      print(f'PnL: {pnl:.2f}')
      

      #Run Cerebro Engine
      cerebro.run()

      """
      """

      Can anyone tell me please why I have an error and if the code is ok to make it run successfully ?

      Thank you for your help!

      run-out 1 Reply Last reply Reply Quote 0
      • run-out
        run-out @houba last edited by

        @houba Can you do us a favour and repost your code as a whole between triple backslashes? See the instructions at the top of the page:

        For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/
        
        H 1 Reply Last reply Reply Quote 0
        • H
          houba @run-out last edited by

          Hi guys ,

          I'm new here.

          I discovered BACKTRADER and I'm struggling with PAIR TRADING even if I found out a GitHub repository where we have the full access...but It doesn't work.

          Anyway , I tried to apply the code to my .csv files but I get this error :

          Traceback (most recent call last):
          File "PairTradingStrategy.py", line 174, in <module>
          cerebro.run()
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1127, in run
          runstrat = self.runstrategies(iterstrat)
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 1212, in runstrategies
          data.preload()
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 688, in preload
          while self.load():
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 479, in load
          _loadret = self._load()
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feed.py", line 710, in _load
          return self._loadline(linetokens)
          File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/feeds/yahoo.py", line 134, in _loadline
          h = float(linetokens[next(i)])
          IndexError: list index out of range

          and the code is as following :

          
          import backtrader as bt
          import backtrader.analyzers as btanalyzers
          import backtrader.indicators as btind
          import datetime
          
          class PairTradingStrategy(bt.Strategy):
          params = dict(
          period=10,
          stake=10,
          qty1=0,
          qty2=0,
          printout=True,
          upper=2.1,
          lower=-2.1,
          up_medium=0.5,
          low_medium=-0.5,
          status=0,
          portfolio_value=10000,
          )
          
          def log(self, txt, dt=None):
              if self.p.printout:
                  dt = dt or self.data.datetime[0]
                  dt = bt.num2date(dt)
                  print('%s, %s' % (dt.isoformat(), txt))
          
          def __init__(self):
             # To control operation entries
              self.orderid = None
              self.qty1 = self.p.qty1
              self.qty2 = self.p.qty2
              self.upper_limit = self.p.upper
              self.lower_limit = self.p.lower
              self.up_medium = self.p.up_medium
              self.low_medium = self.p.low_medium
              self.status = self.p.status
              self.portfolio_value = self.p.portfolio_value
          
          # Signals performed with PD.OLS :
              self.transform = btind.OLS_TransformationN(self.data1, self.data2,
                                                         period=self.p.period)
              self.zscore = self.transform.zscore
          
              # Checking signals built with StatsModel.API :
              # self.ols_transfo = btind.OLS_Transformation(self.data1, self.data2,
              #                                             period=self.p.period,
              #                                             plot=True)
          
          def next(self):
          if self.orderid:
          return # if an order is active, no new orders are allowed
          
              if self.p.printout:
                  print('Self  len:', len(self))
                  print('Data1 len:', len(self.data1))
                  print('Data2 len:', len(self.data2))
                  print('Data1 len == Data2 len:',
                        len(self.data1) == len(self.data2))
          
                  print('Data1 dt:', self.data1.datetime.datetime())
                  print('Data2 dt:', self.data2.datetime.datetime())
          
              print('status is', self.status)
              print('zscore is', self.zscore[0])
          
          
              # Step 2: Check conditions for SHORT & place the order
              # Checking the condition for SHORT
              if (self.zscore[0] > self.upper_limit) and (self.status != 1):
          
                  # Calculating the number of shares for each stock
                  value = 0.5 * self.portfolio_value  # Divide the cash equally
                  x = int(value / (self.data1.close))  # Find the number of shares for Stock1
                  y = int(value / (self.data2.close))  # Find the number of shares for Stock2
                  print('x + self.qty1 is', x + self.qty1)
                  print('y + self.qty2 is', y + self.qty2)
          
                  # Placing the order
                  self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1))
                  self.sell(data=self.data1, size=(x + self.qty1))  # Place an order for buying y + qty2 shares
                  self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("KO", self.data2.close[0], y + self.qty2))
                  self.buy(data=self.data2, size=(y + self.qty2))  # Place an order for selling x + qty1 shares
          
                  # Updating the counters with new value
                  self.qty1 = x  # The new open position quantity for Stock1 is x shares
                  self.qty2 = y  # The new open position quantity for Stock2 is y shares
          
                  self.status = 1  # The current status is "short the spread"
          
                  # Step 3: Check conditions for LONG & place the order
                  # Checking the condition for LONG
              elif (self.zscore[0] < self.lower_limit) and (self.status != 2):
          
                  # Calculating the number of shares for each stock
                  value = 0.5 * self.portfolio_value  # Divide the cash equally
                  x = int(value / (self.data1.close))  # Find the number of shares for Stock1
                  y = int(value / (self.data2.close))  # Find the number of shares for Stock2
                  print('x + self.qty1 is', x + self.qty1)
                  print('y + self.qty2 is', y + self.qty2)
          
                  # Place the order
                  self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data1.close[0], x + self.qty1))
                  self.buy(data=self.data1, size=(x + self.qty1))  # Place an order for buying x + qty1 shares
                  self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data2.close[0], y + self.qty2))
                  self.sell(data=self.data2, size=(y + self.qty2))  # Place an order for selling y + qty2 shares
          
                  # Updating the counters with new value
                  self.qty1 = x  # The new open position quantity for Stock1 is x shares
                  self.qty2 = y  # The new open position quantity for Stock2 is y shares
                  self.status = 2  # The current status is "long the spread"
          
          
                  # Step 4: Check conditions for No Trade
                  # If the z-score is within the two bounds, close all
          
              elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium):
                  self.log('CLOSE LONG %s, price = %.2f' % ("PEP", self.data1.close[0]))
                  self.close(self.data1)
                  self.log('CLOSE LONG %s, price = %.2f' % ("KO", self.data2.close[0]))
                  self.close(self.data2)
          
          
          def stop(self):
                  print('==================================================')
                  print('Starting Value - %.2f' % self.broker.startingcash)
                  print('Ending   Value - %.2f' % self.broker.getvalue())
                  print('==================================================')
          
          #Instantiate Cerebro engine
          cerebro = bt.Cerebro()
          
          #Add data feed to Cerebro
          data1 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AACQW.csv',
          dtformat=('%Y.%m.%d'),
          fromdate = datetime.datetime(2018,1,2),
          todate = datetime.datetime(2021,1,15),
          datetime=0,
          time=-1,
          high=-1,
          low=-1,
          open=-1,
          close=1,
          volume=-1,
          openinterest=-1)
          cerebro.adddata(data1)
          
          data2 = bt.feeds.YahooFinanceCSVData(dataname='/Users/bibani/Desktop/AAME.csv',
          dtformat=('%Y.%m.%d'),
          fromdate = datetime.datetime(2018,1,2),
          todate = datetime.datetime(2021,1,15),
          datetime=0,
          time=-1,
          high=-1,
          low=-1,
          open=-1,
          close=1,
          volume=-1,
          openinterest=-1)
          cerebro.adddata(data2)
          
          #Add strategy to Cerebro
          cerebro.addstrategy(PairTradingStrategy)
          
          
          if name == 'main':
          # Run Cerebro Engine
          start_portfolio_value = cerebro.broker.getvalue()
          
          cerebro.run()
          
          end_portfolio_value = cerebro.broker.getvalue()
          
          pnl = end_portfolio_value - start_portfolio_value
          print(f'Starting Portfolio Value: {start_portfolio_value:2f}')
          print(f'Final Portfolio Value: {end_portfolio_value:2f}')
          print(f'PnL: {pnl:.2f}')
          #Run Cerebro Engine
          cerebro.run()
          
          

          Can anyone tell me please why I have an error and if the code is ok to make it run successfully ?

          Thank you for your help!

          vladisld 1 Reply Last reply Reply Quote 1
          • vladisld
            vladisld @houba last edited by

            @houba YahooFinanceCSVData implementation expect the OHLC columns to be present.

            I guess your data file is not in Yahoo format and/or contains only close prices.

            You may try to use GenericCSVData instead - it is much more forgiving and doesn't request all OHLC fields to be present.

            H 1 Reply Last reply Reply Quote 2
            • H
              houba @vladisld last edited by

              @vladisld yes I found out already ; I should put the GenericCSVData and its arguments as you said)

              Thks

              from __future__ import (absolute_import, division, print_function,
                                      unicode_literals)
              
              import argparse
              import backtrader as bt 
              import backtrader.analyzers as btanalyzers
              import backtrader.feeds as btfeeds
              import backtrader.indicators as btind
              import datetime
              import pandas as pd 
              import matplotlib
              import pandas as pd
              import quantstats
              
              class PairsTradingStrategy(bt.Strategy) : 
                  params = dict(
                      period = 10,
                      stake = 10,
                      qty1 = 0,
                      qty2 = 0,
                      printout = True,
                      upper = 2.1,
                      lower = -2.1,
                      up_medium = 0.5,
                      low_medium = -0.5,
                      upper_level = 2.1,
                      lower_level = -2.1,
                      status = 0,
                      portfolio_value=10000,
                      )
              
                  def log(self,txt,dt=None) : 
                      if self.p.printout :
                          dt = dt or self.data.datetime[0]
                          dt = bt.num2date(dt)
                          print('%s,%s' % (dt.isoformat(),txt))
              
                  def notify_order(self,order) :
                      if order.status in [bt.Order.Submitted,bt.Order.Accepted] : 
                          return 
                      if order.status == order.Completed :
                          if order.isbuy():
                              buytxt = 'BUY COMPLETE,%2f' % order.executed.price
                              self.log(buytxt,order.executed.dt)
                          else:
                              selltxt = 'SELL COMPLETE,%.2f' % order.executed.price
                              self.log(selltxt,order.executed.dt)
              
                      elif  order.status in [order.Expired,order.Canceled,order.Margin]:
                          self.log('%s,'% order.Status[order.status])
                          pass 
              
                      self.orderid = None
              
                  def __init__(self):
              
                      self.orderid = None
                      self.qty1 = self.p.qty1
                      self.qty2 = self.p.qty2
                      self.upper_limit = self.p.upper
                      self.lower_limit = self.p.lower
                      self.up_medium = self.p.up_medium
                      self.low_medium = self.p.low_medium
                      self.status = self.p.status 
                      self.portfolio_value = self.p.portfolio_value
              
                      self.transform = btind.OLS_TransformationN(self.data0,self.data1,period=self.p.period)
              
                      self.zscore = self.transform.zscore
              
              
                  def next(self) :
              
                      if self.orderid : 
                          return 
              
                      if self.p.printout:
                          print('Self  len:', len(self))
                          print('Data0 len:', len(self.data0))
                          print('Data1 len:', len(self.data1))
                          print('Data0 len == Data1 len:',
                                len(self.data0) == len(self.data1))
              
                          print('Data0 dt:', self.data0.datetime.datetime())
                          print('Data1 dt:', self.data1.datetime.datetime())
              
                      print('status is', self.status)
                      print('zscore is', self.zscore[0])
              
                      # Step 2: Check conditions for SHORT & place the order
                      # Checking the condition for SHORT
                      if (self.zscore[0] > self.upper_limit) and (self.status != 1):
              
                          # Calculating the number of shares for each stock
                          value = 0.5 * self.portfolio_value  # Divide the cash equally
                          x = int(value / (self.data0.close))  # Find the number of shares for Stock1
                          y = int(value / (self.data1.close))  # Find the number of shares for Stock2
                          print('x + self.qty1 is', x + self.qty1)
                          print('y + self.qty2 is', y + self.qty2)
              
                          # Placing the order
                          self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data0.close[0], x + self.qty1))
                          self.sell(data=self.data0, size=(x + self.qty1))  # Place an order for buying y + qty2 shares
                          self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data1.close[0], y + self.qty2))
                          self.buy(data=self.data1, size=(y + self.qty2))  # Place an order for selling x + qty1 shares
              
                          # Updating the counters with new value
                          self.qty1 = x  # The new open position quantity for Stock1 is x shares
                          self.qty2 = y  # The new open position quantity for Stock2 is y shares
                          self.status = 1  # The current status is "short the spread"
              
                          # Step 3: Check conditions for LONG & place the order
                          # Checking the condition for LONG
                      elif (self.zscore[0] < self.lower_limit) and (self.status != 2):
              
                          # Calculating the number of shares for each stock
                          value = 0.5 * self.portfolio_value  # Divide the cash equally
                          x = int(value / (self.data0.close))  # Find the number of shares for Stock1
                          y = int(value / (self.data1.close))  # Find the number of shares for Stock2
                          print('x + self.qty1 is', x + self.qty1)
                          print('y + self.qty2 is', y + self.qty2)
              
                          # Place the order
                          self.log('BUY CREATE %s, price = %.2f, qty = %d' % ("AACQW", self.data0.close[0], x + self.qty1))
                          self.buy(data=self.data0, size=(x + self.qty1))  # Place an order for buying x + qty1 shares
                          self.log('SELL CREATE %s, price = %.2f, qty = %d' % ("AAME", self.data1.close[0], y + self.qty2))
                          self.sell(data=self.data1, size=(y + self.qty2))  # Place an order for selling y + qty2 shares
              
                          # Updating the counters with new value
                          self.qty1 = x  # The new open position quantity for Stock1 is x shares
                          self.qty2 = y  # The new open position quantity for Stock2 is y shares
                          self.status = 2  # The current status is "long the spread"
              
                          # Step 4: Check conditions for No Trade
                          # If the z-score is within the two bounds, close all
                     
                      elif (self.zscore[0] < self.up_medium and self.zscore[0] > self.low_medium):
                          self.log('CLOSE LONG %s, price = %.2f' % ("AACQW", self.data0.close[0]))
                          self.close(self.data0)
                          self.log('CLOSE LONG %s, price = %.2f' % ("AAME", self.data1.close[0]))
                          self.close(self.data1)
                          
              
                  def stop(self):
                      print('==================================================')
                      print('Starting Value - %.2f' % self.broker.startingcash)
                      print('Ending   Value - %.2f' % self.broker.getvalue())
                      print('==================================================')
              
                  
              def parse_args():
                  parser = argparse.ArgumentParser(description='MultiData Strategy')
              
                  parser.add_argument('--data0', '-d0',
                                      default='/Users/bibani/Desktop/AACQW.csv',
                                      help='1st data into the system')
              
                  parser.add_argument('--data1', '-d1',
                                      default='/Users/bibani/Desktop/AAME.csv',
                                      help='2nd data into the system')
              
                  parser.add_argument('--fromdate', '-f',
                                      default='2018-01-02',
                                      help='Starting date in YYYY-MM-DD format')
              
                  parser.add_argument('--todate', '-t',
                                      default='2021-01-15',
                                      help='Starting date in YYYY-MM-DD format')
              
                  parser.add_argument('--period', default=10, type=int,
                                      help='Period to apply to the Simple Moving Average')
              
                  parser.add_argument('--cash', default=100000, type=int,
                                      help='Starting Cash')
              
                  parser.add_argument('--runnext', action='store_true',
                                      help='Use next by next instead of runonce')
              
                  parser.add_argument('--nopreload', action='store_true',
                                      help='Do not preload the data')
              
                  parser.add_argument('--oldsync', action='store_true',
                                      help='Use old data synchronization method')
              
                  parser.add_argument('--commperc', default=0.005, type=float,
                                      help='Percentage commission (0.005 is 0.5%%')
              
                  parser.add_argument('--stake', default=10, type=int,
                                      help='Stake to apply in each operation')
              
                  parser.add_argument('--plot', '-p', default=True, action='store_true',
                                      help='Plot the read data')
              
                  parser.add_argument('--numfigs', '-n', default=1,
                                      help='Plot using numfigs figures')
              
                  return parser.parse_args()
              
              def runstrategy():
                  args = parse_args()
              
                  # Create a cerebro
                  cerebro = bt.Cerebro()
              
                  # Get the dates from the args
                  fromdate = datetime.datetime.strptime(args.fromdate, '%Y-%m-%d')
                  todate = datetime.datetime.strptime(args.todate, '%Y-%m-%d')
              
                  # Create the 1st data
                  data0 = btfeeds.GenericCSVData(
                      dataname=args.data0,
                      dtformat = ('%Y-%m-%d'),
                      fromdate=fromdate,
                      todate=todate,
                      datetime=0, 
                      high=-1, 
                      low=-1, 
                      open=-1,
                      close=1, 
                      volume=-1, 
                      openinterest=-1
              )
              
                  # Add the 1st data to cerebro
                  cerebro.adddata(data0)
              
                  # Create the 2nd data
                  data1 = btfeeds.GenericCSVData(
                      dataname=args.data1,
                      dtformat = ('%Y-%m-%d'),
                      fromdate=fromdate,
                      todate=todate,
                      datetime=0, 
                      high=-1, 
                      low=-1, 
                      open=-1,
                      close=1, 
                      volume=-1, 
                      openinterest=-1
                      )
              
                  # Add the 2nd data to cerebro
                  cerebro.adddata(data1)
              
                  # Add the strategy
                  cerebro.addstrategy(PairsTradingStrategy,
                      period=args.period,
                      stake=args.stake)
              
                  cerebro.broker.setcash(args.cash)
              
                  # Add the commission - only stocks like a for each operation
                  cerebro.broker.setcommission(commission=args.commperc)
              
                  # And run it
                  results = cerebro.run(runonce=not args.runnext,
                      preload=not args.nopreload,
                      oldsync=args.oldsync)
              
                  cerebro.broker.getvalue()
              
                  cerebro.addanalyzer(bt.analyzers.SharpeRatio, _name='SharpeRatio')
                  cerebro.addanalyzer(bt.analyzers.DrawDown, _name='DW')
                  end_portfolio_value = cerebro.broker.getvalue()
              
                  #print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
                  #print('SR:', cerebro.analyzers.SharpeRatio.get_analysis())
                  #print('DW:', cerebro.analyzers.DW.get_analysis())
              
                  # Plot if requested
                  if args.plot:
                      cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False)
              
              if __name__ == '__main__':
                  runstrategy()
              
              

              why am I getting this error :

              <IPython.core.display.Javascript object>
              <IPython.core.display.HTML object>
              Traceback (most recent call last):
              File "Test_Iheb.py", line 275, in <module>
              runstrategy()
              File "Test_Iheb.py", line 272, in runstrategy
              cerebro.plot(numfigs=args.numfigs, volume=False, zdown=False)
              File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/cerebro.py", line 996, in plot
              plotter.show()
              File "/opt/anaconda3/lib/python3.7/site-packages/backtrader/plot/plot.py", line 817, in show
              self.mpyplot.show()
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/pyplot.py", line 269, in show
              return _show(*args, **kw)
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 261, in show
              manager.show()
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 90, in show
              self._create_comm()
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 122, in _create_comm
              self.add_web_socket(comm)
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 432, in add_web_socket
              self.resize(w, h)
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 418, in resize
              size=(w / self.canvas._dpi_ratio, h / self.canvas._dpi_ratio))
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 489, in _send_event
              s.send_json(payload)
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 199, in send_json
              self.comm.send({'data': json.dumps(content)})
              File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 123, in send
              data=data, metadata=metadata, buffers=buffers,
              File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 66, in _publish_msg
              self.kernel.session.send(self.kernel.iopub_socket, msg_type,
              AttributeError: 'NoneType' object has no attribute 'session'
              Error in atexit._run_exitfuncs:
              Traceback (most recent call last):
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/_pylab_helpers.py", line 73, in destroy_all
              manager.destroy()
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 126, in destroy
              self._send_event('close')
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_webagg_core.py", line 489, in _send_event
              s.send_json(payload)
              File "/opt/anaconda3/lib/python3.7/site-packages/matplotlib/backends/backend_nbagg.py", line 199, in send_json
              self.comm.send({'data': json.dumps(content)})
              File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 123, in send
              data=data, metadata=metadata, buffers=buffers,
              File "/opt/anaconda3/lib/python3.7/site-packages/ipykernel/comm/comm.py", line 66, in _publish_msg
              self.kernel.session.send(self.kernel.iopub_socket, msg_type,
              AttributeError: 'NoneType' object has no attribute 'session'

              vladisld H 2 Replies Last reply Reply Quote 0
              • vladisld
                vladisld @houba last edited by

                @houba I'm not using IPython myself but probably the following post may help: https://community.backtrader.com/topic/1911/cerebro-plot-does-not-work-with-anaconda-ipython?_=1614109874231

                H 2 Replies Last reply Reply Quote 0
                • H
                  houba @houba last edited by

                  @vladisld thanks again :)

                  1 Reply Last reply Reply Quote 0
                  • H
                    houba @vladisld last edited by

                    @vladisld Actually No , the problem is not in the "cerebro.plot" ....If any one has any idea please do not hesitate

                    1 Reply Last reply Reply Quote 0
                    • H
                      houba @vladisld last edited by

                      @vladisld Actually , YES , it helps but not sufficient :)

                      I have as an ending value : NaN

                      Also , I don't have any signals on the positions taken ....

                      BackTrader_Test.png image url)

                      1 Reply Last reply Reply Quote 0
                      • 1 / 1
                      • First post
                        Last post
                      Copyright © 2016, 2017, 2018 NodeBB Forums | Contributors
                      $(document).ready(function () { app.coldLoad(); }); }