Hi all,
I tried to implement an indicator, which checks the average percentage price change + the standard deviation over the last X days. However, when the indicator tries to update itself, I receive the following runtime error: Cannot implicitly convert type 'Python.Runtime.PyObject' to 'decimal'
class AverageDay(PythonIndicator):
def __init__(self, name, period):
self.Name = name
self.Time = datetime.min
self.Value = {}
self.queue = deque(maxlen=period)
def __repr__(self):
return "{0} -> IsReady: {1}. Time: {2}. Value: {3}".format(self.Name, self.IsReady, self.Time, self.Value)
# Update method is mandatory
def Update(self, input):
r = ((input.Close / input.Open) - 1 ) * 100
self.queue.appendleft(r)
count = len(self.queue)
self.Time = input.EndTime
average = sum(self.queue) / count
deviation = std(self.queue)
self.Value["positive"] = average + (2 * deviation)
self.Value["negative"] = average - (2 * deviation)
return count == self.queue.maxlen
Maybe the issue is also that I have the resolution set to Resolution.Daily, while the rest of the algorithm runs on an hourly basis. Also, is there a way to send debug messages from the update function of an indicator?
Jared Broad
Hey there Simon, welcome to QuantConnect!
You should be able to use the debugger feature to step through the code to find the specific line if you put the class into the same file (main.py). If not please post a slightly longer mock example and I'd be happy to help debug it with you.
My hunch is maybe something about the Value property?
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.
Simon Dallmann
Hi Jared,
thanks for your response. I used the debugger before and there is no issue with setting the value. The code stops at the time of return.... There is not really any indicator in the debugger on why it fails, so I assume it is something in the backend. I pasted the further part of my logic below. Maybe you find the part where I messed up.
from collections import deque from datetime import datetime, timedelta from numpy import sum, std from QuantConnect.Data.Market import QuoteBar class PriceOverreactionsForex(QCAlgorithm): def Initialize(self): self.SetStartDate(2017, 12, 11) # Set Start Date self.SetEndDate(2018, 12, 31) # Set End Date self.SetCash(100000) # Set Strategy Cash self.syls = ["USDCAD","AUDUSD","EURJPY", "EURUSD", "USDCAD"] # Define Symbols for Trading self.days = 20 # Paramater to calculate reference self.open = {} self.averageDay = {} self.intraDay = {} for symbol in self.syls: self.AddForex(symbol, Resolution.Hour, Market.Oanda) self.averageDay[symbol] = AverageDay(symbol, self.days) self.RegisterIndicator(symbol, self.averageDay[symbol], Resolution.Daily) self.intraDay[symbol] = 0.0 self.open[symbol] = 0.0 self.SetWarmup(self.days) ) def OnData(self, data): if self.IsWarmingUp: return for symbol in self.syls: if self.open[symbol] == 0.0: self.open[symbol] = data[symbol].Open self.intraDay[symbol] = UpdateIntraday(symbol, data[symbol].Close) def UpdateIntraday(self, symbol, lastClose): r = 0.0 r = ((lastClose / self.open[symbol])- 1 ) * 100 return r class AverageDay(PythonIndicator): def __init__(self, name, period): self.Name = name self.Time = datetime.min self.Value = {} self.queue = deque(maxlen=period) def __repr__(self): return "{0} -> IsReady: {1}. Time: {2}. Value: {3}".format(self.Name, self.IsReady, self.Time, self.Value) # Update method is mandatory def Update(self, input): r = ((input.Close / input.Open) - 1 ) * 100 self.queue.appendleft(r) count = len(self.queue) self.Time = input.EndTime average = sum(self.queue) / count deviation = std(self.queue) self.Value["positive"] = average + (2 * deviation) self.Value["negative"] = average - (2 * deviation) return count == self.queue.maxlen
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.
Jared Broad
Hey Simon,
The value property is a reserved property in the underlying class. Unfortunately, you cannot convert it to a dictionary but I have rejigged it a little in the backtest attached to store the values to two new properties Positive and Negative. Please see the result attached.
Best
Jared
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!