From d3928fba6bff138d98782cf27de3a2febdc6cd72 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Wed, 21 Feb 2024 09:02:07 -0400 Subject: [PATCH] Manual option contract addition for delisted underlyings error (#7799) * Throw when trying to add option contracts for delisted underlyings * Minor change --- Algorithm/QCAlgorithm.cs | 5 +++++ Tests/Algorithm/AlgorithmAddDataTests.cs | 28 +++++++++++++++++++++++- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs index f4e2c5241ac4..e8b8c9b4d871 100644 --- a/Algorithm/QCAlgorithm.cs +++ b/Algorithm/QCAlgorithm.cs @@ -2341,6 +2341,11 @@ public Option AddOptionContract(Symbol symbol, Resolution? resolution = null, bo underlyingConfigs = SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(underlying); } + else if (underlyingSecurity != null && underlyingSecurity.IsDelisted) + { + throw new ArgumentException($"The underlying {underlying.SecurityType} asset ({underlying.Value}) is delisted " + + $"(current time is {Time})"); + } else { underlyingConfigs = SubscriptionManager.SubscriptionDataConfigService diff --git a/Tests/Algorithm/AlgorithmAddDataTests.cs b/Tests/Algorithm/AlgorithmAddDataTests.cs index 6c93b74db262..67c0c6214583 100644 --- a/Tests/Algorithm/AlgorithmAddDataTests.cs +++ b/Tests/Algorithm/AlgorithmAddDataTests.cs @@ -16,7 +16,6 @@ using System; using System.Collections.Generic; using System.Linq; -using Python.Runtime; using Newtonsoft.Json; using NodaTime; using NUnit.Framework; @@ -645,6 +644,33 @@ public void DoesNotCauseCollision_WhenRegisteringMultipleDifferentCustomDataType Assert.AreNotSame(unlinkedData, bitcoin); } + [TestCase(SecurityType.Equity)] + [TestCase(SecurityType.Index)] + [TestCase(SecurityType.Future)] + public void AddOptionContractWithDelistedUnderlyingThrows(SecurityType underlyingSecurityType) + { + var algorithm = Algorithm(); + algorithm.SetStartDate(2007, 05, 25); + + Security underlying = underlyingSecurityType switch + { + SecurityType.Equity => algorithm.AddEquity("SPY"), + SecurityType.Index => algorithm.AddIndex("SPX"), + SecurityType.Future => algorithm.AddFuture("ES"), + _ => throw new ArgumentException($"Invalid test underlying security type {underlyingSecurityType}") + }; + + underlying.IsDelisted = true; + // let's remove the underlying since it's delisted + algorithm.RemoveSecurity(underlying.Symbol); + + var optionContractSymbol = Symbol.CreateOption(underlying.Symbol, Market.USA, OptionStyle.American, OptionRight.Call, 100, + new DateTime(2007, 06, 15)); + + var exception = Assert.Throws(() => algorithm.AddOptionContract(optionContractSymbol)); + Assert.IsTrue(exception.Message.Contains("is delisted"), $"Unexpected exception message: {exception.Message}"); + } + private static SubscriptionDataConfig GetMatchingSubscription(QCAlgorithm algorithm, Symbol symbol, Type type) { // find a subscription matchin the requested type with a higher resolution than requested