Hi everyone,
I am using an equal-weighted algorithm framework to buy and hold 5 most liquid stocks 5 minutes before the market closes. Specifically, my algorithm is on minute resolution, and it will only emit a 5-day insights at 15:55pm everyday. I also used the provided EqualWeightingPortfolioConstructionModel with rebalance turned off.
However, the order placement is not at all what I expected (see order below). MSFT was bought at 15:55pm and then immediately sold in the next morning. For other tickers, more shares were bought in the next morning for some unknown reason (I turned off rebalance).
Both a sample order history and full algorithm/backtest is attached. Can someone please help? Thank you!
2021-05-03 15:55:00 TSLA Buy Market
Fill: $684.28 USD
29 Filled
2021-05-03 15:55:00 AAPL Buy Market
Fill: $132.245370621 USD
150 Filled
2021-05-03 15:55:00 MSFT Buy Market
Fill: $250.990433034 USD
79 Filled
2021-05-03 15:55:00 FB Buy Market
Fill: $322.31 USD
61 Filled
2021-05-03 15:55:00 AMZN Buy Market
Fill: $3,382.03 USD
5 Filled
2021-05-04 09:31:00 MSFT Sell Market
Fill: $250.182299112 USD
-79 Filled
2021-05-04 09:31:00 AMZN Buy Market
Fill: $3,356.20 USD
2 Filled
2021-05-04 09:31:00 FB Buy Market Fill: $321.23 USD 16 Filled
...
class buyBeforeMarketClose(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2021, 5, 1) # Set Start Date
self.SetCash(100000) # Set Strategy Cash
self.UniverseSettings.Resolution = Resolution.Minute
self.AddUniverseSelection(
FineFundamentalUniverseSelectionModel(self.SelectCoarse, self.SelectFine)
)
self.SetAlpha(buyBeforeMarketCloseAlphaModel())
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel(rebalance = None))
self.SetExecution(ImmediateExecutionModel())
def SelectCoarse(self, coarse):
# select top 3 most liquid
mostliquid = sorted(coarse, key=lambda c: c.DollarVolume, reverse=True)[:5]
return [c.Symbol for c in mostliquid]
def SelectFine(self, fine):
return [f.Symbol for f in fine]
class buyBeforeMarketCloseAlphaModel(AlphaModel):
'''Buy 5 minutes before market close and hold for 5 days'''
def __init__(self):
self.securities = []
self.insightPeriod = timedelta(days=5)
self.direction = InsightDirection.Up
def Update(self, algorithm, data):
insights = []
# buy 5 mins before market close
if algorithm.Time.hour == 15 and algorithm.Time.minute == 55:
for security in self.securities:
insights.append(Insight.Price(security.Symbol, self.insightPeriod, self.direction))
return insights
def OnSecuritiesChanged(self, algorithm, changes):
for added in changes.AddedSecurities:
self.securities.append(added)
Fishstoryyy
Re-formatted the orders make them easier to see…
Derek Melchin
Hi Fishstoryyy,
Refer to this related thread.
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.
Fishstoryyy
Hi Derek,
Just found out there is more to it and this problem is not solved.
Once I set the following per your suggestion, things are as expected until the universe is empty for the day. If the universe if empty for the day, the algorithm suddenly will forget to liquidate a position even when the corresponding insight expires on that day, as if that trading day didn't exist. My expectation is that a certain position should be liquidated if its insight is inactive / or kept if the insight is active, whether or not that asset is selected in the universe. Please advice here. Happy to provide a backtest if needed.
Fishstoryyy
Hi Derek,
Backtest is attached.
I modified your code a little bit to have the algorithm produce an empty universe on every other day. I used the constant alpha model. As you can see, my insight is only valid for 1 day. But somehow the expiry of insights is ignored when the universe is empty for that day.
Derek Melchin
Hi Fishstoryyy,
The issue is that when securities are removed from the universe, their insights are removed from the `InsightCollection` [source]. If the `InsightCollection` doesn't contain any insights, `GetNextExpiryTime` returns `null` [source], which causes `IsRebalanceDue` to return `false` [source] and causes `CreateTargets` to return an empty array of PortfolioTargets [source]. Since there are no PortfolioTargets, the execution model doesn't place any trades [source].
We've created a GitHub Issue to have the problem resolved. Subscribe to our progress here:
Positions aren't always liquidated when insights expire #5654
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.
Fishstoryyy
Hi Derek,
Thank you for submitting this as an issue.
I also created a related issue on Github
Positions of removed securities are always liquidated during rebalance even with active insights #5658
which is somewhat related to the issue in this thread but is different.
Fishstoryyy
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!