From d5690628e42ab8463bc9585fad5db741a5258d99 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Tue, 11 Feb 2025 15:55:56 -0400 Subject: [PATCH 1/3] Add config for custom vix futures chain provider --- .../ChainSymbolProvider.cs | 2 +- .../FutureChainSymbolProvider.cs | 27 +++++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/Lean.DataSource.DerivativeUniverseGenerator/ChainSymbolProvider.cs b/Lean.DataSource.DerivativeUniverseGenerator/ChainSymbolProvider.cs index 93036d9..dd3fd96 100644 --- a/Lean.DataSource.DerivativeUniverseGenerator/ChainSymbolProvider.cs +++ b/Lean.DataSource.DerivativeUniverseGenerator/ChainSymbolProvider.cs @@ -60,7 +60,7 @@ public ChainSymbolProvider(IDataCacheProvider dataCacheProvider, DateTime proces /// /// Gets all the available symbols keyed by the canonical symbol from the available price data in the data folder. /// - public Dictionary> GetSymbols() + public virtual Dictionary> GetSymbols() { var result = new Dictionary>(); diff --git a/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs b/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs index e620e03..a4b3c1a 100644 --- a/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs +++ b/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs @@ -13,8 +13,11 @@ * limitations under the License. */ +using QuantConnect.Configuration; using QuantConnect.DataSource.DerivativeUniverseGenerator; using QuantConnect.Interfaces; +using QuantConnect.Securities; +using QuantConnect.Util; using System; using System.Collections.Generic; using System.IO; @@ -27,6 +30,10 @@ namespace QuantConnect.DataSource.FuturesUniverseGenerator /// public class FutureChainSymbolProvider : ChainSymbolProvider { + private static readonly Symbol VIX = Symbol.Create(Futures.Indices.VIX, SecurityType.Future, Market.CFE); + + private readonly IFutureChainProvider _vixFuturesChainProvider; + /// /// Initializes a new instance of the class /// @@ -34,6 +41,26 @@ public FutureChainSymbolProvider(IDataCacheProvider dataCacheProvider, DateTime string market, string dataFolderRoot) : base(dataCacheProvider, processingDate, securityType, market, dataFolderRoot) { + if (market == Market.CFE && + Config.TryGetValue("vix-futures-chain-provider", out var futuresChainProviderStr) && + !string.IsNullOrEmpty(futuresChainProviderStr)) + { + _vixFuturesChainProvider = Composer.Instance.GetExportedValueByTypeName(futuresChainProviderStr); + } + } + + /// + /// Gets all the available symbols keyed by the canonical symbol from the available price data in the data folder. + /// + public override Dictionary> GetSymbols() + { + if (_vixFuturesChainProvider == null) + { + return base.GetSymbols(); + } + + var symbols = _vixFuturesChainProvider.GetFutureContractList(VIX, _processingDate).ToList(); + return new Dictionary>() { { VIX, symbols } }; } protected override IEnumerable GetZipFileNames(DateTime date, Resolution resolution) From 7a2e0fa7d3dc601ea7c8263ac4d83c5b0b397419 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Tue, 11 Feb 2025 17:36:42 -0400 Subject: [PATCH 2/3] Minor changes --- .../FutureChainSymbolProvider.cs | 49 +++++++++++++++---- 1 file changed, 40 insertions(+), 9 deletions(-) diff --git a/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs b/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs index a4b3c1a..a7a9191 100644 --- a/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs +++ b/Lean.DataSource.FuturesUniverseGenerator/FutureChainSymbolProvider.cs @@ -17,6 +17,7 @@ using QuantConnect.DataSource.DerivativeUniverseGenerator; using QuantConnect.Interfaces; using QuantConnect.Securities; +using QuantConnect.Securities.Future; using QuantConnect.Util; using System; using System.Collections.Generic; @@ -30,9 +31,8 @@ namespace QuantConnect.DataSource.FuturesUniverseGenerator /// public class FutureChainSymbolProvider : ChainSymbolProvider { - private static readonly Symbol VIX = Symbol.Create(Futures.Indices.VIX, SecurityType.Future, Market.CFE); - - private readonly IFutureChainProvider _vixFuturesChainProvider; + private readonly IFutureChainProvider _futuresChainProvider; + private readonly string _market; /// /// Initializes a new instance of the class @@ -41,11 +41,12 @@ public FutureChainSymbolProvider(IDataCacheProvider dataCacheProvider, DateTime string market, string dataFolderRoot) : base(dataCacheProvider, processingDate, securityType, market, dataFolderRoot) { - if (market == Market.CFE && - Config.TryGetValue("vix-futures-chain-provider", out var futuresChainProviderStr) && + _market = market; + + if (Config.TryGetValue("futures-chain-provider", out var futuresChainProviderStr) && !string.IsNullOrEmpty(futuresChainProviderStr)) { - _vixFuturesChainProvider = Composer.Instance.GetExportedValueByTypeName(futuresChainProviderStr); + _futuresChainProvider = Composer.Instance.GetExportedValueByTypeName(futuresChainProviderStr); } } @@ -54,13 +55,43 @@ public FutureChainSymbolProvider(IDataCacheProvider dataCacheProvider, DateTime /// public override Dictionary> GetSymbols() { - if (_vixFuturesChainProvider == null) + if (_futuresChainProvider == null) { return base.GetSymbols(); } - var symbols = _vixFuturesChainProvider.GetFutureContractList(VIX, _processingDate).ToList(); - return new Dictionary>() { { VIX, symbols } }; + var chains = FuturesExpiryFunctions.FuturesExpiryDictionary.Keys + .Where(symbol => symbol.ID.Market == _market) + .Select(symbol => + { + var futureChain = _futuresChainProvider.GetFutureContractList(symbol, _processingDate)?.ToList(); + return KeyValuePair.Create(symbol, futureChain); + }) + .ToList(); + + if (chains.Any(kvp => kvp.Value == null)) + { + // The custom chain provider failed for some symbols, fallback to the default chain provider for those + var baseSymbols = base.GetSymbols(); + if (chains.All(kvp => kvp.Value == null)) + { + return baseSymbols; + } + + return chains + .Select(kvp => + { + if (kvp.Value == null && baseSymbols.TryGetValue(kvp.Key, out var chain)) + { + return KeyValuePair.Create(kvp.Key, chain); + } + return kvp; + }) + .Where(kvp => kvp.Value != null) + .ToDictionary(); + } + + return new Dictionary>(chains); } protected override IEnumerable GetZipFileNames(DateTime date, Resolution resolution) From c465f6c472f2897dec32398b71008409f33a2f61 Mon Sep 17 00:00:00 2001 From: Jhonathan Abreu Date: Tue, 11 Feb 2025 17:41:02 -0400 Subject: [PATCH 3/3] Rename "symbols" config to "universe-generation-symbols" --- DataProcessing/config.json | 2 +- Lean.DataSource.FuturesUniverseGenerator/config.json | 2 +- Lean.DataSource.OptionsUniverseGenerator/config.json | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/DataProcessing/config.json b/DataProcessing/config.json index 17a07ca..39ad385 100644 --- a/DataProcessing/config.json +++ b/DataProcessing/config.json @@ -1,5 +1,5 @@ { "data-folder": "../../../../Lean/Data/", "history-provider": [ "SubscriptionDataReaderHistoryProvider", "IndexHistoryProvider" ], - "symbols": [] + "universe-generation-symbols": [] } \ No newline at end of file diff --git a/Lean.DataSource.FuturesUniverseGenerator/config.json b/Lean.DataSource.FuturesUniverseGenerator/config.json index 11f3ccf..d0b385a 100644 --- a/Lean.DataSource.FuturesUniverseGenerator/config.json +++ b/Lean.DataSource.FuturesUniverseGenerator/config.json @@ -1,5 +1,5 @@ { "data-folder": "../../../Data/", "history-provider": [ "SubscriptionDataReaderHistoryProvider" ], - "symbols": [] + "universe-generation-symbols": [] } \ No newline at end of file diff --git a/Lean.DataSource.OptionsUniverseGenerator/config.json b/Lean.DataSource.OptionsUniverseGenerator/config.json index cd23ba6..ceab1ef 100644 --- a/Lean.DataSource.OptionsUniverseGenerator/config.json +++ b/Lean.DataSource.OptionsUniverseGenerator/config.json @@ -1,5 +1,5 @@ { "data-folder": "../../../Data/", "history-provider": [ "SubscriptionDataReaderHistoryProvider", "IndexHistoryProvider" ], - "symbols": [] + "universe-generation-symbols": [] } \ No newline at end of file