Hello,
I would like to copy the concept of the Coarse Selection Filter as it's laid out in the "Liquid Universe Selection" Tutorial in QuantConnect's Boot Camp. But instead of filtering by dollar volume and picking the 8 symbols with the highest dollar volume, I would like to filter by largest daily gainers and pick all of the top gainers that are up 10% or more on the day. Would anyone mind helping me put that together? Or point me in the right direction to find how to substitute in % gain instead of dollar volume?
Thanks!
Sean
Here is the "Liquid Universe Selection" Tutorial I'm following with the Coarse Selection Filter part beginning at 2:37
https://www.youtube.com/watch?v=rf7t5K1Bczc
Rahul Chowdhury
Hi S O'Keeffe,
In our coarse selection, we can make a history call that retrieves the last close and uses that to find the daily returns.
Then we can filter for symbols with daily returns greater than 10%.
In this example, we created a SymbolData class which can hold the relevant data for each symbol, such as the daily return and last close. Check out the comments inside to see how it works.
S O'Keeffe
This is awesome thank you Rahul! I backtested the last two days, and it seems to be trading a lot of ETF-type symbols. It didn't trade CLR or FRO on 3/10 but both of those were over 10% up on the day. Do you know why those were not traded by the algorithm? Is it because FRO opened 9% up from its previous close? Is there a way to keep a rolling look during the day so that any equity that moves over that 10% gain threshold during the day, it will also get added to the buy list? Thank you so much for your help!
Rahul Chowdhury
Hi S O'Keeffe,
FRO was not selected because it was not in symboldict since it was not included in the top 1000 liquid stocks in the previous days.
CLR was not selected because of a more subtle reason. If we replace the code block starting at line 36 with
for c in coarse: symbol = c.Symbol if symbol in self.symboldict: self.symboldict[symbol].Update(c.AdjustedPrice) if symbol.Value == "FRO" or symbol.Value == "CLR": self.Debug(f"symbol: {symbol.Value} with returns: {self.symboldict[symbol].dailyReturn}") else: if symbol.Value == "FRO" or symbol.Value == "CLR": self.Debug(symbol.Value)
We can first see that FRO did not make it into symboldict. Then we can see that CLR has a daily return of -52%. This is because universe selection for trading on 03/10 is done at midnight:
2020-03-10 00:00:00: symbol: CLR with returns: -0.5262803234501348
The close price of trading on 03/09, 7.03, is compared to the close price of the trading day prior 03/06, 14.84. This means the daily return of CLR at the time of universe selection on 03/10 was -50%. Universe selection for 03/10 can not be done with the market open price on 03/10 because that would introduce a forward bias in our data.
Instead, if you wish to create signals on overnight gaps, you can use a scheduled event at market open. The Fading The Gap bootcamp covers a strategy which utilizes this type of scheduled event
S O'Keeffe
Thank you again Rahul! OK I was hoping CLR and FRO would be seen as 10%+ gainers based on the close price 3/9 compared to the open price 3/10. I will review the Fading the Gap bootcamp
S O'Keeffe
Hi Rahul sorry do you still have time for questions! Is it possible to use the "Fading the Gap" strategy at Second resolution instead of Minute resolution? And if I want to look at all Nasdaq stocks instead of just looking at one equity, how can I accomplish that? Trying to look at all Nasdaq stocks and screen through them based on highest overnight gap is why I initially started with the "Liquid Universe Selection" Tutorial.
My end goal is to buy short squeezes. I want to buy Nasdaq stocks when they break through their HOD if they are up more than 10% for the day. And then sell them pretty quickly as they squeeze up higher. Or sell them quickly at a safety stop if they begin to break down lower.
Jared Broad
Absolutely S O'Keeffe ! Please give it a go, these topics are all covered in Boot Camp. Please finish them and post back your attempt at your questions above.
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.
S O'Keeffe
Wow Hi Jared! Thank you for even taking the time to read my question!
I've finally finished boot camp, and I've tried to piece together what I've learned there to make some semblance of what I want to build (Mostly pulling from the "Fading the Gap" and "Trailing Stop" tutorials). I'm afraid I'm still far off the mark. The main questions I still have are 1) How can I continually scan all Nasdaq stocks instead of just looking at one equity? and 2) How can I buy only when the high of the day has been broken?
I'd love if you could point me in the direction of where I can learn those things! Here is my work-in-progress attempt so far:
class NotebookProject(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2018, 12, 1)
self.SetEndDate(2018, 12, 10)
self.SetCash(100000)
spy = self.AddEquity("SPY", Resolution.Second)
spy.SetDataNormalizationMode(DataNormalizationMode.Raw)
#Schedule event for 3:50pm to close any open positions
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.At(15,50), self.ClosePositions)
#Set scheduled events to scan for any security gapping up 10%+ from previous close
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("SPY", 0), self.ClosingBar)
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("SPY", 1), self.OpeningBar)
#Set this as a relatively infinite rolling window to continually scan throughout the day
self.window = RollingWindow[TradeBar](23,400)
def OnData(self, data):
if data["SPY"] is not None:
#2. Update our standard deviation indicator manually with algorithm time and TSLA's close price
self.window.Update(self.Time, data["SPY"].Close)
def OpeningBar(self):
if self.CurrentSlice["SPY"] is not None:
self.window.Add(self.CurrentSlice["TSLA"])
#3. Use IsReady to check if both volatility and the window are ready, if not ready 'return'
if not self.window.IsReady:
return
#Set up gapping calculation
delta = self.window[0].Open / self.window[1].Close
#Scan for securities gapping 10%+ over previous day's close
#?Only buy when highest price of day is broken and only if security is not already owned?
if delta > 1.1:
self.StopOrder("SPY", .05)
else:
#1. Check if the SPY price is higher that highestSPYPrice.
if self.Securities["SPY"].Close > self.highestSPYPrice:
#2. Save the new high to highestSPYPrice; then update the stop price to 98% of highestSPYPrice
self.highestSPYPrice = self.Securities["SPY"].Close
updateFields = UpdateOrderFields()
updateFields.StopPrice = self.highestSPYPrice * 0.98
self.stopMarketTicket.Update(updateFields)
def ClosePositions(self):
self.Liquidate("SPY")
def ClosingBar(self):
self.window.Add(self.CurrentSlice["SPY"])
Derek Melchin
Hi S O’Keeffe,
Great start! I recommend reviewing our Liquid Universe Selection Bootcamp and our documentation on universe selection. Both resources do a great job of explaining universe selection.
In regards to targeting all Nasdaq stocks instead of a single equity, we can utilize the Morningstar ExchangeId property. Additionally, we can target specific sectors by filtering our universe by the MorningstarSectorCode. Read up on our Morningstar data documentation to see how this works.
Best,
Derek
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.
S O'Keeffe
Hi Derek,
Thanks so much for your response! I think I can't use Universe Selection to get just the securities that are today's biggest gainers. Rahul mentioned that "universe selection ... is done at midnight." But at midnight, we don't know yet which stocks will open the trading day up 10%+ from their previous close price. I think that's why Rahul steered me to the 'Fading the Gap' tutorial. Does that sound right/make sense?
So I began working with the 'Fading the Gap' tutorial like Rahul suggested, but that tutorial is only for one security at a time. I'd like to use the 'Fading the Gap' strategy on any stock that is 10%+ over its previous close price. How can I apply that 'Fading the Gap' strategy to several separate securities at the same time?
Let me know if this is the appropriate way to be asking for help too! I'm happy to pay one of your staff members to tutor me until I can get this right, move over to reddit, or something else if that's better for your team.
Thank you,
Sean
Derek Melchin
Hi Sean,
I've attached an algorithm which monitors the 100 most liquid stocks. When one of these stocks reaches 10%+ on the day within the first 45 minutes of trading, we short it until 45 minutes after the open. This algorithm is just an example. I recommend reviewing our documentation on the Algorithm Framework to understand how the universe selection and alpha models work together to make this happen.
The algorithm can be adjusted to include more stocks within the universe. Additionally, as was mentioned earlier, we can target specific sectors by filtering our universe by the MorningstarSectorCode.
Going forward, the community forums are an appropriate way to ask for help. However, for more involved 1-1 remote educational session, consider our new tutoring packages. More information about them is available on our recent blog post.
Best,
Derek Melchin
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.
S O'Keeffe
Hi Derek,
Thanks so much for putting this together! This seems like a really great start. One of the first things I tried to tweak was to make "self.__numberOfSymbols = 500" instead of just 100. Because I would like to have the algorithm scan as many securities as possible. But that one change throws an error saying "Runtime Error: KeyNotFoundException : 'RE R735QTJ8XC9X' wasn't found in the Slice object, likely because there was no-data at this moment in time and it wasn't possible to fillforward historical data." Is that some obscure security that managed to get through as one of the top 500 most liquid stocks?
I will definitely consider the five hours of tutoring service for $250 too!
Thank you again,
Sean
Derek Melchin
Hi Sean,
As the full error message mentions, we just need to ensure the current slice has data for the symbol we are interested in before we try accessing it. Simply add
or symbol not in slice.Bars
to the condition on line 67 in Update.
See the attached algorithm for reference.
Best,
Derek Melchin
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.
S O'Keeffe
Hi Derek,
That did the trick! Thank you so much. Now if I'm using the 'FadeTheGap' Alpha Model, is it possible to only place an order on a 10%+ security when that security breaks through its high of day mark? Or is it not possible to control the order placement that precisely when using an Alpha Model? I don't necessarily want to buy everything that's 10%+ on the day. Only when a security is 10%+ AND breaking through its high of day mark.
Also, I would probably like to switch to second resolution to make faster entries and exits. Is that even realistic when using an Alpha Model?
Thank you,
Sean
Derek Melchin
Hi Sean,
This is absolutely realistic. To achieve this, we just need to modify the algorithm in the following ways:
(1) Switch the universe resolution to second in Initialize
self.UniverseSettings.Resolution = Resolution.Second
(2) Apply the Maximimum indicator to each security to track its day high mark (reset 45 minutes after the open)
(3) Modify the entry condition to check if the current price is greater than the maximum indicator's value.
(4) Switch the InsightDirection to Up, so we enter long positions.
See the attached backtest for a working solution.
Best,
Derek Melchin
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.
S O'Keeffe
Hi Derek,
This is amazing! Thank you so much again. I changed "SPY" to instead be "W5000" and changed it to say "numberOfSymbols = 1000" to scan a huge chunk of the US markets. I also changed the backtest dates to 5/14 - 5/15 to try to lessen the data required for the backtest. And it looks like it takes a really, really long time to finish running. Does that mean this algorithm wouldn't be able to function at a high speed in live trading?
Thanks!
Sean
Derek Melchin
Hi Sean,
Good question. The `numberOfSymbols` variable is used to control the size of our universe. By default, universe selection occurs at midnight before each trading day. Therefore, the "slow" part of the algorithm will occur outside of trading hours. During regular trading hours, the algorithm should be fast enough to handle any resolution.
Best,
Derek Melchin
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.
S O'Keeffe
Hi Derek,
OK that's great thank you! How is the algorithm deciding when to sell? Is that hardcoded into the "FadeTheGap" Alpha Model or can I change that to be a 2% trailing stop here?
Also I don't have to worry about where it says "Universe selection is not supported by the Interactive Brokers Brokerage data feed at this time" here (
https://www.quantconnect.com/docs/live-trading/paper-trading) right? I can live trade this through IB or another brokerage even though we're using universe selection right?
Thanks!
Sean
Jack Simonson
Hi Sean,
You can select to use the QuantConnect data feed when deploying live to IB, which will allow you to perform Universe Selection.
S O'Keeffe
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!