I was running Covered Call Option tutorial from
https://github.com/QuantConnect/Tutorials/tree/master/07%20Applied%20Options%5B%5D/01%20Covered%20CallI changed the StartDate and EndDate as:
self.SetStartDate(2017, 1, 1)
self.SetEndDate(2017, 7, 1)
After running the backtest I am seeing the following errors in the console. It appears that data is not found, any thoughts ?.
216 | 02:45:34:
Backtest Handled Error: IBM 170127C00167500: The security does not have an accurate price as it has not yet received a bar of data. Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've set the 'Value' property.
217 | 02:45:37:
Backtest Handled Error: IBM 170224C00177500: The security does not have an accurate price as it has not yet received a bar of data. Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've set the 'Value' property.
218 | 02:45:40:
Backtest Handled Error: IBM 170324C00180000: The security does not have an accurate price as it has not yet received a bar of data. Before placing a trade (or using SetHoldings) warm up your algorithm with SetWarmup, or use slice.Contains(symbol) to confirm the Slice object has price before using the data. Data does not necessarily all arrive at the same time so your algorithm should confirm the data is ready before using it. In live trading this can mean you do not have an active subscription to the asset class you're trying to trade. If using custom data make sure you've set the 'Value' property.
219 | 02:45:44:
Backtest Handled Error: The security with symbol 'IBM 170324C00180000' is marked as non-tradable.
Shile Wen
Hi Ron,
Please see our previous thread on this issue.
Thank you for letting us know about the issue with that tutorial, we will fix it as soon as possible.
Best,
Shile Wen
Ron Daniel
Thanks Shile for your response. Per guidance on the other thread, I updated my script. Backtest shows only 9 trades. Why less trades ? Any thoughts ?.
from datetime import timedelta class CoveredCallOptionsAlgorithm(QCAlgorithm): def Initialize(self): self.SetStartDate(2019, 7, 1) self.SetEndDate(2020, 6, 30) self.SetCash(100000) equity = self.AddEquity("GOOG", Resolution.Minute) equity.SetDataNormalizationMode(DataNormalizationMode.Raw) self.SetSecurityInitializer(lambda x: x.SetMarketPrice(self.GetLastKnownPrice(x))) self.underlying = equity.Symbol # use the underlying equity as the benchmark self.SetBenchmark(self.underlying) #self.SetWarmUp(50) # Initialize the call contract self.call = str() def OnData(self,slice): if not self.Portfolio[self.underlying].Invested: self.MarketOrder(self.underlying, 100) # long the underlying stock if not (self.Securities.ContainsKey(self.call) and self.Portfolio[self.underlying].Invested): self.call = self.AddContract(slice) # Add the call option contract (subscribe the contract data) if self.Securities.ContainsKey(self.call) and not self.Portfolio[self.call].Invested: self.Sell(self.call, 1) # short the call option def AddContract(self,slice): filtered_contracts = self.InitialFilter(-3, 3, 0, 7) if len(filtered_contracts) == 0: return str() else: call = [x for x in filtered_contracts if x.ID.OptionRight == OptionRight.Call] # sorted the contracts according to their expiration dates and choose the ATM options contracts = sorted(sorted(call, key = lambda x: abs(self.Securities[self.underlying].Price- x.ID.StrikePrice)), key = lambda x: x.ID.Date, reverse=True) if len(contracts) > 0: self.AddOptionContract(contracts[0], Resolution.Minute) return contracts[0] else: return str() def InitialFilter(self, min_strike_rank, max_strike_rank, min_expiry, max_expiry): ''' This method is an initial filter of option contracts according to the range of strike price and the expiration date ''' contracts = self.OptionChainProvider.GetOptionContractList(self.underlying, self.Time.date()) if len(contracts) == 0 : return [] # fitler the contracts based on the expiry range contract_list = [i for i in contracts if min_expiry < (i.ID.Date.date() - self.Time.date()).days <= max_expiry] # find the strike price of ATM option atm_strike = sorted(contract_list, key = lambda x: abs(x.ID.StrikePrice - self.Securities[self.underlying].Price))[0].ID.StrikePrice strike_list = sorted(set([i.ID.StrikePrice for i in contract_list])) # find the index of ATM strike in the sorted strike list atm_strike_rank = strike_list.index(atm_strike) try: strikes = strike_list[(atm_strike_rank + min_strike_rank):(atm_strike_rank + max_strike_rank)] except: strikes = strike_list filtered_contracts = [i for i in contract_list if i.ID.StrikePrice in strikes] return filtered_contracts def OnOrderEvent(self, orderEvent): self.Log(str(orderEvent))
Shile Wen
Hi Ron,
There may be many reasons the number of trades is different. One idea is that the start and end dates used are different, as
self.SetStartDate(2017, 1, 1) self.SetEndDate(2017, 7, 1)
was used in the first post, then
self.SetStartDate(2019, 7, 1) self.SetEndDate(2020, 6, 30)
was used in the most recent post.
Best,
Shile Wen
Ron Daniel
Hi Shile,
I tried using different date range just to get more trades, but I am not getting more than 9 trades. I am thinking something is not quite right in the script logic.
Any help would be great. Or any working script that does covered call would be helpful for my learning.
-- Ron
Shile Wen
Hi Ron,
I was able to increase the number of trades by setting the start date to 2015. Nonetheless, I adjusted the strategy to buy back the call option every other order to increase the number of trades, which I’ve shown how to do in the attached backtest.
Best,
Shile Wen
Ron Daniel
Thanks Shile for the updated code.
All the trades were done on the first two days of StartDate. Why no trade after that date ?. Just curiious.
Shile Wen
Hi Ron,
That is because the algorithm only trades one contract, and when that contract expires, the algorithm stops trading. I’ve changed the logic of the algorithm slightly so that when a contract expires, which we can tell by checking if self.Portfolio[call symbol].Invested is False, we will sell another call.
Best,
Shile Wen
Ron Daniel
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!