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

SMA doesn't show correct values (vs Tradingview, manual python calculations)



  • Hi All,

    I'm trying to implement a simple SMA double cross strategy, but it seems that values don't match with my references (Tradingview and manual python calculations; these two matching exactly).

    my py method:

    def SMA(values, window):
        return values.rolling(window).mean()
    

    Can you advise?

    Thanks a lot in advance

    from collections import OrderedDict
    
    class SmaCross(bt.SignalStrategy):
            params = (
                ('pfast', 15),
                ('pslow', 100),
                ('printlog', False),
            )
        
            def log(self, txt, dt=None):
                ''' Logging function fot this strategy'''
                dt = dt or self.datas[0].datetime.datetime(0)
                print('%s, %s' % (dt.isoformat(), txt))
    
            def __init__(self):
                self.dataclose = self.datas[0].close
                
                self.order = None
                self.buyprice = None
                self.buycomm = None
                
                sma1 = bt.ind.SimpleMovingAverage(self.data.close, period=self.params.pfast)
                sma2 = bt.ind.SimpleMovingAverage(self.data.close, period=self.params.pslow)
                self.Cross = bt.ind.CrossOver(sma1, sma2)
            
            def next(self):
                if self.order:
                    return
                
                if not self.position:
                    if self.Cross:
                        self.log('BUY CREATE, %.2f' % self.dataclose[0])
                        self.buy(size = 1)
                        
                else:
                    if self.Cross == -1:
                        self.log('SELL CREATE, %.2f' % self.dataclose[0])
                        self.sell(size = 1)
    
    def printTradeAnalysis(analyzer):
        '''
        Function to print the Technical Analysis results in a nice format.
        '''
        #Get the results we are interested in
    
        total_open = analyzer.total.open
        total_closed = analyzer.total.closed
        total_won = analyzer.won.total
        total_lost = analyzer.lost.total
        win_streak = analyzer.streak.won.longest
        lose_streak = analyzer.streak.lost.longest
        pnl_net = round(analyzer.pnl.net.total,2)
        strike_rate = round((total_won / total_closed) * 100, 2)
        #Designate the rows
        h1 = ['Total Open', 'Total Closed', 'Total Won', 'Total Lost']
        h2 = ['Strike Rate','Win Streak', 'Losing Streak', 'PnL Net']
        r1 = [total_open, total_closed,total_won,total_lost]
        r2 = [strike_rate, win_streak, lose_streak, pnl_net]
        #Check which set of headers is the longest.
        if len(h1) > len(h2):
            header_length = len(h1)
        else:
            header_length = len(h2)
        #Print the rows
        print_list = [h1,r1,h2,r2]
        row_format ="{:<15}" * (header_length + 1)
        print("Trade Results:")
        for row in print_list:
            print(row_format.format('',*row))
    
    def printSQN(analyzer):
        sqn = round(analyzer.sqn,2)
        print('SQN: {}'.format(sqn))
    
    
    if __name__ == '__main__':
        
        startcash = 10000
        
        cerebro = bt.Cerebro()
        
        cerebro.addstrategy(SmaCross)
    
        # Datas are in a subfolder of the samples. Need to find where the script is
        # because it could have been called from anywhere
        modpath = os.path.dirname('D:\\Dropbox\\projectPy\\')
        datapath = os.path.join(modpath, 'test4.csv')
    
        # Create a Data Feed
        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,7,2,11,0,1),
            todate = datetime(2018,7,25,11,0,1),
            separator=',',
            dtformat=('%Y-%m-%d %H:%M:%S')
            )
    
        cerebro.adddata(data)
        
        cerebro.broker.setcash(startcash)
        
        # Add the analyzers we are interested in
        cerebro.addanalyzer(bt.analyzers.TradeAnalyzer, _name="ta")
        cerebro.addanalyzer(bt.analyzers.SQN, _name="sqn")
     
        # Run over everything
        strategies = cerebro.run(maxcpus=1)
        SmaCrossStrat = strategies[0]
        
        portvalue = cerebro.broker.getvalue()
     
        #Print out the final result
        print('Final Portfolio Value: ${}\nStarting Cash: ${}'.format(portvalue, startcash))
        
        printSQN(SmaCrossStrat.analyzers.sqn.get_analysis())
        
        # print the analyzers
        printTradeAnalysis(SmaCrossStrat.analyzers.ta.get_analysis())
        #for x in SmaCrossStrat.analyzers:
        #    x.print()
        
        #Finally plot the end results
        cerebro.plot(style='candlestick',barup='green',bardown='red', iplot = False)  
    

    Output:

    2018-07-02T12:00:00, BUY CREATE, 6331.03
    2018-07-07T22:00:00, SELL CREATE, 6530.70
    2018-07-08T01:00:00, BUY CREATE, 6761.80
    2018-07-10T11:00:00, SELL CREATE, 6443.80
    2018-07-15T09:00:00, BUY CREATE, 6278.90
    2018-07-21T11:00:00, SELL CREATE, 7326.00
    2018-07-22T03:00:00, BUY CREATE, 7478.20
    Final Portfolio Value: $11198.3
    Starting Cash: $10000
    SQN: 0.95
    Trade Results:
                   Total Open     Total Closed   Total Won      Total Lost     
                   1              3              2              2              
                   Strike Rate    Win Streak     Losing Streak  PnL Net        
                   66.67          1              1              928.6          
    

    My reference data (both fine with Tradingview and python manual check):
    Close SMA15 SMA100
    Date
    2018-07-02 10:00:00 6341.700000 6334.681390 6196.541828
    2018-07-02 11:00:00 6324.900000 6335.248056 6198.605828
    2018-07-02 12:00:00 6331.026474 6335.763155 6200.873093
    2018-07-02 13:00:00 6341.200000 6335.035098 6203.105093
    2018-07-02 14:00:00 6342.969553 6333.233069 6205.342788
    2018-07-07 20:00:00 6554.000000 6573.993333 6569.899519
    2018-07-07 21:00:00 6541.900000 6570.040000 6569.482519
    2018-07-07 22:00:00 6530.700000 6565.680000 6568.942519
    2018-07-07 23:00:00 6531.700000 6562.273333 6568.460519
    2018-07-08 00:00:00 6579.300000 6561.266667 6568.515519
    2018-07-08 02:00:00 6748.046810 6584.629787 6571.408987
    2018-07-08 03:00:00 6743.100000 6594.629787 6572.729987
    2018-07-08 04:00:00 6747.100000 6605.536454 6575.331987
    2018-07-10 09:00:00 6602.600000 6664.180000 6646.618688
    2018-07-10 10:00:00 6590.900000 6657.053333 6647.275688
    2018-07-10 11:00:00 6443.800000 6639.906667 6646.673688
    2018-07-10 12:00:00 6470.100000 6623.660000 6646.710688
    2018-07-10 13:00:00 6359.200000 6601.000000 6645.463688


  • administrators

    @julianus said in SMA doesn't show correct values (vs Tradingview, manual python calculations):

    but it seems that values don't match with my references

    Your references are then wrong or your comparison/testing method is wrong. I don't really know, but it is as easy to blame those for me as it is to say that this framework produces wrong values.

    @julianus said in SMA doesn't show correct values (vs Tradingview, manual python calculations):

    My reference data (both fine with Tradingview and python manual check):
    Close SMA15 SMA100
    Date
    2018-07-02 10:00:00 6341.700000 6334.681390 6196.541828
    2018-07-02 11:00:00 6324.900000 6335.248056 6198.605828

    See the problem

    • You show data but none of the close prices which lead to the 1st possible calculation of a 100 periods moving average
    • You don't show which values are being produced by backtrader. How can we compare and know what's wrong?
    • We don't have a script to see how you produced those values? (you posted a single method)
    • If the problem is the value of a moving average, why the need for a complete SMA Crossover script? Limit the script to a single moving average and if there is a problem it will be a lot easier to spot it.


  • @backtrader, thanks a lot for your reply.
    After due testing, I've realized that the reason it showed different values was that the SMA calculation start date was different, so then the values.

    Apologies if something slipped through, it was very far from my intention to blame anyone, on the contrary, I'm amazed by the flexibility of the platform and the wide range of strategies I can try out.
    I'm a new one in python and backtrader and sometime a newbie question comes. Good luck with the development!


  • administrators

    No need to apologize. We have all been new to everything and it isn't obvious that when reporting something (even if what we report is wrong), reporting as much information as possible helps.