Optimization standard script doesn't give required output



  • 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?


  • administrators

    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?



  • @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$.


  • administrators

    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 ...



  • @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).


  • administrators

    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.


Log in to reply
 

Looks like your connection to Backtrader Community was lost, please wait while we try to reconnect.