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 -
@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.605828See 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.
- You show data but none of the
-
@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! -
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.
-
Hello, this happens because some platforms prefetch data. Is it possible to do the same in backtrader with IB live trading? For example, if I use 1minute timeframe I want my Moving Averages be calculated using yesterday's data. Is this possible?
Thanks.
Alex.