diff --git a/Algorithm.CSharp/IndicatorHistoryRegressionAlgorithm.cs b/Algorithm.CSharp/IndicatorHistoryRegressionAlgorithm.cs
new file mode 100644
index 000000000000..7026316beba3
--- /dev/null
+++ b/Algorithm.CSharp/IndicatorHistoryRegressionAlgorithm.cs
@@ -0,0 +1,149 @@
+/*
+ * 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.Indicators;
+using QuantConnect.Interfaces;
+
+namespace QuantConnect.Algorithm.CSharp
+{
+ ///
+ /// Regression algorithm asserting the behavior of the indicator history api
+ ///
+ public class IndicatorHistoryRegressionAlgorithm : QCAlgorithm, IRegressionAlgorithmDefinition
+ {
+ private Symbol _symbol;
+
+ ///
+ /// Initialize the data and resolution you require for your strategy
+ ///
+ public override void Initialize()
+ {
+ SetStartDate(2013, 1, 1);
+ SetEndDate(2014, 12, 31);
+
+ _symbol = AddEquity("SPY", Resolution.Daily).Symbol;
+ }
+
+ public void OnData(Slice slice)
+ {
+ var bollingerBands = new BollingerBands("BB", 20, 2.0m, MovingAverageType.Simple);
+
+ if (bollingerBands.Window.IsReady)
+ {
+ throw new RegressionTestException("Unexpected ready bollinger bands state");
+ }
+
+ var indicatorHistory = IndicatorHistory(bollingerBands, _symbol, 50);
+
+ if (!bollingerBands.Window.IsReady)
+ {
+ throw new RegressionTestException("Unexpected not ready bollinger bands state");
+ }
+
+ // we ask for 50 data points
+ if (indicatorHistory.Count != 50)
+ {
+ throw new RegressionTestException($"Unexpected indicators values {indicatorHistory.Count}");
+ }
+
+ foreach (var indicatorDataPoints in indicatorHistory)
+ {
+ var upperBand = ((dynamic)indicatorDataPoints).UpperBand;
+ Debug($"BB @{indicatorDataPoints.Current}: middleband: {indicatorDataPoints["middleband"]} upperBand {upperBand}");
+
+ if (indicatorDataPoints == 0)
+ {
+ throw new RegressionTestException($"Unexpected indicators point {indicatorDataPoints}");
+ }
+ }
+
+ var currentValues = indicatorHistory.Current;
+ if (currentValues.Count != 50 || currentValues.Any(x => x.Value == 0))
+ {
+ throw new RegressionTestException($"Unexpected indicators current values {currentValues.Count}");
+ }
+ var upperBandPoints = indicatorHistory["UpperBand"];
+ if (upperBandPoints.Count != 50 || upperBandPoints.Any(x => x.Value == 0))
+ {
+ throw new RegressionTestException($"Unexpected indicators upperBandPoints values {upperBandPoints.Count}");
+ }
+
+ // We are done now!
+ Quit();
+ }
+
+ ///
+ /// 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, Language.Python };
+
+ ///
+ /// Data Points count of all timeslices of algorithm
+ ///
+ public long DataPoints => 9;
+
+ ///
+ /// Data Points count of the algorithm history
+ ///
+ public int AlgorithmHistoryDataPoints => 70;
+
+ ///
+ /// 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", "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%"},
+ {"OrderListHash", "d41d8cd98f00b204e9800998ecf8427e"}
+ };
+ }
+}
diff --git a/Algorithm.Python/IndicatorHistoryRegressionAlgorithm.py b/Algorithm.Python/IndicatorHistoryRegressionAlgorithm.py
new file mode 100644
index 000000000000..36a8a9175bbc
--- /dev/null
+++ b/Algorithm.Python/IndicatorHistoryRegressionAlgorithm.py
@@ -0,0 +1,62 @@
+# 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 asserting the behavior of the indicator history api
+###
+class IndicatorHistoryRegressionAlgorithm(QCAlgorithm):
+ '''Regression algorithm asserting the behavior of the indicator history api'''
+
+ def initialize(self):
+ '''Initialise the data and resolution required, as well as the cash and start-end dates for your algorithm. All algorithms must initialized.'''
+ self.set_start_date(2013, 1, 1)
+ self.set_end_date(2014, 12, 31)
+
+ self._symbol = self.add_equity("SPY", Resolution.DAILY).symbol
+
+ def on_data(self, slice: Slice):
+ self.bollinger_bands = BollingerBands("BB", 20, 2.0, MovingAverageType.SIMPLE)
+
+ if self.bollinger_bands.window.is_ready:
+ raise ValueError("Unexpected ready bollinger bands state")
+
+ indicatorHistory = self.indicator_history(self.bollinger_bands, self._symbol, 50)
+
+ self.debug(f"indicatorHistory: {indicatorHistory}")
+
+ self.debug(f"data_frame: {indicatorHistory.data_frame}")
+
+ if not self.bollinger_bands.window.is_ready:
+ raise ValueError("Unexpected not ready bollinger bands state")
+
+ # we ask for 50 data points
+ if indicatorHistory.count != 50:
+ raise ValueError(f"Unexpected indicators values {indicatorHistory.count}")
+
+ for indicatorDataPoints in indicatorHistory:
+ middle_band = indicatorDataPoints["middle_band"]
+ self.debug(f"BB @{indicatorDataPoints.current}: middle_band: {middle_band} upper_band: {indicatorDataPoints.upper_band}")
+ if indicatorDataPoints == 0:
+ raise ValueError(f"Unexpected indicators point {indicatorDataPoints}")
+
+ currentValues = indicatorHistory.current
+ if len(currentValues) != 50 or len([x for x in currentValues if x.value == 0]) > 0:
+ raise ValueError(f"Unexpected indicators current values {len(currentValues)}")
+ upperBandPoints = indicatorHistory["upper_band"]
+ if len(upperBandPoints) != 50 or len([x for x in upperBandPoints if x.value == 0]) > 0:
+ raise ValueError(f"Unexpected indicators upperBandPoints values {len(upperBandPoints)}")
+
+ # We are done now!
+ self.quit()
diff --git a/Algorithm/QCAlgorithm.Indicators.cs b/Algorithm/QCAlgorithm.Indicators.cs
index d8721edf5449..d7356bee197b 100644
--- a/Algorithm/QCAlgorithm.Indicators.cs
+++ b/Algorithm/QCAlgorithm.Indicators.cs
@@ -3294,9 +3294,9 @@ public IDataConsolidator Consolidate(Symbol symbol, FuncThe resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
{
- return Indicator(indicator, new[] { symbol }, period, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, period, resolution, selector);
}
///
@@ -3309,10 +3309,11 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null)
{
- var history = History(symbols, period, resolution);
- return Indicator(indicator, history, selector);
+ var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0;
+ var history = History(symbols, period + warmupPeriod, resolution);
+ return IndicatorHistory(indicator, history, selector);
}
///
@@ -3325,10 +3326,10 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- return Indicator(indicator, new[] { symbol }, period, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, period, resolution, selector);
}
///
@@ -3341,11 +3342,12 @@ public DataHistory Indicator(IndicatorBase indicator, Sym
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- var history = History(symbols, period, resolution);
- return Indicator(indicator, history, selector);
+ var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0;
+ var history = History(symbols, period + warmupPeriod, resolution);
+ return IndicatorHistory(indicator, history, selector);
}
///
@@ -3358,9 +3360,9 @@ public DataHistory Indicator(IndicatorBase indicator, IEn
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
{
- return Indicator(indicator, new[] { symbol }, span, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, span, resolution, selector);
}
///
@@ -3373,10 +3375,9 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null)
{
- var history = History(symbols, span, resolution);
- return Indicator(indicator, history, selector);
+ return IndicatorHistory(indicator, symbols, Time - span, Time, resolution, selector);
}
///
@@ -3389,11 +3390,10 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- var history = History(symbols, span, resolution);
- return Indicator(indicator, history, selector);
+ return IndicatorHistory(indicator, symbols, Time - span, Time, resolution, selector);
}
///
@@ -3406,10 +3406,10 @@ public DataHistory Indicator(IndicatorBase indicator, IEn
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- return Indicator(indicator, new[] { symbol }, span, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, span, resolution, selector);
}
///
@@ -3423,10 +3423,10 @@ public DataHistory Indicator(IndicatorBase indicator, Sym
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
{
- var history = History(symbols, start, end, resolution);
- return Indicator(indicator, history, selector);
+ var history = History(symbols, GetIndicatorAdjustedHistoryStart(indicator, symbols, start, end, resolution), end, resolution);
+ return IndicatorHistory(indicator, history, selector);
}
///
@@ -3440,9 +3440,9 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
{
- return Indicator(indicator, new[] { symbol }, start, end, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, start, end, resolution, selector);
}
///
@@ -3456,10 +3456,10 @@ public DataHistory Indicator(IndicatorBase
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- return Indicator(indicator, new[] { symbol }, start, end, resolution, selector);
+ return IndicatorHistory(indicator, new[] { symbol }, start, end, resolution, selector);
}
///
@@ -3473,11 +3473,11 @@ public DataHistory Indicator(IndicatorBase indicator, Sym
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of a bar indicator
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
where T : IBaseData
{
- var history = History(symbols, start, end, resolution);
- return Indicator(indicator, history, selector);
+ var history = History(symbols, GetIndicatorAdjustedHistoryStart(indicator, symbols, start, end, resolution), end, resolution);
+ return IndicatorHistory(indicator, history, selector);
}
///
@@ -3487,10 +3487,10 @@ public DataHistory Indicator(IndicatorBase indicator, IEn
/// Historical data used to calculate the indicator
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame containing the historical data of
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable history, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Func selector = null)
{
selector ??= (x => x.Value);
- return Indicator(indicator, history, (bar) => indicator.Update(bar.EndTime, selector(bar)));
+ return IndicatorHistory(indicator, history, (bar) => indicator.Update(bar.EndTime, selector(bar)));
}
///
@@ -3500,11 +3500,11 @@ public DataHistory Indicator(IndicatorBase
/// Historical data used to calculate the indicator
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame containing the historical data of
- public DataHistory Indicator(IndicatorBase indicator, IEnumerable history, Func selector = null)
+ public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Func selector = null)
where T : IBaseData
{
selector ??= (x => (T)x);
- return Indicator(indicator, history, (bar) => indicator.Update(selector(bar)));
+ return IndicatorHistory(indicator, history, (bar) => indicator.Update(selector(bar)));
}
///
@@ -3635,20 +3635,38 @@ private void RegisterConsolidator(IndicatorBase indicatorBase, Symbol symbol, ID
SubscriptionManager.AddConsolidator(symbol, consolidator);
}
- private DataHistory Indicator(IndicatorBase indicator, IEnumerable history, Action updateIndicator)
+ private DateTime GetIndicatorAdjustedHistoryStart(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null)
+ {
+ var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0;
+ if (warmupPeriod != 0)
+ {
+ foreach (var request in CreateDateRangeHistoryRequests(symbols, start, end, resolution))
+ {
+ var adjustedStart = _historyRequestFactory.GetStartTimeAlgoTz(request.StartTimeUtc, request.Symbol, warmupPeriod, request.Resolution,
+ request.ExchangeHours, request.DataTimeZone, request.IncludeExtendedMarketHours);
+ if (adjustedStart < start)
+ {
+ start = adjustedStart;
+ }
+ }
+ }
+ return start;
+ }
+
+ private IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Action updateIndicator)
{
// Reset the indicator
indicator.Reset();
var indicatorType = indicator.GetType();
// Create a dictionary of the indicator properties & the indicator value itself
- var name = indicatorType.Name;
- var indicatorValues = indicatorType.GetProperties()
+ var indicatorsDataPointPerProperty = indicatorType.GetProperties()
.Where(x => x.PropertyType.IsGenericType && x.Name != "Consolidators" && x.Name != "Window")
- .Select(x => IndicatorValues.Create(indicator, x))
- .Concat(new[] { IndicatorValues.Create(indicator, name) })
+ .Select(x => InternalIndicatorValues.Create(indicator, x))
+ .Concat(new[] { InternalIndicatorValues.Create(indicator, "Current") })
.ToList();
+ var indicatorsDataPointsByTime = new List();
IndicatorDataPoint lastPoint = null;
void consumeLastPoint()
{
@@ -3657,9 +3675,12 @@ void consumeLastPoint()
return;
}
- for (var i = 0; i < indicatorValues.Count; i++)
+ var IndicatorDataPoints = new IndicatorDataPoints { Time = lastPoint.Time, EndTime = lastPoint.EndTime };
+ indicatorsDataPointsByTime.Add(IndicatorDataPoints);
+ for (var i = 0; i < indicatorsDataPointPerProperty.Count; i++)
{
- indicatorValues[i].UpdateValue(lastPoint);
+ var newPoint = indicatorsDataPointPerProperty[i].UpdateValue();
+ IndicatorDataPoints.SetProperty(indicatorsDataPointPerProperty[i].Name, newPoint);
}
lastPoint = null;
}
@@ -3687,8 +3708,8 @@ void consumeLastPoint()
history.PushThrough(bar => updateIndicator(bar));
indicator.Updated -= callback;
- return new DataHistory(indicatorValues,
- new Lazy(() => PandasConverter.GetIndicatorDataFrame(indicatorValues.Select(x => new KeyValuePair>(x.Name, x.Values)))));
+ return new IndicatorHistory(indicatorsDataPointsByTime, indicatorsDataPointPerProperty,
+ new Lazy(() => PandasConverter.GetIndicatorDataFrame(indicatorsDataPointPerProperty.Select(x => new KeyValuePair>(x.Name, x.Values)))));
}
}
}
diff --git a/Algorithm/QCAlgorithm.Python.cs b/Algorithm/QCAlgorithm.Python.cs
index 1d89b67f8528..f47cd6ad80bb 100644
--- a/Algorithm/QCAlgorithm.Python.cs
+++ b/Algorithm/QCAlgorithm.Python.cs
@@ -1489,22 +1489,22 @@ public IDataConsolidator Consolidate(Symbol symbol, Func
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(PyObject indicator, PyObject symbol, int period, Resolution? resolution = null, PyObject selector = null)
+ public IndicatorHistory IndicatorHistory(PyObject indicator, PyObject symbol, int period, Resolution? resolution = null, PyObject selector = null)
{
var symbols = symbol.ConvertToSymbolEnumerable();
if (indicator.TryConvert(out IndicatorBase indicatorDataPoint))
{
- return Indicator(indicatorDataPoint, symbols, period, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorDataPoint, symbols, period, resolution, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorBar))
{
- return Indicator(indicatorBar, symbols, period, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorBar, symbols, period, resolution, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorTradeBar))
{
- return Indicator(indicatorTradeBar, symbols, period, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorTradeBar, symbols, period, resolution, selector?.ConvertToDelegate>());
}
- return Indicator(WrapPythonIndicator(indicator), symbols, period, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(WrapPythonIndicator(indicator), symbols, period, resolution, selector?.ConvertToDelegate>());
}
///
@@ -1517,22 +1517,9 @@ public DataHistory Indicator(PyObject indicator, PyObject symbo
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(PyObject indicator, PyObject symbol, TimeSpan span, Resolution? resolution = null, PyObject selector = null)
+ public IndicatorHistory IndicatorHistory(PyObject indicator, PyObject symbol, TimeSpan span, Resolution? resolution = null, PyObject selector = null)
{
- var symbols = symbol.ConvertToSymbolEnumerable();
- if (indicator.TryConvert(out IndicatorBase indicatorDataPoint))
- {
- return Indicator(indicatorDataPoint, symbols, span, resolution, selector?.ConvertToDelegate>());
- }
- else if (indicator.TryConvert(out IndicatorBase indicatorBar))
- {
- return Indicator(indicatorBar, symbols, span, resolution, selector?.ConvertToDelegate>());
- }
- else if (indicator.TryConvert(out IndicatorBase indicatorTradeBar))
- {
- return Indicator(indicatorTradeBar, symbols, span, resolution, selector?.ConvertToDelegate>());
- }
- return Indicator(WrapPythonIndicator(indicator), symbols, span, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicator, symbol, Time - span, Time, resolution, selector);
}
///
@@ -1546,22 +1533,22 @@ public DataHistory Indicator(PyObject indicator, PyObject symbo
/// The resolution to request
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame of historical data of an indicator
- public DataHistory Indicator(PyObject indicator, PyObject symbol, DateTime start, DateTime end, Resolution? resolution = null, PyObject selector = null)
+ public IndicatorHistory IndicatorHistory(PyObject indicator, PyObject symbol, DateTime start, DateTime end, Resolution? resolution = null, PyObject selector = null)
{
var symbols = symbol.ConvertToSymbolEnumerable();
if (indicator.TryConvert(out IndicatorBase indicatorDataPoint))
{
- return Indicator(indicatorDataPoint, symbols, start, end, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorDataPoint, symbols, start, end, resolution, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorBar))
{
- return Indicator(indicatorBar, symbols, start, end, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorBar, symbols, start, end, resolution, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorTradeBar))
{
- return Indicator(indicatorTradeBar, symbols, start, end, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorTradeBar, symbols, start, end, resolution, selector?.ConvertToDelegate>());
}
- return Indicator(WrapPythonIndicator(indicator), symbols, start, end, resolution, selector?.ConvertToDelegate>());
+ return IndicatorHistory(WrapPythonIndicator(indicator), symbols, start, end, resolution, selector?.ConvertToDelegate>());
}
///
@@ -1571,21 +1558,21 @@ public DataHistory Indicator(PyObject indicator, PyObject symbo
/// Historical data used to calculate the indicator
/// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
/// pandas.DataFrame containing the historical data of
- public DataHistory Indicator(PyObject indicator, IEnumerable history, PyObject selector = null)
+ public IndicatorHistory IndicatorHistory(PyObject indicator, IEnumerable history, PyObject selector = null)
{
if (indicator.TryConvert(out IndicatorBase indicatorDataPoint))
{
- return Indicator(indicatorDataPoint, history, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorDataPoint, history, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorBar))
{
- return Indicator(indicatorBar, history, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorBar, history, selector?.ConvertToDelegate>());
}
else if (indicator.TryConvert(out IndicatorBase indicatorTradeBar))
{
- return Indicator(indicatorTradeBar, history, selector?.ConvertToDelegate>());
+ return IndicatorHistory(indicatorTradeBar, history, selector?.ConvertToDelegate>());
}
- return Indicator(WrapPythonIndicator(indicator), history, selector?.ConvertToDelegate>());
+ return IndicatorHistory(WrapPythonIndicator(indicator), history, selector?.ConvertToDelegate>());
}
///
diff --git a/Common/Data/DynamicData.cs b/Common/Data/DynamicData.cs
index 407cb962f73e..bc2ed9c68ff1 100644
--- a/Common/Data/DynamicData.cs
+++ b/Common/Data/DynamicData.cs
@@ -32,6 +32,7 @@ public abstract class DynamicData : BaseData, IDynamicMetaObjectProvider
private static readonly MethodInfo SetPropertyMethodInfo = typeof(DynamicData).GetMethod("SetProperty");
private static readonly MethodInfo GetPropertyMethodInfo = typeof(DynamicData).GetMethod("GetProperty");
+ private readonly IDictionary _snakeNameStorage = new Dictionary();
private readonly IDictionary _storage = new Dictionary();
///
@@ -50,6 +51,8 @@ public DynamicMetaObject GetMetaObject(Expression parameter)
/// Returns the input value back to the caller
public object SetProperty(string name, object value)
{
+ // let's be polite and support snake name access for the given object value too
+ var snakeName = name.ToSnakeCase();
name = name.LazyToLower();
if (name == "time")
@@ -105,6 +108,10 @@ public object SetProperty(string name, object value)
}
_storage[name] = value;
+ if (snakeName != name)
+ {
+ _snakeNameStorage[snakeName] = value;
+ }
return value;
}
@@ -140,7 +147,7 @@ public object GetProperty(string name)
}
object value;
- if (!_storage.TryGetValue(name, out value))
+ if (!_storage.TryGetValue(name, out value) && !_snakeNameStorage.TryGetValue(name, out value))
{
// let the user know the property name that we couldn't find
throw new KeyNotFoundException(
diff --git a/Common/Data/HistoryRequestFactory.cs b/Common/Data/HistoryRequestFactory.cs
index 1c2dbafc62f2..e43ae007d8e7 100644
--- a/Common/Data/HistoryRequestFactory.cs
+++ b/Common/Data/HistoryRequestFactory.cs
@@ -114,10 +114,34 @@ public HistoryRequest CreateHistoryRequest(SubscriptionDataConfig subscription,
return request;
}
+ ///
+ /// Gets the start time required for the specified bar count in terms of the algorithm's time zone
+ ///
+ /// The symbol to select proper config
+ /// The number of bars requested
+ /// The length of each bar
+ /// The exchange hours used for market open hours
+ /// The time zone in which data are stored
+ ///
+ /// True to include extended market hours data, false otherwise.
+ /// If not passed, the config will be used to determined whether to include extended market hours.
+ ///
+ /// The start time that would provide the specified number of bars ending at the algorithm's current time
+ public DateTime GetStartTimeAlgoTz(
+ Symbol symbol,
+ int periods,
+ Resolution resolution,
+ SecurityExchangeHours exchange,
+ DateTimeZone dataTimeZone,
+ bool? extendedMarketHours = null)
+ {
+ return GetStartTimeAlgoTz(_algorithm.UtcTime, symbol, periods, resolution, exchange, dataTimeZone, extendedMarketHours);
+ }
///
/// Gets the start time required for the specified bar count in terms of the algorithm's time zone
///
+ /// The end time in utc
/// The symbol to select proper config
/// The number of bars requested
/// The length of each bar
@@ -129,6 +153,7 @@ public HistoryRequest CreateHistoryRequest(SubscriptionDataConfig subscription,
///
/// The start time that would provide the specified number of bars ending at the algorithm's current time
public DateTime GetStartTimeAlgoTz(
+ DateTime referenceUtcTime,
Symbol symbol,
int periods,
Resolution resolution,
@@ -159,7 +184,7 @@ public DateTime GetStartTimeAlgoTz(
var localStartTime = Time.GetStartTimeForTradeBars(
exchange,
- _algorithm.UtcTime.ConvertFromUtc(exchange.TimeZone),
+ referenceUtcTime.ConvertFromUtc(exchange.TimeZone),
timeSpan,
periods,
isExtendedMarketHours,
diff --git a/Common/Data/IndicatorHistory.cs b/Common/Data/IndicatorHistory.cs
new file mode 100644
index 000000000000..9d7002cfa5b5
--- /dev/null
+++ b/Common/Data/IndicatorHistory.cs
@@ -0,0 +1,64 @@
+/*
+ * 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 Python.Runtime;
+using QuantConnect.Indicators;
+using System.Collections.Generic;
+
+namespace QuantConnect.Data
+{
+ ///
+ /// Provides historical values of an indicator
+ ///
+ public class IndicatorHistory : DataHistory
+ {
+ private readonly Dictionary> _pointsPerName;
+
+ ///
+ /// The indicators historical values
+ ///
+ public List Current => this["current"];
+
+ ///
+ /// Creates a new instance
+ ///
+ /// Indicators data points by time
+ /// Indicators data points by property name
+ /// The lazy data frame constructor
+ public IndicatorHistory(List indicatorsDataPointsByTime, List indicatorsDataPointPerProperty, Lazy dataframe)
+ : base(indicatorsDataPointsByTime, dataframe)
+ {
+ // for the index accessor we enforce uniqueness by name
+ _pointsPerName = indicatorsDataPointPerProperty.DistinctBy(x => x.Name.ToLowerInvariant()).ToDictionary(x => x.Name.ToSnakeCase(), x => x.Values);
+ }
+
+ ///
+ /// Access the historical indicator values per indicator property name
+ ///
+ public List this[string name]
+ {
+ get
+ {
+ if (_pointsPerName.TryGetValue(name.ToSnakeCase().ToLowerInvariant(), out var result))
+ {
+ return result;
+ }
+ return null;
+ }
+ }
+ }
+}
diff --git a/Common/Indicators/InternalIndicatorValues.cs b/Common/Indicators/InternalIndicatorValues.cs
new file mode 100644
index 000000000000..2a219ce92a09
--- /dev/null
+++ b/Common/Indicators/InternalIndicatorValues.cs
@@ -0,0 +1,173 @@
+/*
+ * 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.Linq;
+using System.Reflection;
+using QuantConnect.Data;
+using System.Collections;
+using System.Collections.Generic;
+
+namespace QuantConnect.Indicators
+{
+ ///
+ /// Collection of indicator data points for a given time
+ ///
+ public class IndicatorDataPoints : DynamicData
+ {
+ ///
+ /// The indicator value at a given point
+ ///
+ public IndicatorDataPoint Current => (IndicatorDataPoint)GetProperty("Current");
+
+ ///
+ /// The indicator value at a given point
+ ///
+ public override decimal Value => Current.Value;
+
+ ///
+ /// Access the historical indicator values per indicator property name
+ ///
+ public IndicatorDataPoint this[string name]
+ {
+ get
+ {
+ return GetProperty(name) as IndicatorDataPoint;
+ }
+ }
+
+ ///
+ /// String representation
+ ///
+ public override string ToString()
+ {
+ return $"{EndTime} {string.Join(", ", GetStorageDictionary().OrderBy(x => x.Key).Select(x => $"{x.Key}: {HandleObjectStorage(x.Value)}"))}";
+ }
+
+ ///
+ /// Returns the current data value held within the instance
+ ///
+ /// The DataPoint instance
+ /// The current data value held within the instance
+ public static implicit operator decimal(IndicatorDataPoints instance)
+ {
+ return instance.Value;
+ }
+
+ private static string HandleObjectStorage(object storedObject)
+ {
+ if (storedObject is IndicatorDataPoint point)
+ {
+ return point.Value.SmartRounding().ToStringInvariant();
+ }
+ return storedObject?.ToString() ?? string.Empty;
+ }
+ }
+
+ ///
+ /// Internal carrier of an indicator values by property name
+ ///
+ public class InternalIndicatorValues : IEnumerable
+ {
+ ///
+ /// The name of the values associated to this dto
+ ///
+ public string Name { get; }
+
+ ///
+ /// The indicator values
+ ///
+ public List Values { get; }
+
+ ///
+ /// The target indicator
+ ///
+ protected IIndicator Indicator { get; }
+
+ ///
+ /// Creates a new instance
+ ///
+ public InternalIndicatorValues(IIndicator indicator, string name)
+ {
+ Name = name;
+ Values = new();
+ Indicator = indicator;
+ }
+
+ ///
+ /// Update with a new indicator point
+ ///
+ public virtual IndicatorDataPoint UpdateValue()
+ {
+ Values.Add(Indicator.Current);
+ return Indicator.Current;
+ }
+
+ ///
+ /// Creates a new instance
+ ///
+ public static InternalIndicatorValues Create(IIndicator indicator, string name)
+ {
+ return new InternalIndicatorValues(indicator, name);
+ }
+
+ ///
+ /// Creates a new instance
+ ///
+ public static InternalIndicatorValues Create(IIndicator indicator, PropertyInfo propertyInfo)
+ {
+ return new IndicatorPropertyValues(indicator, propertyInfo);
+ }
+
+ ///
+ /// String representation
+ ///
+ public override string ToString()
+ {
+ return $"{Name} {Values.Count} indicator values";
+ }
+
+ public IEnumerator GetEnumerator()
+ {
+ return ((IEnumerable)Values).GetEnumerator();
+ }
+
+ IEnumerator IEnumerable.GetEnumerator()
+ {
+ return ((IEnumerable)Values).GetEnumerator();
+ }
+
+ private class IndicatorPropertyValues : InternalIndicatorValues
+ {
+ private readonly PropertyInfo _currentInfo;
+ private readonly PropertyInfo _propertyInfo;
+ public IndicatorPropertyValues(IIndicator indicator, PropertyInfo propertyInfo) : base(indicator, propertyInfo.Name)
+ {
+ _propertyInfo = propertyInfo;
+ _currentInfo = _propertyInfo.PropertyType.GetProperty("Current");
+ }
+ public override IndicatorDataPoint UpdateValue()
+ {
+ var value = _propertyInfo.GetValue(Indicator);
+ if (_currentInfo != null)
+ {
+ value = _currentInfo.GetValue(value);
+ }
+ var point = value as IndicatorDataPoint;
+ Values.Add(point);
+ return point;
+ }
+ }
+ }
+}
diff --git a/Indicators/IndicatorValues.cs b/Indicators/IndicatorValues.cs
deleted file mode 100644
index 1106019f04be..000000000000
--- a/Indicators/IndicatorValues.cs
+++ /dev/null
@@ -1,114 +0,0 @@
-/*
- * 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.Reflection;
-using System.Collections;
-using System.Collections.Generic;
-
-namespace QuantConnect.Indicators
-{
- ///
- /// Carrier of an indicator values
- ///
- public class IndicatorValues : IEnumerable
- {
- ///
- /// The name of the values associated to this dto
- ///
- public string Name { get; }
-
- ///
- /// The indicator values
- ///
- public List Values { get; }
-
- ///
- /// The target indicator
- ///
- protected IndicatorBase Indicator { get; }
-
- ///
- /// Creates a new instance
- ///
- public IndicatorValues(IndicatorBase indicator, string name)
- {
- Name = name;
- Values = new();
- Indicator = indicator;
- }
-
- ///
- /// Update with a new indicator point
- ///
- public virtual void UpdateValue(IndicatorDataPoint point)
- {
- Values.Add(point);
- }
-
- ///
- /// Creates a new instance
- ///
- public static IndicatorValues Create(IndicatorBase indicator, string name)
- {
- return new IndicatorValues(indicator, name);
- }
-
- ///
- /// Creates a new instance
- ///
- public static IndicatorValues Create(IndicatorBase indicator, PropertyInfo propertyInfo)
- {
- return new IndicatorPropertyValues(indicator, propertyInfo);
- }
-
- ///
- /// String representation
- ///
- public override string ToString()
- {
- return $"{Name} {Values.Count} indicator values";
- }
-
- public IEnumerator GetEnumerator()
- {
- return ((IEnumerable)Values).GetEnumerator();
- }
-
- IEnumerator IEnumerable.GetEnumerator()
- {
- return ((IEnumerable)Values).GetEnumerator();
- }
-
- private class IndicatorPropertyValues : IndicatorValues
- {
- private readonly PropertyInfo _currentInfo;
- private readonly PropertyInfo _propertyInfo;
- public IndicatorPropertyValues(IndicatorBase indicator, PropertyInfo propertyInfo) : base(indicator, propertyInfo.Name)
- {
- _propertyInfo = propertyInfo;
- _currentInfo = _propertyInfo.PropertyType.GetProperty("Current");
- }
- public override void UpdateValue(IndicatorDataPoint _)
- {
- var value = _propertyInfo.GetValue(Indicator);
- if (_currentInfo != null)
- {
- value = _currentInfo.GetValue(value);
- }
- Values.Add(value as IndicatorDataPoint);
- }
- }
- }
-}
diff --git a/Research/QuantBook.cs b/Research/QuantBook.cs
index bf7b9f708983..20e451fa5412 100644
--- a/Research/QuantBook.cs
+++ b/Research/QuantBook.cs
@@ -36,6 +36,7 @@
using System.Threading.Tasks;
using QuantConnect.Data.UniverseSelection;
using QuantConnect.Lean.Engine.Setup;
+using QuantConnect.Indicators;
namespace QuantConnect.Research
{
@@ -523,6 +524,159 @@ public FutureHistory GetFutureHistory(Symbol symbol, DateTime start, DateTime? e
return FutureHistory(symbol, start, end, resolution, fillForward, extendedMarketHours);
}
+ ///
+ /// Gets the historical data of an indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// The symbol to retrieve historical data for
+ /// The number of bars to request
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of an indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, period, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// The symbol to retrieve historical data for
+ /// The number of bars to request
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, period, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// The symbol to retrieve historical data for
+ /// The number of bars to request
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, period, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of an indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The span over which to retrieve recent historical data
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of an indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, span, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The span over which to retrieve recent historical data
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, span, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The span over which to retrieve recent historical data
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, span, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of an indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The start time in the algorithm's time zone
+ /// The end time in the algorithm's time zone
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of an indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, start, end, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The start time in the algorithm's time zone
+ /// The end time in the algorithm's time zone
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null)
+ {
+ var history = History(new[] { symbol }, start, end, resolution);
+ return IndicatorHistory(indicator, history, selector).DataFrame;
+ }
+
+ ///
+ /// Gets the historical data of a bar indicator for the specified symbol. The exact number of bars will be returned.
+ /// The symbol must exist in the Securities collection.
+ ///
+ /// Indicator
+ /// The symbol to retrieve historical data for
+ /// The start time in the algorithm's time zone
+ /// The end time in the algorithm's time zone
+ /// The resolution to request
+ /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value)
+ /// pandas.DataFrame of historical data of a bar indicator
+ [Obsolete("Please use the 'IndicatorHistory()', pandas dataframe available through '.DataFrame'")]
+ public PyObject Indicator(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func