I have a very simple, buy-at-open and sell-at-close algorithm and have been testing various schedules with it. In theory, using self.TimeRules.AfterMarketOpen(symbol, 0) and self.TimeRules.At(9, 30) interchangeably should yield the exact same results, all else equal. However, the difference in returns between the two are more than 2x. Code below for both. What could be causing this in the LEAN engine?
class BuyOpenSellCloseSPY(QCAlgorithm):
def Initialize(self):
self.SetTimeZone("America/New_York")
self.SetStartDate(2017, 1, 1)
self.SetCash(100000)
self.ticker = self.AddEquity("SPY", Resolution.Minute, extendedMarketHours = True).Symbol
self.Schedule.On(self.DateRules.EveryDay(self.ticker), self.TimeRules.AfterMarketOpen(self.ticker, 0), self.BuyOnOpen)
self.Schedule.On(self.DateRules.EveryDay(self.ticker), self.TimeRules.BeforeMarketClose(self.ticker, 0), self.SellOnClose)
def BuyOnOpen(self):
self.SetHoldings(self.ticker, 1)
def SellOnClose(self):
self.Liquidate()
And again here, modified:
class BuyOpenSellCloseSPY(QCAlgorithm):
def Initialize(self):
self.SetTimeZone("America/New_York")
self.SetStartDate(2017, 1, 1)
self.SetCash(100000)
self.ticker = self.AddEquity("SPY", Resolution.Minute, extendedMarketHours = True).Symbol
self.Schedule.On(self.DateRules.EveryDay(self.ticker), self.TimeRules.At(9, 30), self.BuyOnOpen)
self.Schedule.On(self.DateRules.EveryDay(self.ticker), self.TimeRules.BeforeMarketClose(self.ticker, 0), self.SellOnClose)
def BuyOnOpen(self):
self.SetHoldings(self.ticker, 1)
def SellOnClose(self):
self.Liquidate()
Cole S
Look at the orders in the backtest and you should be able to see when they are executing. Â My guess is that one of these is doing a MarketOnOpen order and the other is buying at 9:31.
Since you have minute data you won't receive your first candle until 9:31. Â When I want to use open time in my algo's (minute data usually) I use 9:31 instead of 9:30.
Fred Painchaud
Indeed.
self.TimeRules.AfterMarketOpen(self.ticker, 0) is really self.TimeRules.AfterMarketOpen(self.ticker, 0, false) which means 0 minute after market open for ticker in non-extended hours (thus regular hours). This is 9:30 for SPY.
This is the important piece of code:
self.TimeRules.At(9, 30) is 9:30 every day. Not trading days, every day. In both cases, DateRules.EveryDay means every day.
In this case, you trade outside open hours and those orders are converted to OMO orders.
Fred
James Hawkins
Fred Painchaud interesting. So if it am trading at 0930 everyday but am using self.TimeRules.BeforeMarketClose(), how does this affect the process? Take the weekend for example; would setting holdings to 1 at 0930 on Saturday close out of the position on market close of Monday?
Fred Painchaud
Hi James,
Checked the code for BeforeMarketClose… I never tested that but the intention of the code is to set the order for x minutes (second param) before market close for the soonest trading day (can be today, of course, or tomorrow, or Monday).
Fred
James Hawkins
The material on this website is provided for informational purposes only and does not constitute an offer to sell, a solicitation to buy, or a recommendation or endorsement for any security or strategy, nor does it constitute an offer to provide investment advisory services by QuantConnect. In addition, the material offers no opinion with respect to the suitability of any security or specific investment. QuantConnect makes no guarantees as to the accuracy or completeness of the views expressed in the website. The views are subject to change, and may have become unreliable for various reasons, including changes in market conditions or economic circumstances. All investments involve risk, including loss of principal. You should consult with an investment professional before making any investment decisions.
To unlock posting to the community forums please complete at least 30% of Boot Camp.
You can continue your Boot Camp training progress from the terminal. We hope to see you in the community soon!