Back

Algorithm Framework close all positions at End of Day

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

 

Update Backtest








0

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.


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

1


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

 

0

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

 

0

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:

 

"Runtime Error: In Scheduled Event 'EveryDay: W5000: 1 min before MarketClose', NameError : name 'algorithm' is not defined at ClosePositions in main.py:line 79 :: currInvested = [x.Symbol for x in algorithm.Securities[symbol].Invested] NameError : name 'algorithm' is not defined"

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

 

0

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.

2

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.


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.

0

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

0


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

 

0


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.

2

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

0

Update Backtest





0

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.


Loading...

This discussion is closed