Hi,
I am new to the platform and working on a better understading of the api. I am trying to build a modified version of the EMA universe selection algo.
Instead of using the on securities change method, I want to set the Universe Resolution to minute data so I can rebalance only positive profit positions every 60 minutes for example. Although I am using minute data to capture intraday asset price movements for rebalancing I would like using Daily indicators. Not sure if I am going about this correctly.
I am using some code from the bootcamp and also searched the forums. I am stuck with code below. I am getting the errors below, also not sure if my my code is using best api practices.
Backtest Handled Error: CBLI TKH7EPK7SRC5: The security does not have an accurate price
as it has not yet received a bar of data. Before placing a trade (or using SetHoldings)
warm up your algorithm with SetWarmup, or use
slice.Contains(symbol) to confirm the Slice object has price before using the data.
Data does not necessarily all arrive at the same time so your algorithm should confirm
the data is ready before using it. In live trading this can mean you do not have an
active subscription to the asset class you're trying to trade. If using custom data
make sure you've set the 'Value' property.
Basel B
I changed the algo a bit to handle longs and shorts. I currently have the resolution set on daily but ultimately I would like help setting the resolution to Minute but using Daily indicators. But even with daily indicators I am now getting this error. Coule not attach the backtest for some reason
Runtime Error: In Scheduled Event 'SPY: EveryDay: Every 60 min', KeyNotFoundException : This asset symbol (INTU R735QTJ8XC9X) was not found in your security list. Please add this security or check it exists before using it with 'Securities.ContainsKey("INTU R735QTJ8XC9X")' at QuantConnect.Securities.SecurityManager.get_Item (QuantConnect.Symbol symbol) [0x00021] in <4fc3bcd66016475d97c581dc9193f674>:0 at QuantConnect.Securities.SecurityPortfolioManager.get_Item (QuantConnect.Symbol symbol) [0x00000] in <4fc3bcd66016475d97c581dc9193f674>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0 KeyNotFoundException : This asset symbol (INTU R735QTJ8XC9X) was not found in your security list. Please add this security or check it exists before using it with 'Securities.ContainsKey("INTU R735QTJ8XC9X")' at QuantConnect.Securities.SecurityManager.get_Item (QuantConnect.Symbol symbol) [0x00021] in <4fc3bcd66016475d97c581dc9193f674>:0 at QuantConnect.Securities.SecurityPortfolioManager.get_Item (QuantConnect.Symbol symbol) [0x00000] in <4fc3bcd66016475d97c581dc9193f674>:0 at (wrapper managed-to-native) System.Reflection.MonoMethod.InternalInvoke(System.Reflection.MonoMethod,object,object[],System.Exception&) at System.Reflection.MonoMethod.Invoke (System.Object obj, System.Reflection.BindingFlags invokeAttr, System.Reflection.Binder binder, System.Object[] parameters, System.Globalization.CultureInfo culture) [0x00032] in <b0e1ad7573a24fd5a9f2af9595e677e7>:0 (Open Stacktrace)
class EmaCrossUniverseSelectionAlgorithm(QCAlgorithm): def Initialize(self): '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.''' self.SetStartDate(2012,3,1) #Set Start Date self.SetEndDate(2013,6,30) #Set End Date self.SetCash(25000) #Set Strategy Cash self.spy = self.AddEquity("SPY", Resolution.Daily).Symbol self.UniverseSettings.Resolution = Resolution.Daily self.UniverseSettings.Leverage = 2 self.coarse_count = 50 self.averages = { } self.hold_day={ } # Make an empty dictionary to store holding days self.long = [ ] self.short = [ ] # this add universe method accepts two parameters: # - coarse selection function: accepts an IEnumerable<CoarseFundamental> and returns an IEnumerable<Symbol> self.AddUniverse(self.CoarseSelectionFunction) # Schedule the rebalance function to execute at user defined period self.Schedule.On(self.DateRules.EveryDay(self.spy), self.TimeRules.Every(TimeSpan.FromMinutes(60)), Action(self.rebalance)) # Schedule the holding period function to execute every day self.Schedule.On(self.DateRules.EveryDay(self.spy), self.TimeRules.BeforeMarketClose(self.spy, 15), Action(self.check_days)) # sort the data by daily dollar volume and take the top 'NumberOfSymbols' def CoarseSelectionFunction(self, coarse): filtered = [x for x in coarse if 5 < x.Price < 500 and x.DollarVolume > 1000000 and x.HasFundamentalData ] # We are going to use a dictionary to refer the object that will keep the moving averages for cf in filtered: symbol = cf.Symbol if symbol not in self.averages: # Call history to get an array of 50 days of history data #history = self.History(symbol, 100, Resolution.Daily) self.averages[symbol] = SymbolData(symbol) # Updates the SymbolData object with current EOD price avg = self.averages[symbol] avg.update(cf.EndTime, cf.AdjustedPrice) # Filter the values of the dict: we only want up-trending securities values = list(filter(lambda x: x.difference, self.averages.values())) # Sorts the values of the dict: we want those with greater difference between the moving averages values.sort(key=lambda x: x.difference, reverse=True) # for x in values[:self.coarse_count]: # self.Debug('symbol: ' + str(x.symbol.Value) + ' scale: ' + str(x.scale)) self.longList = [x.symbol for x in values[:self.coarse_count] if x.is_ready()] self.shortList = [x.symbol for x in values[-self.coarse_count:] if x.is_ready()] self.tradingList = self.long + self.short # we need to return only the symbol objects return self.tradingList def OnData(self, data): pass def rebalance(self): # self.Debug("Rebalance Event started running at: " + str(self.Time)) # 1. Cancel entryLong and entryShort tagged limit orders # 2a. Liquidate Positions that reached Max TakeProfit or Holding Time; set hold_day to -1 for i in self.Portfolio.Values: if i.Invested: if self.Portfolio[i.Symbol].UnrealizedProfitPercent > 0.0101 or \ self.hold_day[i.Symbol.Value] >= 5: self.Debug( str(i.Symbol.Value) + "Profit :" + str(self.Portfolio[i.Symbol].UnrealizedProfitPercent)) self.Liquidate(i.Symbol) try: self.hold_day[i.Symbol.Value] = -1 except: self.Debug("RemovedfromDict: " + str(i.Symbol.Value)) # 3. Reset holding percentage for positive profit positions only for i in self.Portfolio.Values: if i.Invested: if self.hold_day[i.Symbol.Value] >= 5 or self.Portfolio[i.Symbol].UnrealizedProfitPercent > 0.005: self.SetHoldings(i.Symbol, 0.02) self.Debug("Reseting:" + str(i.Symbol.Value)) # 4. Enter new position if it meets long/short entry criteria and not currently # invested in that asset, enter into long and short positions equally tradingCandidates = self.tradingList for longPos, shortPos in zip(self.longList, self.shortList): if self.Portfolio.MarginRemaining > 1000: if not self.Portfolio[longPos].Invested: self.SetHoldings(symbol, 0.02, False, "entryLong") self.Debug("entryLong: " + str(symbol)) self.hold_day[symbol.Value] = 0 # Add stock and 0 days to the dictionary if not self.Portfolio[shortPos].Invested: self.SetHoldings(symbol, 0.02, False, "entryShort") self.Debug("entryLong: " + str(symbol)) self.hold_day[symbol.Value] = 0 # Add stock and 0 days to the dictionary # this event fires whenever we have changes to our universe #def OnSecuritiesChanged(self, changes): # liquidate removed securities #for security in changes.RemovedSecurities: #if security.Invested: #self.Liquidate(security.Symbol) # we want 20% allocation in each security in our universe #for security in changes.AddedSecurities: #self.SetHoldings(security.Symbol, 0.1) # Helper function to count holding days for each holding stock def check_days(self): for i in self.Portfolio.Values: if i.Invested: self.hold_day[i.Symbol.Value] += 1 # Increment on each holding stock by 1 day class SymbolData(): """ Class to update Universe technical indicator data """ def __init__(self, symbol): self.tolerance = 1.01 self.symbol = symbol self.fast = ExponentialMovingAverage(3) self.slow = ExponentialMovingAverage(45) #self.mom = MomentumPercent(100) self.difference = 0 #for bar in history.itertuples(): # self.fast.Update(bar.Index[1], bar.close) # self.slow.Update(bar.Index[1], bar.close) # self.mom.Update(bar.Index[1], bar.close) def is_ready(self): return self.slow.IsReady and self.fast.IsReady def update(self, time, value): if self.fast.Update(time, value) and self.slow.Update(time, value): fast = self.fast.Current.Value slow = self.slow.Current.Value #mom = self.mom.Current.Value self.difference = fast > slow * self.tolerance #and mom > 0.0025
Shile Wen
Hi Basel,
Sorry for the late reply.
The error is caused by line 127 in the first posted code, when the variable symbol which isn't set to anything, is used as an argument. I isolate the source of the error in the following backtest (shared through link because failed backtests can't be attached):
https://www.quantconnect.com/terminal/processCache?request=embedded_backtest_b69b4cbde8dd0899da626b6855a60322.html
Best,
Shile Wen
Bo Vargas
Why would I get this same error on when Live, but not when back testing?
Unable to compute order quantity of 6E XG4S03C2H2IP. Reason: 6E XG4S03C2H2IP: The security does not have an accurate price as it has not yet received a bar of data. Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've set the 'Value' property. Returning null.
Basel B
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!