Backtrader Community

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

    Backtest running but no trade happening

    General Code/Help
    2
    12
    5198
    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.
    • M
      mahbubk9 last edited by

      Hi,
      I am running this code below, with simple strategy, which should result in lots of buy/sell, but i don't see any happening and end portfolio values stays same.

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import datetime  # For datetime objects
      import os.path  # To manage paths
      import sys  # To find out the script name (in argv[0])
      
      # Import the backtrader platform
      import backtrader as bt
      import backtrader.feeds as btfeeds
      
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
          params = (
              ('maperiod', 15),
          )
      
          def log(self, txt, dt=None):
              ''' Logging function fot this strategy'''
              dt = dt or self.datas[0].datetime.date(0)
              print('%s, %s' % (dt.isoformat(), txt))
      
          def __init__(self):
              # Keep a reference to the "close" line in the data[0] dataseries
              self.dataclose = self.datas[0].close
      
              # To keep track of pending orders and buy price/commission
              self.order = None
              self.buyprice = None
              self.buycomm = None
      
              # Add a MovingAverageSimple indicator
              self.sma = bt.indicators.SimpleMovingAverage(
                  self.datas[0], period=self.params.maperiod)
              self.ADX= bt.indicators.DirectionalMovementIndex(self.data,period=12)
              self.ATR= bt.indicators.ATR(self.data,period=12)
              # Indicators for the plotting show
              bt.indicators.ExponentialMovingAverage(self.datas[0], period=25)
              '''
              bt.indicators.WeightedMovingAverage(self.datas[0], period=25,
                                                  subplot=True)
              bt.indicators.StochasticSlow(self.datas[0])
              bt.indicators.MACDHisto(self.datas[0])
              rsi = bt.indicators.RSI(self.datas[0])
              bt.indicators.SmoothedMovingAverage(rsi, period=10)
              bt.indicators.ATR(self.datas[0], plot=False)
              '''
      
          def notify_order(self, order):
              if order.status in [order.Submitted, order.Accepted]:
                  # Buy/Sell order submitted/accepted to/by broker - Nothing to do
                  return
      
              # Check if an order has been completed
              # Attention: broker could reject order if not enougth cash
              if order.status in [order.Completed]:
                  if order.isbuy():
                      self.log(
                          'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                          (order.executed.price,
                           order.executed.value,
                           order.executed.comm))
      
                      self.buyprice = order.executed.price
                      self.buycomm = order.executed.comm
                  else:  # Sell
                      self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' %
                               (order.executed.price,
                                order.executed.value,
                                order.executed.comm))
      
                  self.bar_executed = len(self)
      
              elif order.status in [order.Canceled, order.Margin, order.Rejected]:
                  self.log('Order Canceled/Margin/Rejected')
      
              # Write down: no pending order
              self.order = None
      
          def notify_trade(self, trade):
              if not trade.isclosed:
                  return
      
              self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' %
                       (trade.pnl, trade.pnlcomm))
      
          def next(self):
              # Simply log the closing price of the series from the reference
              self.log('Close, %.2f' % self.dataclose[0])
      
              # Check if an order is pending ... if yes, we cannot send a 2nd one
              if self.order:
                  return
      
              # Check if we are in the market
              if not self.position:
                  
      
                  # Not yet ... we MIGHT BUY if ...
                if (self.ADX[-1] > 35  
                        and self.ADX.DIplus[-1]>25 ):
                    self.log('BUY CREATE, %.2f' % self.dataclose[0])
                    self.order = self.buy()
      
      
                    
                       
                     
              else:
                  
                   if (self.ADX[-1] > 35 
                        and self.ADX.DIminus[-1]>25 ):
                       self.log('SELL CREATE, %.2f' % self.dataclose[0])
                       self.order = self.sell()
                       
      
                  
                      
      
      
      if __name__ == '__main__':
          # Create a cerebro entity
          cerebro = bt.Cerebro()
      
          # Add a strategy
          cerebro.addstrategy(TestStrategy)
      
          # Datas are in a subfolder of the samples. Need to find where the script is
          # because it could have been called from anywhere
          modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
          datapath = os.path.join(modpath, 'data/gbpusd 1min data.csv')
           # Create a Data Feed
          data = btfeeds.GenericCSVData(
          dataname= datapath,
      
          fromdate=datetime.datetime(2016, 3, 1),
          todate=datetime.datetime(2016,4 , 1),
      
          nullvalue=0.0,
      
          dtformat=('%d.%m.%Y %H:%M:%S.%f'),
      
          datetime=0,
          open=1,
          high=2,
          low=3,
          close=4,
          volume=5,
          openinterest=-1)
      
          # Add the Data Feed to Cerebro
          cerebro.adddata(data)
      
          # Set our desired cash start
          cerebro.broker.setcash(1000.0)
      
          # Add a FixedSize sizer according to the stake
          cerebro.addsizer(bt.sizers.FixedSize, stake=10)
      
          # Set the commission
          cerebro.broker.setcommission(commission=0.0)
      
          # Print out the starting conditions
          print('Starting Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          # Run over everything
          cerebro.run()
      
          # Print out the final result
          print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          # Plot the result
          cerebro.plot()
      

      Is something wrong with my strategy?
      Thanks

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

        Most probably with your data. But there is no sample

        1 Reply Last reply Reply Quote 0
        • M
          mahbubk9 last edited by

          Hi,
          I changed data to yahoo finance data

           modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
              datapath = os.path.join(modpath, 'data/s&p500 daily.csv')
              
              data = btfeeds.YahooFinanceCSVData(
                      
                      
                      dataname=datapath,
                      #reversed=True,
                      fromdate=datetime.datetime(2016, 5, 31),
                      todate=datetime.datetime(2017, 5, 26),
                      timeframe=bt.TimeFrame.Days,
                      compression=1,
                      name='GSPC'
                      )
          

          Got this error

           dt = date(int(dttxt[0:4]), int(dttxt[5:7]), int(dttxt[8:10]))
          
          ValueError: invalid literal for int() with base 10: '31/0'
          

          Thanks

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

            Obviously the data you are feeding to YahooFinanceCSVData is not compatible with the expected date format.

            In any case it seems in all your examples that you never configure timeframe and compression for the data feeds, which unless it happens to be the default (Days/1) will obviously not produce the desired effects.

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

              You may want to read the Community - FAQ where timeframe and compression are specifically mentioned

              1 Reply Last reply Reply Quote 0
              • M
                mahbubk9 last edited by

                I got it, for the genericCSVdata i did not put timeframe, but the the data for yahooFinanceCSVData is downloaded from yahoo historical prices and it does have time frame and compression, so why am i getting the error.
                Also, i just put the time frame and compression on my genericCSVdata code and run it, but the same result, no buy sell.

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

                  The Yahoo prices have this format: YYYY-MM-DD. It has always been so with the dead API and it seems so far to be the with the new.

                  What was fed into the YahooFinanceCSVData has apparently this format: DD/MM/YY??. It might be that you downloaded it from Yahoo or may be not, or it was a tool that changed the format.

                  The situation here is that the data is the key to the problems shown here and the only thing for which not a single sample line is shown.

                  1 Reply Last reply Reply Quote 0
                  • M
                    mahbubk9 last edited by backtrader

                    Thanks,
                    The format of my data is DD/MM/YYYY, downloaded from yahoo historical prices, i didn't make any change afterwards. I actually don't need yahoo data, was just trying out...
                    So, my main problem is loading genericCSVdata, the data i have is 1 min time frame data, shall i download tick data (instrument/date/bid/ask format) and let backtrader resample?

                    This is my 1 min data

                    0_1496077702230_e7b24477-ef88-445b-abf6-327b8055f95e-image.png

                    Local time	Open	High	Low	Close	Volume
                    29.02.2016 00:00:00.000	1.38606	1.38614	1.38591	1.38593	97.64
                    29.02.2016 00:01:00.000	1.38593	1.38616	1.38591	1.38598	142.93
                    29.02.2016 00:02:00.000	1.38599	1.38606	1.38596	1.38597	101.98
                    
                    

                    This is tick data

                    0_1496077984610_a9bed27c-4f44-4810-b32a-b9cbdfeb8e9e-image.png

                    GBP/USD	20160601 00:00:00.133	1.44831	1.44842
                    GBP/USD	20160601 00:00:00.134	1.44831	1.44842
                    GBP/USD	20160601 00:00:00.294	1.44831	1.44842
                    GBP/USD	20160601 00:00:00.300	1.44831	1.44842
                    

                    What changes do I need to make for it to work, please?

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

                      If your data is already in 1-minute format you have to tell GenericCSVData that the timeframe=bt.TimeFrame.Minutes.

                      The data feed cannot magically know what the timeframe of your data is. And even if you thing it should, because it could scan the file and apply heuristics, that would take time and could not be applied to dynamic data feeds.

                      1 Reply Last reply Reply Quote 0
                      • M
                        mahbubk9 last edited by

                        I understand your point, but why is it not trading after putting the the timeframe and compression? what can be still wrong with the data?

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

                          Dataless based diagnostics are impossible. Let's elaborate:

                          • You have a strategy which is not producing trades

                          • The data is apparently loaded with the wrong timeframe (default is Days, but the data is Minutes)

                            • Which would confuse the broker if the timespan is too short
                          • Once the timeframe is correctly specified, the following could for example happen:

                            • The minimum period calculated by the indicators is too large for the the input data to move into actual next (i.e.: it remains in the prenext phase)

                            • The conditions for the trades are never met (regardless of whether they were correctly or incorrectly specified)

                          Your strategy has a

                          self.log('Close, %.2f' % self.dataclose[0])
                          

                          By simply seeing if that statement produces output, you can rule out if you never make it to next.

                          You could also not only print the close price, but also print the value of the indicators or look at the plotted chart to see if the values are being met.

                          Using a writer (with csv) activated can save you some time into getting the indicator values printed out. See:

                          • Docs - Writer
                          • Blos - Writers - Write it down

                          For each indicator for which you want output you need to do:

                          myind.csv = True
                          
                          1 Reply Last reply Reply Quote 1
                          • M
                            mahbubk9 last edited by

                            Thanks for elaborating, this is the output;

                            016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-03-31, Close, 1.44
                            2016-04-01, Close, 1.44
                            Final Portfolio Value: 1000.44
                            
                            1 Reply Last reply Reply Quote 0
                            • 1 / 1
                            • First post
                              Last post
                            Copyright © 2016, 2017, 2018, 2019, 2020, 2021 NodeBB Forums | Contributors