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/

    Optimization standard script doesn't give required output

    General Code/Help
    2
    6
    1308
    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.
    • fbleaux
      fbleaux last edited by

      from __future__ import (absolute_import, division, print_function,
                              unicode_literals)
      
      import datetime  # For datetime objects
      import backtrader.feeds as btfeed
      # Import the backtrader platform
      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)
      
          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.dataclose[0] > self.sma[0]:
      
                      # BUY, BUY, BUY!!! (with all possible 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:
      
                  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)
      
      # Create a cerebro entity
      cerebro = bt.Cerebro()
      # Add a strategy
      cerebro.addstrategy(TestStrategy)
      # Create a Data Feed
      class Tickstory(btfeed.GenericCSVData):
          params = (
              ('dtformat', '%Y%m%d %H:%M:%S'),
              ('datetime', 0),
              ('time', -1),
              ('open', 1),
              ('high', 2),
              ('low', 3),
              ('close', 4),
              ('volume', -1),
              ('openinterest', -1),
              ('timeframe', bt.TimeFrame.Minutes),
              ('compression', 1)
          )
      # Develop feed    
      data1 = Tickstory(dataname='/Users/rf/Documents/DSC/Datasets/inga.csv')
      # Add the Data Feed to Cerebro
      cerebro.adddata(data1)
      # Add a strategy
      strats = cerebro.optstrategy(
          TestStrategy,
          maperiod=range(10, 31))
      # 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 - 0.1% ... divide by 100 to remove the %
      cerebro.broker.setcommission(commission=0.0)
      # Run over everything
      cerebro.run()
      

      Gives output:

      2017-09-04, (MA Period 15) Ending Value 151113.20
      2017-09-04, (MA Period 20) Ending Value 151113.20
      2017-09-04, (MA Period 15) Ending Value 151040.80
      2017-09-04, (MA Period 19) Ending Value 151040.80
      2017-09-04, (MA Period 15) Ending Value 151569.50
      2017-09-04, (MA Period 18) Ending Value 151569.50
      2017-09-04, (MA Period 15) Ending Value 151032.00
      2017-09-04, (MA Period 21) Ending Value 151032.00
      2017-09-04, (MA Period 15) Ending Value 151565.15
      2017-09-04, (MA Period 13) Ending Value 151565.15
      2017-09-04, (MA Period 15) Ending Value 151794.85
      2017-09-04, (MA Period 10) Ending Value 151794.85
      2017-09-04, (MA Period 15) Ending Value 151411.65
      2017-09-04, (MA Period 12) Ending Value 151411.65
      2017-09-04, (MA Period 15) Ending Value 151186.20
      2017-09-04, (MA Period 11) Ending Value 151186.20
      2017-09-04, (MA Period 15) Ending Value 150927.00
      2017-09-04, (MA Period 22) Ending Value 150927.00
      2017-09-04, (MA Period 15) Ending Value 901.50
      2017-09-04, (MA Period 15) Ending Value 901.50
      2017-09-04, (MA Period 15) Ending Value 151446.85
      2017-09-04, (MA Period 14) Ending Value 151446.85
      2017-09-04, (MA Period 15) Ending Value 151019.40
      2017-09-04, (MA Period 16) Ending Value 151019.40
      2017-09-04, (MA Period 15) Ending Value 151564.30
      2017-09-04, (MA Period 17) Ending Value 151564.30
      2017-09-04, (MA Period 15) Ending Value 151569.50
      2017-09-04, (MA Period 18) Ending Value 151569.50
      2017-09-04, (MA Period 15) Ending Value 151040.80
      2017-09-04, (MA Period 19) Ending Value 151040.80
      2017-09-04, (MA Period 15) Ending Value 151113.20
      2017-09-04, (MA Period 20) Ending Value 151113.20
      2017-09-04, (MA Period 15) Ending Value 151032.00
      2017-09-04, (MA Period 21) Ending Value 151032.00
      2017-09-04, (MA Period 15) Ending Value 150927.00
      2017-09-04, (MA Period 22) Ending Value 150927.00
      2017-09-04, (MA Period 15) Ending Value 151008.05
      2017-09-04, (MA Period 23) Ending Value 151008.05
      2017-09-04, (MA Period 15) Ending Value 151091.55
      2017-09-04, (MA Period 24) Ending Value 151091.55
      2017-09-04, (MA Period 15) Ending Value 150822.85
      2017-09-04, (MA Period 25) Ending Value 150822.85
      2017-09-04, (MA Period 15) Ending Value 150686.25
      2017-09-04, (MA Period 26) Ending Value 150686.25
      2017-09-04, (MA Period 15) Ending Value 150413.45
      2017-09-04, (MA Period 27) Ending Value 150413.45
      2017-09-04, (MA Period 15) Ending Value 150523.50
      2017-09-04, (MA Period 28) Ending Value 150523.50
      2017-09-04, (MA Period 15) Ending Value 150556.80
      2017-09-04, (MA Period 29) Ending Value 150556.80
      2017-09-04, (MA Period 15) Ending Value 150265.75
      2017-09-04, (MA Period 30) Ending Value 150265.75
      Out[4]: 
      [[<backtrader.cerebro.OptReturn at 0x102aea0b8>,
        <backtrader.cerebro.OptReturn at 0x102aea208>],
       [<backtrader.cerebro.OptReturn at 0x102aea320>,
        <backtrader.cerebro.OptReturn at 0x102aea4a8>],
       [<backtrader.cerebro.OptReturn at 0x102aea128>,
        <backtrader.cerebro.OptReturn at 0x102aea358>],
       [<backtrader.cerebro.OptReturn at 0x102ad1d68>,
        <backtrader.cerebro.OptReturn at 0x102ad1ef0>],
       [<backtrader.cerebro.OptReturn at 0x102aea588>,
        <backtrader.cerebro.OptReturn at 0x102aea898>],
       [<backtrader.cerebro.OptReturn at 0x102aea048>,
        <backtrader.cerebro.OptReturn at 0x102aea748>],
       [<backtrader.cerebro.OptReturn at 0x102aea6d8>,
        <backtrader.cerebro.OptReturn at 0x102aea9e8>],
       [<backtrader.cerebro.OptReturn at 0x102aea828>,
        <backtrader.cerebro.OptReturn at 0x102aeab38>],
       [<backtrader.cerebro.OptReturn at 0x102aea978>,
        <backtrader.cerebro.OptReturn at 0x102aeac88>],
       [<backtrader.cerebro.OptReturn at 0x102aeaac8>,
        <backtrader.cerebro.OptReturn at 0x102aeadd8>],
       [<backtrader.cerebro.OptReturn at 0x102aeac18>,
        <backtrader.cerebro.OptReturn at 0x102aeaf28>],
       [<backtrader.cerebro.OptReturn at 0x102aeaef0>,
        <backtrader.cerebro.OptReturn at 0x102ac50b8>],
       [<backtrader.cerebro.OptReturn at 0x102aea080>,
        <backtrader.cerebro.OptReturn at 0x102ac5208>],
       [<backtrader.cerebro.OptReturn at 0x102ac5048>,
        <backtrader.cerebro.OptReturn at 0x102ac5358>],
       [<backtrader.cerebro.OptReturn at 0x102ac5198>,
        <backtrader.cerebro.OptReturn at 0x102ac54a8>],
       [<backtrader.cerebro.OptReturn at 0x102ac52e8>,
        <backtrader.cerebro.OptReturn at 0x102ac55f8>],
       [<backtrader.cerebro.OptReturn at 0x102ac5438>,
        <backtrader.cerebro.OptReturn at 0x102ac5748>],
       [<backtrader.cerebro.OptReturn at 0x102ac5828>,
        <backtrader.cerebro.OptReturn at 0x102ac5978>],
       [<backtrader.cerebro.OptReturn at 0x102ac5588>,
        <backtrader.cerebro.OptReturn at 0x102ac57f0>],
       [<backtrader.cerebro.OptReturn at 0x102ac56d8>,
        <backtrader.cerebro.OptReturn at 0x102ac5b38>],
       [<backtrader.cerebro.OptReturn at 0x102ac5c18>,
        <backtrader.cerebro.OptReturn at 0x102ac5d68>]]
      

      And should give:

      2000-12-29, (MA Period 10) Ending Value 880.30
      2000-12-29, (MA Period 11) Ending Value 880.00
      2000-12-29, (MA Period 12) Ending Value 830.30
      2000-12-29, (MA Period 13) Ending Value 893.90
      2000-12-29, (MA Period 14) Ending Value 896.90
      2000-12-29, (MA Period 15) Ending Value 973.90
      2000-12-29, (MA Period 16) Ending Value 959.40
      2000-12-29, (MA Period 17) Ending Value 949.80
      2000-12-29, (MA Period 18) Ending Value 1011.90
      2000-12-29, (MA Period 19) Ending Value 1041.90
      2000-12-29, (MA Period 20) Ending Value 1078.00
      2000-12-29, (MA Period 21) Ending Value 1058.80
      2000-12-29, (MA Period 22) Ending Value 1061.50
      2000-12-29, (MA Period 23) Ending Value 1023.00
      2000-12-29, (MA Period 24) Ending Value 1020.10
      2000-12-29, (MA Period 25) Ending Value 1013.30
      2000-12-29, (MA Period 26) Ending Value 998.30
      2000-12-29, (MA Period 27) Ending Value 982.20
      2000-12-29, (MA Period 28) Ending Value 975.70
      2000-12-29, (MA Period 29) Ending Value 983.30
      2000-12-29, (MA Period 30) Ending Value 979.80
      

      As stated in https://www.backtrader.com/docu/quickstart/quickstart.html.

      # Set our desired cash start
      cerebro.broker.setcash(1000.0)
      

      It's very strange as it gives one good output:

      2017-09-04, (MA Period 15) Ending Value 901.50
      2017-09-04, (MA Period 15) Ending Value 901.50
      

      Can someone asses the script and see where the fault lies?

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

        The tutorial targets a specific data feed which ends on 2000-12-29 and is of daily nature.

        You are targetting a custom data feed which is of Minutes nature and ends on 2017-09-04.

        Why should the results be the same?

        fbleaux 1 Reply Last reply Reply Quote 0
        • fbleaux
          fbleaux @backtrader last edited by

          @backtrader It's not about the date but about the cashflow. It gives value above the 150000 and I like to know where it comes from as I set the cash to 1000$.

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

            Sorry but the messages are confusing.

            • You first say the output should give the same as stated in the Quickstart Guide, which is obviously impossible.

            Then

            • You show several runs of scripts, which is also not in the Quickstart Guide including for example:
              2017-09-04, (MA Period 15) Ending Value 151113.20
              

            But you then say

            @fbleaux said in Optimization standard script doesn't give required output:

            It's very strange as it gives one good output:

            2017-09-04, (MA Period 15) Ending Value 901.50
            2017-09-04, (MA Period 15) Ending Value 901.50
            

            Which doesn't match any of the previous shown output.

            At the end the only reason for a value increase is that you constantly sell the asset (no safeguards in place) which increases your cash reserves.

            But without data, without any hint as to how things are executed ...

            fbleaux 1 Reply Last reply Reply Quote 0
            • fbleaux
              fbleaux @backtrader last edited by

              @backtrader This is the logic behind the script:

                          # Not yet ... we MIGHT BUY if ...
                          if self.dataclose[0] > self.sma[0]:
              
                              # BUY, BUY, BUY!!! (with all possible 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:
              
                          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)
              

              I've uploaded the dataset to: https://ufile.io/cmhym
              Btw, I am well aware that MA run on daily basis and not made for intraday so I'll have to configure later the parameters optimization to use linspace 540 lines (one trading day).

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

                Your best bet is to see the buy/sell output lines in a non-optimized run. Your cash (and therefore value) increase when you sell an asset. And that's probably what's happening.

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