Hello to all !
I am trying to use a custom indicator class in Alpha framework and load history data to warmup the indicators.
However I am getting the runtime error :
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 key exist in the collection and/or that collection is not empty. KeyError : (<QuantConnect.Symbol object at 0x7f7c9c8d6390>,) (Open Stacktrace)
Any ideas where that might come from?
Is the implementation ok apart from that?
Thank you!
Victor Goujon
from Execution.ImmediateExecutionModel import ImmediateExecutionModel from Portfolio.EqualWeightingPortfolioConstructionModel import EqualWeightingPortfolioConstructionModel import numpy as np from collections import deque from datetime import datetime, timedelta from array import * from MovingReturn import MovRet from MovingVolatility import MovVol from clr import AddReference AddReference("QuantConnect.Common") AddReference("QuantConnect.Algorithm") AddReference("QuantConnect.Algorithm.Framework") AddReference("QuantConnect.Indicators") from QuantConnect import * from QuantConnect.Indicators import * from QuantConnect.Algorithm import * from QuantConnect.Algorithm.Framework import * from QuantConnect.Algorithm.Framework.Alphas import * class NadionResistanceAutosequencers(QCAlgorithmFramework): def Initialize(self): self.SetStartDate(2020, 6, 4) # Set Start Date self.SetCash(100000) # Set Strategy Cash # self.AddEquity("SPY", Resolution.Minute) self.SetExecution(ImmediateExecutionModel()) self.SetPortfolioConstruction(NullPortfolioConstructionModel()) self.SetRiskManagement(NullRiskManagementModel()) self.SetPortfolioConstruction(EqualWeightingPortfolioConstructionModel()) self.tickers = ["SPY","IWM","QQQ","EFA","EEM","VNQ","LQD","GLD","SHY","IEF","TLT","AGG"] # Define symbols for Trading self.UniverseSettings.Resolution = Resolution.Daily # self.AddUniverseSelection(ScheduledUniverseSelectionModel(self.DateRules.Every(DayOfWeek.Friday),self.TimeRules.Every(timedelta(hours = 24)),self.SelectSymbols)) self.sym=[] self.SetAlpha(RisingAssetsAlphaModel()) for x in self.tickers: a=self.AddEquity(x, Resolution.Daily) self.sym.append(self.AddEquity(x, Resolution.Daily).Symbol) self.SetUniverseSelection( ManualUniverseSelectionModel(self.sym) ) # def SelectSymbols(self,datetime): # sym=[] # for x in self.tickers: # a=self.AddEquity(x, Resolution.Daily) # sym.append(self.AddEquity(x, Resolution.Daily).Symbol) # return sym class RisingAssetsAlphaModel(AlphaModel): def __init__(self): self.M1={} self.M3={} self.M6={} self.M12={} self.MomentumScore={} self.V61={} self.active_sym=[] self.ready={} self.N=5 def OnSecuritiesChanged(self,algorithm, changes): for security in changes.AddedSecurities: symbol = security.Symbol self.M1[symbol] = MovRet(symbol,21) self.M3[symbol] = MovRet(symbol,21*3) self.M6[symbol] = MovRet(symbol,21*6) self.M12[symbol] = MovRet(symbol,21*12) # self.V61[symbol]=MovVol(symbol,21*3) algorithm.Debug(self.M12[symbol].Value) history = algorithm.History(symbol, 21*12+1) self.M1[symbol].Warmup(history) self.M3[symbol].Warmup(history) self.M6[symbol].Warmup(history) self.M12[symbol].Warmup(history) # self.V61[symbol].Warmup(history) # if self.M1[symbol].IsReady and self.M3[symbol].IsReady and self.M6[symbol].IsReady and self.M12[symbol].IsReady and self.V61[symbol].IsReady: # self.ready[symbol]= True algorithm.RegisterIndicator(symbol, self.M1[symbol], Resolution.Daily) algorithm.RegisterIndicator(symbol, self.M3[symbol], Resolution.Daily) algorithm.RegisterIndicator(symbol, self.M6[symbol], Resolution.Daily) algorithm.RegisterIndicator(symbol, self.M12[symbol], Resolution.Daily) algorithm.RegisterIndicator(symbol, self.V61[symbol], Resolution.Daily) self.active_sym.append(symbol) def Update(self, algorithm, data): return for symbol in self.active_sym: algorithm.Debug(self.M12[symbol].IsReady) if self.M12[symbol].IsReady : algorithm.Debug(2) self.MomentumScore[symbol]=np.mean([self.M1[symbol].Value,self.M3[symbol].Value,self.M6[symbol].Value,self.M12[symbol].Value],dtype=np.float64) algorithm.Debug(self.MomentumScore) # algorithm.Debug(self.MomentumScore) # #3. Return a group of insights, emitting InsightDirection.Up for the first item of ordered, and InsightDirection.Flat for the second # return Insight.Group([ # # Create a grouped insight # Insight.Price(ordered[0]["symbol"], timedelta(1), InsightDirection.Up), # Insight.Price(ordered[1]["symbol"], timedelta(1),InsightDirection.Flat) # ]) class MovRet(): def __init__(self,symbol, periods): self.symbol=symbol self.N=periods self.window = RollingWindow[float](periods) self.window_Close=RollingWindow[float](2) self.IsReady=False self.IsReadyClose=False # Volatility is a mandatory attribute self.Value = 0 self.Close=0 self.Time=None # Updates this model using the new price information in the specified security instance # Update is a mandatory method def Update(self,input): self.Close=input.Close if self.window_Close.IsReady: self.IsReadyClose=True self.window.Add(float(self.window_Close[0] / self.window_Close[1]) - 1.0) if self.window.IsReady: self.Value=np.mean([ x for x in self.window ]) self.IsReady=self.window.IsReady if self.window.Count<self.N: self.Value=0 if self.window.Count<2: self.Value=0 self.IsReadyClose=False def Warmup(self,history): for index, row in history.loc[str(self.symbol)].iterrows(): self.Close=row["close"] self.window_Close.Add(row["close"]) self.Time=index
Shile Wen
Hi Victor,
If we are using an Algo Framework Universe, in this case a Manual Universe, we do not need to call AddEquity, and we can instead create Symbol objects using Symbol.Create. On the other hand, if we call AddEquity, we don't need to use the Manual Universe, as it would be redundant. Furthermore, our Update method of our Alpha Model needs to return a collection of Insights, so I've made it return an empty list.
The reason we have a KeyError is because is commented out self.V61[symbol].Warmup(history), so when we try to call algorithm.RegisterIndicator(symbol, self.V61[symbol], Resolution.Daily), we try to access a dict that doesn't doesn't contain our key, and so we just need to comment this line out.I've shown these changes in the attached backtest. For future reference please use our Debugger to find bugs in the logic.
Best,
Shile Wen
Victor Goujon
Thank you !
Best,
Victor
Victor Goujon
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!