I try to create an option universe. Working as instructed on other posts in the forum, I filtered option contract s in the OnSecuritiesChanged method (in contrast to what is shown on options docs example for option chain provider) and I can not add the option contract after filtering them out. I use self.AddOptionContract and it throws the following error  

  1. Runtime Error: NotSupportedException : BacktestingOptionChainProvider.GetOptionContractList(): SecurityType.Equity, SecurityType.Future, or SecurityType.Index is expected but was Option

here's the code

  1. class MeasuredApricotCamel(QCAlgorithm):
  2. def Initialize(self):
  3. self.SetStartDate(2021, 12, 17)
  4. self.SetEndDate(2022,1,1)
  5. self.SetCash(100000)
  6. self.rebalanceTime = datetime.min
  7. self.activeStocks = set()
  8. self.activeOptions = set()
  9. self.AddUniverse(self.CoarseFilter)
  10. self.UniverseSettings.DataNormalizationMode = DataNormalizationMode.Raw
  11. self.counter = 1000
  12. def CoarseFilter(self, coarse):
  13. if self.Time <= self.rebalanceTime:
  14. return self.Universe.Unchanged
  15. sortedByVolume = sorted(coarse, key = lambda x: x.Volume, reverse = True)
  16. filtered = [x.Symbol for x in sortedByVolume if x.Price <= 200 and x.Price <= 50]
  17. self.rebalanceTime = self.Time + timedelta(days = 45)
  18. return filtered[0:10]
  19. def OptionsFilter(self, stock):
  20. contracts = self.OptionChainProvider.GetOptionContractList(stock, self.Time)
  21. #selects the type of option to be Put contract
  22. puts = [x for x in contracts if x.ID.OptionRight == OptionRight.Put]
  23. #sorts contracts by closet expiring date date and closest strike price (sorts in ascending order)
  24. puts = sorted(sorted(puts, key = lambda x: x.ID.Date), key = lambda x: x.ID.StrikePrice)
  25. #then selects all contracts that meet our expiration criteria
  26. #We want between 30 and 60 days as we do not want to hold our options close to expiration
  27. puts = [x for x in puts if 30<(x.ID.Date - self.Time).days <= 60]
  28. if not puts:
  29. return
  30. #selects the type of option to be Put contract
  31. call = [x for x in contracts if x.ID.OptionRight ==OptionRight.Call]
  32. #sorts contracts by closet expiring date date and closest strike price (sorts in ascending order)
  33. call = sorted(sorted(call, key = lambda x: x.ID.Date), key = lambda x: x.ID.StrikePrice , reverse = True)
  34. #then selects all contracts that meet our expiration criteria
  35. call = [x for x in call if 30 <(x.ID.Date - self.Time).days <= 45]
  36. if not call:
  37. return
  38. #will eventually return array of optimal puts and calls
  39. #self.AddOptionContract(puts[0], Resolution.Minute)
  40. #self.AddOptionContract(call[0], Resolution.Minute)
  41. return (puts[0],call[0])
  42. def OnSecuritiesChanged(self, changes):
  43. for x in changes.RemovedSecurities:
  44. self.Liquidate(x.Symbol)
  45. self.activeStocks.remove(x.Symbol)
  46. for x in changes.AddedSecurities:
  47. self.activeStocks.add(x.Symbol)
  48. options = self.OptionsFilter(x.Symbol)
  49. loggg = ""
  50. if options:
  51. put, call = options[0], options[1]
  52. self.activeOptions.add((put,call))
  53. loggg += put.Value + ", " + call.Value
  54. self.Log(loggg)
  55. def checkOptionStatus(self, option):
  56. if option.ID.Date < self.Time + timedelta(days = 7):
  57. #It is time to sell
  58. pass
  59. pass
  60. def OnData(self, data):
  61. if self.activeOptions:
  62. for option in self.activeOptions:
  63. pass
  64. if self.counter == 0:
  65. self.Log(",".join([x.Value for x in self.activeStocks]))
  66. #self.Log(self.activeOptions)
  67. self.counter = 1000
  68. else:
  69. self.counter -= 1
+ Expand

Author

Yarden Gur

February 2022