This is the opening range breakout strat from the Boot Camp. I am trying to copy and paste this into a new algorithm and play around with it. I am able to add a new symbol like SPY fine, but when I change the time above 40 minutes, I get no results. If the time frame is 30 minutes, then it kicks out over 90 trades? What would be causing this not to work on a 60-minute time delta? I know that we break the high or low often in a 60-minute range so it should be triggering.
I am just learning the API now, but if I wanted to backtest futures on the opening range breakout, how would I go about structuring this for the ES E-mini. Ultimately what I am looking to do is get long or short on the break of the High or Low and then get flat by either 4:00 pm eastern or when high + 0.3 *(High-Low) is hit. Please any help or guidance is greatly appreciated.
Douglas Stridsberg
Hi Joshua - not sure you attached the right version of the backtest. The one you attached has no trading logic. Would you mind attaching the most up-to-date version so we can take a look and see why it's not placing trades with a 60min consolidator?
To add the E-mini, you would simply replace your self.AddEquity call with self.AddFuture(Futures.Indices.SP500EMini).
Joshua Dawson
Douglas- Thank you for taking the time to answer my post and showing me how to call futures.
I do apologize I did attach the wrong notebook. I have modified the code and made comments in the code to explain my idea. I clearly did this wrong because it is not running a backtest. Hopefully, you can give me some insight.
# I am new to programming with about a years experience mostly in Pandas and Quantopian. I suck at Quantopian IDE but am okay in the
# research area, probably because of Pandas. I am going to master quantconnect. I will focus two hours a day at this, I want to deploy
# algos for the AlphaStream. I know my code is rough and my understanding is limited but just hang in there with me. Give me advice
# even if it's not related to the current algo and I will do my best to learn it. Thank you for your help, it means more to me then
# you know!
class OpeningRangeBreakout(QCAlgorithm):
openingBar = None
closingBar = None
def Initialize(self):
self.SetStartDate(2018, 7, 10)
self.SetEndDate(2019, 6, 30)
self.SetCash(100000)
# Used code that Douglas provided to me for futures symbol. Not sure if I deployed this correctly?
self.AddFuture(Futures.Indices.SP500EMini)
self.Consolidate("SP500EMini", timedelta(minutes=60), self.OnDataConsolidated)
# here I attempted to assign the self.symbol a "call tag"? Naming the SP500EMini to make easier to type.
# this line of code throughout errors.
#ES = self.Symbol(Futures.Indices."SP500EMini")
#3. Create a scheduled event triggered at 13:30 calling the ClosePositions function-Direct from the tutorial. I modified the
#time and symbols. I am not sure if that is the correct way to call futures?
self.Schedule.On(self.DateRules.EveryDay("SP500EMini"), self.TimeRules.At(15, 45), self.ClosePositions)
# Here I am attempting to measure the range in the first hour of trading. 9:30 am - 10:30 am. I am then setting the targets
# to 30% of the range to the high side. The thought process behind this- The Algo will get long at the break of the High of the
#first 60-minute candle. The Algo will exit with a limit order at the IBH30(30% greater than the high of the first hours' range)
# I went ahead and calculated different range expression in attempts to manually optimize the code. I still need to learn how
# have the software optimize settings for me.
IBH30 = High + .30 * (High-Low)
IBH40 = High + .40 * (High-Low)
IBH50 = High + .50 * (High-Low)
IBH70 = High + .70 * (High-Low)
# This is code from the tutorial in boot camp "Opening Range", my understanding is this is buying at the break of the first 60min
# candle. What I am attempting to modify is instead of getting flat at a time exit, I want to get flat at IBH30 or 15:45 whichever
# event happens first.
def OnData(self, data):
if self.Portfolio.Invested or self.openingBar is None:
return
if data["SP500EMini"].Close > self.openingBar.High:
self.SetHoldings("SP500EMini", 1)
elif data["SP500EMini"].Close < self.openingBar.Low:
self.SetHoldings("SP500EMini", -1)
#Here I am attempting to place the exit limit order at the IBH30. TBH I am totally lost at this point and I am just guessing.
# I am trying to use the documentation that is provided but not sure if I have it correct?
if self.Portfolio.Invested:
return
if data['SP500EMini'].Close >= IBH30:
self.LimitOrder("SP500EMini",1,lastClose,stringtag =IBH30)
def OnDataConsolidated(self, bar):
if bar.Time.hour == 9 and bar.Time.minute == 30:
self.openingBar = bar
#1. Create a function named ClosePositions(self)
def ClosePositions(self):
#2. Set self.openingBar to None, and liquidate ES
self.openingBar = None
self.Liquidate("SP500EMini")
# I ran the backtest and it took around 60 seconds- I am sure the computer was saying WTF is this BS lol.
# Ultimately I want to build on top of this strategy. I would like to put a stop at Mid (High + Low / 2) if High breaks first then
# stop loss at mid.
# I also want to code in the IBL 30 etc. I like to see how the admin structures this code so that I can play around with it
# to see if I can get things to start working on the Low side.
# Exception : Please register to receive data for symbol ' ' using the AddSecurity() function. *** I keep getting this error but
# I am logged in.
Joshua Dawson
Also, I tried attaching the correct Backtest with the project but for reason, I could not get it to load. I do apologize for my stupidity.
Douglas Stridsberg
Hi Joshua,
FYI, next time you post code, please use the Insert Code Snippet button to make it easier to read.
My bad here, I've inadvertently sold you a concept in a very simplified fashion. In reality, working with futures is trickier since you need to also select the right futures contract (usually people want to trade the front month, but they might want to trade other contracts for various reasons).
For an example of functionality, please see the futures template file. Other example files are available in that folder and you can use these to familiarise yourself with how futures work in QC.
For now, unless you absolutely must use futures, I would stick with ETFs and stocks are these are quite a lot simpler to work with.
Joshua Dawson
No worries Douglas. I run a CTA so I have to do futures and get more comfortable with it. I started learning Python bc a lot of investors keep asking about quantitive strategies. I really need to get this down! If I sign up for the $20 a month program, will the quantconnect team be able to help me more with my code? I am sure you get tons of crazy request per day! Also I have no clue why I didn’t use the code snippet for entering my code-my bad man. Will you be able to help me troubleshoot this or should I sign up for a premium account? I will re submit the code with the code snippet so it’s easier to read. I do appreciate your time and help.
Joshua Dawson
class OpeningRangeBreakout(QCAlgorithm): openingBar = None closingBar = None def Initialize(self): self.SetStartDate(2018, 7, 10) self.SetEndDate(2019, 6, 30) self.SetCash(100000) # Used code that Douglas provided to me for futures symbol. Not sure if I deployed this correctly? self.AddFuture(Futures.Indices.SP500EMini) self.Consolidate("SP500EMini", timedelta(minutes=60), self.OnDataConsolidated) # here I attempted to assign the self.symbol a "call tag"? Naming the SP500EMini to make easier to type. # this line of code throughout errors. #ES = self.Symbol(Futures.Indices."SP500EMini") #3. Create a scheduled event triggered at 13:30 calling the ClosePositions function-Direct from the tutorial. I modified the #time and symbols. I am not sure if that is the correct way to call futures? self.Schedule.On(self.DateRules.EveryDay("SP500EMini"), self.TimeRules.At(15, 45), self.ClosePositions) # Here I am attempting to measure the range in the first hour of trading. 9:30 am - 10:30 am. I am then setting the targets # to 30% of the range to the high side. The thought process behind this- The Algo will get long at the break of the High of the #first 60-minute candle. The Algo will exit with a limit order at the IBH30(30% greater than the high of the first hours' range) # I went ahead and calculated different range expression in attempts to manually optimize the code. I still need to learn how # have the software optimize settings for me. IBH30 = High + .30 * (High-Low) IBH40 = High + .40 * (High-Low) IBH50 = High + .50 * (High-Low) IBH70 = High + .70 * (High-Low) # This is code from the tutorial in boot camp "Opening Range", my understanding is this is buying at the break of the first 60min # candle. What I am attempting to modify is instead of getting flat at a time exit, I want to get flat at IBH30 or 15:45 whichever # event happens first. def OnData(self, data): if self.Portfolio.Invested or self.openingBar is None: return if data["SP500EMini"].Close > self.openingBar.High: self.SetHoldings("SP500EMini", 1) elif data["SP500EMini"].Close < self.openingBar.Low: self.SetHoldings("SP500EMini", -1) #Here I am attempting to place the exit limit order at the IBH30. TBH I am totally lost at this point and I am just guessing. # I am trying to use the documentation that is provided but not sure if I have it correct? if self.Portfolio.Invested: return if data['SP500EMini'].Close >= IBH30: self.LimitOrder("SP500EMini",1,lastClose,stringtag =IBH30) def OnDataConsolidated(self, bar): if bar.Time.hour == 9 and bar.Time.minute == 30: self.openingBar = bar #1. Create a function named ClosePositions(self) def ClosePositions(self): #2. Set self.openingBar to None, and liquidate ES self.openingBar = None self.Liquidate("SP500EMini") # I ran the backtest and it took around 60 seconds- I am sure the computer was saying WTF is this BS lol. # Ultimately I want to build on top of this strategy. I would like to put a stop at Mid (High + Low / 2) if High breaks first then # stop loss at mid. # I also want to code in the IBL 30 etc. I like to see how the admin structures this code so that I can play around with it # to see if I can get things to start working on the Low side. # Exception : Please register to receive data for symbol ' ' using the AddSecurity() function. *** I keep getting this error but # I am logged in.
Lmao no wonder you were like " yea bro that sucks to read code the way you posted it" Thanks for being nice about that :)
Douglas Stridsberg
Hey, I'll leave the bit about whether upgrading gives you access to more support to someone from the team to answer.
About futures - once you have functionality in place to a) select the right contract and b) roll into a new contract in time for expiry, you should be able to apply any logic you've written for traditional assets without problems. You just need to be mindful of how the rolls can introduce gaps in your price data (in case you're feeding this to indicators).
A good place to start with a relatively simple algorithm (but more advanced than the template file I linked) would be the commodity momentum tutorial.
Jared Broad
>If I sign up for the $20 a month program, will the quantconnect team be able to help me more with my code?
Sorry we have limited ability to help people with coding directly so do not offer it officially but if there's bandwidth we always help where we can.
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.
Joshua Dawson
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!