Hello

I'm using the following to initialize the VIX data:

  1. # add underlying for option data
  2. self.opt_equity = self.AddData( CBOE, "VIX" )
  3. self.opt_equity.SetDataNormalizationMode(DataNormalizationMode.Raw)

Than I'm using the following to get the Option Chain for the VIX options

  1. self.OptionChainProvider.GetOptionContractList(self.opt_equity.Symbol, data.Time)

It looks like it does not like VIX.CBOE as an index, how to get the Options on the VIX?

Thankx for help

 

This is the code:

  1. from datetime import timedelta
  2. class VIXCallProtection(QCAlgorithm):
  3. def Initialize(self):
  4. # set start/end date for backtest
  5. self.SetStartDate(2019, 10, 1)
  6. self.SetEndDate(2020, 10, 1)
  7. # set starting balance for backtest
  8. self.SetCash(1000000)
  9. # add asset
  10. self.equity = self.AddEquity("SPY", Resolution.Minute)
  11. self.equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
  12. # add underlying for option data
  13. self.opt_equity = self.AddData( CBOE, "VIX" )
  14. self.opt_equity.SetDataNormalizationMode(DataNormalizationMode.Raw)
  15. # initialize the option contract with empty string
  16. self.contract = str()
  17. self.contractsAdded = set()
  18. # parameters ------------------------------------------------------------
  19. self.DaysBeforeExp = 2 # number of days before expiry to exit
  20. self.DTE = 25 # target days till expiration
  21. self.OTM = 0.05 # target percentage OTM of put
  22. self.lookbackIV = 150 # lookback length of IV indicator
  23. self.percentage = 0.9 # percentage of portfolio for underlying asset
  24. self.options_alloc = 90 # 1 option for X num of shares (balanced would be 100)
  25. # ------------------------------------------------------------------------
  26. # schedule Plotting function 30 minutes after every market open
  27. self.Schedule.On(self.DateRules.EveryDay(self.equity.Symbol), \
  28. self.TimeRules.AfterMarketOpen(self.equity.Symbol, 30), \
  29. self.Plotting)
  30. # warmup for IV indicator of data
  31. self.SetWarmUp(timedelta(self.lookbackIV))
  32. def OnData(self, data):
  33. '''OnData event is the primary entry point for your algorithm. Each new data point will be pumped in here.
  34. Arguments:
  35. data: Slice object keyed by symbol containing the stock data
  36. '''
  37. if(self.IsWarmingUp):
  38. return
  39. # buy underlying asset
  40. if not self.Portfolio[self.equity.Symbol].Invested:
  41. self.SetHoldings(self.equity.Symbol, self.percentage)
  42. # self.BuyPut(data)
  43. if self.Securities[self.opt_equity.Symbol].Price > 20:
  44. self.BuyPut(data)
  45. # close put before it expires
  46. if self.contract:
  47. if (self.contract.ID.Date - self.Time) <= timedelta(self.DaysBeforeExp):
  48. self.Liquidate(self.contract)
  49. self.Log("Closed: too close to expiration")
  50. self.contract = str()
  51. def BuyPut(self, data):
  52. # get option data
  53. if self.contract == str():
  54. self.contract = self.OptionsFilter(data)
  55. return
  56. # if not invested and option data added successfully, buy option
  57. elif not self.Portfolio[self.contract].Invested and data.ContainsKey(self.contract):
  58. #self.Buy(self.contract, round(self.Portfolio[self.symbol].Quantity / self.options_alloc))
  59. self.Buy(self.contract, 1)
  60. def OptionsFilter(self, data):
  61. ''' OptionChainProvider gets a list of option contracts for an underlying symbol at requested date.
  62. Then you can manually filter the contract list returned by GetOptionContractList.
  63. The manual filtering will be limited to the information included in the Symbol
  64. (strike, expiration, type, style) and/or prices from a History call '''
  65. #contracts = self.OptionChainProvider.GetOptionContractList(self.symbol, data.Time)
  66. #self.underlyingPrice = self.Securities[self.symbol].Price
  67. contracts = self.OptionChainProvider.GetOptionContractList(self.opt_equity.Symbol, data.Time)
  68. self.underlyingPrice = self.Securities[self.opt_equity.Symbol].Price
  69. # filter the out-of-money put options from the contract list which expire close to self.DTE num of days from now
  70. otm_calls = [i for i in contracts if i.ID.OptionRight == OptionRight.Call and
  71. i.ID.StrikePrice - self.underlyingPrice > self.OTM * self.underlyingPrice and
  72. self.DTE - 8 < (i.ID.Date - data.Time).days < self.DTE + 8]
  73. if len(otm_calls) > 0:
  74. # sort options by closest to self.DTE days from now and desired strike, and pick first
  75. contract = sorted(sorted(otm_calls, key = lambda x: abs((x.ID.Date - self.Time).days - self.DTE)),
  76. key = lambda x: x.ID.StrikePrice - self.underlyingPrice)[0]
  77. if contract not in self.contractsAdded:
  78. self.contractsAdded.add(contract)
  79. # use AddOptionContract() to subscribe the data for specified contract
  80. self.AddOptionContract(contract, Resolution.Minute)
  81. #option=self.AddOptionContract(contract, Resolution.Minute)
  82. return contract
  83. else:
  84. return str()
  85. def Plotting(self):
  86. # plot underlying's price
  87. self.Plot("Data Chart", self.equity.Symbol, self.Securities[self.equity.Symbol].Close)
  88. # plot strike of put option
  89. option_invested = [x.Key for x in self.Portfolio if x.Value.Invested and x.Value.Type==SecurityType.Option]
  90. if option_invested:
  91. self.Plot("Data Chart", "strike", option_invested[0].ID.StrikePrice)
  92. def OnOrderEvent(self, orderEvent):
  93. # log order events
  94. self.Log(str(orderEvent))
+ Expand

 

Author

Carsten

November 2021