Hello,
I have been working on this alogrithm that using Bollinger Bands and MACD to confirm and place trades. However when I try and backtest it i get an error:
Runtime Error: AttributeError : 'MethodBinding' object has no attribute 'IsReady'
at OnData in main.py:line 54
AttributeError : 'MethodBinding' object has no attribute 'IsReady'
I ONLY have this error with MACD never with Bolband no matter which order thery are in. This seems to be the last issue I have that is preventing this from running. Alex has been helping me a lot with this and about adding extra stocks to it and not just using a universe to better control the portfolio. He wanted me to add adding several specfric stocks to this forum post as well for other people who are interesated. It was adding AAPL and NVDA to the algorithm to be traded on indeendant of each other. What he said was:Essentially, you need to create a class that will include all the indicators and a dictionary keyed by the security Symbol:
class SymbolData:
def __init__(self, symbol, algorithm):
self.Symbol = symbol
self.MACD = algorithm.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)
In Initilialize:
self.aapl = self.AddEquity("AAPL", Resolution.Daily).Symbol
self.nvda = self.AddEquity("NVDA", Resolution.Daily).Symbol
self.cache = {
self.aapl: SymbolData(self.aapl, self),
self.nvda: SymbolData(self.nvda, self)
}
If anyone has a solution to the Runtime Error I am getting I would very much appreciate it!
Link Liang
Hi Hunter,
"AttributeError" is thrown because the indicator is not initialized. Adding MACD alpha model does not initialize MACD indicator automatically. By implementing SymbolData class, it would be initialized inside there and accessed by self.cache[self.aapl].MACD.
In addition, indicator is assigned for each symbol, and requires a period of warmup phase before use. However, with a dynamic universe selection model (coarse-fine selection), securities are constantly adding to and removing from the universe. It leads to a problem that symbols might be (in fact, in most of the cases) removed even before its indicator is warmed up, and all strategy based on that indicator would never work properly.
Hope it helps!
Hunter Feulner
Hello Link Liang,
I will be honest I don't really understand how to implement what you said is there any chance you can show am an example so I may better comprehend what you are telling me to do. I still do not know how to get it to run in the multi-security environment.
Are you telling me that this algorithm with the conditions given cannot be run in a universe?
from datetime import datetime import decimal import numpy as np from Alphas.MacdAlphaModel import MacdAlphaModel class SymbolData: def __init__(self, symbol, algorithm): self.Symbol = symbol self.MACD = algorithm.MACD(symbol, 12, 26, 9, MovingAverageType.Exponential, Resolution.Daily) self.buypoint, self.sellpoint= None, None self.longLiqPoint, self.shortLiqPoint, self.yesterdayclose= None, None, None self.numdays = 30 self.Bolband = algorithm.BB(symbol, self.numdays, 2, MovingAverageType.Simple, Resolution.Daily) self.__previous = datetime.min class OptimizedDynamicRegulators(QCAlgorithm): def Initialize(self): self.SetStartDate(2018, 10, 25) # Set Start Date self.SetCash(100000) # Set Strategy Cash # self.AddEquity("SPY", Resolution.Minute) self.AddAlpha(MacdAlphaModel(12, 26, 9, MovingAverageType.Exponential, Resolution.Daily)) self.numdays = 30 self.ceiling,self.floor = 60,20 self.SetBenchmark("SPY") self.aapl = self.AddEquity("AAPL", Resolution.Daily).Symbol self.nvda = self.AddEquity("NVDA", Resolution.Daily).Symbol self.cache = { self.aapl: SymbolData(self.aapl, self), self.nvda: SymbolData(self.nvda, self) } def SetSignal(self): close = self.History(self.syl, 31, Resolution.Daily)['close'] todayvol = np.std(close[1:31]) yesterdayvol = np.std(close[0:30]) deltavol = (todayvol - yesterdayvol) / todayvol self.numdays = int(round(self.numdays * (1 + deltavol))) if self.numdays > self.ceiling: self.numdays = self.ceiling elif self.numdays < self.floor: self.numdays = self.floor self.high = self.History(self.syl, self.numdays, Resolution.Daily)['high'] self.low = self.History(self.syl, self.numdays, Resolution.Daily)['low'] self.buypoint = max(self.high) self.sellpoint = min(self.low) historyclose = self.History(self.syl, self.numdays, Resolution.Daily)['close'] self.longLiqPoint = np.mean(historyclose) self.shortLiqPoint = np.mean(historyclose) self.yesterdayclose = historyclose.iloc[-1] # wait for our BollingerBand to fully initialize if not self.Bolband.IsReady: return holdings = self.Portfolio[self.syl].Quantity if self.yesterdayclose > self.Bolband.UpperBand.Current.Value and self.Portfolio[self.syl].Price >= self.buypoint: self.SetHoldings(self.syl, 1) elif self.yesterdayclose < self.Bolband.LowerBand.Current.Value and self.Portfolio[self.syl].Price <= self.sellpoint: self.SetHoldings(self.syl, -1) if holdings > 0 and self.Portfolio[self.syl].Price <= self.shortLiqPoint: self.Liquidate(self.syl) elif holdings < 0 and self.Portfolio[self.syl].Price >= self.shortLiqPoint: self.Liquidate(self.syl) self.Log(str(self.yesterdayclose)+(" # of days ")+(str(self.numdays))) def OnData(self,data): '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.''' # wait for our macd to fully initialize if not self.MACD.IsReady: return # only once per day if self.__previous.date() == self.Time.date(): return # define a small tolerance on our checks to avoid bouncing tolerance = 0.0025 holdings = self.Portfolio[self.cache].Quantity signalDeltaPercent = (self.MACD.Current.Value - self.MACD.Signal.Current.Value)/self.MACD.Fast.Current.Value # if our macd is greater than our signal, then let's go long if holdings <= 0 and signalDeltaPercent > tolerance: # 0.01% # longterm says buy as well self.SetHoldings("AAPL", 1.0) self.SetHoldings("NVDA", 1.0) # of our macd is less than our signal, then let's go short elif holdings >= 0 and signalDeltaPercent < -tolerance: self.Liquidate("AAPL") self.Liquidate("NVDA") self.__previous = self.Time
Link Liang
Hi Hunter,
"AttributeError" is thrown because the indicator is not initialized. Adding MACD alpha model does not initialize MACD indicator automatically. By implementing SymbolData class, it would be initialized inside there and accessed by self.cache[self.aapl].MACD.
In addition, indicator is assigned for each symbol, and requires a period of warmup phase before use. However, with a dynamic universe selection model (coarse-fine selection), securities are constantly adding to and removing from the universe. It leads to a problem that symbols might be (in fact, in most of the cases) removed even before its indicator is warmed up, and all strategy based on that indicator would never work properly.
Hope it helps!
Hunter Feulner
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!