Lean  $LEAN_TAG$
IndexOptionSymbol.cs
1 /*
2  * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
3  * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14 */
15 
16 using System;
17 using System.Linq;
18 using System.Collections.Generic;
20 
22 {
23  /// <summary>
24  /// Index Option Symbol
25  /// </summary>
26  public static class IndexOptionSymbol
27  {
28  private static readonly Dictionary<string, string> _nonStandardOptionToIndex = new()
29  {
30  { "SPXW", "SPX" },
31  { "VIXW", "VIX" },
32  { "NDXP", "NDX" },
33  { "NQX", "NDX" },
34  };
35 
36  /// <summary>
37  /// These are known assets that are weeklies or end-of-month settled contracts.
38  /// </summary>
39  private static readonly HashSet<string> _nonStandardIndexOptionTickers = new()
40  {
41  // Weeklies
42  "SPXW",
43  "VIXW",
44  // PM-Settled
45  "NDXP",
46  // reduced value index options, 20%
47  "NQX"
48  };
49 
50  /// <summary>
51  /// Supported index option tickers
52  /// </summary>
53  public static readonly HashSet<string> SupportedIndexOptionTickers = new string[] { "SPX", "NDX", "VIX" }
54  .Union(_nonStandardIndexOptionTickers)
55  .ToHashSet();
56 
57  /// <summary>
58  /// Determines if the Index Option Symbol is for a monthly contract
59  /// </summary>
60  /// <param name="symbol">Index Option Symbol</param>
61  /// <returns>True if monthly contract, false otherwise</returns>
62  public static bool IsStandard(Symbol symbol)
63  {
64  if (symbol.ID.Market != Market.USA)
65  {
66  return true;
67  }
68 
69  switch (symbol.ID.Symbol)
70  {
71  case "NQX":
72  case "SPXW":
73  // they have weeklies and monthly contracts
74  // NQX https://www.nasdaq.com/docs/NQXFactSheet.pdf
75  // SPXW https://www.cboe.com/tradable_products/sp_500/spx_weekly_options/specifications/
76  return FuturesExpiryUtilityFunctions.ThirdFriday(symbol.ID.Date) == symbol.ID.Date;
77  default:
78  // NDX/SPX/NQX/VIX/VIXW/NDXP are all normal contracts
79  return true;
80  }
81  }
82 
83  /// <summary>
84  /// Checks if the ticker provided is a supported Index Option
85  /// </summary>
86  /// <param name="ticker">Ticker of the index option</param>
87  /// <returns>true if the ticker matches an index option's ticker</returns>
88  /// <remarks>
89  /// This is only used in IB brokerage, since they don't distinguish index options
90  /// from regular equity options. When we do the conversion from a contract to a SecurityType,
91  /// the only information we're provided that can reverse it to the <see cref="SecurityType.IndexOption"/>
92  /// enum value is the ticker.
93  /// </remarks>
94  public static bool IsIndexOption(string ticker)
95  {
96  return SupportedIndexOptionTickers.Contains(ticker.LazyToUpper());
97  }
98 
99  /// <summary>
100  /// Maps an index option ticker to its underlying index ticker
101  /// </summary>
102  /// <param name="indexOption">Index option ticker to map to the underlying</param>
103  /// <returns>Index ticker</returns>
104  public static string MapToUnderlying(string indexOption)
105  {
106  if(_nonStandardOptionToIndex.TryGetValue(indexOption.LazyToUpper(), out var index))
107  {
108  return index;
109  }
110 
111  return indexOption;
112  }
113 
114  /// <summary>
115  /// Returns the last trading date for the given index option ticker and expiration date
116  /// </summary>
117  /// <remarks>This is useful for IB brokerage</remarks>
118  public static DateTime GetLastTradingDate(string ticker, DateTime expirationDate)
119  {
120  return expirationDate.AddDays(-GetExpirationOffset(ticker));
121  }
122 
123  /// <summary>
124  /// Returns the expiry date for the given index option ticker and last trading date
125  /// </summary>
126  /// <remarks>This is useful for IB brokerage</remarks>
127  public static DateTime GetExpiryDate(string ticker, DateTime lastTradingDate)
128  {
129  return lastTradingDate.AddDays(GetExpirationOffset(ticker));
130  }
131 
132  /// <summary>
133  /// Some index options last tradable date is the previous day to the expiration
134  /// https://www.cboe.com/tradable_products/vix/vix_options/specifications/
135  /// </summary>
136  private static int GetExpirationOffset(string ticker)
137  {
138  switch (ticker)
139  {
140  case "SPX":
141  case "NDX":
142  case "VIX":
143  case "VIXW":
144  return 1;
145  default:
146  // SPXW, NQX, NDXP
147  return 0;
148  }
149  }
150  }
151 }