chore: import upstream snapshot with attribution

This commit is contained in:
wehub-resource-sync
2026-07-13 13:02:50 +08:00
commit 0fc60fdcb1
5008 changed files with 910633 additions and 0 deletions
@@ -0,0 +1,106 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using QuantConnect.Data;
using QuantConnect.Orders.Fees;
using QuantConnect.Orders.Fills;
using QuantConnect.Orders.Slippage;
using QuantConnect.Securities.Option;
namespace QuantConnect.Securities.IndexOption
{
/// <summary>
/// Index Options security
/// </summary>
public class IndexOption : Option.Option
{
/// <summary>
/// Constructor for the index option security
/// </summary>
/// <param name="symbol">Symbol of the index option</param>
/// <param name="exchangeHours">Exchange hours of the index option</param>
/// <param name="quoteCurrency">Quoted currency of the index option</param>
/// <param name="symbolProperties">Symbol properties of the index option</param>
/// <param name="currencyConverter">Currency converter</param>
/// <param name="registeredTypes">Provides all data types registered to the algorithm</param>
/// <param name="securityCache">Cache of security objects</param>
/// <param name="underlying">Future underlying security</param>
/// <param name="settlementType">Settlement type for the index option. Most index options are cash-settled.</param>
/// <param name="priceModelProvider">The option price model provider</param>
public IndexOption(Symbol symbol,
SecurityExchangeHours exchangeHours,
Cash quoteCurrency,
IndexOptionSymbolProperties symbolProperties,
ICurrencyConverter currencyConverter,
IRegisteredSecurityDataTypesProvider registeredTypes,
SecurityCache securityCache,
Security underlying,
SettlementType settlementType = SettlementType.Cash,
IOptionPriceModelProvider priceModelProvider = null)
: base(symbol,
quoteCurrency,
symbolProperties,
new OptionExchange(exchangeHours),
securityCache,
new OptionPortfolioModel(),
new ImmediateFillModel(),
new InteractiveBrokersFeeModel(),
NullSlippageModel.Instance,
new ImmediateSettlementModel(),
Securities.VolatilityModel.Null,
new OptionMarginModel(),
new OptionDataFilter(),
new IndexOptionPriceVariationModel(),
currencyConverter,
registeredTypes,
underlying,
priceModelProvider
)
{
ExerciseSettlement = settlementType;
}
/// <summary>
/// Consumes market price data and updates the minimum price variation
/// </summary>
/// <param name="data">Market price data</param>
/// <remarks>
/// Index options have variable sized minimum price variations.
/// For prices greater than or equal to $3.00 USD, the minimum price variation is $0.10 USD.
/// For prices less than $3.00 USD, the minimum price variation is $0.05 USD.
/// </remarks>
protected override void UpdateConsumersMarketPrice(BaseData data)
{
base.UpdateConsumersMarketPrice(data);
((IndexOptionSymbolProperties)SymbolProperties).UpdateMarketPrice(data);
}
/// <summary>
/// Updates the symbol properties of this security
/// </summary>
internal override void UpdateSymbolProperties(SymbolProperties symbolProperties)
{
if (symbolProperties != null)
{
SymbolProperties = new IndexOptionSymbolProperties(symbolProperties);
}
}
/// <summary>
/// Returns the securities symbol
/// </summary>
public static implicit operator Symbol(IndexOption security) => security.Symbol;
}
}
@@ -0,0 +1,25 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
namespace QuantConnect.Securities.IndexOption
{
/// <summary>
/// Index option specific caching support
/// </summary>
/// <seealso cref="SecurityCache"/>
public class IndexOptionCache : Option.OptionCache
{
}
}
@@ -0,0 +1,34 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
namespace QuantConnect.Securities.IndexOption
{
/// <summary>
/// The index option price variation model
/// </summary>
public class IndexOptionPriceVariationModel : IPriceVariationModel
{
/// <summary>
/// Get the minimum price variation from a security
/// </summary>
/// <param name="parameters">An object containing the method parameters</param>
/// <returns>Decimal minimum price variation of a given security</returns>
public decimal GetMinimumPriceVariation(GetMinimumPriceVariationParameters parameters)
{
return IndexOptionSymbolProperties.MinimumPriceVariationForPrice(parameters.Security.Symbol, parameters.ReferencePrice);
}
}
}
@@ -0,0 +1,165 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
using System;
using System.Linq;
using System.Collections.Generic;
using QuantConnect.Securities.Future;
namespace QuantConnect.Securities.IndexOption
{
/// <summary>
/// Index Option Symbol
/// </summary>
public static class IndexOptionSymbol
{
private static readonly Dictionary<string, string> _nonStandardOptionToIndex = new()
{
{ "RUTW", "RUT" },
{ "SPXW", "SPX" },
{ "VIXW", "VIX" },
{ "NDXP", "NDX" },
{ "NQX", "NDX" },
};
/// <summary>
/// These are known assets that are weeklies or end-of-month settled contracts.
/// </summary>
private static readonly HashSet<string> _nonStandardIndexOptionTickers = new()
{
// Weeklies
"RUTW", // PM-Settled. While RUT AM-Settled on 3rd Fridays
"SPXW",
"VIXW",
// PM-Settled
"NDXP",
// reduced value index options, 20%
"NQX"
};
/// <summary>
/// Supported index option tickers
/// </summary>
public static readonly HashSet<string> SupportedIndexOptionTickers = new string[] { "SPX", "NDX", "VIX", "RUT" }
.Union(_nonStandardIndexOptionTickers)
.ToHashSet();
/// <summary>
/// Determines if the Index Option Symbol is for a monthly contract
/// </summary>
/// <param name="symbol">Index Option Symbol</param>
/// <returns>True if monthly contract, false otherwise</returns>
public static bool IsStandard(Symbol symbol)
{
if (symbol.ID.Market != Market.USA)
{
return true;
}
switch (symbol.ID.Symbol)
{
case "NQX":
case "SPXW":
case "RUTW":
// they have weeklies and monthly contracts
// NQX https://www.nasdaq.com/docs/NQXFactSheet.pdf
// SPXW https://www.cboe.com/tradable_products/sp_500/spx_weekly_options/specifications/
// RUTW expires every day
return FuturesExpiryUtilityFunctions.ThirdFriday(symbol.ID.Date) == symbol.ID.Date;
default:
// NDX/SPX/NQX/VIX/VIXW/NDXP/RUT are all normal contracts
return true;
}
}
/// <summary>
/// Returns true if the index option is AM settled
/// </summary>
public static bool IsAMSettled(Symbol symbol)
{
return !_nonStandardIndexOptionTickers.Contains(symbol.ID.Symbol.LazyToUpper());
}
/// <summary>
/// Checks if the ticker provided is a supported Index Option
/// </summary>
/// <param name="ticker">Ticker of the index option</param>
/// <returns>true if the ticker matches an index option's ticker</returns>
/// <remarks>
/// This is only used in IB brokerage, since they don't distinguish index options
/// from regular equity options. When we do the conversion from a contract to a SecurityType,
/// the only information we're provided that can reverse it to the <see cref="SecurityType.IndexOption"/>
/// enum value is the ticker.
/// </remarks>
public static bool IsIndexOption(string ticker)
{
return SupportedIndexOptionTickers.Contains(ticker.LazyToUpper());
}
/// <summary>
/// Maps an index option ticker to its underlying index ticker
/// </summary>
/// <param name="indexOption">Index option ticker to map to the underlying</param>
/// <returns>Index ticker</returns>
public static string MapToUnderlying(string indexOption)
{
if (_nonStandardOptionToIndex.TryGetValue(indexOption.LazyToUpper(), out var index))
{
return index;
}
return indexOption;
}
/// <summary>
/// Returns the last trading date for the given index option ticker and expiration date
/// </summary>
/// <remarks>This is useful for IB brokerage</remarks>
public static DateTime GetLastTradingDate(string ticker, DateTime expirationDate)
{
return expirationDate.AddDays(-GetExpirationOffset(ticker));
}
/// <summary>
/// Returns the expiry date for the given index option ticker and last trading date
/// </summary>
/// <remarks>This is useful for IB brokerage</remarks>
public static DateTime GetExpiryDate(string ticker, DateTime lastTradingDate)
{
return lastTradingDate.AddDays(GetExpirationOffset(ticker));
}
/// <summary>
/// Some index options last tradable date is the previous day to the expiration
/// https://www.cboe.com/tradable_products/vix/vix_options/specifications/
/// https://www.cboe.com/tradable_products/ftse_russell/russell_2000_index_options/rut_specifications
/// </summary>
private static int GetExpirationOffset(string ticker)
{
switch (ticker)
{
case "SPX":
case "NDX":
case "VIX":
case "VIXW":
case "RUT":
return 1;
default:
// SPXW, NQX, NDXP, RUTW
return 0;
}
}
}
}
@@ -0,0 +1,100 @@
/*
* QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals.
* Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
using QuantConnect.Data;
using QuantConnect.Securities.Option;
namespace QuantConnect.Securities.IndexOption
{
/// <summary>
/// Index Option Symbol Properties
/// </summary>
public class IndexOptionSymbolProperties : OptionSymbolProperties
{
private BaseData _lastData;
/// <summary>
/// Minimum price variation, subject to variability due to contract price
/// </summary>
public override decimal MinimumPriceVariation => MinimumPriceVariationForPrice(_lastData?.Symbol, _lastData?.Price);
/// <summary>
/// Creates an instance of index symbol properties
/// </summary>
/// <param name="description">Description of the Symbol</param>
/// <param name="quoteCurrency">Currency the price is quoted in</param>
/// <param name="contractMultiplier">Contract multiplier of the index option</param>
/// <param name="pipSize">Minimum price variation</param>
/// <param name="lotSize">Minimum order lot size</param>
public IndexOptionSymbolProperties(
string description,
string quoteCurrency,
decimal contractMultiplier,
decimal pipSize,
decimal lotSize
)
: base(description, quoteCurrency, contractMultiplier, pipSize, lotSize)
{
}
/// <summary>
/// Creates instance of index symbol properties
/// </summary>
/// <param name="properties"></param>
public IndexOptionSymbolProperties(SymbolProperties properties)
: base(properties)
{
}
/// <summary>
/// Updates the last data received, required for calculating some
/// index options contracts that have a variable step size for their premium's quotes
/// </summary>
/// <param name="marketData">Data to update with</param>
internal void UpdateMarketPrice(BaseData marketData)
{
_lastData = marketData;
}
/// <summary>
/// Minimum price variation, subject to variability due to contract price
/// </summary>
/// <remarks>https://www.cboe.com/tradable_products/vix/vix_options/specifications/
/// https://www.cboe.com/tradable_products/sp_500/spx_options/specifications/
/// https://www.nasdaq.com/docs/2022/08/24/1926-Q22_NDX%20Fact%20Sheet_NAM_v3.pdf</remarks>
public static decimal MinimumPriceVariationForPrice(Symbol symbol, decimal? referencePrice)
{
if(symbol == null || !referencePrice.HasValue)
{
return 0.05m;
}
var aboveThree = 0.1m;
var belowThree = 0.05m;
if(symbol.ID.Symbol == "VIXW")
{
aboveThree = belowThree = 0.01m;
}
else if (symbol.ID.Symbol == "VIX")
{
belowThree = 0.01m;
aboveThree = 0.05m;
}
return referencePrice.HasValue && referencePrice >= 3m ? aboveThree : belowThree;
}
}
}