Hi, i am attempting to add custom period indicator to my algorithm class Symbol Data, so that i can reference them later on for multiple securities, unfortunately i keep getting this:
'SymbolData' object has no attribute 'RegisterIndicator' I would appreciate if someone can point out my error and offer a solution,Here is the algorithmi was working on.from datetime import timedelta, datetime
class SwimmingYellowGreenAntelope(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2015, 12, 1) # Set Start Date
self.SetEndDate(2020, 12, 1)
self.SetCash(100000) # Set Strategy Cash
#EURUSD", "USDJPY", "GBPUSD", "AUDUSD" "USDCAD",
#"GBPJPY", "EURUSD", "AUDUSD", "EURJPY", "EURGBP"
self.Data = {}
for ticker in ["EURUSD","NZDUSD","USDJPY"]:
symbol = self.AddForex(ticker, Resolution.Hour, Market.FXCM).Symbol
self.Data[symbol] = SymbolData(self, symbol)
self.stopLossLevel = -0.05 # stop loss percentage
self.stopProfitLevel = 0.01# stop profit percentage
self.SetWarmUp(200, Resolution.Hour)
def OnData(self, data):
if self.IsWarmingUp:
return
for symbol, symbolData in self.Data.items():
if not (data.ContainsKey(symbol) and data[symbol] is not None and symbolData.IsReady):
continue
RSI = symbolData.rsi.Current.Value
current_price = data[symbol].Close
if self.Portfolio[symbol].Invested:
if self.isLong:
condStopProfit = (current_price - self.buyInPrice)/self.buyInPrice > self.stopProfitLevel
condStopLoss = (current_price - self.buyInPrice)/self.buyInPrice < self.stopLossLevel
if condStopProfit:
self.Liquidate(symbol)
self.Log(f"{self.Time} Long Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(symbol)
self.Log(f"{self.Time} Long Position Stop Loss at {current_price}")
else:
condStopProfit = (self.sellInPrice - current_price)/self.sellInPrice > self.stopProfitLevel
condStopLoss = (self.sellInPrice - current_price)/self.sellInPrice < self.stopLossLevel
if condStopProfit:
self.Liquidate(symbol)
self.Log(f"{self.Time} Short Position Stop Profit at {current_price}")
if condStopLoss:
self.Liquidate(symbol)
self.Log(f"{self.Time} Short Position Stop Loss at {current_price}")
if not self.Portfolio[symbol].Invested:
lbbclose = symbolData.closeWindow[20] # self.closeWindow[20]
lbsclose = symbolData.closeWindow[10] # self.closeWindow[10]
if RSI < 50 and current_price < lbbclose and current_price > lbsclose:
self.SetHoldings(symbol, 0)
# get buy-in price for trailing stop loss/profit
self.buyInPrice = current_price
# entered long position
self.isLong = True
self.Log(f"{self.Time} Entered Long Position at {current_price}")
if RSI > 50 and current_price > lbbclose and current_price < lbsclose:
self.SetHoldings(symbol, -1)
# get sell-in price for trailing stop loss/profit
self.sellInPrice = current_price
# entered short position
self.isLong = False
self.Log(f"{self.Time} Entered Short Position at {current_price}")
class SymbolData:
def __init__(self, algorithm, symbol):
self.rsi = RelativeStrengthIndex(14, MovingAverageType.Simple)
self.rsiWindow = RollingWindow[IndicatorDataPoint](2)
#Generating 14-period RSI values of 4 hours Resolution.
self.RegisterIndicator(symbol, self.rsi, timedelta(hours=4))
self.rsi.Updated += self.RsiUpdated
self.closeWindow = RollingWindow[float](21)
# Add consolidator to track rolling close prices
self.consolidator = QuoteBarConsolidator(4)
self.consolidator.DataConsolidated += self.CloseUpdated
algorithm.SubscriptionManager.AddConsolidator(symbol, self.consolidator)
def RsiUpdated(self, sender, updated):
'''Event holder to update the RSI Rolling Window values'''
if self.rsi.IsReady:
self.rsiWindow.Add(updated)
def CloseUpdated(self, sender, bar):
'''Event holder to update the close Rolling Window values'''
self.closeWindow.Add(bar.Close)
@property
def IsReady(self):
return self.closeWindow.IsReady and self.rsi.IsReady
Shile Wen
Hi Samwei,
For methods we would usually call in QCAlgorithm, in the SymbolData, we would need to call the method on the "algorithm" field. For example: self.RegisterIndicator(symbol, self.rsi, timedelta(hours=4)) would be changed to algorithm.RegisterIndicator(symbol, self.rsi, timedelta(hours=4))
Best,
Shile Wen
Paul Sattler
Shile Wen,
I am getting this same error in my code as well. I have 2 questions:
Non Compete
The original code posted by Samwel Kibet didn't call RegisterIndicator on the algorithm variable, which was the issue. Change
self.RegisterIndicator(symbol, self.rsi, timedelta(hours=4))
to
algorithm.RegisterIndicator(symbol, self.rsi, timedelta(hours=4))
Paul Sattler I think you would need to post some of the code because it sounds like you are calling it correctly.
Louis Szeto
Hi Paul
Although it is not directly calling RegisterIndicator method, but you can take a look at this template algorithm on how to properly implement a SymbolData class object.
Best
Louis
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.
Samwel Kibet
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!