Multiday Position
vp724172
Posts: 6
Trying a very simple script to simulate holding a position over multiple days. Buy execution is successful but if I try to sell as "exit", order is not filled.
Even account position the day after buy shows no position.
Script is below. Any ideas? Thanks
@classmethod
def is_symbol_qualified(cls, symbol, md, service, account):
return symbol == 'MSFT'
def on_start(self, md, order, service, account):
self.startflg = 1
pass
def on_minute_bar(self, event, md, order, service, account, bar):
#Buy on 1/4/18 @ 10
if service.time_to_string(service.system_time, '%Y-%m-%d') == '2018-01-04' and event.timestamp>service.time(hour=10,minute=0,second=0,millisecond=0) and self.startflg == 1:
order.algo_buy(self.symbol, "market", intent="init", order_quantity=100)
print('Buy')
self.startflg = 2
#Sell as "exit" on 1/5/18 @ 10
if service.time_to_string(service.system_time, '%Y-%m-%d') == '2018-01-05' and event.timestamp>service.time(hour=10,minute=0,second=0,millisecond=0) and self.startflg == 1:
print account[self.symbol].position
order.algo_sell(self.symbol, "market", intent="exit")
print('Sell')
self.startflg = 2
pass
Comments
VP
Some things to note about the backtesting system. Whenever a backtest for any date is spun up it is its own unique instance.
Backtests are run in one of two main ways. Parallelized or as one Single Multiday Job.
The benefits of Parallelization are obvious, you can run lots of days all at once!
But if you want to write a mutliday hold model, day 2 needs to know what day 1 did, therefor they have to run one at a time, in order.. much slower.
A model that takes five minutes to run for each day, running for 30 days, across 30 parallelized backtests takes 5 minutes. The same model run mutliday takes 30x5 .. 2.5 hours.
Class variable are maintained across the daily tests, self. variables are not.
If you comment out your exit code and add the following print statement you can see that you are indeed still in a position on the second day...
There is a really interesting dictionary called a default dict that will return a default value if a value is not found rather than erroring, this can be very useful.
If you place it as a class variable then it will persist across the days. There are a number of ways to reference a class variable from within your code. I prefer to use the name of the class (in this case mutlidayModel)
Here is the code I use. Run for any 5 days, it enters on the first day and exits on the fifth...
Hopefully this helps!
Paul
other ways to reference a class variable....
self.class.variable_name (only when the callback includes self)
cls.variable_name (only when the callback includes cls)
The nice thing about using the name of your class (class scriptname(Strategy): at the top of your script) is that it works across the board.