From c648de8051b9ffb5eef82f121954754f6c864375 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Fri, 13 Dec 2024 15:49:50 -0400 Subject: [PATCH] Modify helper method to calculate settlement time instead of expiration time --- Common/Securities/Option/OptionSymbol.cs | 19 ++++++++++--------- Indicators/ImpliedVolatility.cs | 2 +- Indicators/OptionGreekIndicatorBase.cs | 2 +- .../Securities/Options/OptionSymbolTests.cs | 6 +++--- 4 files changed, 15 insertions(+), 14 deletions(-) diff --git a/Common/Securities/Option/OptionSymbol.cs b/Common/Securities/Option/OptionSymbol.cs index 2d94b92cc382..f5c98abb5c74 100644 --- a/Common/Securities/Option/OptionSymbol.cs +++ b/Common/Securities/Option/OptionSymbol.cs @@ -122,17 +122,23 @@ public static DateTime GetLastDayOfTrading(Symbol symbol) } /// - /// Returns the actual expiration date time, adjusted to market close of the expiration day. + /// Returns the settlement date time of the option contract. /// /// The option contract symbol - /// The expiration date time, adjusted to market close of the expiration day - public static DateTime GetExpirationDateTime(Symbol symbol) + /// The settlement date time + public static DateTime GetSettlementDateTime(Symbol symbol) { - if (!TryGetExpirationDateTime(symbol, out var expiryTime, out _)) + if (!TryGetExpirationDateTime(symbol, out var expiryTime, out var exchangeHours)) { throw new ArgumentException("The symbol must be an option type"); } + // Standard index options are AM-settled, which means they settle on market open of the expiration date + if (expiryTime.Date == symbol.ID.Date.Date && symbol.SecurityType == SecurityType.IndexOption && IsStandard(symbol)) + { + expiryTime = exchangeHours.GetNextMarketOpen(expiryTime.Date, false); + } + return expiryTime; } @@ -189,11 +195,6 @@ private static bool TryGetExpirationDateTime(Symbol symbol, out DateTime expiryT } expiryTime = symbol.ID.Date.AddDays(1).Date; } - // Standard index options are AM-settled, which means they settle on market open of the last trading date - else if (symbol.SecurityType == SecurityType.IndexOption && IsStandard(symbol)) - { - expiryTime = exchangeHours.GetNextMarketOpen(expiryTime.Date, false); - } return true; } diff --git a/Indicators/ImpliedVolatility.cs b/Indicators/ImpliedVolatility.cs index c3eb788cba18..14c89d1deb32 100644 --- a/Indicators/ImpliedVolatility.cs +++ b/Indicators/ImpliedVolatility.cs @@ -266,7 +266,7 @@ protected override decimal Calculate(IndicatorDataPoint input) DividendYield.Update(time, _dividendYieldModel.GetDividendYield(time, UnderlyingPrice.Current.Value)); var timeTillExpiry = Convert.ToDecimal( - OptionGreekIndicatorsHelper.TimeTillExpiry(Securities.Option.OptionSymbol.GetExpirationDateTime(OptionSymbol), time)); + OptionGreekIndicatorsHelper.TimeTillExpiry(Securities.Option.OptionSymbol.GetSettlementDateTime(OptionSymbol), time)); _impliedVolatility = CalculateIV(timeTillExpiry); } diff --git a/Indicators/OptionGreekIndicatorBase.cs b/Indicators/OptionGreekIndicatorBase.cs index edbc04c08954..c93e47a33f50 100644 --- a/Indicators/OptionGreekIndicatorBase.cs +++ b/Indicators/OptionGreekIndicatorBase.cs @@ -184,7 +184,7 @@ protected override decimal Calculate(IndicatorDataPoint input) DividendYield.Update(time, _dividendYieldModel.GetDividendYield(time, UnderlyingPrice.Current.Value)); var timeTillExpiry = Convert.ToDecimal( - OptionGreekIndicatorsHelper.TimeTillExpiry(Securities.Option.OptionSymbol.GetExpirationDateTime(OptionSymbol), time)); + OptionGreekIndicatorsHelper.TimeTillExpiry(Securities.Option.OptionSymbol.GetSettlementDateTime(OptionSymbol), time)); try { _greekValue = timeTillExpiry < 0 ? 0 : CalculateGreek(timeTillExpiry); diff --git a/Tests/Common/Securities/Options/OptionSymbolTests.cs b/Tests/Common/Securities/Options/OptionSymbolTests.cs index 0bb9b47c2074..f87317d42b2d 100644 --- a/Tests/Common/Securities/Options/OptionSymbolTests.cs +++ b/Tests/Common/Securities/Options/OptionSymbolTests.cs @@ -90,10 +90,10 @@ private static IEnumerable ExpirationDateTimeTestCases() } [TestCaseSource(nameof(ExpirationDateTimeTestCases))] - public void CalculatesExpirationDateTime(Symbol symbol, DateTime expectedExpirationDateTime) + public void CalculatesSettlementDateTime(Symbol symbol, DateTime expectedSettlementDateTime) { - var expirationDateTime = OptionSymbol.GetExpirationDateTime(symbol); - Assert.AreEqual(expectedExpirationDateTime, expirationDateTime); + var settlementDateTime = OptionSymbol.GetSettlementDateTime(symbol); + Assert.AreEqual(expectedSettlementDateTime, settlementDateTime); } } }