For code/output blocks: Use ``` (aka backtick or grave accent) in a single line before and after the block. See: http://commonmark.org/help/

Basic MultiTimeframe order



  • So I have been following along with multitimeframe indicators as shown by the Backtrader website however I am having issues with sending basic buy and sell orders through.

    Where I am folloing along

    from __future__ import (absolute_import, division, print_function,
                            unicode_literals)
    import argparse
    
    import backtrader as bt
    import backtrader.feeds as btfeeds
    import backtrader.indicators as btind
    from datetime import datetime
    
    class SMAStrategy(bt.Strategy):
        params = (
            ('period', 10),
            ('onlydaily', False),
        )
    
        def __init__(self):
            self.sma_small_tf = btind.MACDHisto(self.data, period_me1 = 12, period_me2 = 26, period_signal=9)
            if not self.p.onlydaily:
                self.sma_large_tf = btind.MACDHisto(self.data1, period_me1 = 12, period_me2 = 26, period_signal=9)
    
        def nextstart(self):
            print('--------------------------------------------------')
            print('nextstart called with len', len(self))
            print('--------------------------------------------------')
            if not self.position:
                if self.sma_large_tf.histo > self.sma_large_tf.histo[-1] and self.sma_small_tf.histo > self.sma_large_tf.histo[-1]:
                    self.buy()
                    print("Orderbuy")
            else:
                if self.sma_large_tf.histo < self.sma_large_tf.histo[-1] and self.sma_small_tf.histo < self.sma_small_tf.histo[-1]:
                    self.sell()
            super(SMAStrategy, self).nextstart()
    
    def runstrat():
        args = parse_args()
    
        # Create a cerebro entity
        startcash = 10000
        cerebro = bt.Cerebro(stdstats=False)
    
        # Add a strategy
        if not args.indicators:
            cerebro.addstrategy(bt.Strategy)
        else:
            cerebro.addstrategy(
                SMAStrategy,
    
                # args for the strategy
                period=args.period,
                onlydaily=args.onlydaily,
            )
    
        # Load the Data
        datapath = args.dataname or '../../datas/2006-day-001.txt'
        data = bt.feeds.YahooFinanceData(
        dataname='SPY',
        fromdate = datetime(2020,1,1),
        todate = datetime(2020,4,1),
        timeframe = bt.TimeFrame.Days,
        buffered= True
        )
        cerebro.adddata(data)  # First add the original data - smaller timeframe
    
        tframes = dict(daily=bt.TimeFrame.Days, weekly=bt.TimeFrame.Weeks,
                       monthly=bt.TimeFrame.Months)
    
        # Handy dictionary for the argument timeframe conversion
        # Resample the data
        if args.noresample:
            datapath = args.dataname2 or '../../datas/2006-week-001.txt'
            data2 = btfeeds.BacktraderCSVData(dataname=datapath)
            # And then the large timeframe
            cerebro.adddata(data2)
        else:
            cerebro.resampledata(data, timeframe=tframes[args.timeframe],
                                 compression=args.compression)
    
        # Run over everything
        cerebro.run()
        portvalue = cerebro.broker.getvalue()
        pnl = portvalue - startcash
    
        #Print out the final result
        print('Final Portfolio Value: ${}'.format(portvalue))
        print('P/L: ${}'.format(pnl))
        # Plot the result
        cerebro.plot(style='bar')
    
    
    def parse_args():
        parser = argparse.ArgumentParser(
            description='Multitimeframe test')
    
        parser.add_argument('--dataname', default='', required=False,
                            help='File Data to Load')
    
        parser.add_argument('--dataname2', default='', required=False,
                            help='Larger timeframe file to load')
    
        parser.add_argument('--noresample', action='store_true',
                            help='Do not resample, rather load larger timeframe')
    
        parser.add_argument('--timeframe', default='weekly', required=False,
                            choices=['daily', 'weekly', 'monhtly'],
                            help='Timeframe to resample to')
    
        parser.add_argument('--compression', default=1, required=False, type=int,
                            help='Compress n bars into 1')
    
        parser.add_argument('--indicators', action='store_true',
                            help='Wether to apply Strategy with indicators')
    
        parser.add_argument('--onlydaily', action='store_true',
                            help='Indicator only to be applied to daily timeframe')
    
        parser.add_argument('--period', default=10, required=False, type=int,
                            help='Period to apply to indicator')
    
        return parser.parse_args()
    
    if __name__ == '__main__':
    

    I placed the order logic in nextstart() because if it is my understanding a nextstart() will initiate after the higher timeframe will close. Any guidance will be greatly appreciated



  • From Operating the Platform in the docs.

    nextstart

    Called exactly ONCE when the minimum period for the line iterator` has been met.

    The default behavior is to forward the call to next, but can of course be overriden if needed.

    Place your orders in next().



  • @run-out Ok I think I understand now. So nextstart() ensures that the higher time frame completes the bar before letting the program continue? Also indicators from a higher time frame have there current index equals to their previous, [0] becomes [-1]? I understand where self.data gets its data however I am a bit confused about self.data1, does it originate from the cerebor.resampledata?

    Thank You!! Much appreciated



  • @Paul-Park said in Basic MultiTimeframe order:

    So nextstart() ensures that the higher time frame completes the bar before letting the program continue?

    nextstart() has no relation to time frames. It is called once between last prenext() call and first next() call - ref Docs - Strategy.



  • @ab_trader said in Basic MultiTimeframe order:

    @Paul-Park said in Basic MultiTimeframe order:

    So nextstart() ensures that the higher time frame completes the bar before letting the program continue?

    nextstart() has no relation to time frames.

    Ahh I see where my confusion was now. Thank you very much.


Log in to reply
 

});