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

optstrategy same results in Jupyter



  • Hey all,

    First of all congrats for backtrader for the platform, it seems awesome. Although I'm just starting to use it, ended up in a problem during strategy optimization. With stop(self) works fine, but when I want to get the results based on the objects list, it circulates with the same figures.
    Here's the code:

    import backtrader as bt
    from datetime import datetime
    
    class firstStrategy(bt.Strategy):
        params = (
            ('period',21),
            )
     
        def __init__(self):
            self.startcash = self.broker.getvalue()
            self.rsi = bt.indicators.RSI_SMA(self.data.close, period=self.params.period)
     
        def next(self):
            if not self.position:
                if self.rsi < 30:
                    self.buy(size=1)
            else:
                if self.rsi > 65:
                    self.sell(size=1)
     
        def stop(self):
            pnl = round(self.broker.getvalue() - self.startcash,2)
            print('RSI Period: {} Final PnL: {}'.format(
                self.params.period, pnl))        
               
    if __name__ == '__main__':
        startcash = 10000
        cerebro = bt.Cerebro(optreturn=False)
    
        cerebro.optstrategy(firstStrategy, period=range(20,25))
    
        modpath = os.path.dirname('D:\\Dropbox\\hye\\')
        datapath = os.path.join(modpath, 'test4.csv')
        
        data = bt.feeds.GenericCSVData(
            dataname=datapath,
            timeframe=bt.TimeFrame.Minutes, compression=60,
            datetime=0,
            open = 1,
            high = 3,
            low = 4,
            close = 2,
            volume = 5,
            openinterest = -1,
            fromdate = datetime(2018,5,2,11,0,1),
            todate = datetime(2018,5,20,11,0,1),
            separator=',',
            dtformat=('%Y-%m-%d %H:%M:%S')
            )
        
        cerebro.adddata(data)
        cerebro.broker.setcash(startcash)
    
        opt_runs = cerebro.run(maxcpus=1)   
           
        final_results_list = []
        for run in opt_runs:       
            for strategy in run:
                value = round(strategy.broker.get_value(),2)
                PnL = round(value - startcash,2)
                period = strategy.params.period
                final_results_list.append([period,PnL])
                
        by_period = sorted(final_results_list, key=lambda x: x[0])
        by_PnL = sorted(final_results_list, key=lambda x: x[1], reverse=True)
     
        print('\nResults: Ordered by period:')
        for result in by_period:
            print('Period: {}, PnL: {}'.format(result[0], result[1]))
        print('Results: Ordered by Profit:')
        for result in by_PnL:
            print('Period: {}, PnL: {}'.format(result[0], result[1]))
    

    This gives out:

    RSI Period: 20 Final PnL: -628.52
    RSI Period: 21 Final PnL: -658.0
    RSI Period: 22 Final PnL: -718.4
    RSI Period: 23 Final PnL: -601.3
    RSI Period: 24 Final PnL: -502.5
    
    Results: Ordered by period:
    Period: 20, PnL: -502.5
    Period: 21, PnL: -502.5
    Period: 22, PnL: -502.5
    Period: 23, PnL: -502.5
    Period: 24, PnL: -502.5
    Results: Ordered by Profit:
    Period: 20, PnL: -502.5
    Period: 21, PnL: -502.5
    Period: 22, PnL: -502.5
    Period: 23, PnL: -502.5
    Period: 24, PnL: -502.5
    

    Thanks a lot for your help.


  • administrators

    This has nothing to with Jupyter and the question has already been asked and answered. See here: https://community.backtrader.com/topic/1149/optimization-can-you-reproduce-this-bug/

    The stop method is there to collect the results. If you optimize and later collect results you are only accessing what has happened in the main process, which is the one you are operating in.



  • @backtrader thanks a lot, working as needed now.