@chan, pls edit your first msg and correct the title, it's buy at open, sell on close, thanks.
None of these backtests are actually doing that by the way, they always specify running some number of minutes away from open and close.
However, if you set one to try to do so (below), it barely does beat the benchmark yet would be worse with commissions.
However, I have a question aside from that:
Setting a breakpoint inside on_open(), the debugger will show a time of day relevant to your time zone.
As we know, the first minute of the trading day does not run for us to be able to enter an order then.
One would expect the minute that shows up in on_open() then to be :31.
Instead, it will be :35, :33, :34 etc. On 2005-01-31 it is :37.
The question is:
Assuming that's because XLP is thinly traded, is the backtester trying to be helpful and smart by not running on_open() until the first minute that a security in the universe is traded, and, do we always miss the first trade using schedule_function() this way ? (We can enter an order in that minute, however to trade in that minute we would have had to have entered the order in the previous minute or before)
Or will time_rules.market_open() cause the first run to be the minute before a first trade?
Assuming this is on target, can someone check online please, was the first trade of XLP on 2005-01-31 at US/Eastern 9:37 or 9:38? Thanks.
context.xlp = symbol('XLP')
schedule_function(on_open, date_rules.every_day(), time_rules.market_open())
schedule_function(on_clos, date_rules.every_day(), time_rules.market_close())
def on_open(context, data):
if get_open_orders(): return
xlp = context.xlp
closes = history(3, '1d', 'close_price')[xlp]
# From http://www.quantifiedstrategies.com/trade-the-boring-consumer-stocks-when-they-open-down-and-yesterday-was-a-down-day/
# "Yesterday must have been a down day of at least 0.25%."
# "If XLP opens down more than 0.1% today, go long and exit on the close."
if closes[-2] < closes[-3] * (100 - .25 / 100):
if data[xlp].price < closes[-2] * (100 - .1 / 100):
def on_clos(context, data):
# This is a side-problem by the way, it should not wait 24 hrs to sell all, it should check again every minute
if get_open_orders(): return # Live/real, if the sell doesn't go thru, the sell order would be canceled. Should re-open next morning, must do manually. I don't think anyone has been doing that, have not seen a function for it, and it didn't occur to me until now.
def handle_data(context, data):