Hello,

Apologies if this is a stupid question, but is there another way to completely liquidate a position once a certain parameter is met with an algorithm framework?  I am receiving the error message " 'FadeTheGapModel' object has no attribute 'Liquidate'  " when trying to backtest the below algorithm.  Can I use 'self.MarketOrder(symbol, -10)' with some way of automating the "-10" value to match the current number of shares the portfolio is holding?  

 

class QuantumHorizontalRegulators(QCAlgorithm):

def Initialize(self):
self.SetStartDate(2020, 5, 18) # Set Start Date
self.SetEndDate(2020, 5, 19)
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(FadeTheGapModel(self))

self.SetExecution(ImmediateExecutionModel())

self.SetPortfolioConstruction(AccumulativeInsightPortfolioConstructionModel(lambda time: None))

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 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 FadeTheGapModel(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

# Calculate return sign yesterday's close
yest_close = self.symbolData[symbol].yest_close
close = slice[symbol].Close
ret = (close - yest_close) / yest_close
high_of_day_break = close > self.symbolData[symbol].max.Current.Value
if ret >= 0.1 and high_of_day_break: # Up 10% on the day & breaks high of day
insights.append(Insight(symbol, timedelta(seconds=insight_seconds), InsightType.Price, InsightDirection.Up))

# Update max indicator for all symbols
for symbol in self.symbolData:
if symbol in slice.Bars:
self.symbolData[symbol].max.Update(slice.Time, slice.Bars[symbol].High)


# 2% Trailing Stop Order
for symbol in self.symbolData:
if symbol in slice.Bars and slice[symbol].Close <= 0.98*self.symbolData[symbol].max.Current.Value:
self.Liquidate[symbol]


return Insight.Group(insights)



def OnSecuritiesChanged(self, algorithm, changes):
if len(changes.AddedSecurities) > 0:
# Get history of symbols over lookback window
added_symbols = [x.Symbol for x in changes.AddedSecurities]
history = algorithm.History(added_symbols, 1, Resolution.Daily)['close']

for added in changes.AddedSecurities:
# Save yesterday's close
closes = history.loc[[str(added.Symbol.ID)]].values
if len(closes) < 1:
continue
self.symbolData[added.Symbol] = SymbolData(closes[0])

for removed in changes.RemovedSecurities:
# Delete yesterday's close tracker
self.symbolData.pop(removed.Symbol, None)

class SymbolData:
def __init__(self, yest_close):
self.yest_close = yest_close
self.max = Maximum(45*60) # 45 minutes

 

Thank you,
Sean

Author