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]]
Alexandre Catarino
Hi Nathan Wells ,
In a Historical data request, we can eventually not be able to fetch data for all requested symbols. It may be a data issue that QuantConnect Data Team may need to investigate. However, if we want to continue the execution, we need to check whether data from a given symbol is included in the dataframe.
In this particular case, we need to add the following check:
if not str(x.Symbol) in history.index: continue
before line 52.
It will lead to another issue at line 57 because volumeTop has fewer elements than filter_market_cap.
Also, please note that MarketCap is an attribute of FineFundamental:
filter_market_cap = [f for f in fine if f.MarketCap > 500000000]
Nathan
Thank you! I also searched for MarketCap but for some reason didn't find it, so thanks!
Now just working through the issue on line 57, I'll ask if I can't figure it out.
Nathan
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!