Hi,
I am using code referenced from the demostration algorithm near the botton of the below link. Other than some naming changes, the only major change between my code and the demostration code is that I added the percentage change logic in its own method so I can call it at a specified time of the day.
https://www.quantconnect.com/docs/alternative-data/cboe
I get the below error when I run the attached code:
`Runtime Error: In Scheduled Event 'EveryDay: SPY: 15 min after MarketOpen', AttributeError : 'VixAlgo' object has no attribute 'pct_change' AttributeError : 'VixAlgo' object has no attribute 'pct_change' (Open Stacktrace)`
Rahul Chowdhury
Hey Kyle,
I couldn't reproduce the issue with the available information. It's difficult to debug the issue without seeing the code which produces it. Please post a code snippet or a back test which produces the issue.
Best
Rahul
Kyle sn
Apologies, I thought I had a project attached. See below:
from QuantConnect.Data.Custom.CBOE import * class VixAlgo(QCAlgorithm): def Initialize(self): self.SetStartDate(2020, 1, 1) self.SetEndDate(2020, 5, 1) self.SetCash(10000) self.spy = self.AddEquity("SPY", Resolution.Minute).Symbol self.cboeVix = self.AddData(CBOE, "VIX").Symbol self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen(self.spy, 15), Action(self.Buy)) self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.AfterMarketOpen(self.spy, 60), Action(self.Sell)) ''' for the benchmark charting overlay on equity curve ''' self.benchmarkTicker = "SPY" self.SetBenchmark(self.benchmarkTicker) self.initBenchmarkPrice = None self.Schedule.On(self.DateRules.EveryDay(), self.TimeRules.BeforeMarketClose(self.spy, 1), Action(self.PlotBenchmark)) def OnData(self, data): if not data.Bars.ContainsKey("SPY"): return if not data.ContainsKey(self.cboeVix): return vix = data.Get(CBOE, self.cboeVix) current = vix.Close if self.previous != 0: self.pct_change = (current - self.previous) / self.previous self.Log("VIX percent change is {}".format(self.pct_change)) def Buy(self): if self.pct_change > 0.05: self.Log("VIX percent change of {} is greater than 5%. Trading today".format(self.pct_change)) self.SetHoldings("SPY", 1) def Sell(self): self.SetHoldings("SPY", 0) def UpdateBenchmarkValue(self): ''' Simulate buy and hold the Benchmark ''' if self.initBenchmarkPrice is None: self.initBenchmarkCash = self.Portfolio.Cash self.initBenchmarkPrice = self.Benchmark.Evaluate(self.Time) self.benchmarkValue = self.initBenchmarkCash else: currentBenchmarkPrice = self.Benchmark.Evaluate(self.Time) self.benchmarkValue = (currentBenchmarkPrice / self.initBenchmarkPrice) * self.initBenchmarkCash def PlotBenchmark(self): self.Plot('Strategy Equity', self.benchmarkTicker, self.benchmarkValue)
Derek Melchin
Hi Kyle,
The reason this error is encountered when executing the algorithm is because `self.pct_change` has not been defined at the point when it is evaluated inside the Buy() method. It is not defined after the first 15 minutes of running the algorithm because of the guards set in OnData. As we can see in Initialize, we set the resolution of SPY to minute. However, our documentation shows that CBOE VIX data is in daily resolution.
Since the algorithm doesn't have a warmup period set, the algo is only fed SPY data for the first 15 minutes. Thus, the guard in OnData that states
if not data.ContainsKey(self.cboeVix): return
causes the lines that calculates `self.pct_change` to not be executed within the first 15 minutes of the algorithm running. Therefore, when Buy() is invoked, it throws the error.
I've attached a backtest which resolves this issue. Specifically, we set a warmup period of 2 days to ensure we have the previous 2 VIX data points before the algorithm starts looking for trades. We also adjust the guards in OnData to manage a rolling record of the 2 latest VIX data points.
For full understanding, I recommend reviewing the attached code files, as well as our documentations on warmup periods and understanding time.
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.
Kyle sn
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!