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/

    Backtrader TestStrategy Output Repeating

    General Code/Help
    2
    3
    70
    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.
    • O
      Onkoko last edited by

      Hi,
      I've read a lot here but this is my first post.
      I've been tring the backtrader quickstart guide.
      The code and source data are all the same with website like copy/paste but the output is not the same and on the other hand my output is repeating the "maperiod=15" after every line in the loop and I couldn't find it why. Any ideas?

      Here is my code which is no different than the tutorial..

      import backtrader as bt
      
      
      # Create a Stratey
      class TestStrategy(bt.Strategy):
          params = (
              ('maperiod', 15),
              ('printlog', False),
          )
      
          def log(self, txt, dt=None, doprint=False):
              ''' Logging function fot this strategy'''
              if self.params.printlog or doprint:
                  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)
      
              # 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 enough 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:
                      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.dataclose[0] > self.sma[0]:
                      # BUY, BUY, BUY!!! (with default parameters)
                      self.log('BUY CREATE, %.2f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.buy()
      
              else:
      
                  # Already in the market ... we might sell
                  if self.dataclose[0] < self.sma[0]:
                      # SELL, SELL, SELL!!! (with all possible default parameters)
                      self.log('SELL CREATE, %.2f' % self.dataclose[0])
      
                      # Keep track of the created order to avoid a 2nd order
                      self.order = self.sell()
      
          def stop(self):
              self.log('(MA Period %2d) Ending Value %.2f' %
                       (self.params.maperiod, self.broker.getvalue()), doprint=True)
      
      

      This is my main.py

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import backtrader as bt
      import datetime  # For datetime objects
      import os.path  # To manage paths
      import sys  # To find out the script name (in argv[0])
      from TestStrategy import TestStrategy
      
      
      if __name__ == '__main__':
          cerebro = bt.Cerebro()
      
          # Add a strategy
          strats = cerebro.optstrategy(
              TestStrategy,
              maperiod=range(10, 31))
      
          cerebro.addstrategy(TestStrategy)
      
          modpath = os.path.dirname(os.path.abspath(sys.argv[0]))
          datapath = os.path.join(modpath, 'datas/orcl-1995-2014.txt')
      
          # Create a Data Feed
          data = bt.feeds.YahooFinanceCSVData(
              dataname=datapath,
              # Do not pass values before this date
              fromdate=datetime.datetime(2000, 1, 1),
              # Do not pass values after this date
              todate=datetime.datetime(2000, 12, 31),
              reverse=False)
      
          # 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)
      
          # Run over everything
          cerebro.run(maxcpus=1)
         # print('Final Portfolio Value: %.2f' % cerebro.broker.getvalue())
      
          #cerebro.plot(style='candlestick')
      
      

      Here is the output..

      2000-12-29, (MA Period 10) Ending Value 10807.80
      2000-12-29, (MA Period 15) Ending Value 10807.80
      2000-12-29, (MA Period 11) Ending Value 10731.00
      2000-12-29, (MA Period 15) Ending Value 10731.00
      2000-12-29, (MA Period 12) Ending Value 10811.00
      2000-12-29, (MA Period 15) Ending Value 10811.00
      2000-12-29, (MA Period 13) Ending Value 10637.90
      2000-12-29, (MA Period 15) Ending Value 10637.90
      2000-12-29, (MA Period 14) Ending Value 10557.30
      2000-12-29, (MA Period 15) Ending Value 10557.30
      2000-12-29, (MA Period 15) Ending Value 953.40
      2000-12-29, (MA Period 15) Ending Value 953.40
      2000-12-29, (MA Period 16) Ending Value 6922.80
      2000-12-29, (MA Period 15) Ending Value 6922.80
      2000-12-29, (MA Period 17) Ending Value 10443.70
      2000-12-29, (MA Period 15) Ending Value 10443.70
      2000-12-29, (MA Period 18) Ending Value 10686.00
      2000-12-29, (MA Period 15) Ending Value 10686.00
      2000-12-29, (MA Period 19) Ending Value 9572.00
      2000-12-29, (MA Period 15) Ending Value 9572.00
      2000-12-29, (MA Period 20) Ending Value 9615.10
      2000-12-29, (MA Period 15) Ending Value 9615.10
      2000-12-29, (MA Period 21) Ending Value 11161.50
      2000-12-29, (MA Period 15) Ending Value 11161.50
      2000-12-29, (MA Period 22) Ending Value 11220.80
      2000-12-29, (MA Period 15) Ending Value 11220.80
      2000-12-29, (MA Period 23) Ending Value 9844.60
      2000-12-29, (MA Period 15) Ending Value 9844.60
      2000-12-29, (MA Period 24) Ending Value 9882.70
      2000-12-29, (MA Period 15) Ending Value 9882.70
      2000-12-29, (MA Period 25) Ending Value 9882.70
      2000-12-29, (MA Period 15) Ending Value 9882.70
      2000-12-29, (MA Period 26) Ending Value 11160.70
      2000-12-29, (MA Period 15) Ending Value 11160.70
      2000-12-29, (MA Period 27) Ending Value 11161.00
      2000-12-29, (MA Period 15) Ending Value 11161.00
      2000-12-29, (MA Period 28) Ending Value 9851.50
      2000-12-29, (MA Period 15) Ending Value 9851.50
      2000-12-29, (MA Period 29) Ending Value 9851.50
      2000-12-29, (MA Period 15) Ending Value 9851.50
      2000-12-29, (MA Period 30) Ending Value 9851.50
      2000-12-29, (MA Period 15) Ending Value 9851.50

      Process finished with exit code 0

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

        @onkoko

        The problem is that in addition to using optstrategy call you are adding yet another instance of the stragegy to the pull by using addstrategy ( probably copy/paste error ). It means that during the optimization run, two strategies will always be instantiated for each permutation of parameters ( in your case for each value of maperiod from 10 to 31 ) - one added through optstrategy and the other through addstrategy.

        So since the '(MA Perios XX)is printed inside yourstopstrategy's method - each time some strategy instance will complete, itsstop` method will be called and the above log will be printed.

        O 1 Reply Last reply Reply Quote 2
        • O
          Onkoko @vladisld last edited by

          @vladisld Thank you very much..

          your recomendation solved the issue perfectly..

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