Skip to content

Commit d3928fb

Browse files
authored
Manual option contract addition for delisted underlyings error (QuantConnect#7799)
* Throw when trying to add option contracts for delisted underlyings * Minor change
1 parent 09db45c commit d3928fb

File tree

2 files changed

+32
-1
lines changed

2 files changed

+32
-1
lines changed

Algorithm/QCAlgorithm.cs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2341,6 +2341,11 @@ public Option AddOptionContract(Symbol symbol, Resolution? resolution = null, bo
23412341
underlyingConfigs = SubscriptionManager.SubscriptionDataConfigService
23422342
.GetSubscriptionDataConfigs(underlying);
23432343
}
2344+
else if (underlyingSecurity != null && underlyingSecurity.IsDelisted)
2345+
{
2346+
throw new ArgumentException($"The underlying {underlying.SecurityType} asset ({underlying.Value}) is delisted " +
2347+
$"(current time is {Time})");
2348+
}
23442349
else
23452350
{
23462351
underlyingConfigs = SubscriptionManager.SubscriptionDataConfigService

Tests/Algorithm/AlgorithmAddDataTests.cs

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
using System;
1717
using System.Collections.Generic;
1818
using System.Linq;
19-
using Python.Runtime;
2019
using Newtonsoft.Json;
2120
using NodaTime;
2221
using NUnit.Framework;
@@ -645,6 +644,33 @@ public void DoesNotCauseCollision_WhenRegisteringMultipleDifferentCustomDataType
645644
Assert.AreNotSame(unlinkedData, bitcoin);
646645
}
647646

647+
[TestCase(SecurityType.Equity)]
648+
[TestCase(SecurityType.Index)]
649+
[TestCase(SecurityType.Future)]
650+
public void AddOptionContractWithDelistedUnderlyingThrows(SecurityType underlyingSecurityType)
651+
{
652+
var algorithm = Algorithm();
653+
algorithm.SetStartDate(2007, 05, 25);
654+
655+
Security underlying = underlyingSecurityType switch
656+
{
657+
SecurityType.Equity => algorithm.AddEquity("SPY"),
658+
SecurityType.Index => algorithm.AddIndex("SPX"),
659+
SecurityType.Future => algorithm.AddFuture("ES"),
660+
_ => throw new ArgumentException($"Invalid test underlying security type {underlyingSecurityType}")
661+
};
662+
663+
underlying.IsDelisted = true;
664+
// let's remove the underlying since it's delisted
665+
algorithm.RemoveSecurity(underlying.Symbol);
666+
667+
var optionContractSymbol = Symbol.CreateOption(underlying.Symbol, Market.USA, OptionStyle.American, OptionRight.Call, 100,
668+
new DateTime(2007, 06, 15));
669+
670+
var exception = Assert.Throws<ArgumentException>(() => algorithm.AddOptionContract(optionContractSymbol));
671+
Assert.IsTrue(exception.Message.Contains("is delisted"), $"Unexpected exception message: {exception.Message}");
672+
}
673+
648674
private static SubscriptionDataConfig GetMatchingSubscription(QCAlgorithm algorithm, Symbol symbol, Type type)
649675
{
650676
// find a subscription matchin the requested type with a higher resolution than requested

0 commit comments

Comments
 (0)