Hey guys!
I am performing a backtest using two indicators, the stochastic and MACD, however, I need to access the values immediately prior to the position I am in now, ie "self.macd.Signal [1]", however, when trying to do this you receive the error below, I read several pages to solve this problem, but I can't evolve. Help me please!!
from clr import AddReference
AddReference("System")
AddReference("QuantConnect.Algorithm")
AddReference("QuantConnect.Common")
from System import *
from QuantConnect import *
from QuantConnect.Algorithm import *
from QuantConnect.Brokerages import *
from QuantConnect.Orders import *
class BasicTemplateCryptoAlgorithm(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._macd = {}
self._stoch = {}
self.SetStartDate(2020, 1, 1) #Set Start Date
self.SetEndDate(2021, 4, 1) #Set End Date
self.SetCash(1000)
# Set Strategy Cash (EUR)
# EUR/USD conversion rate will be updated dynamically
# self.SetCash("EUR", 10000)
# self.SetCash("BTC", 1)
# self.SetCash("ETH", 5)
self.SetBrokerageModel(BrokerageName.GDAX, AccountType.Cash)
symbol = self.AddCrypto("BTCUSD", Resolution.Minute).Symbol
# self.AddCrypto("ETHUSD", Resolution.Minute)
# self.AddCrypto("BTCEUR", Resolution.Minute)
self.AddSecurity(SecurityType.Equity, symbol, Resolution.Minute)
self.macd = self.MACD(symbol, 12, 26, 9, MovingAverageType.Simple, Resolution.Minute)
self.macdHistogram = RollingWindow[float](5)
self.macdMACD = RollingWindow[float](5)
self.macdSIGNAL = RollingWindow[float](5)
self.macdHistogram.Add(self.macd.Histogram.Current.Value)
self.macdMACD.Add(self.macd.Current.Value)
self.macdSIGNAL.Add(self.macd.Signal.Current.Value)
self.stocha = self.STO(symbol, 14, Resolution.Minute)
self.stochStochK = RollingWindow[float](5)
self.stochStochD = RollingWindow[float](5)
self.stochStochK.Add(self.stocha.StochK.Current.Value)
self.stochStochD.Add(self.stocha.StochD.Current.Value)
self.control = False
def OnData(self, data):
# if not (self._macd["Histogram"].IsReady and self._macd["MACD"].IsReady and self._macd["SIGNAL"].IsReady and self._stoch['StochK'].IsReady and self._stoch['StochD'].IsReady): return
if not (self.macd.IsReady and self.stocha.IsReady):
return
if self.macdHistogram[0] < self.macdHistogram[1] and ((self.stochStochK[0] > self.stochStochD[0] and self.stochStochK[1] < self.stochStochD[1]) or self.stochStochK[0] > self.stochStochD[0]) and self.macdHistogram[0] < 0 and self.stochStochD[0] < 40 and self.control == False:
self.control = True
usdTotal = self.Portfolio.CashBook["USD"].Amount
limitPrice = round(self.Securities["BTCUSD"].Price * 0.95, 2)
# use only half of our total USD
quantity = usdTotal * 0.5 / limitPrice
self.MarketOrder("BTCUSD", quantity)
elif (self.macdSIGNAL[0] > self.macdMACD[0] and sself.macdSIGNAL[1] < self.macdMACD[1])and self.control == True:
self.control = False
limitPrice = round(self.Securities["BTCUSD"].Price * 1.00, 2)
quantity = self.Portfolio.CashBook["BTC"].Amount
self.MarketOrder("BTCUSD", -quantity)
def OnOrderEvent(self, orderEvent):
self.Debug("{} {}".format(self.Time, orderEvent.ToString()))
def OnEndOfAlgorithm(self):
self.Log("{} - TotalPortfolioValue: {}".format(self.Time, self.Portfolio.TotalPortfolioValue))
self.Log("{} - CashBook: {}".format(self.Time, self.Portfolio.CashBook))
Error:
Runtime Error: ArgumentOutOfRangeException : Index must be between 0 and 0 (entry 1 does not exist yet)
Parameter name: i
Actual value was 1.
at QuantConnect.Indicators.RollingWindow`1[T].get_Item (System.Int32 i) [0x000bf] in <22157ec9a8b14f939cbe63f7e831e8ce>: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
at OnData
if self.macdHistogram[0] < self.macdHistogram[1] and ((self.stochStochK[0] > self.stochStochD[0] and self.stochStochK[1] < self.stochStochD[1]) or self.stochStochK[0] > self.stochStochD[0]) and self.macdHistogram[0] < 0 and self.stochStochD[0] < 40 and self.control == False:
===
at Python.Runtime.PyObject.Invoke (Python.Runtime.PyTuple args in main.py:line 63
ArgumentOutOfRangeException : Index must be between 0 and 0 (entry 1 does not exist yet)
Parameter name: i
Actual value was 1.
at QuantConnect.Indicators.RollingWindow`1[T].get_Item (System.Int32 i) [0x000bf] in <22157ec9a8b14f939cbe63f7e831e8ce>: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)
Mislav Sagovac
Try to change :
if not (self.macd.IsReady and self.stocha.IsReady): return
with:
if not (self.macd.IsReady and self.stocha.IsReady and self.stochStochK.IsReady and self.stochStochD.IsReady and self.macdSIGNAL[1]): return
You have some typos too, like:
elif (self.macdSIGNAL[0] > self.macdMACD[0] and sself.macdSIGNAL[1] < self.macdMACD[1])and self.control == True:
Eric Reis
I made some changes to the code, and when performing the DEBUG in Initialize (), removing the OnData () logic in some loops you can identify macdSignal [1], however, when inserting the onData () logic, you never make the purchase or sale, returns the error that the index [1] does not exist. Is there a way to insert Ondata () to identify that index [1] does not exist yet and return to Initialize () to add index [1]?
Runtime Error: ArgumentOutOfRangeException : Rolling window is empty (Parameter 'i')
at QuantConnect.Indicators.RollingWindow`1.get_Item(Int32 i) in /LeanCloud/CI.Builder/bin/Debug/src/QuantConnect/Lean/Common/Indicators/RollingWindow.cs:line 100
at OnData
if not (self.IsWarmingUp and self.macdHistogram[1]):
===
at Python.Runtime.PyObject.Invoke(PyTuple args in main.py:line 69
ArgumentOutOfRangeException : Rolling window is empty (Parameter 'i')
at QuantConnect.Indicators.RollingWindow`1.get_Item(Int32 i) in /LeanCloud/CI.Builder/bin/Debug/src/QuantConnect/Lean/Common/Indicators/RollingWindow.cs:line 100 (Open Stacktrace)
Derek Melchin
Hi Eric,
We can ensure the RollingWindows are full in OnData by adding a manual warm-up in the Initialize method.
period = max(self.macd.WarmUpPeriod, self.stocha.WarmUpPeriod) + window_length history = self.History(symbol, period, Resolution.Minute) if history.empty: return history = history.loc[symbol] for time, row in history.iterrows(): tradebar = TradeBar(time, symbol, row.open, row.high, row.low, row.close, row.volume) if self.macd.Update(IndicatorDataPoint(tradebar)): self.macdHistogram.Add(self.macd.Histogram.Current.Value) self.macdMACD.Add(self.macd.Current.Value) self.macdSIGNAL.Add(self.macd.Signal.Current.Value) if self.stocha.Update(tradebar): self.stochStochK.Add(self.stocha.StochK.Current.Value) self.stochStochD.Add(self.stocha.StochD.Current.Value)
See the attached backtest for reference.
Best,
Derek Melchin
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.
Vladimir
Here is my attempt at solving the puzzle using IndicatorExtensions Delay.
Vladimir
Here is my attempt at solving the puzzle using IndicatorExtensions Delay.
Eric Reis
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!