Optimization standard script doesn't give required output
-
from __future__ import (absolute_import, division, print_function, unicode_literals) import datetime # For datetime objects import backtrader.feeds as btfeed # Import the backtrader platform import backtrader as bt # Create a Stratey class TestStrategy(bt.Strategy): params = ( ('maperiod', 15), ('printlog', False), ) def log(self, txt, dt=None, doprint=False): ''' Logging function fot this strategy''' if self.params.printlog or doprint: dt = dt or self.datas[0].datetime.date(0) print('%s, %s' % (dt.isoformat(), txt)) def __init__(self): # Keep a reference to the "close" line in the data[0] dataseries self.dataclose = self.datas[0].close # To keep track of pending orders and buy price/commission self.order = None self.buyprice = None self.buycomm = None # Add a MovingAverageSimple indicator self.sma = bt.indicators.SimpleMovingAverage( self.datas[0], period=self.params.maperiod) def notify_order(self, order): if order.status in [order.Submitted, order.Accepted]: # Buy/Sell order submitted/accepted to/by broker - Nothing to do return # Check if an order has been completed # Attention: broker could reject order if not enougth cash if order.status in [order.Completed]: if order.isbuy(): self.log( 'BUY EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.buyprice = order.executed.price self.buycomm = order.executed.comm else: # Sell self.log('SELL EXECUTED, Price: %.2f, Cost: %.2f, Comm %.2f' % (order.executed.price, order.executed.value, order.executed.comm)) self.bar_executed = len(self) elif order.status in [order.Canceled, order.Margin, order.Rejected]: self.log('Order Canceled/Margin/Rejected') # Write down: no pending order self.order = None def notify_trade(self, trade): if not trade.isclosed: return self.log('OPERATION PROFIT, GROSS %.2f, NET %.2f' % (trade.pnl, trade.pnlcomm)) def next(self): # Simply log the closing price of the series from the reference self.log('Close, %.2f' % self.dataclose[0]) # Check if an order is pending ... if yes, we cannot send a 2nd one if self.order: return # Check if we are in the market if not self.position: # Not yet ... we MIGHT BUY if ... if self.dataclose[0] > self.sma[0]: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell() def stop(self): self.log('(MA Period %2d) Ending Value %.2f' % (self.params.maperiod, self.broker.getvalue()), doprint=True) # Create a cerebro entity cerebro = bt.Cerebro() # Add a strategy cerebro.addstrategy(TestStrategy) # Create a Data Feed class Tickstory(btfeed.GenericCSVData): params = ( ('dtformat', '%Y%m%d %H:%M:%S'), ('datetime', 0), ('time', -1), ('open', 1), ('high', 2), ('low', 3), ('close', 4), ('volume', -1), ('openinterest', -1), ('timeframe', bt.TimeFrame.Minutes), ('compression', 1) ) # Develop feed data1 = Tickstory(dataname='/Users/rf/Documents/DSC/Datasets/inga.csv') # Add the Data Feed to Cerebro cerebro.adddata(data1) # Add a strategy strats = cerebro.optstrategy( TestStrategy, maperiod=range(10, 31)) # Set our desired cash start cerebro.broker.setcash(1000.0) # Add a FixedSize sizer according to the stake cerebro.addsizer(bt.sizers.FixedSize, stake=10) # Set the commission - 0.1% ... divide by 100 to remove the % cerebro.broker.setcommission(commission=0.0) # Run over everything cerebro.run()
Gives output:
2017-09-04, (MA Period 15) Ending Value 151113.20 2017-09-04, (MA Period 20) Ending Value 151113.20 2017-09-04, (MA Period 15) Ending Value 151040.80 2017-09-04, (MA Period 19) Ending Value 151040.80 2017-09-04, (MA Period 15) Ending Value 151569.50 2017-09-04, (MA Period 18) Ending Value 151569.50 2017-09-04, (MA Period 15) Ending Value 151032.00 2017-09-04, (MA Period 21) Ending Value 151032.00 2017-09-04, (MA Period 15) Ending Value 151565.15 2017-09-04, (MA Period 13) Ending Value 151565.15 2017-09-04, (MA Period 15) Ending Value 151794.85 2017-09-04, (MA Period 10) Ending Value 151794.85 2017-09-04, (MA Period 15) Ending Value 151411.65 2017-09-04, (MA Period 12) Ending Value 151411.65 2017-09-04, (MA Period 15) Ending Value 151186.20 2017-09-04, (MA Period 11) Ending Value 151186.20 2017-09-04, (MA Period 15) Ending Value 150927.00 2017-09-04, (MA Period 22) Ending Value 150927.00 2017-09-04, (MA Period 15) Ending Value 901.50 2017-09-04, (MA Period 15) Ending Value 901.50 2017-09-04, (MA Period 15) Ending Value 151446.85 2017-09-04, (MA Period 14) Ending Value 151446.85 2017-09-04, (MA Period 15) Ending Value 151019.40 2017-09-04, (MA Period 16) Ending Value 151019.40 2017-09-04, (MA Period 15) Ending Value 151564.30 2017-09-04, (MA Period 17) Ending Value 151564.30 2017-09-04, (MA Period 15) Ending Value 151569.50 2017-09-04, (MA Period 18) Ending Value 151569.50 2017-09-04, (MA Period 15) Ending Value 151040.80 2017-09-04, (MA Period 19) Ending Value 151040.80 2017-09-04, (MA Period 15) Ending Value 151113.20 2017-09-04, (MA Period 20) Ending Value 151113.20 2017-09-04, (MA Period 15) Ending Value 151032.00 2017-09-04, (MA Period 21) Ending Value 151032.00 2017-09-04, (MA Period 15) Ending Value 150927.00 2017-09-04, (MA Period 22) Ending Value 150927.00 2017-09-04, (MA Period 15) Ending Value 151008.05 2017-09-04, (MA Period 23) Ending Value 151008.05 2017-09-04, (MA Period 15) Ending Value 151091.55 2017-09-04, (MA Period 24) Ending Value 151091.55 2017-09-04, (MA Period 15) Ending Value 150822.85 2017-09-04, (MA Period 25) Ending Value 150822.85 2017-09-04, (MA Period 15) Ending Value 150686.25 2017-09-04, (MA Period 26) Ending Value 150686.25 2017-09-04, (MA Period 15) Ending Value 150413.45 2017-09-04, (MA Period 27) Ending Value 150413.45 2017-09-04, (MA Period 15) Ending Value 150523.50 2017-09-04, (MA Period 28) Ending Value 150523.50 2017-09-04, (MA Period 15) Ending Value 150556.80 2017-09-04, (MA Period 29) Ending Value 150556.80 2017-09-04, (MA Period 15) Ending Value 150265.75 2017-09-04, (MA Period 30) Ending Value 150265.75 Out[4]: [[<backtrader.cerebro.OptReturn at 0x102aea0b8>, <backtrader.cerebro.OptReturn at 0x102aea208>], [<backtrader.cerebro.OptReturn at 0x102aea320>, <backtrader.cerebro.OptReturn at 0x102aea4a8>], [<backtrader.cerebro.OptReturn at 0x102aea128>, <backtrader.cerebro.OptReturn at 0x102aea358>], [<backtrader.cerebro.OptReturn at 0x102ad1d68>, <backtrader.cerebro.OptReturn at 0x102ad1ef0>], [<backtrader.cerebro.OptReturn at 0x102aea588>, <backtrader.cerebro.OptReturn at 0x102aea898>], [<backtrader.cerebro.OptReturn at 0x102aea048>, <backtrader.cerebro.OptReturn at 0x102aea748>], [<backtrader.cerebro.OptReturn at 0x102aea6d8>, <backtrader.cerebro.OptReturn at 0x102aea9e8>], [<backtrader.cerebro.OptReturn at 0x102aea828>, <backtrader.cerebro.OptReturn at 0x102aeab38>], [<backtrader.cerebro.OptReturn at 0x102aea978>, <backtrader.cerebro.OptReturn at 0x102aeac88>], [<backtrader.cerebro.OptReturn at 0x102aeaac8>, <backtrader.cerebro.OptReturn at 0x102aeadd8>], [<backtrader.cerebro.OptReturn at 0x102aeac18>, <backtrader.cerebro.OptReturn at 0x102aeaf28>], [<backtrader.cerebro.OptReturn at 0x102aeaef0>, <backtrader.cerebro.OptReturn at 0x102ac50b8>], [<backtrader.cerebro.OptReturn at 0x102aea080>, <backtrader.cerebro.OptReturn at 0x102ac5208>], [<backtrader.cerebro.OptReturn at 0x102ac5048>, <backtrader.cerebro.OptReturn at 0x102ac5358>], [<backtrader.cerebro.OptReturn at 0x102ac5198>, <backtrader.cerebro.OptReturn at 0x102ac54a8>], [<backtrader.cerebro.OptReturn at 0x102ac52e8>, <backtrader.cerebro.OptReturn at 0x102ac55f8>], [<backtrader.cerebro.OptReturn at 0x102ac5438>, <backtrader.cerebro.OptReturn at 0x102ac5748>], [<backtrader.cerebro.OptReturn at 0x102ac5828>, <backtrader.cerebro.OptReturn at 0x102ac5978>], [<backtrader.cerebro.OptReturn at 0x102ac5588>, <backtrader.cerebro.OptReturn at 0x102ac57f0>], [<backtrader.cerebro.OptReturn at 0x102ac56d8>, <backtrader.cerebro.OptReturn at 0x102ac5b38>], [<backtrader.cerebro.OptReturn at 0x102ac5c18>, <backtrader.cerebro.OptReturn at 0x102ac5d68>]]
And should give:
2000-12-29, (MA Period 10) Ending Value 880.30 2000-12-29, (MA Period 11) Ending Value 880.00 2000-12-29, (MA Period 12) Ending Value 830.30 2000-12-29, (MA Period 13) Ending Value 893.90 2000-12-29, (MA Period 14) Ending Value 896.90 2000-12-29, (MA Period 15) Ending Value 973.90 2000-12-29, (MA Period 16) Ending Value 959.40 2000-12-29, (MA Period 17) Ending Value 949.80 2000-12-29, (MA Period 18) Ending Value 1011.90 2000-12-29, (MA Period 19) Ending Value 1041.90 2000-12-29, (MA Period 20) Ending Value 1078.00 2000-12-29, (MA Period 21) Ending Value 1058.80 2000-12-29, (MA Period 22) Ending Value 1061.50 2000-12-29, (MA Period 23) Ending Value 1023.00 2000-12-29, (MA Period 24) Ending Value 1020.10 2000-12-29, (MA Period 25) Ending Value 1013.30 2000-12-29, (MA Period 26) Ending Value 998.30 2000-12-29, (MA Period 27) Ending Value 982.20 2000-12-29, (MA Period 28) Ending Value 975.70 2000-12-29, (MA Period 29) Ending Value 983.30 2000-12-29, (MA Period 30) Ending Value 979.80
As stated in https://www.backtrader.com/docu/quickstart/quickstart.html.
# Set our desired cash start cerebro.broker.setcash(1000.0)
It's very strange as it gives one good output:
2017-09-04, (MA Period 15) Ending Value 901.50 2017-09-04, (MA Period 15) Ending Value 901.50
Can someone asses the script and see where the fault lies?
-
The tutorial targets a specific data feed which ends on
2000-12-29
and is of daily nature.You are targetting a custom data feed which is of
Minutes
nature and ends on2017-09-04
.Why should the results be the same?
-
@backtrader It's not about the date but about the cashflow. It gives value above the 150000 and I like to know where it comes from as I set the cash to 1000$.
-
Sorry but the messages are confusing.
- You first say the output should give the same as stated in the Quickstart Guide, which is obviously impossible.
Then
- You show several runs of scripts, which is also not in the Quickstart Guide including for example:
2017-09-04, (MA Period 15) Ending Value 151113.20
But you then say
@fbleaux said in Optimization standard script doesn't give required output:
It's very strange as it gives one good output:
2017-09-04, (MA Period 15) Ending Value 901.50 2017-09-04, (MA Period 15) Ending Value 901.50
Which doesn't match any of the previous shown output.
At the end the only reason for a value increase is that you constantly sell the asset (no safeguards in place) which increases your cash reserves.
But without data, without any hint as to how things are executed ...
-
@backtrader This is the logic behind the script:
# Not yet ... we MIGHT BUY if ... if self.dataclose[0] > self.sma[0]: # BUY, BUY, BUY!!! (with all possible default parameters) self.log('BUY CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.buy() else: if self.dataclose[0] < self.sma[0]: # SELL, SELL, SELL!!! (with all possible default parameters) self.log('SELL CREATE, %.2f' % self.dataclose[0]) # Keep track of the created order to avoid a 2nd order self.order = self.sell() def stop(self): self.log('(MA Period %2d) Ending Value %.2f' % (self.params.maperiod, self.broker.getvalue()), doprint=True)
I've uploaded the dataset to: https://ufile.io/cmhym
Btw, I am well aware that MA run on daily basis and not made for intraday so I'll have to configure later the parameters optimization to use linspace 540 lines (one trading day). -
Your best bet is to see the buy/sell output lines in a non-optimized run. Your cash (and therefore value) increase when you sell an asset. And that's probably what's happening.