diff --git a/Algorithm.CSharp/AuxiliaryDataHandlersRegressionAlgorithm.cs b/Algorithm.CSharp/AuxiliaryDataHandlersRegressionAlgorithm.cs
index 26b22be5da87..ac9b6cc3ba3d 100644
--- a/Algorithm.CSharp/AuxiliaryDataHandlersRegressionAlgorithm.cs
+++ b/Algorithm.CSharp/AuxiliaryDataHandlersRegressionAlgorithm.cs
@@ -119,7 +119,7 @@ public override void OnEndOfAlgorithm()
///
/// Data Points count of all timeslices of algorithm
///
- public long DataPoints => 126222;
+ public long DataPoints => 17270;
///
/// Data Points count of the algorithm history
diff --git a/Algorithm.CSharp/EquityOptionsUniverseSettingsRegressionAlgorithm.cs b/Algorithm.CSharp/EquityOptionsUniverseSettingsRegressionAlgorithm.cs
new file mode 100644
index 000000000000..98be0c1c70e1
--- /dev/null
+++ b/Algorithm.CSharp/EquityOptionsUniverseSettingsRegressionAlgorithm.cs
@@ -0,0 +1,153 @@
+/*
+ * 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.Collections.Generic;
+using System.Linq;
+using QuantConnect.Data;
+using QuantConnect.Interfaces;
+using QuantConnect.Data.UniverseSelection;
+using QuantConnect.Securities;
+using System;
+
+namespace QuantConnect.Algorithm.CSharp
+{
+ ///
+ /// Regression algorithm asserting that options from universe are added with the same resolution, fill forward and extended market hours settings as the universe settings.
+ ///
+ public class EquityOptionsUniverseSettingsRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
+ {
+ private SecurityType[] _securityTypes;
+ private HashSet _checkedSecurityTypes = new();
+
+ protected virtual DateTime TestStartDate => new DateTime(2015, 12, 24);
+
+ public override void Initialize()
+ {
+ SetStartDate(TestStartDate);
+ SetEndDate(TestStartDate.AddDays(1));
+ SetCash(100000);
+
+ UniverseSettings.Resolution = Resolution.Daily;
+ UniverseSettings.FillForward = false;
+ UniverseSettings.ExtendedMarketHours = true;
+
+ _securityTypes = AddSecurity();
+ }
+
+ protected virtual SecurityType[] AddSecurity()
+ {
+ var equity = AddEquity("GOOG");
+ var option = AddOption(equity.Symbol);
+ option.SetFilter(u => u.StandardsOnly().Strikes(-2, +2).Expiration(0, 180));
+
+ return [option.Symbol.SecurityType];
+ }
+
+ public override void OnSecuritiesChanged(SecurityChanges changes)
+ {
+ var securities = changes.AddedSecurities.Where(x => _securityTypes.Contains(x.Type) && !x.Symbol.IsCanonical()).Select(x => x.Symbol).ToList();
+ var configs = SubscriptionManager.Subscriptions.Where(x => securities.Contains(x.Symbol));
+
+ foreach (var config in configs)
+ {
+ if (config.Resolution != UniverseSettings.Resolution)
+ {
+ throw new RegressionTestException($"Config '{config}' resolution {config.Resolution} does not match universe settings resolution {UniverseSettings.Resolution}");
+ }
+
+ if (config.FillDataForward != UniverseSettings.FillForward)
+ {
+ throw new RegressionTestException($"Config '{config}' fill forward {config.FillDataForward} does not match universe settings fill forward {UniverseSettings.FillForward}");
+ }
+
+ if (config.ExtendedMarketHours != UniverseSettings.ExtendedMarketHours)
+ {
+ throw new RegressionTestException($"Config '{config}' extended market hours {config.ExtendedMarketHours} does not match universe settings extended market hours {UniverseSettings.ExtendedMarketHours}");
+ }
+
+ _checkedSecurityTypes.Add(config.SecurityType);
+ }
+ }
+
+ public override void OnEndOfAlgorithm()
+ {
+ if (_checkedSecurityTypes.Count != _securityTypes.Length || !_securityTypes.All(_checkedSecurityTypes.Contains))
+ {
+ throw new RegressionTestException($"Not all security types were checked. Expected: {string.Join(", ", _securityTypes)}. Checked: {string.Join(", ", _checkedSecurityTypes)}");
+ }
+ }
+
+ ///
+ /// 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 List Languages { get; } = new() { Language.CSharp };
+
+ ///
+ /// Data Points count of all timeslices of algorithm
+ ///
+ public virtual long DataPoints => 4276;
+
+ ///
+ /// Data Points count of the algorithm history
+ ///
+ public int AlgorithmHistoryDataPoints => 0;
+
+ ///
+ /// 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 virtual Dictionary ExpectedStatistics => new Dictionary
+ {
+ {"Total Orders", "0"},
+ {"Average Win", "0%"},
+ {"Average Loss", "0%"},
+ {"Compounding Annual Return", "0%"},
+ {"Drawdown", "0%"},
+ {"Expectancy", "0"},
+ {"Start Equity", "100000"},
+ {"End Equity", "100000"},
+ {"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", "$0.00"},
+ {"Estimated Strategy Capacity", "$0"},
+ {"Lowest Capacity Asset", ""},
+ {"Portfolio Turnover", "0%"},
+ {"Drawdown Recovery", "0"},
+ {"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
+ };
+ }
+}
diff --git a/Algorithm.CSharp/FundamentalRegressionAlgorithm.cs b/Algorithm.CSharp/FundamentalRegressionAlgorithm.cs
index 9de985b97bf0..8ef65262f824 100644
--- a/Algorithm.CSharp/FundamentalRegressionAlgorithm.cs
+++ b/Algorithm.CSharp/FundamentalRegressionAlgorithm.cs
@@ -222,7 +222,7 @@ public override void OnSecuritiesChanged(SecurityChanges changes)
///
/// Data Points count of all timeslices of algorithm
///
- public long DataPoints => 77169;
+ public long DataPoints => 70972;
///
/// Data Points count of the algorithm history
@@ -239,34 +239,34 @@ public override void OnSecuritiesChanged(SecurityChanges changes)
///
public Dictionary ExpectedStatistics => new Dictionary
{
- {"Total Orders", "2"},
+ {"Total Orders", "3"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
- {"Compounding Annual Return", "-1.016%"},
+ {"Compounding Annual Return", "-1.169%"},
{"Drawdown", "0.100%"},
{"Expectancy", "0"},
{"Start Equity", "100000"},
- {"End Equity", "99963.64"},
- {"Net Profit", "-0.036%"},
- {"Sharpe Ratio", "-4.731"},
- {"Sortino Ratio", "-6.776"},
- {"Probabilistic Sharpe Ratio", "24.373%"},
+ {"End Equity", "99958.14"},
+ {"Net Profit", "-0.042%"},
+ {"Sharpe Ratio", "-3.451"},
+ {"Sortino Ratio", "-4.933"},
+ {"Probabilistic Sharpe Ratio", "27.530%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
{"Alpha", "-0.013"},
- {"Beta", "0.023"},
- {"Annual Standard Deviation", "0.003"},
+ {"Beta", "0.043"},
+ {"Annual Standard Deviation", "0.005"},
{"Annual Variance", "0"},
{"Information Ratio", "0.607"},
- {"Tracking Error", "0.095"},
- {"Treynor Ratio", "-0.654"},
- {"Total Fees", "$2.00"},
+ {"Tracking Error", "0.093"},
+ {"Treynor Ratio", "-0.381"},
+ {"Total Fees", "$3.00"},
{"Estimated Strategy Capacity", "$1900000000.00"},
{"Lowest Capacity Asset", "IBM R735QTJ8XC9X"},
- {"Portfolio Turnover", "0.30%"},
- {"Drawdown Recovery", "5"},
- {"OrderListHash", "9b3bf202c3d5707779f25e9c7f7fdc92"}
+ {"Portfolio Turnover", "0.45%"},
+ {"Drawdown Recovery", "4"},
+ {"OrderListHash", "63a37fcfe86bca2e037d9dbb9c531e43"}
};
}
}
diff --git a/Algorithm.CSharp/FuturesAndFutureOptionsUniverseSettingsRegressionAlgorithm.cs b/Algorithm.CSharp/FuturesAndFutureOptionsUniverseSettingsRegressionAlgorithm.cs
new file mode 100644
index 000000000000..eee258196fc6
--- /dev/null
+++ b/Algorithm.CSharp/FuturesAndFutureOptionsUniverseSettingsRegressionAlgorithm.cs
@@ -0,0 +1,44 @@
+/*
+ * 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 QuantConnect.Securities;
+using System;
+
+namespace QuantConnect.Algorithm.CSharp
+{
+ ///
+ /// Regression algorithm asserting that futures and future options from universe are added with the same resolution, fill forward and extended market hours settings as the universe settings.
+ ///
+ public class FuturesAndFutureOptionsUniverseSettingsRegressionAlgorithm : EquityOptionsUniverseSettingsRegressionAlgorithm
+ {
+ protected override DateTime TestStartDate => new DateTime(2020, 01, 03);
+
+ protected override SecurityType[] AddSecurity()
+ {
+ var futures = AddFuture(Futures.Indices.SP500EMini);
+ futures.SetFilter(0, 180);
+
+ AddFutureOption(futures.Symbol, universe => universe.Strikes(-5, +5));
+
+ return [SecurityType.Future, SecurityType.FutureOption];
+ }
+
+ ///
+ /// Data Points count of all timeslices of algorithm
+ ///
+ public override long DataPoints => 456;
+ }
+}
diff --git a/Algorithm.CSharp/IndexOptionsUniverseSettingsRegressionAlgorithm.cs b/Algorithm.CSharp/IndexOptionsUniverseSettingsRegressionAlgorithm.cs
new file mode 100644
index 000000000000..5bc4a843f1c3
--- /dev/null
+++ b/Algorithm.CSharp/IndexOptionsUniverseSettingsRegressionAlgorithm.cs
@@ -0,0 +1,78 @@
+/*
+ * 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;
+
+namespace QuantConnect.Algorithm.CSharp
+{
+ ///
+ /// Regression algorithm asserting that index options from universe are added with the same resolution, fill forward and extended market hours settings as the universe settings.
+ ///
+ public class IndexOptionsUniverseSettingsRegressionAlgorithm : EquityOptionsUniverseSettingsRegressionAlgorithm
+ {
+ protected override DateTime TestStartDate => new DateTime(2021, 01, 05);
+
+ protected override SecurityType[] AddSecurity()
+ {
+ var index = AddIndex("SPX");
+ var indexOption = AddOption(index.Symbol);
+ indexOption.SetFilter(u => u.Strikes(-2, +2).Expiration(0, 180));
+
+ return [indexOption.Symbol.SecurityType];
+ }
+
+ ///
+ /// Data Points count of all timeslices of algorithm
+ ///
+ public override long DataPoints => 46;
+
+ ///
+ /// This is used by the regression test system to indicate what the expected statistics are from running the algorithm
+ ///
+ public override Dictionary ExpectedStatistics => new Dictionary
+ {
+ {"Total Orders", "0"},
+ {"Average Win", "0%"},
+ {"Average Loss", "0%"},
+ {"Compounding Annual Return", "0%"},
+ {"Drawdown", "0%"},
+ {"Expectancy", "0"},
+ {"Start Equity", "100000"},
+ {"End Equity", "100000"},
+ {"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", "-16.713"},
+ {"Tracking Error", "0.067"},
+ {"Treynor Ratio", "0"},
+ {"Total Fees", "$0.00"},
+ {"Estimated Strategy Capacity", "$0"},
+ {"Lowest Capacity Asset", ""},
+ {"Portfolio Turnover", "0%"},
+ {"Drawdown Recovery", "0"},
+ {"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
+ };
+ }
+}
diff --git a/Algorithm.Python/IndexOptionCallButterflyAlgorithm.py b/Algorithm.Python/IndexOptionCallButterflyAlgorithm.py
index db29bd15c86a..715b13c0f7e7 100644
--- a/Algorithm.Python/IndexOptionCallButterflyAlgorithm.py
+++ b/Algorithm.Python/IndexOptionCallButterflyAlgorithm.py
@@ -65,6 +65,5 @@ def on_data(self, slice: Slice) -> None:
call_butterfly = OptionStrategies.call_butterfly(self.spxw, otm_strike, atm_strike, itm_strike, expiry)
price = sum([abs(self.securities[x.symbol].price * x.quantity) * self.multiplier for x in call_butterfly.underlying_legs])
if price > 0:
- quantity = self.portfolio.total_portfolio_value // price
+ quantity = int(self.portfolio.total_portfolio_value // price)
self.tickets = self.buy(call_butterfly, quantity, asynchronous=True)
-
\ No newline at end of file
diff --git a/Algorithm.Python/IndexOptionPutButterflyAlgorithm.py b/Algorithm.Python/IndexOptionPutButterflyAlgorithm.py
index f6e0d82a816a..5ee1a3055d54 100644
--- a/Algorithm.Python/IndexOptionPutButterflyAlgorithm.py
+++ b/Algorithm.Python/IndexOptionPutButterflyAlgorithm.py
@@ -65,6 +65,5 @@ def on_data(self, slice: Slice) -> None:
put_butterfly = OptionStrategies.put_butterfly(self.spxw, itm_strike, atm_strike, otm_strike, expiry)
price = sum([abs(self.securities[x.symbol].price * x.quantity) * self.multiplier for x in put_butterfly.underlying_legs])
if price > 0:
- quantity = self.portfolio.total_portfolio_value // price
+ quantity = int(self.portfolio.total_portfolio_value // price)
self.tickets = self.buy(put_butterfly, quantity, asynchronous=True)
-
\ No newline at end of file
diff --git a/Algorithm/QCAlgorithm.cs b/Algorithm/QCAlgorithm.cs
index aa88d9d4a498..28ae1f6e0802 100644
--- a/Algorithm/QCAlgorithm.cs
+++ b/Algorithm/QCAlgorithm.cs
@@ -1903,7 +1903,7 @@ public void SetTradeBuilder(ITradeBuilder tradeBuilder)
/// The contract mapping mode to use for the security
/// The price scaling mode to use for the security
[DocumentationAttribute(AddingData)]
- public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution = null, bool fillForward = true, bool extendedMarketHours = false,
+ public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution = null, bool? fillForward = null, bool? extendedMarketHours = null,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null)
{
return AddSecurity(securityType, ticker, resolution, fillForward, Security.NullLeverage, extendedMarketHours, dataMappingMode, dataNormalizationMode);
@@ -1922,7 +1922,7 @@ public Security AddSecurity(SecurityType securityType, string ticker, Resolution
/// The price scaling mode to use for the security
/// AddSecurity(SecurityType securityType, Symbol symbol, Resolution resolution, bool fillForward, decimal leverage, bool extendedMarketHours)
[DocumentationAttribute(AddingData)]
- public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution, bool fillForward, decimal leverage, bool extendedMarketHours,
+ public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution, bool? fillForward, decimal leverage, bool? extendedMarketHours,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null)
{
return AddSecurity(securityType, ticker, resolution, null, fillForward, leverage, extendedMarketHours, dataMappingMode, dataNormalizationMode);
@@ -1941,7 +1941,7 @@ public Security AddSecurity(SecurityType securityType, string ticker, Resolution
/// The contract mapping mode to use for the security
/// The price scaling mode to use for the security
[DocumentationAttribute(AddingData)]
- public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution, string market, bool fillForward, decimal leverage, bool extendedMarketHours,
+ public Security AddSecurity(SecurityType securityType, string ticker, Resolution? resolution, string market, bool? fillForward, decimal leverage, bool? extendedMarketHours,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null)
{
// if AddSecurity method is called to add an option or a future, we delegate a call to respective methods
@@ -1990,7 +1990,7 @@ public Security AddSecurity(SecurityType securityType, string ticker, Resolution
/// For example, 0 (default) will use the front month, 1 will use the back month contract
/// The new Security that was added to the algorithm
[DocumentationAttribute(AddingData)]
- public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool fillForward = true, decimal leverage = Security.NullLeverage, bool extendedMarketHours = false,
+ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool? fillForward = null, decimal leverage = Security.NullLeverage, bool? extendedMarketHours = null,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null, int contractDepthOffset = 0)
{
// allow users to specify negative numbers, we get the abs of it
@@ -2002,15 +2002,16 @@ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool f
}
var isCanonical = symbol.IsCanonical();
+ var securityFillForward = fillForward ??= UniverseSettings.FillForward;
+ extendedMarketHours ??= UniverseSettings.ExtendedMarketHours;
// Short-circuit to AddOptionContract because it will add the underlying if required
if (!isCanonical && symbol.SecurityType.IsOption())
{
- return AddOptionContract(symbol, resolution, fillForward, leverage, extendedMarketHours);
+ return AddOptionContract(symbol, resolution, securityFillForward, leverage, extendedMarketHours.Value);
}
var securityResolution = resolution;
- var securityFillForward = fillForward;
if (isCanonical)
{
// canonical options and futures are daily only
@@ -2027,7 +2028,7 @@ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool f
configs = SubscriptionManager.SubscriptionDataConfigService.Add(symbol,
securityResolution,
securityFillForward,
- extendedMarketHours,
+ extendedMarketHours.Value,
isFilteredSubscription,
dataNormalizationMode: dataNormalizationMode.Value,
contractDepthOffset: (uint)contractDepthOffset);
@@ -2037,7 +2038,7 @@ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool f
configs = SubscriptionManager.SubscriptionDataConfigService.Add(symbol,
securityResolution,
securityFillForward,
- extendedMarketHours,
+ extendedMarketHours.Value,
isFilteredSubscription,
contractDepthOffset: (uint)contractDepthOffset);
}
@@ -2055,7 +2056,7 @@ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool f
{
var canonicalConfig = configs.First();
var universeSettingsResolution = resolution ?? UniverseSettings.Resolution;
- var settings = new UniverseSettings(universeSettingsResolution, leverage, fillForward, extendedMarketHours, UniverseSettings.MinimumTimeInUniverse)
+ var settings = new UniverseSettings(universeSettingsResolution, leverage, fillForward.Value, extendedMarketHours.Value, UniverseSettings.MinimumTimeInUniverse)
{
Asynchronous = UniverseSettings.Asynchronous
};
@@ -2071,7 +2072,8 @@ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool f
GetResolution(symbol, resolution, null), isCanonical: false);
var continuousUniverseSettings = new UniverseSettings(settings)
{
- ExtendedMarketHours = extendedMarketHours,
+ ExtendedMarketHours = extendedMarketHours.Value,
+ FillForward = fillForward.Value,
DataMappingMode = dataMappingMode ?? UniverseSettings.GetUniverseMappingModeOrDefault(symbol.SecurityType, symbol.ID.Market),
DataNormalizationMode = dataNormalizationMode ?? UniverseSettings.GetUniverseNormalizationModeOrDefault(symbol.SecurityType),
ContractDepthOffset = (int)contractOffset,
@@ -2131,7 +2133,7 @@ public Equity AddEquity(string ticker, Resolution? resolution = null, string mar
/// The requested leverage for this equity. Default is set by
/// The new security
[DocumentationAttribute(AddingData)]
- public Option AddOption(string underlying, Resolution? resolution = null, string market = null, bool fillForward = true, decimal leverage = Security.NullLeverage)
+ public Option AddOption(string underlying, Resolution? resolution = null, string market = null, bool? fillForward = null, decimal leverage = Security.NullLeverage)
{
market = GetMarket(market, underlying, SecurityType.Option);
@@ -2152,7 +2154,7 @@ public Option AddOption(string underlying, Resolution? resolution = null, string
/// The new option security instance
///
[DocumentationAttribute(AddingData)]
- public Option AddOption(Symbol underlying, Resolution? resolution = null, string market = null, bool fillForward = true, decimal leverage = Security.NullLeverage)
+ public Option AddOption(Symbol underlying, Resolution? resolution = null, string market = null, bool? fillForward = null, decimal leverage = Security.NullLeverage)
{
return AddOption(underlying, null, resolution, market, fillForward, leverage);
}
@@ -2172,7 +2174,7 @@ public Option AddOption(Symbol underlying, Resolution? resolution = null, string
///
[DocumentationAttribute(AddingData)]
public Option AddOption(Symbol underlying, string targetOption, Resolution? resolution = null,
- string market = null, bool fillForward = true, decimal leverage = Security.NullLeverage)
+ string market = null, bool? fillForward = null, decimal leverage = Security.NullLeverage)
{
var optionType = QuantConnect.Symbol.GetOptionTypeFromUnderlying(underlying);
@@ -2215,7 +2217,7 @@ public Option AddOption(Symbol underlying, string targetOption, Resolution? reso
/// The new security
[DocumentationAttribute(AddingData)]
public Future AddFuture(string ticker, Resolution? resolution = null, string market = null,
- bool fillForward = true, decimal leverage = Security.NullLeverage, bool extendedMarketHours = false,
+ bool? fillForward = null, decimal leverage = Security.NullLeverage, bool? extendedMarketHours = null,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null, int contractDepthOffset = 0)
{
market = GetMarket(market, ticker, SecurityType.Future);
@@ -2283,7 +2285,7 @@ public void AddFutureOption(Symbol symbol, FuncThe leverage to apply to the option contract
/// Use extended market hours data
/// Option security
- /// Symbol is canonical (i.e. a generic Symbol returned from or )
+ /// Symbol is canonical (i.e. a generic Symbol returned from or )
[DocumentationAttribute(AddingData)]
public Option AddFutureOptionContract(Symbol symbol, Resolution? resolution = null, bool fillForward = true,
decimal leverage = Security.NullLeverage, bool extendedMarketHours = false)
diff --git a/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs b/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs
index 1d31c7398079..6af94c1b877b 100644
--- a/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs
+++ b/AlgorithmFactory/Python/Wrappers/AlgorithmPythonWrapper.cs
@@ -593,7 +593,7 @@ public int ProjectId
/// Use extended market hours data
/// The contract mapping mode to use for the security
/// The price scaling mode to use for the security
- public Security AddSecurity(SecurityType securityType, string symbol, Resolution? resolution, string market, bool fillForward, decimal leverage, bool extendedMarketHours,
+ public Security AddSecurity(SecurityType securityType, string symbol, Resolution? resolution, string market, bool? fillForward, decimal leverage, bool? extendedMarketHours,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null)
=> _baseAlgorithm.AddSecurity(securityType, symbol, resolution, market, fillForward, leverage, extendedMarketHours, dataMappingMode, dataNormalizationMode);
@@ -611,7 +611,7 @@ public Security AddSecurity(SecurityType securityType, string symbol, Resolution
/// The continuous contract desired offset from the current front month.
/// For example, 0 (default) will use the front month, 1 will use the back month contract
/// The new Security that was added to the algorithm
- public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool fillForward = true, decimal leverage = Security.NullLeverage, bool extendedMarketHours = false,
+ public Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool? fillForward = null, decimal leverage = Security.NullLeverage, bool? extendedMarketHours = null,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null, int contractDepthOffset = 0)
=> _baseAlgorithm.AddSecurity(symbol, resolution, fillForward, leverage, extendedMarketHours, dataMappingMode, dataNormalizationMode, contractDepthOffset);
diff --git a/Common/Interfaces/IAlgorithm.cs b/Common/Interfaces/IAlgorithm.cs
index 87489d7a1472..a4221bd440e5 100644
--- a/Common/Interfaces/IAlgorithm.cs
+++ b/Common/Interfaces/IAlgorithm.cs
@@ -710,7 +710,7 @@ InsightManager Insights
/// ExtendedMarketHours send in data from 4am - 8pm, not used for FOREX
/// The contract mapping mode to use for the security
/// The price scaling mode to use for the security
- Security AddSecurity(SecurityType securityType, string symbol, Resolution? resolution, string market, bool fillForward, decimal leverage, bool extendedMarketHours,
+ Security AddSecurity(SecurityType securityType, string symbol, Resolution? resolution, string market, bool? fillForward, decimal leverage, bool? extendedMarketHours,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null);
///
@@ -726,7 +726,7 @@ Security AddSecurity(SecurityType securityType, string symbol, Resolution? resol
/// The continuous contract desired offset from the current front month.
/// For example, 0 (default) will use the front month, 1 will use the back month contract
/// The new Security that was added to the algorithm
- Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool fillForward = true, decimal leverage = Security.NullLeverage, bool extendedMarketHours = false,
+ Security AddSecurity(Symbol symbol, Resolution? resolution = null, bool? fillForward = null, decimal leverage = Security.NullLeverage, bool? extendedMarketHours = null,
DataMappingMode? dataMappingMode = null, DataNormalizationMode? dataNormalizationMode = null, int contractDepthOffset = 0);
///
diff --git a/Engine/DataFeeds/DataManager.cs b/Engine/DataFeeds/DataManager.cs
index 4f21d859231e..b37761a077e6 100644
--- a/Engine/DataFeeds/DataManager.cs
+++ b/Engine/DataFeeds/DataManager.cs
@@ -41,6 +41,9 @@ public class DataManager : IAlgorithmSubscriptionManager, IDataFeedSubscriptionM
private readonly IRegisteredSecurityDataTypesProvider _registeredTypesProvider;
private readonly IDataPermissionManager _dataPermissionManager;
private List _subscriptionDataConfigsEnumerator;
+ private readonly IAlgorithm _algorithm;
+
+ private bool _unsupportedUniverseSettingsResolutionWarningSent;
/// There is no ConcurrentHashSet collection in .NET,
/// so we use ConcurrentDictionary with byte value to minimize memory usage
@@ -78,6 +81,7 @@ public DataManager(
_liveMode = liveMode;
_registeredTypesProvider = registeredTypesProvider;
_dataPermissionManager = dataPermissionManager;
+ _algorithm = algorithm;
// wire ourselves up to receive notifications when universes are added/removed
algorithm.UniverseManager.CollectionChanged += (sender, args) =>
@@ -597,6 +601,25 @@ public List Add(
if (!resolutionWasProvided)
{
var defaultResolution = baseInstance.DefaultResolution();
+ if (LeanData.IsCommonLeanDataType(typeTuple.Item1))
+ {
+ var res = _algorithm.UniverseSettings.Resolution;
+
+ if (!_liveMode && !baseInstance.SupportedResolutions().Contains(res))
+ {
+ if (!_unsupportedUniverseSettingsResolutionWarningSent)
+ {
+ _algorithm.Log($"Warning: Resolution {_algorithm.UniverseSettings.Resolution} for {symbol} and type {typeTuple.Item1} is not supported. " +
+ $"The data type default resolution '{defaultResolution}' will be used instead");
+ _unsupportedUniverseSettingsResolutionWarningSent = true;
+ }
+ }
+ else
+ {
+ defaultResolution = res;
+ }
+ }
+
if (resolution.HasValue && resolution != defaultResolution)
{
// we are here because there are multiple 'dataTypes'.
diff --git a/Tests/Common/Data/Fundamental/FundamentalUniverseSelectionModelTests.cs b/Tests/Common/Data/Fundamental/FundamentalUniverseSelectionModelTests.cs
index c69adc811762..ac81b133b086 100644
--- a/Tests/Common/Data/Fundamental/FundamentalUniverseSelectionModelTests.cs
+++ b/Tests/Common/Data/Fundamental/FundamentalUniverseSelectionModelTests.cs
@@ -27,30 +27,30 @@ public void PythonAlgorithmUsingCSharpSelection()
{
var parameter = new RegressionTests.AlgorithmStatisticsTestParameters("FundamentalUniverseSelectionAlgorithm",
new Dictionary {
- {PerformanceMetrics.TotalOrders, "2"},
+ {PerformanceMetrics.TotalOrders, "3"},
{"Average Win", "0%"},
{"Average Loss", "0%"},
- {"Compounding Annual Return", "-2.391%"},
+ {"Compounding Annual Return", "-3.123%"},
{"Drawdown", "0.100%"},
{"Expectancy", "0"},
- {"Net Profit", "-0.093%"},
- {"Sharpe Ratio", "-6.659"},
- {"Probabilistic Sharpe Ratio", "9.792%"},
+ {"Net Profit", "-0.122%"},
+ {"Sharpe Ratio", "-5.568"},
+ {"Probabilistic Sharpe Ratio", "11.594%"},
{"Loss Rate", "0%"},
{"Win Rate", "0%"},
{"Profit-Loss Ratio", "0"},
- {"Alpha", "-0.02"},
- {"Beta", "0.028"},
- {"Annual Standard Deviation", "0.004"},
+ {"Alpha", "-0.022"},
+ {"Beta", "0.048"},
+ {"Annual Standard Deviation", "0.006"},
{"Annual Variance", "0"},
- {"Information Ratio", "1.733"},
- {"Tracking Error", "0.095"},
- {"Treynor Ratio", "-0.914"},
- {"Total Fees", "$2.00"},
+ {"Information Ratio", "1.712"},
+ {"Tracking Error", "0.093"},
+ {"Treynor Ratio", "-0.636"},
+ {"Total Fees", "$3.00"},
{"Estimated Strategy Capacity", "$2300000000.00"},
{"Lowest Capacity Asset", "IBM R735QTJ8XC9X"},
- {"Portfolio Turnover", "0.28%"},
- {"OrderListHash", "b1cac6a779b73bde09a895c7cc970082"}
+ {"Portfolio Turnover", "0.42%"},
+ {"OrderListHash", "9bd2017fdcf8f503e86dfa3bf6e33520"}
},
Language.Python,
AlgorithmStatus.Completed);