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  { "RUTW", "RUT" },
31  { "SPXW", "SPX" },
32  { "VIXW", "VIX" },
33  { "NDXP", "NDX" },
34  { "NQX", "NDX" },
35  };
36 
37  /// <summary>
38  /// These are known assets that are weeklies or end-of-month settled contracts.
39  /// </summary>
40  private static readonly HashSet<string> _nonStandardIndexOptionTickers = new()
41  {
42  // Weeklies
43  "RUTW", // PM-Settled. While RUT AM-Settled on 3rd Fridays
44  "SPXW",
45  "VIXW",
46  // PM-Settled
47  "NDXP",
48  // reduced value index options, 20%
49  "NQX"
50  };
51 
52  /// <summary>
53  /// Supported index option tickers
54  /// </summary>
55  public static readonly HashSet<string> SupportedIndexOptionTickers = new string[] { "SPX", "NDX", "VIX", "RUT" }
56  .Union(_nonStandardIndexOptionTickers)
57  .ToHashSet();
58 
59  /// <summary>
60  /// Determines if the Index Option Symbol is for a monthly contract
61  /// </summary>
62  /// <param name="symbol">Index Option Symbol</param>
63  /// <returns>True if monthly contract, false otherwise</returns>
64  public static bool IsStandard(Symbol symbol)
65  {
66  if (symbol.ID.Market != Market.USA)
67  {
68  return true;
69  }
70 
71  switch (symbol.ID.Symbol)
72  {
73  case "NQX":
74  case "SPXW":
75  case "RUTW":
76  // they have weeklies and monthly contracts
77  // NQX https://www.nasdaq.com/docs/NQXFactSheet.pdf
78  // SPXW https://www.cboe.com/tradable_products/sp_500/spx_weekly_options/specifications/
79  // RUTW expires every day
80  return FuturesExpiryUtilityFunctions.ThirdFriday(symbol.ID.Date) == symbol.ID.Date;
81  default:
82  // NDX/SPX/NQX/VIX/VIXW/NDXP/RUT are all normal contracts
83  return true;
84  }
85  }
86 
87  /// <summary>
88  /// Checks if the ticker provided is a supported Index Option
89  /// </summary>
90  /// <param name="ticker">Ticker of the index option</param>
91  /// <returns>true if the ticker matches an index option's ticker</returns>
92  /// <remarks>
93  /// This is only used in IB brokerage, since they don't distinguish index options
94  /// from regular equity options. When we do the conversion from a contract to a SecurityType,
95  /// the only information we're provided that can reverse it to the <see cref="SecurityType.IndexOption"/>
96  /// enum value is the ticker.
97  /// </remarks>
98  public static bool IsIndexOption(string ticker)
99  {
100  return SupportedIndexOptionTickers.Contains(ticker.LazyToUpper());
101  }
102 
103  /// <summary>
104  /// Maps an index option ticker to its underlying index ticker
105  /// </summary>
106  /// <param name="indexOption">Index option ticker to map to the underlying</param>
107  /// <returns>Index ticker</returns>
108  public static string MapToUnderlying(string indexOption)
109  {
110  if(_nonStandardOptionToIndex.TryGetValue(indexOption.LazyToUpper(), out var index))
111  {
112  return index;
113  }
114 
115  return indexOption;
116  }
117 
118  /// <summary>
119  /// Returns the last trading date for the given index option ticker and expiration date
120  /// </summary>
121  /// <remarks>This is useful for IB brokerage</remarks>
122  public static DateTime GetLastTradingDate(string ticker, DateTime expirationDate)
123  {
124  return expirationDate.AddDays(-GetExpirationOffset(ticker));
125  }
126 
127  /// <summary>
128  /// Returns the expiry date for the given index option ticker and last trading date
129  /// </summary>
130  /// <remarks>This is useful for IB brokerage</remarks>
131  public static DateTime GetExpiryDate(string ticker, DateTime lastTradingDate)
132  {
133  return lastTradingDate.AddDays(GetExpirationOffset(ticker));
134  }
135 
136  /// <summary>
137  /// Some index options last tradable date is the previous day to the expiration
138  /// https://www.cboe.com/tradable_products/vix/vix_options/specifications/
139  /// https://www.cboe.com/tradable_products/ftse_russell/russell_2000_index_options/rut_specifications
140  /// </summary>
141  private static int GetExpirationOffset(string ticker)
142  {
143  switch (ticker)
144  {
145  case "SPX":
146  case "NDX":
147  case "VIX":
148  case "VIXW":
149  case "RUT":
150  return 1;
151  default:
152  // SPXW, NQX, NDXP, RUTW
153  return 0;
154  }
155  }
156  }
157 }