'How to create an indicator extension with QuantConnect
I have created an indicator for the ratio between PEPSI (PEP) and Coca Cola (COKE) and am trying to create a 5 days simple moving average (sma) from this indicator using IndicatorExtension
and then plot the result. The offending code is at the end of the script:
import numpy as np
class SquareLightBrownPanda(QCAlgorithm):
def Initialize(self):
self.SetStartDate(2020, 1, 1) # Set Start Date
self.SetEndDate(2021,1,1) # Set End Date
self.SetCash(100000) # Set Strategy Cash
self.pep = self.AddEquity("PEP", Resolution.Daily).Symbol # Add data for PEP
self.coke = self.AddEquity("COKE", Resolution.Daily).Symbol # Add data for COKE
self.log_ratio_spread=0
self.sma_pep = self.SMA(self.pep,5,Resolution.Daily) #create 5 simple moving average indicator
self.sma_coke = self.SMA(self.coke,5,Resolution.Daily) #create 5 simple moving average indicator
closing_price_pep = self.History(self.pep,5,Resolution.Daily)["close"] #historic information for the past 5 bars.
closing_price_coke = self.History(self.coke,5,Resolution.Daily)["close"] #historic information for the past 5 bars.
for time, price in closing_price_pep.loc[self.pep].items(): #iterate over time and price information in the closing price dataframe
self.sma_pep.Update(time, price) #update sma indicator is ready to use from the beginning
for time, price in closing_price_coke.loc[self.coke].items(): #iterate over time and price information in the closing price dataframe
self.sma_coke.Update(time, price) #update sma indicator is ready to use from the beginning
def OnData(self, data):
if not self.sma_pep.IsReady and not self.sma_coke.IsReady:
return
#save the high and low price of the last year - not efficient use rolling window
hist_pep = self.History(self.pep, timedelta(365),Resolution.Daily)
hist_coke = self.History(self.coke, timedelta(365),Resolution.Daily)
price_pep = self.Securities[self.pep].Price ##save PEP's most recent price to the price variable
price_coke = self.Securities[self.coke].Price ##save COKE's most recent price to the price variable
log_ratio_pep = np.log(price_pep/self.sma_pep.Current.Value)
log_ratio_coke = np.log(price_coke/self.sma_coke.Current.Value)
self.log_ratio_spread = log_ratio_pep - log_ratio_coke
#TRYING TO CREATE 5 DAY MOVING AVERAGE OF log_ratio_spread HERE
self.log_ratio_spread_sma = IndicatorExtensions.SMA(self.log_ratio_spread,5,Resolution.Daily)
self.Plot("Spread","log_ratio_spread_sma",self.log_ratio_spread_sma)
However when I run the code in QuantConnect I get the error:
Runtime Error: Trying to dynamically access a method that does not exist throws a TypeError exception. To prevent the exception, ensure each parameter type matches those required by the 'int'>) method. Please checkout the API documentation.
at OnData
ratio_spread = IndicatorExtensions.SMA(self.log_ratio_spread in main.py: line 53
(Open Stacktrace)
which is associated with the flollowing line:
self.log_ratio_spread_sma = IndicatorExtensions.SMA(self.log_ratio_spread,5,Resolution.Daily)
What am I doing wrong?
Solution 1:[1]
The issue is that the IndicatorExtensions.SMA
method expects an indicator object, but self.log_ratio_spread
is a decimal.
To resolve the issue, create a SimpleMovingAverage
indicator and manually update it with the log ratio spread.
log_ratio_pep = np.log(data[self.pep].Price / self.sma_pep.Current.Value)
log_ratio_coke = np.log(data[self.coke].Price / self.sma_coke.Current.Value)
log_ratio_spread = log_ratio_pep - log_ratio_coke
self.log_ratio_spread_sma.Update(data.Time, log_ratio_spread)
For a full example, see this backtest.
Best,
Derek Melchin
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | Derek |