I am getting this error when I backtest:
Runtime Error: Trying to retrieve an element from a collection using a key that does not exist in that collection throws a KeyError exception. To prevent the exception, ensure that the ANGI V1OBWK1IM6HX key exist in the collection and/or that collection is not empty.
at <lambda> in FundamentalUniverseSelectionModel.py:line 3
KeyError : 'the label [ANGI V1OBWK1IM6HX] is not in the [index]'
Would anyone be willing to look at my code and tell me what I am doing wrong? I believe it is in the #Top 1500 Volume section (because it worked before I added that).
from Selection.FundamentalUniverseSelectionModel import FundamentalUniverseSelectionModel
class VentralModulatedThrustAssembly(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2019, 7, 9) # Set Start Date
self.SetCash(10000) # Set Strategy Cash
self.SetUniverseSelection(SelectionModel())
self.SetAlpha(ConstantAlphaModel(InsightType.Price, InsightDirection.Up, timedelta(1), 0.025, None))
self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel())
class SelectionModel(FundamentalUniverseSelectionModel):
def __init__(self,
filterFineData = True,
universeSettings = None,
securityInitializer = None):
super().__init__(filterFineData, universeSettings, securityInitializer)
self.periodCheck = -1
self.coarse = dict()
self.num_screener = 50
self.smaDictionary = {}
def SelectCoarse(self, algorithm, coarse):
if algorithm.Time.year == self.periodCheck:
return Universe.Unchanged
self.coarse = {x.Symbol: x
for x in coarse if x.HasFundamentalData and x.Volume > 0 and x.Price > 0}
return [symbol for symbol,_ in self.coarse.items()]
def SelectFine(self, algorithm, fine):
# Filter by Market Capitalization
marketCap = {}
for i in fine:
marketCap[i] = (i.EarningReports.BasicAverageShares.ThreeMonths * (i.EarningReports.BasicEPS.TwelveMonths * i.ValuationRatios.PERatio))
filter_market_cap = list(filter(lambda x: marketCap[x] > 500000000, fine))
symbols = [x.Symbol for x in filter_market_cap]
history = algorithm.History(symbols, 200, Resolution.Daily)
#Top 1500 Volume
volumeTop = {}
for x in filter_market_cap:
## Find hsitory for specific symbol
#self.debug(f'Updated this {str(x.Symbol)} ...')
symbolVolumeHistory = history.loc[str(x.Symbol)]
## Create SMA for symbol and register it with algorithm
symbolSMA = SimpleMovingAverage(200)
## Iterate through historical data
for tuple in symbolVolumeHistory.itertuples():
## Update SMA with data time and volume
symbolSMA.Update(tuple.Index, tuple.volume)
#self.Debug(f'Updating {symbol.Value} SMA...')
## Add SMA to dictionary so you can access it later
volumeTop[x] = symbolSMA
#volume_all = list(filter(lambda x: volumeTop[x] > 0, filter_market_cap))
filter_volume = sorted(filter_market_cap, key=lambda x: volumeTop[x], reverse=True)[:1500]
self.periodCheck = algorithm.Time.year
sorted_top_quality = sorted(filter_volume, key=lambda x: x.OperationRatios.ROIC.ThreeMonths + x.OperationRatios.LongTermDebtEquityRatio.ThreeMonths + (x.ValuationRatios.CashReturn + x.ValuationRatios.FCFYield), reverse=True)[:self.num_screener]
symbols = [x.Symbol for x in sorted_top_quality]
averages = dict()
history = algorithm.History(symbols, 200, Resolution.Daily).close.unstack(0)
#Filter top momentum
for symbol in symbols:
# Remove NaN: symbol does not have 200 daily data points
df = history[symbol].dropna()
if df.empty:
continue
mom = Momentum(126)
for time, close in df.iteritems():
mom.Update(time, close)
# Adds Momentum to dict only if it is ready
if mom.IsReady:
averages[symbol] = mom
# Update with current data
for symbol, mom in averages.items():
c = self.coarse.pop(symbol, None)
mom.Update(c.EndTime, c.AdjustedPrice)
sortedbyMomentum = sorted(averages.items(), key=lambda x: x[1], reverse=True)
return [x[0] for x in sortedbyMomentum[:5]]