Hello,
I am trying to get this algorithm to close all open positions before the closing bell. I tried this:
for symbol in self.symbolData:
if symbol in slice.Bars and algorithm.Securities[symbol].Invested and TimeRules.BeforeMarketClose[symbol]:
insights.append(Insight(symbol, timedelta(seconds=insight_seconds), InsightType.Price, InsightDirection.Flat))
but that did not work. Is there something similar to 'BeforeMarketClose' that can be substituted in here within an algorithm framework? I have read through this thread here as well:
quantconnect.com/forum/discussion/1037/day-trading-close-all-positions-at-close-of-day/p1
Thank you!
Sean
Arthur Asenheimer
Hi,
regarding your question:
>> Is there something similar to 'BeforeMarketClose' that can be substituted in here within an algorithm framework?<<
Yes, check the Documentation here.
self.Schedule.On(self.DateRules.EveryDay("SPY"), self.TimeRules.BeforeMarketClose("SPY", 1), self.DoSomething)
I've attached a minimalistic example so you can see it in action.
If you really want to liquidate at Market Close exactly, you need to use a MarketOnClose Order.
S O'Keeffe
Hi Arthur,
Thank you so much for your response! I'm using the Algorithm Framework setup with Insights instead of a normal Python algorithm. So I think I need to submit everything as Flat insights, otherwise the Up insight will remain in place and the algorithm will begin a position again immediately. I think this thread describes really well what I'm looking to do (quantconnect.com/forum/discussion/4665/managing-universe-and-trades-within-algorithm-framework/p1). I cannot used a fixed expiration timer like Emilio did though because my trades do not happen all at the same time.
Is there a way to use a scheduled event to trigger a Flat insight for every open position just before market close?
Thanks!
Sean
Adam W
Yes you can just do,
def Initialize(self): self.Schedule.On(self.DateRules.EveryDay('SPY'), self.TimeRules.BeforeMarketClose(0), self.ClosePositions) def ClosePositions(self): currInvested = [x.Symbol for x in algorithm.Portfolio.Values if x.Invested] toLiquidate = [] for symbol in currInvested: insight = Insight(symbol, timedelta(hours=16) # Some timedelta before next market open; overlapping ones will overwrite the flat InsightType.Price, InsightDirection.Flat, *args) toLiquidate.append(insight) self.EmitInsights(toLiquidate) return
S O'Keeffe
Hi Adam,
Thank you so much! I'm sorry that I am really bad at python. I fixed a couple errors it was giving me, but now I'm stuck on this one:
Is this because I am defining 'ClosePosition' before I've started the algorithm framework? Here is the updated code of the first half of the algorithm since it won't let me attach a broken backtest here:
class QuantumHorizontalRegulators(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 7, 14) # Set Start Date self.SetEndDate(2020, 7, 15) self.SetCash(100000) # Set Strategy Cash self.AddEquity("W5000", Resolution.Second) self.scaning = False self.lastToggle = None self.__numberOfSymbols =100 self.SetUniverseSelection(FineFundamentalUniverseSelectionModel(self.CoarseSelectionFunction, self.FineSelectionFunction, None, None)) self.UniverseSettings.Resolution = Resolution.Second self.AddAlpha(ShortSqueezeModel(self)) self.SetExecution(ImmediateExecutionModel()) self.SetPortfolioConstruction(AccumulativeInsightPortfolioConstructionModel(lambda time: None)) self.SetRiskManagement(MaximumUnrealizedProfitPercentPerSecurity(maximumUnrealizedProfitPercent = 0.01)) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose("W5000", 1), self.ClosePositions) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("W5000", 0), self.toggleScan) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("W5000", 45), self.toggleScan) def toggleScan(self): self.scaning = not self.scaning self.lastToggle = self.Time if not self.scaning: self.needs_reset = True def ClosePositions(self): currInvested = [x.Symbol for x in algorithm.Securities[symbol].Invested] toLiquidate = [] for symbol in currInvested: insight = Insight(symbol, timedelta(hours=16), InsightType.Price, InsightDirection.Flat, *args) toLiquidate.append(insight) # Some timedelta before next market open; overlapping ones will overwrite the flat self.EmitInsights(toLiquidate) return def CoarseSelectionFunction(self, coarse): # Stocks with the most dollar volume traded yesterday sortedByDollarVolume = sorted(coarse, key=lambda x: x.DollarVolume, reverse=True) return [ x.Symbol for x in sortedByDollarVolume[:self.__numberOfSymbols] ] def FineSelectionFunction(self, fine): return [ x.Symbol for x in fine ] class ShortSqueezeModel(AlphaModel): symbolData = {} def __init__(self, algo): self.algo = algo def Update(self, algorithm, slice): if algorithm.IsWarmingUp: return [] # If it's the end of the day, update the yesterday close of each indicator if not algorithm.Securities['W5000'].Exchange.ExchangeOpen: for symbol in self.symbolData: if symbol in slice.Bars: self.symbolData[symbol].yest_close = slice.Bars[symbol].Close if not self.algo.scaning: # Reset max indicator if self.algo.needs_reset: for symbol in self.symbolData: self.symbolData[symbol].max.Reset() self.algo.needs_reset = False return [] insights = [] insight_seconds = 99999999999 # Create insights for symbols up at least 10% on the day for symbol in self.symbolData: # If already invested, continue to next symbol if algorithm.Securities[symbol].Invested or symbol not in slice.Bars or self.symbolData[symbol].max.Samples == 0: continue
Thank you so much!
Sean
Alexandre Catarino
Hi S O'Keeffe ,
I would recommend setting the Insight.CloseTimeUtc with the time that the exchange closes:
if ret >= 0.1 and high_of_day_break: hours = algorithm.Securities[symbol].Exchange.Hours # 1-minute before the close closeTime = hours.GetNextMarketClose(algorithm.Time, False) - timedelta(minutes=1) insights.append(Insight.Price(symbol, closeTime, InsightDirection.Up))
and let the PortfolioConstructionModel + ExecutionModel liquidate the position.
By the way, I would suggest using ManualUniverseSelectionModel with 2-3 symbols and minute resolution in the AlphaModel development phase.
Adam W
Typo there - this line should be self not algorithm:
currInvested = [x.Symbol for x in self.Portfolio.Values if x.Invested]
The method that Alexandre suggested works as well - fundamentally should be the same logic whether you are emitting Flat insights to "overwrite" any existing ones until the next market open, or simply making sure Insights expire at a certain time before market close.
S O'Keeffe
Ahhh thank you Adam!
And thank you Alexandre! I've changed the resolution to 'Minute' to speed up backtests while developing. I left the symbols as 1,000 because I wanted to make sure I had a lot of examples of potential edge cases. And it looks like there are a couple edge cases at the end of the 'Orders' tab. There are five 'Sell Market On Open' orders instead of everything being closed out at EOD. Do you know why PLAY, LYB, PLNT, PRNB, and WIMI didn't liquidate before EOD?
If I may ask one other (potentially stupid) question too. Why does the algorithm essentially stop buying at 10:14am? BE continues to set new high of day marks (which should trigger buying) until 12:30pm. Do I need to add in more lines that look like this with other minute checkpoints for later in the day?
self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen("W5000", 45), self.toggleScan)
Thank you!
Sean
S O'Keeffe
Correction I only have one question now. When I try extending the attached to more days to see if it can remain profitable, I am getting the error "Runtime Error: AttributeError : 'QuantumHorizontalRegulators' object has no attribute 'needs_reset' at Update in main.py:line 105 :: if self.algo.needs_reset: AttributeError : 'QuantumHorizontalRegulators' object has no attribute 'needs_reset' " Do you know how I can fix that?
Nevermind on the previous two questions! I understand now that "self.toggleScan" means toggling the scannner part of the algorithm between on and off. So I extended that scanning window to toggle off after 360 minutes (at 3:30pm) instead of after 45 minutes. And I set the 'closeTime' to be 10 minutes before closing, which seems to have solved the 'Sell Market On Open' issue.
Thank you!
Sean
Adam W
The problem there is this line:
if self.algo.needs_reset:
for symbol in self.symbolData:
self.symbolData[symbol].max.Reset()
self.algo.needs_reset = True
self.algo refers to the instance of the base algorithm object, and checking that if statement throws an error since the attribute .needs_reset is not defined yet. You should initialize the variable with:
def Initialize(self):
self.needs_reset = False # Add this
There's a Debugger in the IDE that helps with errors like these, or you should get familiar with interpreting the errors/warnings from the stacktrace to make future debugging easier.
S O'Keeffe
Thank you so much Adam! Sorry I am trying to learn as much python as I can while piecing together this algorithm. I will try to understand more and get better at debugging. I really appreciate your help!
Sean
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!