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