diff --git a/Algorithm.CSharp/AddAndRemoveOptionContractRegressionAlgorithm.cs b/Algorithm.CSharp/AddAndRemoveOptionContractRegressionAlgorithm.cs index 0a8cce770c88..4ae44e2c4905 100644 --- a/Algorithm.CSharp/AddAndRemoveOptionContractRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddAndRemoveOptionContractRegressionAlgorithm.cs @@ -40,8 +40,8 @@ public override void Initialize() var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA); - _contract = OptionChainProvider.GetOptionContractList(aapl, Time) - .OrderBy(symbol => symbol.ID.Symbol) + _contract = OptionChain(aapl) + .OrderBy(x => x.ID.Symbol) .FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American); AddOptionContract(_contract); diff --git a/Algorithm.CSharp/AddAndRemoveSecuritySameLoopRegressionAlgorithm.cs b/Algorithm.CSharp/AddAndRemoveSecuritySameLoopRegressionAlgorithm.cs index bcb0030789f8..af89a0823cbe 100644 --- a/Algorithm.CSharp/AddAndRemoveSecuritySameLoopRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddAndRemoveSecuritySameLoopRegressionAlgorithm.cs @@ -39,8 +39,8 @@ public override void Initialize() var aapl = AddEquity("AAPL").Symbol; - _contract = OptionChainProvider.GetOptionContractList(aapl, Time) - .OrderBy(symbol => symbol.ID.Symbol) + _contract = OptionChain(aapl) + .OrderBy(x => x.ID.Symbol) .FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American); } diff --git a/Algorithm.CSharp/AddFutureOptionContractFromFutureChainRegressionAlgorithm.cs b/Algorithm.CSharp/AddFutureOptionContractFromFutureChainRegressionAlgorithm.cs index f735b4f83384..cc31259c1d97 100644 --- a/Algorithm.CSharp/AddFutureOptionContractFromFutureChainRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddFutureOptionContractFromFutureChainRegressionAlgorithm.cs @@ -49,7 +49,7 @@ public override void OnData(Slice slice) { foreach (var contract in futuresContracts) { - var option_contract_symbols = OptionChainProvider.GetOptionContractList(contract.Symbol, Time).ToList(); + var option_contract_symbols = OptionChain(contract.Symbol).ToList(); if(option_contract_symbols.Count == 0) { continue; diff --git a/Algorithm.CSharp/AddOptionContractExpiresRegressionAlgorithm.cs b/Algorithm.CSharp/AddOptionContractExpiresRegressionAlgorithm.cs index f772559aa43d..c6d8bbd98b0e 100644 --- a/Algorithm.CSharp/AddOptionContractExpiresRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddOptionContractExpiresRegressionAlgorithm.cs @@ -46,8 +46,8 @@ public override void OnData(Slice slice) { if (_option == null) { - var option = OptionChainProvider.GetOptionContractList(_twx, Time) - .OrderBy(symbol => symbol.ID.Symbol) + var option = OptionChain(_twx) + .OrderBy(x => x.ID.Symbol) .FirstOrDefault(optionContract => optionContract.ID.Date == _expiration && optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American); diff --git a/Algorithm.CSharp/AddOptionContractFromUniverseRegressionAlgorithm.cs b/Algorithm.CSharp/AddOptionContractFromUniverseRegressionAlgorithm.cs index fa6cdb6fc3cf..88c72be803f0 100644 --- a/Algorithm.CSharp/AddOptionContractFromUniverseRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddOptionContractFromUniverseRegressionAlgorithm.cs @@ -13,12 +13,12 @@ * limitations under the License. */ -using System; -using System.Collections.Generic; -using System.Linq; using QuantConnect.Data; using QuantConnect.Data.UniverseSelection; using QuantConnect.Interfaces; +using System; +using System.Collections.Generic; +using System.Linq; namespace QuantConnect.Algorithm.CSharp { @@ -110,14 +110,14 @@ public override void OnSecuritiesChanged(SecurityChanges changes) foreach (var addedSecurity in changes.AddedSecurities) { - var option = OptionChainProvider.GetOptionContractList(addedSecurity.Symbol, Time) - .OrderBy(symbol => symbol.ID.Symbol) + var option = OptionChain(addedSecurity.Symbol) + .OrderBy(contractData => contractData.ID.Symbol) .First(optionContract => optionContract.ID.Date == _expiration && optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American); AddOptionContract(option); - foreach (var symbol in new[] { option, option.Underlying }) + foreach (var symbol in new[] { option.Symbol, option.Underlying.Symbol }) { var config = SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).ToList(); diff --git a/Algorithm.CSharp/AddOptionContractTwiceRegressionAlgorithm.cs b/Algorithm.CSharp/AddOptionContractTwiceRegressionAlgorithm.cs index 3b2e387a0431..c36a31ead83b 100644 --- a/Algorithm.CSharp/AddOptionContractTwiceRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddOptionContractTwiceRegressionAlgorithm.cs @@ -43,8 +43,8 @@ public override void Initialize() var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA); - _contract = OptionChainProvider.GetOptionContractList(aapl, Time) - .OrderBy(symbol => symbol.ID.StrikePrice) + _contract = OptionChain(aapl) + .OrderBy(x => x.ID.StrikePrice) .FirstOrDefault(optionContract => optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American); AddOptionContract(_contract); diff --git a/Algorithm.CSharp/AddTwoAndRemoveOneOptionContractRegressionAlgorithm.cs b/Algorithm.CSharp/AddTwoAndRemoveOneOptionContractRegressionAlgorithm.cs index 2ac31c437381..64e01265ed97 100644 --- a/Algorithm.CSharp/AddTwoAndRemoveOneOptionContractRegressionAlgorithm.cs +++ b/Algorithm.CSharp/AddTwoAndRemoveOneOptionContractRegressionAlgorithm.cs @@ -41,8 +41,8 @@ public override void Initialize() var aapl = QuantConnect.Symbol.Create("AAPL", SecurityType.Equity, Market.USA); - var contracts = OptionChainProvider.GetOptionContractList(aapl, Time) - .OrderBy(symbol => symbol.ID.StrikePrice) + var contracts = OptionChain(aapl) + .OrderBy(x => x.ID.StrikePrice) .Where(optionContract => optionContract.ID.OptionRight == OptionRight.Call && optionContract.ID.OptionStyle == OptionStyle.American) .Take(2) diff --git a/Algorithm.CSharp/DelayedSettlementAfterManualSecurityRemovalAlgorithm.cs b/Algorithm.CSharp/DelayedSettlementAfterManualSecurityRemovalAlgorithm.cs index 18e1a78e4405..d2fc422e32a4 100644 --- a/Algorithm.CSharp/DelayedSettlementAfterManualSecurityRemovalAlgorithm.cs +++ b/Algorithm.CSharp/DelayedSettlementAfterManualSecurityRemovalAlgorithm.cs @@ -37,9 +37,9 @@ public override void Initialize() var equity = AddEquity("GOOG"); - _optionSymbol = OptionChainProvider.GetOptionContractList(equity.Symbol, Time) - .OrderBy(symbol => symbol.ID.StrikePrice) - .ThenByDescending(symbol => symbol.ID.Date) + _optionSymbol = OptionChain(equity.Symbol) + .OrderBy(x => x.ID.StrikePrice) + .ThenByDescending(x => x.ID.Date) .First(optionContract => optionContract.ID.OptionRight == OptionRight.Call); var option = AddOptionContract(_optionSymbol); diff --git a/Algorithm.CSharp/DelistedIndexOptionDivestedRegression.cs b/Algorithm.CSharp/DelistedIndexOptionDivestedRegression.cs index 9665b5f47a4f..c5520a8548a9 100644 --- a/Algorithm.CSharp/DelistedIndexOptionDivestedRegression.cs +++ b/Algorithm.CSharp/DelistedIndexOptionDivestedRegression.cs @@ -51,10 +51,7 @@ public override void OnData(Slice slice) if (_addOption) { - var contracts = OptionChainProvider.GetOptionContractList(_spx, Time); - contracts = contracts.Where(x => - x.ID.OptionRight == OptionRight.Put && - x.ID.Date.Date == new DateTime(2021, 1, 15)); + var contracts = OptionChain(_spx).Where(x => x.ID.OptionRight == OptionRight.Put && x.ID.Date.Date == new DateTime(2021, 1, 15)); var option = AddIndexOptionContract(contracts.First(), Resolution.Minute); _optionExpiry = option.Expiry; diff --git a/Algorithm.CSharp/FutureOptionBuySellCallIntradayRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionBuySellCallIntradayRegressionAlgorithm.cs index ec9de2233f86..0b2df56cc07b 100644 --- a/Algorithm.CSharp/FutureOptionBuySellCallIntradayRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionBuySellCallIntradayRegressionAlgorithm.cs @@ -58,10 +58,10 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - var esOptions = OptionChainProvider.GetOptionContractList(es20m20, Time) - .Concat(OptionChainProvider.GetOptionContractList(es20h20, Time)) - .Where(x => x.ID.StrikePrice == 3200m && x.ID.OptionRight == OptionRight.Call) - .Select(x => AddFutureOptionContract(x, Resolution.Minute).Symbol) + var esOptions = OptionChain(es20m20) + .Concat(OptionChain(es20h20)) + .Where(contractData => contractData.ID.StrikePrice == 3200m && contractData.ID.OptionRight == OptionRight.Call) + .Select(contractData => AddFutureOptionContract(contractData, Resolution.Minute).Symbol) .ToList(); var expectedContracts = new[] diff --git a/Algorithm.CSharp/FutureOptionCallITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionCallITMExpiryRegressionAlgorithm.cs index a511f150aad3..25f88b83b090 100644 --- a/Algorithm.CSharp/FutureOptionCallITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionCallITMExpiryRegressionAlgorithm.cs @@ -53,7 +53,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionCallITMGreeksExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionCallITMGreeksExpiryRegressionAlgorithm.cs index d77a6d33e1a2..68bce654dfe6 100644 --- a/Algorithm.CSharp/FutureOptionCallITMGreeksExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionCallITMGreeksExpiryRegressionAlgorithm.cs @@ -55,7 +55,7 @@ public override void Initialize() TimeSpan.FromMinutes(1)); // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20.Symbol, new DateTime(2020, 1, 5)) + _esOption = AddFutureOptionContract(OptionChain(_es19m20.Symbol) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionCallOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionCallOTMExpiryRegressionAlgorithm.cs index 53a192780aaf..19c4bfb64db7 100644 --- a/Algorithm.CSharp/FutureOptionCallOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionCallOTMExpiryRegressionAlgorithm.cs @@ -59,9 +59,9 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option call expiring OTM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) - .Where(x => x.ID.StrikePrice >= 3300m && x.ID.OptionRight == OptionRight.Call) - .OrderBy(x => x.ID.StrikePrice) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) + .Where(contractData => contractData.ID.StrikePrice >= 3300m && contractData.ID.OptionRight == OptionRight.Call) + .OrderBy(contractData => contractData.ID.StrikePrice) .Take(1) .Single(), Resolution.Minute).Symbol; diff --git a/Algorithm.CSharp/FutureOptionDailyRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionDailyRegressionAlgorithm.cs index dd868d446f14..0a94b6140b9f 100644 --- a/Algorithm.CSharp/FutureOptionDailyRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionDailyRegressionAlgorithm.cs @@ -47,7 +47,7 @@ public override void Initialize() Resolution).Symbol; // Attempt to fetch a specific future option contract - DcOption = OptionChainProvider.GetOptionContractList(dc, Time) + DcOption = OptionChain(dc) .Where(x => x.ID.StrikePrice == 17m && x.ID.OptionRight == OptionRight.Call) .Select(x => AddFutureOptionContract(x, Resolution).Symbol) .FirstOrDefault(); diff --git a/Algorithm.CSharp/FutureOptionIndicatorsRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionIndicatorsRegressionAlgorithm.cs index 6cfea60abec0..96a22e915009 100644 --- a/Algorithm.CSharp/FutureOptionIndicatorsRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionIndicatorsRegressionAlgorithm.cs @@ -32,7 +32,7 @@ public override void Initialize() var underlying = AddFutureContract(QuantConnect.Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, new DateTime(2020, 3, 20)), Resolution.Minute).Symbol; - var option = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(underlying, Time) + var option = AddFutureOptionContract(OptionChain(underlying) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionPutITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionPutITMExpiryRegressionAlgorithm.cs index b32e72d62fb2..c0a01fa99020 100644 --- a/Algorithm.CSharp/FutureOptionPutITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionPutITMExpiryRegressionAlgorithm.cs @@ -54,7 +54,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice >= 3300m && x.ID.OptionRight == OptionRight.Put) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionPutOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionPutOTMExpiryRegressionAlgorithm.cs index 0077f4e64a05..50d24d7ca9df 100644 --- a/Algorithm.CSharp/FutureOptionPutOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionPutOTMExpiryRegressionAlgorithm.cs @@ -58,7 +58,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice <= 3150m && x.ID.OptionRight == OptionRight.Put) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionShortCallITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionShortCallITMExpiryRegressionAlgorithm.cs index f8e8601e961c..d97531471a15 100644 --- a/Algorithm.CSharp/FutureOptionShortCallITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionShortCallITMExpiryRegressionAlgorithm.cs @@ -54,7 +54,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice <= 3100m && x.ID.OptionRight == OptionRight.Call) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionShortCallOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionShortCallOTMExpiryRegressionAlgorithm.cs index ec3224197a55..3387daef3906 100644 --- a/Algorithm.CSharp/FutureOptionShortCallOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionShortCallOTMExpiryRegressionAlgorithm.cs @@ -55,7 +55,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice >= 3400m && x.ID.OptionRight == OptionRight.Call) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionShortPutITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionShortPutITMExpiryRegressionAlgorithm.cs index fdc2c27e247e..deedc5a91894 100644 --- a/Algorithm.CSharp/FutureOptionShortPutITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionShortPutITMExpiryRegressionAlgorithm.cs @@ -54,7 +54,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice <= 3400m && x.ID.OptionRight == OptionRight.Put) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/FutureOptionShortPutOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/FutureOptionShortPutOTMExpiryRegressionAlgorithm.cs index c079df2a0eb2..cb9e6c11a9b9 100644 --- a/Algorithm.CSharp/FutureOptionShortPutOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/FutureOptionShortPutOTMExpiryRegressionAlgorithm.cs @@ -55,7 +55,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option expiring ITM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice <= 3000m && x.ID.OptionRight == OptionRight.Put) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionBuySellCallIntradayRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionBuySellCallIntradayRegressionAlgorithm.cs index 27127b8515d0..1de0f5a77fbb 100644 --- a/Algorithm.CSharp/IndexOptionBuySellCallIntradayRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionBuySellCallIntradayRegressionAlgorithm.cs @@ -46,7 +46,7 @@ public override void Initialize() var spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - var spxOptions = OptionChainProvider.GetOptionContractList(spx, Time) + var spxOptions = OptionChain(spx) .Where(x => (x.ID.StrikePrice == 3700m || x.ID.StrikePrice == 3800m) && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .Select(x => AddIndexOptionContract(x, Resolution.Minute).Symbol) .OrderBy(x => x.ID.StrikePrice) diff --git a/Algorithm.CSharp/IndexOptionCallITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionCallITMExpiryRegressionAlgorithm.cs index ed604b2615e9..f868b73299b3 100644 --- a/Algorithm.CSharp/IndexOptionCallITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionCallITMExpiryRegressionAlgorithm.cs @@ -51,7 +51,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution).Symbol; // Select an index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.cs index c46bd8533015..7b845267bf3e 100644 --- a/Algorithm.CSharp/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.cs @@ -45,7 +45,7 @@ public override void Initialize() _spx = spx.Symbol; // Select an index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionCallOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionCallOTMExpiryRegressionAlgorithm.cs index 4dd82cf71fdf..9e351045a653 100644 --- a/Algorithm.CSharp/IndexOptionCallOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionCallOTMExpiryRegressionAlgorithm.cs @@ -56,7 +56,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution).Symbol; // Select a index option call expiring OTM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice >= 4250m && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionPutITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionPutITMExpiryRegressionAlgorithm.cs index 6a0f654dc2f8..02b54cc168b1 100644 --- a/Algorithm.CSharp/IndexOptionPutITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionPutITMExpiryRegressionAlgorithm.cs @@ -48,7 +48,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice >= 4200m && x.ID.OptionRight == OptionRight.Put && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionPutOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionPutOTMExpiryRegressionAlgorithm.cs index 968ba699559d..0e8ba5681485 100644 --- a/Algorithm.CSharp/IndexOptionPutOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionPutOTMExpiryRegressionAlgorithm.cs @@ -53,7 +53,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Put && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionShortCallITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionShortCallITMExpiryRegressionAlgorithm.cs index 702c96164e2e..60548ffc3de3 100644 --- a/Algorithm.CSharp/IndexOptionShortCallITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionShortCallITMExpiryRegressionAlgorithm.cs @@ -60,9 +60,9 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _esOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) - .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) - .OrderByDescending(x => x.ID.StrikePrice) + _esOption = AddIndexOptionContract(OptionChain(_spx) + .Where(contractData => contractData.ID.StrikePrice <= 3200m && contractData.ID.OptionRight == OptionRight.Call && contractData.ID.Date.Year == 2021 && contractData.ID.Date.Month == 1) + .OrderByDescending(contractData => contractData.ID.StrikePrice) .Take(1) .Single(), Resolution.Minute).Symbol; diff --git a/Algorithm.CSharp/IndexOptionShortCallOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionShortCallOTMExpiryRegressionAlgorithm.cs index 03158317a59b..3eae41d4adff 100644 --- a/Algorithm.CSharp/IndexOptionShortCallOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionShortCallOTMExpiryRegressionAlgorithm.cs @@ -50,7 +50,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice >= 4250m && x.ID.OptionRight == OptionRight.Call && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/IndexOptionShortPutITMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionShortPutITMExpiryRegressionAlgorithm.cs index bde4f77e7e34..e72fd7824d5a 100644 --- a/Algorithm.CSharp/IndexOptionShortPutITMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionShortPutITMExpiryRegressionAlgorithm.cs @@ -59,9 +59,9 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) - .Where(x => x.ID.StrikePrice <= 4200m && x.ID.OptionRight == OptionRight.Put && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) - .OrderByDescending(x => x.ID.StrikePrice) + _spxOption = AddIndexOptionContract(OptionChain(_spx) + .Where(contractData => contractData.ID.StrikePrice <= 4200m && contractData.ID.OptionRight == OptionRight.Put && contractData.ID.Date.Year == 2021 && contractData.ID.Date.Month == 1) + .OrderByDescending(contractData => contractData.ID.StrikePrice) .Take(1) .Single(), Resolution.Minute).Symbol; diff --git a/Algorithm.CSharp/IndexOptionShortPutOTMExpiryRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionShortPutOTMExpiryRegressionAlgorithm.cs index b425ef5a67d6..1861abe7d9d9 100644 --- a/Algorithm.CSharp/IndexOptionShortPutOTMExpiryRegressionAlgorithm.cs +++ b/Algorithm.CSharp/IndexOptionShortPutOTMExpiryRegressionAlgorithm.cs @@ -50,7 +50,7 @@ public override void Initialize() _spx = AddIndex("SPX", Resolution.Minute).Symbol; // Select a index option expiring ITM, and adds it to the algorithm. - _spxOption = AddIndexOptionContract(OptionChainProvider.GetOptionContractList(_spx, Time) + _spxOption = AddIndexOptionContract(OptionChain(_spx) .Where(x => x.ID.StrikePrice <= 3200m && x.ID.OptionRight == OptionRight.Put && x.ID.Date.Year == 2021 && x.ID.Date.Month == 1) .OrderByDescending(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/InsufficientBuyingPowerForAutomaticExerciseRegressionAlgorithm.cs b/Algorithm.CSharp/InsufficientBuyingPowerForAutomaticExerciseRegressionAlgorithm.cs index 6571d5e534a2..9557e626bcdd 100644 --- a/Algorithm.CSharp/InsufficientBuyingPowerForAutomaticExerciseRegressionAlgorithm.cs +++ b/Algorithm.CSharp/InsufficientBuyingPowerForAutomaticExerciseRegressionAlgorithm.cs @@ -44,7 +44,7 @@ public override void Initialize() _stock = AddEquity("GOOG").Symbol; - var contracts = OptionChainProvider.GetOptionContractList(_stock, UtcTime).ToList(); + var contracts = OptionChain(_stock).ToList(); _option = contracts .Where(c => c.ID.OptionRight == OptionRight.Put) .OrderBy(c => c.ID.Date) diff --git a/Algorithm.CSharp/OptionAssignmentRegressionAlgorithm.cs b/Algorithm.CSharp/OptionAssignmentRegressionAlgorithm.cs index 00adbd3f630b..b000d57959b4 100644 --- a/Algorithm.CSharp/OptionAssignmentRegressionAlgorithm.cs +++ b/Algorithm.CSharp/OptionAssignmentRegressionAlgorithm.cs @@ -46,7 +46,7 @@ public override void Initialize() SetCash(100000); Stock = AddEquity("GOOG", Resolution.Minute); - var contracts = OptionChainProvider.GetOptionContractList(Stock.Symbol, UtcTime).ToList(); + var contracts = OptionChain(Stock.Symbol).ToList(); PutOptionSymbol = contracts .Where(c => c.ID.OptionRight == OptionRight.Put) diff --git a/Algorithm.CSharp/OptionAssignmentStatisticsRegressionAlgorithm.cs b/Algorithm.CSharp/OptionAssignmentStatisticsRegressionAlgorithm.cs index 36eb30ec531f..57026b06d8c1 100644 --- a/Algorithm.CSharp/OptionAssignmentStatisticsRegressionAlgorithm.cs +++ b/Algorithm.CSharp/OptionAssignmentStatisticsRegressionAlgorithm.cs @@ -48,7 +48,7 @@ public override void Initialize() _goog = AddEquity("GOOG", Resolution.Minute); - var contracts = OptionChainProvider.GetOptionContractList(_goog.Symbol, UtcTime).ToList(); + var contracts = OptionChain(_goog.Symbol).ToList(); _googCall600Symbol = contracts .Where(c => c.ID.OptionRight == OptionRight.Call) diff --git a/Algorithm.CSharp/OptionChainFullDataRegressionAlgorithm.cs b/Algorithm.CSharp/OptionChainFullDataRegressionAlgorithm.cs new file mode 100644 index 000000000000..ce1fe0705ab6 --- /dev/null +++ b/Algorithm.CSharp/OptionChainFullDataRegressionAlgorithm.cs @@ -0,0 +1,127 @@ +/* + * 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.Collections.Generic; +using System.Linq; +using QuantConnect.Data; +using QuantConnect.Interfaces; +using QuantConnect.Securities; + +namespace QuantConnect.Algorithm.CSharp +{ + /// + /// Regression algorithm illustrating the usage of the method + /// to get an option chain, which contains additional data besides the symbols, including prices, implied volatility and greeks. + /// It also shows how this data can be used to filter the contracts based on certain criteria. + /// + public class OptionChainFullDataRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition + { + private Symbol _optionContract; + + public override void Initialize() + { + SetStartDate(2015, 12, 24); + SetEndDate(2015, 12, 24); + SetCash(100000); + + var goog = AddEquity("GOOG").Symbol; + + _optionContract = OptionChain(goog) + // Get contracts expiring within 10 days, with an implied volatility greater than 0.5 and a delta less than 0.5 + .Where(contractData => contractData.ID.Date - Time <= TimeSpan.FromDays(10) && + contractData.ImpliedVolatility > 0.5m && + contractData.Greeks.Delta < 0.5m) + // Get the contract with the latest expiration date + .OrderByDescending(x => x.ID.Date) + .First(); + + AddOptionContract(_optionContract); + } + + public override void OnData(Slice slice) + { + // Do some trading with the selected contract for sample purposes + if (!Portfolio.Invested) + { + MarketOrder(_optionContract, 1); + } + else + { + Liquidate(); + } + } + + /// + /// This is used by the regression test system to indicate if the open source Lean repository has the required data to run this algorithm. + /// + public bool CanRunLocally { get; } = true; + + /// + /// This is used by the regression test system to indicate which languages this algorithm is written in. + /// + public virtual List Languages { get; } = new() { Language.CSharp, Language.Python }; + + /// + /// Data Points count of all timeslices of algorithm + /// + public long DataPoints => 1057; + + /// + /// Data Points count of the algorithm history + /// + public int AlgorithmHistoryDataPoints => 1; + + /// + /// Final status of the algorithm + /// + public AlgorithmStatus AlgorithmStatus => AlgorithmStatus.Completed; + + /// + /// This is used by the regression test system to indicate what the expected statistics are from running the algorithm + /// + public Dictionary ExpectedStatistics => new Dictionary + { + {"Total Orders", "210"}, + {"Average Win", "0%"}, + {"Average Loss", "0%"}, + {"Compounding Annual Return", "0%"}, + {"Drawdown", "0%"}, + {"Expectancy", "0"}, + {"Start Equity", "100000"}, + {"End Equity", "96041"}, + {"Net Profit", "0%"}, + {"Sharpe Ratio", "0"}, + {"Sortino Ratio", "0"}, + {"Probabilistic Sharpe Ratio", "0%"}, + {"Loss Rate", "0%"}, + {"Win Rate", "0%"}, + {"Profit-Loss Ratio", "0"}, + {"Alpha", "0"}, + {"Beta", "0"}, + {"Annual Standard Deviation", "0"}, + {"Annual Variance", "0"}, + {"Information Ratio", "0"}, + {"Tracking Error", "0"}, + {"Treynor Ratio", "0"}, + {"Total Fees", "$209.00"}, + {"Estimated Strategy Capacity", "$0"}, + {"Lowest Capacity Asset", "GOOCV W6U7PD1F2WYU|GOOCV VP83T1ZUHROL"}, + {"Portfolio Turnover", "85.46%"}, + {"OrderListHash", "a7ab1a9e64fe9ba76ea33a40a78a4e3b"} + }; + } +} diff --git a/Algorithm.CSharp/OptionOTMExpiryOrderHasZeroPriceRegressionAlgorithm.cs b/Algorithm.CSharp/OptionOTMExpiryOrderHasZeroPriceRegressionAlgorithm.cs index 890343d44067..4e496f3e5ddf 100644 --- a/Algorithm.CSharp/OptionOTMExpiryOrderHasZeroPriceRegressionAlgorithm.cs +++ b/Algorithm.CSharp/OptionOTMExpiryOrderHasZeroPriceRegressionAlgorithm.cs @@ -58,7 +58,7 @@ public override void Initialize() Resolution.Minute).Symbol; // Select a future option call expiring OTM, and adds it to the algorithm. - _esOption = AddFutureOptionContract(OptionChainProvider.GetOptionContractList(_es19m20, Time) + _esOption = AddFutureOptionContract(OptionChain(_es19m20) .Where(x => x.ID.StrikePrice >= 3300m && x.ID.OptionRight == OptionRight.Call) .OrderBy(x => x.ID.StrikePrice) .Take(1) diff --git a/Algorithm.CSharp/OptionSymbolCanonicalRegressionAlgorithm.cs b/Algorithm.CSharp/OptionSymbolCanonicalRegressionAlgorithm.cs index 677147453982..8a29c1b295e6 100644 --- a/Algorithm.CSharp/OptionSymbolCanonicalRegressionAlgorithm.cs +++ b/Algorithm.CSharp/OptionSymbolCanonicalRegressionAlgorithm.cs @@ -36,7 +36,7 @@ public override void Initialize() SetEndDate(2014, 06, 09); var equitySymbol = AddEquity("TWX").Symbol; - var contracts = OptionChainProvider.GetOptionContractList(equitySymbol, UtcTime).ToList(); + var contracts = OptionChain(equitySymbol).ToList(); var callOptionSymbol = contracts .Where(c => c.ID.OptionRight == OptionRight.Call) diff --git a/Algorithm.CSharp/OptionTimeSliceRegressionAlgorithm.cs b/Algorithm.CSharp/OptionTimeSliceRegressionAlgorithm.cs index 74a79c9e097b..8ac65831cc4d 100644 --- a/Algorithm.CSharp/OptionTimeSliceRegressionAlgorithm.cs +++ b/Algorithm.CSharp/OptionTimeSliceRegressionAlgorithm.cs @@ -54,7 +54,7 @@ public override void OnData(Slice slice) _lastSliceTime = Time; var underlyingPrice = Securities[_symbol].Price; - var contractSymbol = OptionChainProvider.GetOptionContractList(_symbol, Time) + var contractSymbol = OptionChain(_symbol) .Where(x => x.ID.StrikePrice - underlyingPrice > 0) .OrderBy(x => x.ID.Date) .FirstOrDefault(); @@ -91,7 +91,7 @@ public override void OnEndOfAlgorithm() /// /// Data Points count of the algorithm history /// - public int AlgorithmHistoryDataPoints => 3; + public int AlgorithmHistoryDataPoints => 787; /// /// Final status of the algorithm diff --git a/Algorithm.CSharp/UniverseSelectionSymbolCacheRemovalRegressionTest.cs b/Algorithm.CSharp/UniverseSelectionSymbolCacheRemovalRegressionTest.cs index 9c22e90f6d8b..8661b9405f1c 100644 --- a/Algorithm.CSharp/UniverseSelectionSymbolCacheRemovalRegressionTest.cs +++ b/Algorithm.CSharp/UniverseSelectionSymbolCacheRemovalRegressionTest.cs @@ -1,4 +1,4 @@ - + /* * QUANTCONNECT.COM - Democratizing Finance, Empowering Individuals. * Lean Algorithmic Trading Engine v2.0. Copyright 2014 QuantConnect Corporation. @@ -43,7 +43,7 @@ public override void Initialize() AddEquity("AAPL", Resolution.Daily); _equitySymbol = AddEquity("TWX", Resolution.Minute).Symbol; - var contracts = OptionChainProvider.GetOptionContractList(_equitySymbol, UtcTime).ToList(); + var contracts = OptionChain(_equitySymbol).ToList(); var callOptionSymbol = contracts .Where(c => c.ID.OptionRight == OptionRight.Call) diff --git a/Algorithm.Python/AddOptionContractExpiresRegressionAlgorithm.py b/Algorithm.Python/AddOptionContractExpiresRegressionAlgorithm.py index 20f5496e4cd4..928ecc75b510 100644 --- a/Algorithm.Python/AddOptionContractExpiresRegressionAlgorithm.py +++ b/Algorithm.Python/AddOptionContractExpiresRegressionAlgorithm.py @@ -43,7 +43,7 @@ def on_data(self, data): data: Slice object keyed by symbol containing the stock data ''' if self._option == None: - options = self.option_chain_provider.get_option_contract_list(self._twx, self.time) + options = self.option_chain(self._twx) options = sorted(options, key=lambda x: x.id.symbol) option = next((option diff --git a/Algorithm.Python/AddOptionContractFromUniverseRegressionAlgorithm.py b/Algorithm.Python/AddOptionContractFromUniverseRegressionAlgorithm.py index 9ae4482ddfae..c6a25867253d 100644 --- a/Algorithm.Python/AddOptionContractFromUniverseRegressionAlgorithm.py +++ b/Algorithm.Python/AddOptionContractFromUniverseRegressionAlgorithm.py @@ -67,7 +67,7 @@ def on_securities_changed(self, changes): return for addedSecurity in changes.added_securities: - options = self.option_chain_provider.get_option_contract_list(addedSecurity.symbol, self.time) + options = self.option_chain(addedSecurity.symbol) options = sorted(options, key=lambda x: x.id.symbol) option = next((option diff --git a/Algorithm.Python/FutureOptionBuySellCallIntradayRegressionAlgorithm.py b/Algorithm.Python/FutureOptionBuySellCallIntradayRegressionAlgorithm.py index 37e47c3dc427..4d80427cd61a 100644 --- a/Algorithm.Python/FutureOptionBuySellCallIntradayRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionBuySellCallIntradayRegressionAlgorithm.py @@ -52,8 +52,7 @@ def initialize(self): # Select a future option expiring ITM, and adds it to the algorithm. self.es_options = [ self.add_future_option_contract(i, Resolution.MINUTE).symbol - for i in (self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) + - self.option_chain_provider.get_option_contract_list(self.es20h20, self.time)) + for i in (list(self.option_chain(self.es19m20)) + list(self.option_chain(self.es20h20))) if i.id.strike_price == 3200.0 and i.id.option_right == OptionRight.CALL ] diff --git a/Algorithm.Python/FutureOptionCallITMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionCallITMExpiryRegressionAlgorithm.py index 10164f439e04..055558c83e2e 100644 --- a/Algorithm.Python/FutureOptionCallITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionCallITMExpiryRegressionAlgorithm.py @@ -41,7 +41,8 @@ def initialize(self): # Select a future option expiring ITM, and adds it to the algorithm. self.es_option = self.add_future_option_contract( list( - sorted([x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price <= 3200.0 and x.id.option_right == OptionRight.CALL], key=lambda x: x.id.strike_price, reverse=True) + sorted([x for x in self.option_chain(self.es19m20) if x.id.strike_price <= 3200.0 and x.id.option_right == OptionRight.CALL], + key=lambda x: x.id.strike_price, reverse=True) )[0], Resolution.MINUTE).symbol self.expected_contract = Symbol.create_option(self.es19m20, Market.CME, OptionStyle.AMERICAN, OptionRight.CALL, 3200.0, datetime(2020, 6, 19)) diff --git a/Algorithm.Python/FutureOptionCallOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionCallOTMExpiryRegressionAlgorithm.py index 548ffe36f655..bad1b3a048c5 100644 --- a/Algorithm.Python/FutureOptionCallOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionCallOTMExpiryRegressionAlgorithm.py @@ -45,7 +45,8 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price >= 3300.0 and x.id.option_right == OptionRight.CALL], + [x for x in self.option_chain(self.es19m20) + if x.id.strike_price >= 3300.0 and x.id.option_right == OptionRight.CALL], key=lambda x: x.id.strike_price ) )[0], Resolution.MINUTE).symbol diff --git a/Algorithm.Python/FutureOptionDailyRegressionAlgorithm.py b/Algorithm.Python/FutureOptionDailyRegressionAlgorithm.py index a82004978c72..cad3b9f9f8d2 100644 --- a/Algorithm.Python/FutureOptionDailyRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionDailyRegressionAlgorithm.py @@ -34,7 +34,9 @@ def initialize(self): # Attempt to fetch a specific ITM future option contract dc_options = [ - self.add_future_option_contract(x, resolution).symbol for x in (self.option_chain_provider.get_option_contract_list(self.dc, self.time)) if x.id.strike_price == 17 and x.id.option_right == OptionRight.CALL + self.add_future_option_contract(x, resolution).symbol + for x in self.option_chain(self.dc) + if x.id.strike_price == 17 and x.id.option_right == OptionRight.CALL ] self.dc_option = dc_options[0] diff --git a/Algorithm.Python/FutureOptionPutITMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionPutITMExpiryRegressionAlgorithm.py index bc365833c6e3..a69896238abb 100644 --- a/Algorithm.Python/FutureOptionPutITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionPutITMExpiryRegressionAlgorithm.py @@ -40,7 +40,8 @@ def initialize(self): # Select a future option expiring ITM, and adds it to the algorithm. self.es_option = self.add_future_option_contract( list( - sorted([x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price >= 3300.0 and x.id.option_right == OptionRight.PUT], key=lambda x: x.id.strike_price) + sorted([x for x in self.option_chain(self.es19m20) if x.id.strike_price >= 3300.0 and x.id.option_right == OptionRight.PUT], + key=lambda x: x.id.strike_price) )[0], Resolution.MINUTE).symbol self.expected_contract = Symbol.create_option(self.es19m20, Market.CME, OptionStyle.AMERICAN, OptionRight.PUT, 3300.0, datetime(2020, 6, 19)) diff --git a/Algorithm.Python/FutureOptionPutOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionPutOTMExpiryRegressionAlgorithm.py index 52a6b85041fe..b467eecf0cda 100644 --- a/Algorithm.Python/FutureOptionPutOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionPutOTMExpiryRegressionAlgorithm.py @@ -45,7 +45,7 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price <= 3150.0 and x.id.option_right == OptionRight.PUT], + [x for x in self.option_chain(self.es19m20) if x.id.strike_price <= 3150.0 and x.id.option_right == OptionRight.PUT], key=lambda x: x.id.strike_price, reverse=True ) @@ -71,7 +71,7 @@ def on_data(self, data: Slice): if delisting.type == DelistingType.DELISTED: if delisting.time != datetime(2020, 6, 20): raise AssertionError(f"Delisting happened at unexpected date: {delisting.time}") - + def on_order_event(self, order_event: OrderEvent): if order_event.status != OrderStatus.FILLED: # There's lots of noise with OnOrderEvent, but we're only interested in fills. diff --git a/Algorithm.Python/FutureOptionShortCallITMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionShortCallITMExpiryRegressionAlgorithm.py index c1a37a2156c9..18ca83d8767c 100644 --- a/Algorithm.Python/FutureOptionShortCallITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionShortCallITMExpiryRegressionAlgorithm.py @@ -41,7 +41,7 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price <= 3100.0 and x.id.option_right == OptionRight.CALL], + [x for x in self.option_chain(self.es19m20) if x.id.strike_price <= 3100.0 and x.id.option_right == OptionRight.CALL], key=lambda x: x.id.strike_price, reverse=True ) diff --git a/Algorithm.Python/FutureOptionShortCallOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionShortCallOTMExpiryRegressionAlgorithm.py index 0290c7f50705..0857ada5aed3 100644 --- a/Algorithm.Python/FutureOptionShortCallOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionShortCallOTMExpiryRegressionAlgorithm.py @@ -42,7 +42,7 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price >= 3400.0 and x.id.option_right == OptionRight.CALL], + [x for x in self.option_chain(self.es19m20) if x.id.strike_price >= 3400.0 and x.id.option_right == OptionRight.CALL], key=lambda x: x.id.strike_price ) )[0], Resolution.MINUTE).symbol diff --git a/Algorithm.Python/FutureOptionShortPutITMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionShortPutITMExpiryRegressionAlgorithm.py index 07733699b55a..db1ce2f80a57 100644 --- a/Algorithm.Python/FutureOptionShortPutITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionShortPutITMExpiryRegressionAlgorithm.py @@ -41,7 +41,7 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price <= 3400.0 and x.id.option_right == OptionRight.PUT], + [x for x in self.option_chain(self.es19m20) if x.id.strike_price <= 3400.0 and x.id.option_right == OptionRight.PUT], key=lambda x: x.id.strike_price, reverse=True ) diff --git a/Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py index fca36816b119..a1dfc198c203 100644 --- a/Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/FutureOptionShortPutOTMExpiryRegressionAlgorithm.py @@ -42,7 +42,7 @@ def initialize(self): self.es_option = self.add_future_option_contract( list( sorted( - [x for x in self.option_chain_provider.get_option_contract_list(self.es19m20, self.time) if x.id.strike_price <= 3000.0 and x.id.option_right == OptionRight.PUT], + [x for x in self.option_chain(self.es19m20) if x.id.strike_price <= 3000.0 and x.id.option_right == OptionRight.PUT], key=lambda x: x.id.strike_price, reverse=True ) diff --git a/Algorithm.Python/IndexOptionBuySellCallIntradayRegressionAlgorithm.py b/Algorithm.Python/IndexOptionBuySellCallIntradayRegressionAlgorithm.py index 7420cff78cc9..51ec095dc7d0 100644 --- a/Algorithm.Python/IndexOptionBuySellCallIntradayRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionBuySellCallIntradayRegressionAlgorithm.py @@ -38,7 +38,7 @@ def initialize(self): # Select a index option expiring ITM, and adds it to the algorithm. spx_options = list(sorted([ self.add_index_option_contract(i, Resolution.MINUTE).symbol \ - for i in self.option_chain_provider.get_option_contract_list(spx, self.time)\ + for i in self.option_chain(spx)\ if (i.id.strike_price == 3700 or i.id.strike_price == 3800) and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1], key=lambda x: x.id.strike_price )) @@ -66,7 +66,7 @@ def initialize(self): if spx_options[0] != expectedContract3700: raise Exception(f"Contract {expectedContract3700} was not found in the chain, found instead: {spx_options[0]}") - + if spx_options[1] != expectedContract3800: raise Exception(f"Contract {expectedContract3800} was not found in the chain, found instead: {spx_options[1]}") diff --git a/Algorithm.Python/IndexOptionCallITMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionCallITMExpiryRegressionAlgorithm.py index 38179fef8fe1..28bc6e457717 100644 --- a/Algorithm.Python/IndexOptionCallITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionCallITMExpiryRegressionAlgorithm.py @@ -33,7 +33,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select an index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 3200 and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol @@ -43,8 +43,8 @@ def initialize(self): raise Exception(f"Contract {self.expected_option_contract} was not found in the chain") self.schedule.on( - self.date_rules.tomorrow, - self.time_rules.after_market_open(self.spx, 1), + self.date_rules.tomorrow, + self.time_rules.after_market_open(self.spx, 1), lambda: self.market_order(self.spx_option, 1) ) @@ -55,7 +55,7 @@ def on_data(self, data: Slice): if delisting.type == DelistingType.WARNING: if delisting.time != datetime(2021, 1, 15): raise Exception(f"Delisting warning issued at unexpected date: {delisting.time}") - + if delisting.type == DelistingType.DELISTED: if delisting.time != datetime(2021, 1, 16): raise Exception(f"Delisting happened at unexpected date: {delisting.time}") diff --git a/Algorithm.Python/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.py index 793a12e80ea1..d14a4e8c7ff9 100644 --- a/Algorithm.Python/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionCallITMGreeksExpiryRegressionAlgorithm.py @@ -30,7 +30,7 @@ def initialize(self): self.spx = spx.symbol # Select a index option call expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 3200 and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE) @@ -81,7 +81,7 @@ def on_data(self, data: Slice): if any([i for i in rho if i == 0]): raise Exception("Option contract Rho was equal to zero") - + if any([i for i in theta if i == 0]): raise Exception("Option contract Theta was equal to zero") diff --git a/Algorithm.Python/IndexOptionCallOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionCallOTMExpiryRegressionAlgorithm.py index fe2a16dfbf5b..de9dc846fd21 100644 --- a/Algorithm.Python/IndexOptionCallOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionCallOTMExpiryRegressionAlgorithm.py @@ -38,17 +38,17 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option call expiring OTM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price >= 4250 and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol self.expected_contract = Symbol.create_option( - self.spx, - Market.USA, - OptionStyle.EUROPEAN, - OptionRight.CALL, - 4250, + self.spx, + Market.USA, + OptionStyle.EUROPEAN, + OptionRight.CALL, + 4250, datetime(2021, 1, 15) ) @@ -56,8 +56,8 @@ def initialize(self): raise Exception(f"Contract {self.expected_contract} was not found in the chain") self.schedule.on( - self.date_rules.tomorrow, - self.time_rules.after_market_open(self.spx, 1), + self.date_rules.tomorrow, + self.time_rules.after_market_open(self.spx, 1), lambda: self.market_order(self.spx_option, 1) ) diff --git a/Algorithm.Python/IndexOptionPutITMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionPutITMExpiryRegressionAlgorithm.py index 2a241f79daf6..47fddb9de64a 100644 --- a/Algorithm.Python/IndexOptionPutITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionPutITMExpiryRegressionAlgorithm.py @@ -32,7 +32,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price >= 4200 and i.id.option_right == OptionRight.PUT and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol diff --git a/Algorithm.Python/IndexOptionPutOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionPutOTMExpiryRegressionAlgorithm.py index 43d6c648bfdc..20362670f508 100644 --- a/Algorithm.Python/IndexOptionPutOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionPutOTMExpiryRegressionAlgorithm.py @@ -38,17 +38,17 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option call expiring OTM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 3200 and i.id.option_right == OptionRight.PUT and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol self.expected_contract = Symbol.create_option( - self.spx, - Market.USA, - OptionStyle.EUROPEAN, - OptionRight.PUT, - 3200, + self.spx, + Market.USA, + OptionStyle.EUROPEAN, + OptionRight.PUT, + 3200, datetime(2021, 1, 15) ) @@ -56,8 +56,8 @@ def initialize(self): raise Exception(f"Contract {self.expected_contract} was not found in the chain") self.schedule.on( - self.date_rules.tomorrow, - self.time_rules.after_market_open(self.spx, 1), + self.date_rules.tomorrow, + self.time_rules.after_market_open(self.spx, 1), lambda: self.market_order(self.spx_option, 1) ) diff --git a/Algorithm.Python/IndexOptionShortCallITMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionShortCallITMExpiryRegressionAlgorithm.py index 975311ac67fe..89ab74131c71 100644 --- a/Algorithm.Python/IndexOptionShortCallITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionShortCallITMExpiryRegressionAlgorithm.py @@ -38,7 +38,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 3200 and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol diff --git a/Algorithm.Python/IndexOptionShortCallOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionShortCallOTMExpiryRegressionAlgorithm.py index 687f7c2d9016..9c4d1afb7b6a 100644 --- a/Algorithm.Python/IndexOptionShortCallOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionShortCallOTMExpiryRegressionAlgorithm.py @@ -34,7 +34,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price >= 4250 and i.id.option_right == OptionRight.CALL and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol diff --git a/Algorithm.Python/IndexOptionShortPutITMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionShortPutITMExpiryRegressionAlgorithm.py index 04e672786542..c7fcb5b86064 100644 --- a/Algorithm.Python/IndexOptionShortPutITMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionShortPutITMExpiryRegressionAlgorithm.py @@ -38,7 +38,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 4200 and i.id.option_right == OptionRight.PUT and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol diff --git a/Algorithm.Python/IndexOptionShortPutOTMExpiryRegressionAlgorithm.py b/Algorithm.Python/IndexOptionShortPutOTMExpiryRegressionAlgorithm.py index 628ab1c3f84e..b1d1829a42dd 100644 --- a/Algorithm.Python/IndexOptionShortPutOTMExpiryRegressionAlgorithm.py +++ b/Algorithm.Python/IndexOptionShortPutOTMExpiryRegressionAlgorithm.py @@ -34,7 +34,7 @@ def initialize(self): self.spx = self.add_index("SPX", Resolution.MINUTE).symbol # Select a index option expiring ITM, and adds it to the algorithm. - self.spx_option = list(self.option_chain_provider.get_option_contract_list(self.spx, self.time)) + self.spx_option = list(self.option_chain(self.spx)) self.spx_option = [i for i in self.spx_option if i.id.strike_price <= 3200 and i.id.option_right == OptionRight.PUT and i.id.date.year == 2021 and i.id.date.month == 1] self.spx_option = list(sorted(self.spx_option, key=lambda x: x.id.strike_price, reverse=True))[0] self.spx_option = self.add_index_option_contract(self.spx_option, Resolution.MINUTE).symbol diff --git a/Algorithm.Python/OptionChainFullDataRegressionAlgorithm.py b/Algorithm.Python/OptionChainFullDataRegressionAlgorithm.py new file mode 100644 index 000000000000..976d69469d01 --- /dev/null +++ b/Algorithm.Python/OptionChainFullDataRegressionAlgorithm.py @@ -0,0 +1,46 @@ +# 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. + +from AlgorithmImports import * + +### +### Regression algorithm illustrating the usage of the method +### to get an option chain, which contains additional data besides the symbols, including prices, implied volatility and greeks. +### It also shows how this data can be used to filter the contracts based on certain criteria. +### +class OptionChainFullDataRegressionAlgorithm(QCAlgorithm): + + def initialize(self): + self.set_start_date(2015, 12, 24) + self.set_end_date(2015, 12, 24) + self.set_cash(100000) + + goog = self.add_equity("GOOG").symbol + + # Get contracts expiring within 10 days, with an implied volatility greater than 0.5 and a delta less than 0.5 + contracts = [ + contract_data + for contract_data in self.option_chain(goog) + if contract_data.id.date - self.time <= timedelta(days=10) and contract_data.implied_volatility > 0.5 and contract_data.greeks.delta < 0.5 + ] + # Get the contract with the latest expiration date + self._option_contract = sorted(contracts, key=lambda x: x.id.date, reverse=True)[0] + + self.add_option_contract(self._option_contract) + + def on_data(self, data): + # Do some trading with the selected contract for sample purposes + if not self.portfolio.invested: + self.market_order(self._option_contract, 1) + else: + self.liquidate() diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs index 1ee6e0692b55..1f7b8008ea1a 100644 --- a/Algorithm/QCAlgorithm.cs +++ b/Algorithm/QCAlgorithm.cs @@ -53,6 +53,7 @@ using QuantConnect.Securities.CryptoFuture; using QuantConnect.Algorithm.Framework.Alphas.Analysis; using QuantConnect.Algorithm.Framework.Portfolio.SignalExports; +using Python.Runtime; namespace QuantConnect.Algorithm { @@ -467,6 +468,9 @@ public IAlgorithmSettings Settings /// Gets the option chain provider, used to get the list of option contracts for an underlying symbol /// [DocumentationAttribute(AddingData)] + [Obsolete("OptionChainProvider property is will soon be deprecated. " + + "The new OptionChain() method should be used to fetch equity and index option chains, " + + "which will contain additional data per contract, like daily price data, implied volatility and greeks.")] public IOptionChainProvider OptionChainProvider { get; private set; } /// @@ -2281,7 +2285,7 @@ public IndexOption AddIndexOption(string underlying, string targetOption, Resolu { throw new KeyNotFoundException($"No default market set for underlying security type: {SecurityType.Index}"); } - + return AddIndexOption( QuantConnect.Symbol.Create(underlying, SecurityType.Index, market), targetOption, resolution, fillForward); @@ -3325,6 +3329,65 @@ public List Fundamentals(List symbols) return symbols.Select(symbol => Fundamentals(symbol)).ToList(); } + /// + /// Get the option chain for the specified symbol at the current time () + /// + /// + /// The symbol for which the option chain is asked for. + /// It can be either the canonical option or the underlying symbol. + /// + /// + /// The option chain as an enumerable of , + /// each containing the contract symbol along with additional data, including daily price data, + /// implied volatility and greeks. + /// + /// + /// As of 2024/09/11, future options chain will not contain any additional data (e.g. daily price data, implied volatility and greeks), + /// it will be populated with the contract symbol only. This is expected to change in the future. + /// + [DocumentationAttribute(AddingData)] + public DataHistory OptionChain(Symbol symbol) + { + var canonicalSymbol = GetCanonicalOptionSymbol(symbol); + IEnumerable optionChain; + + // TODO: Until future options are supported by OptionUniverse, we need to fall back to the OptionChainProvider for them + if (canonicalSymbol.SecurityType != SecurityType.FutureOption) + { + // TODO: History(canonicalSymbol, 1) should be enough, + // the universe resolution should always be daily. Change this when this is fixed in #8317 + var history = History(canonicalSymbol, 1, Resolution.Daily); + optionChain = history?.SingleOrDefault()?.Data?.Cast() ?? Enumerable.Empty(); + } + else + { + optionChain = OptionChainProvider.GetOptionContractList(canonicalSymbol, Time) + .Select(contractSymbol => new OptionUniverse() + { + Symbol = contractSymbol, + EndTime = Time.Date + }); + } + + return new DataHistory(optionChain, new Lazy(() => PandasConverter.GetDataFrame(optionChain))); + } + + private static Symbol GetCanonicalOptionSymbol(Symbol symbol) + { + // We got the underlying + if (symbol.SecurityType.HasOptions()) + { + return QuantConnect.Symbol.CreateCanonicalOption(symbol); + } + + if (symbol.SecurityType.IsOption()) + { + return symbol.Canonical; + } + + throw new ArgumentException($"The symbol {symbol} is not an option or an underlying symbol."); + } + /// /// Set the properties and exchange hours for a given key into our databases /// diff --git a/Tests/Algorithm/AlgorithmChainsTests.cs b/Tests/Algorithm/AlgorithmChainsTests.cs new file mode 100644 index 000000000000..af02e9aafd9b --- /dev/null +++ b/Tests/Algorithm/AlgorithmChainsTests.cs @@ -0,0 +1,75 @@ +/* + * 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 NUnit.Framework; +using QuantConnect.Algorithm; +using QuantConnect.Data; +using QuantConnect.Interfaces; +using QuantConnect.Lean.Engine.DataFeeds; +using QuantConnect.Securities; +using QuantConnect.Tests.Engine.DataFeeds; +using QuantConnect.Util; + +namespace QuantConnect.Tests.Algorithm +{ + [TestFixture] + public class AlgorithmChainsTest + { + private QCAlgorithm _algorithm; + private BacktestingOptionChainProvider _optionChainProvider; + + [OneTimeSetUp] + public void OneTimeSetUp() + { + var historyProvider = Composer.Instance.GetExportedValueByTypeName("SubscriptionDataReaderHistoryProvider", true); + var parameters = new HistoryProviderInitializeParameters(null, null, TestGlobals.DataProvider, TestGlobals.DataCacheProvider, + TestGlobals.MapFileProvider, TestGlobals.FactorFileProvider, (_) => { }, true, new DataPermissionManager(), null, + new AlgorithmSettings()); + historyProvider.Initialize(parameters); + + _algorithm = new QCAlgorithm(); + _algorithm.SetHistoryProvider(historyProvider); + _algorithm.SubscriptionManager.SetDataManager(new DataManagerStub(_algorithm)); + + _optionChainProvider = new BacktestingOptionChainProvider(TestGlobals.DataCacheProvider, TestGlobals.MapFileProvider); + _algorithm.SetOptionChainProvider(_optionChainProvider); + } + + private static TestCaseData[] OptionChainTestCases = new TestCaseData[] + { + // By underlying + new(Symbols.AAPL, new DateTime(2014, 06, 06, 12, 0, 0)), + new(Symbols.SPX, new DateTime(2021, 01, 04, 12, 0, 0)), + // By canonical + new(Symbol.CreateCanonicalOption(Symbols.AAPL), new DateTime(2014, 06, 06, 12, 0, 0)), + new(Symbol.CreateCanonicalOption(Symbols.SPX), new DateTime(2021, 01, 04, 12, 0, 0)), + new(Symbol.CreateFuture(Futures.Indices.SP500EMini, Market.CME, new DateTime(2020, 6, 19)), new DateTime(2020, 01, 05, 12, 0, 0)), + }; + + [TestCaseSource(nameof(OptionChainTestCases))] + public void GetsFullDataOptionChain(Symbol symbol, DateTime date) + { + _algorithm.SetDateTime(date.ConvertToUtc(_algorithm.TimeZone)); + var optionContractsData = _algorithm.OptionChain(symbol).ToList(); + Assert.IsNotEmpty(optionContractsData); + + var optionContractsSymbols = _optionChainProvider.GetOptionContractList(symbol, date.Date).ToList(); + + CollectionAssert.AreEquivalent(optionContractsSymbols, optionContractsData.Select(x => x.Symbol)); + } + } +}