/* * 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.Data; using QuantConnect.Data.Consolidators; using QuantConnect.Data.Market; using QuantConnect.Indicators; using System; using System.Collections.Generic; using System.Linq; using Python.Runtime; using QuantConnect.Util; using static QuantConnect.StringExtensions; using QuantConnect.Python; namespace QuantConnect.Algorithm { public partial class QCAlgorithm { private readonly List> _quoteRequiredFields = new() { Field.BidPrice, Field.AskPrice, Field.BidClose, Field.BidOpen, Field.BidLow, Field.BidHigh, Field.AskClose, Field.AskOpen, Field.AskLow, Field.AskHigh, }; private static readonly HashSet _ignoredProperties = new HashSet { "Consolidators", "Current", "Previous", "Name", "Samples", "IsReady", "Window", "Item", "WarmUpPeriod", "Period" }; /// /// Gets whether or not WarmUpIndicator is allowed to warm up indicators /// [Obsolete("Please use Settings.AutomaticIndicatorWarmUp")] public bool EnableAutomaticIndicatorWarmUp { get { return Settings.AutomaticIndicatorWarmUp; } set { Settings.AutomaticIndicatorWarmUp = value; } } /// /// Creates a new Acceleration Bands indicator. /// /// The symbol whose Acceleration Bands we want. /// The period of the three moving average (middle, upper and lower band). /// A coefficient specifying the distance between the middle band and upper or lower bands. /// Type of the moving average. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar. /// [DocumentationAttribute(Indicators)] public AccelerationBands ABANDS(Symbol symbol, int period, decimal width = 4, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ABANDS({period},{width})", resolution); var accelerationBands = new AccelerationBands(name, period, width, movingAverageType); InitializeIndicator(accelerationBands, resolution, selector, symbol); return accelerationBands; } /// /// Creates a new AccumulationDistribution indicator. /// /// The symbol whose AD we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The AccumulationDistribution indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AccumulationDistribution AD(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "AD", resolution); var accumulationDistribution = new AccumulationDistribution(name); InitializeIndicator(accumulationDistribution, resolution, selector, symbol); return accumulationDistribution; } /// /// Creates a new AccumulationDistributionOscillator indicator. /// /// The symbol whose ADOSC we want /// The fast moving average period /// The slow moving average period /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The AccumulationDistributionOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AccumulationDistributionOscillator ADOSC(Symbol symbol, int fastPeriod, int slowPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ADOSC({fastPeriod},{slowPeriod})", resolution); var accumulationDistributionOscillator = new AccumulationDistributionOscillator(name, fastPeriod, slowPeriod); InitializeIndicator(accumulationDistributionOscillator, resolution, selector, symbol); return accumulationDistributionOscillator; } /// /// Creates a Alpha indicator for the given target symbol in relation with the reference used. /// The indicator will be automatically updated on the given resolution. /// /// The target symbol whose Alpha value we want /// The reference symbol to compare with the target symbol /// The period of the Alpha indicator /// The period of the Beta indicator /// The resolution /// The risk free rate /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Alpha indicator for the given parameters [DocumentationAttribute(Indicators)] public Alpha A(Symbol target, Symbol reference, int alphaPeriod = 1, int betaPeriod = 252, Resolution? resolution = null, decimal? riskFreeRate = null, Func selector = null) { var baseBame = riskFreeRate.HasValue ? $"A({alphaPeriod},{betaPeriod},{riskFreeRate})" : $"A({alphaPeriod},{betaPeriod})"; var name = CreateIndicatorName(target, baseBame, resolution); // If risk free rate is not specified, use the default risk free rate model IRiskFreeInterestRateModel riskFreeRateModel = riskFreeRate.HasValue ? new ConstantRiskFreeRateInterestRateModel(riskFreeRate.Value) : new FuncRiskFreeRateInterestRateModel((datetime) => RiskFreeInterestRateModel.GetInterestRate(datetime)); var alpha = new Alpha(name, target, reference, alphaPeriod, betaPeriod, riskFreeRateModel); InitializeIndicator(alpha, resolution, selector, target, reference); return alpha; } /// /// Creates a new Average Range (AR) indicator. /// /// The symbol whose Average Range we want to calculate /// The period over which to compute the Average Range /// The resolution /// Selects a value from the BaseData to send into the indicator. If null, defaults to the Value property of BaseData (x => x.Value). /// The Average Range indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AverageRange AR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"AR({period})", resolution); var averageRange = new AverageRange(name, period); InitializeIndicator(averageRange, resolution, selector, symbol); return averageRange; } /// /// Creates a new ARIMA indicator. /// /// The symbol whose ARIMA indicator we want /// AR order (p) -- defines the number of past values to consider in the AR component of the model. /// Difference order (d) -- defines how many times to difference the model before fitting parameters. /// MA order (q) -- defines the number of past values to consider in the MA component of the model. /// Size of the rolling series to fit onto /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ARIMA indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AutoRegressiveIntegratedMovingAverage ARIMA(Symbol symbol, int arOrder, int diffOrder, int maOrder, int period, Resolution? resolution = null, Func selector = null) { return ARIMA(symbol, arOrder, diffOrder, maOrder, period, true, resolution, selector); } /// /// Creates a new ARIMA indicator. /// /// The symbol whose ARIMA indicator we want /// AR order (p) -- defines the number of past values to consider in the AR component of the model. /// Difference order (d) -- defines how many times to difference the model before fitting parameters. /// MA order (q) -- defines the number of past values to consider in the MA component of the model. /// Size of the rolling series to fit onto /// Whether or not to include the intercept term /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ARIMA indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AutoRegressiveIntegratedMovingAverage ARIMA(Symbol symbol, int arOrder, int diffOrder, int maOrder, int period, bool intercept, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ARIMA({arOrder},{diffOrder},{maOrder},{period})", resolution); var arimaIndicator = new AutoRegressiveIntegratedMovingAverage(name, arOrder, diffOrder, maOrder, period, intercept); InitializeIndicator(arimaIndicator, resolution, selector, symbol); return arimaIndicator; } /// /// Creates a new Average Directional Index indicator. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Average Directional Index we seek /// The resolution. /// The period over which to compute the Average Directional Index /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Average Directional Index indicator for the requested symbol. [DocumentationAttribute(Indicators)] public AverageDirectionalIndex ADX(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ADX({period})", resolution); var averageDirectionalIndex = new AverageDirectionalIndex(name, period); InitializeIndicator(averageDirectionalIndex, resolution, selector, symbol); return averageDirectionalIndex; } /// /// Creates a new Awesome Oscillator from the specified periods. /// /// The symbol whose Awesome Oscillator we seek /// The resolution. /// The period of the fast moving average associated with the AO /// The period of the slow moving average associated with the AO /// The type of moving average used when computing the fast and slow term. Defaults to simple moving average. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar [DocumentationAttribute(Indicators)] public AwesomeOscillator AO(Symbol symbol, int fastPeriod, int slowPeriod, MovingAverageType type, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"AO({fastPeriod},{slowPeriod},{type})", resolution); var awesomeOscillator = new AwesomeOscillator(name, fastPeriod, slowPeriod, type); InitializeIndicator(awesomeOscillator, resolution, selector, symbol); return awesomeOscillator; } /// /// Creates a new AverageDirectionalMovementIndexRating indicator. /// /// The symbol whose ADXR we want /// The period over which to compute the ADXR /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The AverageDirectionalMovementIndexRating indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AverageDirectionalMovementIndexRating ADXR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ADXR({period})", resolution); var averageDirectionalMovementIndexRating = new AverageDirectionalMovementIndexRating(name, period); InitializeIndicator(averageDirectionalMovementIndexRating, resolution, selector, symbol); return averageDirectionalMovementIndexRating; } /// /// Creates a new ArnaudLegouxMovingAverage indicator. /// /// The symbol whose ALMA we want /// int - the number of periods to calculate the ALMA /// int - this parameter is responsible for the shape of the curve coefficients. /// /// /// decimal - This parameter allows regulating the smoothness and high sensitivity of the /// Moving Average. The range for this parameter is [0, 1]. /// /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ArnaudLegouxMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ArnaudLegouxMovingAverage ALMA(Symbol symbol, int period, int sigma = 6, decimal offset = 0.85m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ALMA({period},{sigma},{offset})", resolution); var arnaudLegouxMovingAverage = new ArnaudLegouxMovingAverage(name, period, sigma, offset); InitializeIndicator(arnaudLegouxMovingAverage, resolution, selector, symbol); return arnaudLegouxMovingAverage; } /// /// Creates a new AbsolutePriceOscillator indicator. /// /// The symbol whose APO we want /// The fast moving average period /// The slow moving average period /// The type of moving average to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The AbsolutePriceOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AbsolutePriceOscillator APO(Symbol symbol, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"APO({fastPeriod},{slowPeriod})", resolution); var absolutePriceOscillator = new AbsolutePriceOscillator(name, fastPeriod, slowPeriod, movingAverageType); InitializeIndicator(absolutePriceOscillator, resolution, selector, symbol); return absolutePriceOscillator; } /// /// Creates a new AroonOscillator indicator which will compute the AroonUp and AroonDown (as well as the delta) /// /// The symbol whose Aroon we seek /// The look back period for computing number of periods since maximum and minimum /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// An AroonOscillator configured with the specified periods [DocumentationAttribute(Indicators)] public AroonOscillator AROON(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return AROON(symbol, period, period, resolution, selector); } /// /// Creates a new AroonOscillator indicator which will compute the AroonUp and AroonDown (as well as the delta) /// /// The symbol whose Aroon we seek /// The look back period for computing number of periods since maximum /// The look back period for computing number of periods since minimum /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// An AroonOscillator configured with the specified periods [DocumentationAttribute(Indicators)] public AroonOscillator AROON(Symbol symbol, int upPeriod, int downPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"AROON({upPeriod},{downPeriod})", resolution); var aroonOscillator = new AroonOscillator(name, upPeriod, downPeriod); InitializeIndicator(aroonOscillator, resolution, selector, symbol); return aroonOscillator; } /// /// Creates a new AverageTrueRange indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose ATR we want /// The smoothing period used to smooth the computed TrueRange values /// The type of smoothing to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new AverageTrueRange indicator with the specified smoothing type and period [DocumentationAttribute(Indicators)] public AverageTrueRange ATR(Symbol symbol, int period, MovingAverageType type = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ATR({period})", resolution); var averageTrueRange = new AverageTrueRange(name, period, type); InitializeIndicator(averageTrueRange, resolution, selector, symbol); return averageTrueRange; } /// /// Creates an AugenPriceSpike indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose APS we want /// The period of the APS /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The AugenPriceSpike indicator for the given parameters [DocumentationAttribute(Indicators)] public AugenPriceSpike APS(Symbol symbol, int period = 3, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"APS({period})", resolution); var augenPriceSpike = new AugenPriceSpike(name, period); InitializeIndicator(augenPriceSpike, resolution, selector, symbol); return augenPriceSpike; } /// /// Creates a new BollingerBands indicator which will compute the MiddleBand, UpperBand, LowerBand, and StandardDeviation /// /// The symbol whose BollingerBands we seek /// The period of the standard deviation and moving average (middle band) /// The number of standard deviations specifying the distance between the middle band and upper or lower bands /// The type of moving average to be used /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// A BollingerBands configured with the specified period [DocumentationAttribute(Indicators)] public BollingerBands BB(Symbol symbol, int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"BB({period},{k})", resolution); var bollingerBands = new BollingerBands(name, period, k, movingAverageType); InitializeIndicator(bollingerBands, resolution, selector, symbol); return bollingerBands; } /// /// Creates a Beta indicator for the given target symbol in relation with the reference used. /// The indicator will be automatically updated on the given resolution. /// /// The target symbol whose Beta value we want /// The reference symbol to compare with the target symbol /// The period of the Beta indicator /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Beta indicator for the given parameters [DocumentationAttribute(Indicators)] public Beta B(Symbol target, Symbol reference, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"B({period})", resolution); var beta = new Beta(name, target, reference, period); InitializeIndicator(beta, resolution, selector, target, reference); return beta; } /// /// Creates a new Balance Of Power indicator. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Balance Of Power we seek /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Balance Of Power indicator for the requested symbol. [DocumentationAttribute(Indicators)] public BalanceOfPower BOP(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "BOP", resolution); var balanceOfPower = new BalanceOfPower(name); InitializeIndicator(balanceOfPower, resolution, selector, symbol); return balanceOfPower; } /// /// Initializes a new instance of the indicator /// /// The symbol whose Coppock Curve we want /// The period for the short ROC /// The period for the long ROC /// The period for the LWMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Coppock Curve indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public CoppockCurve CC(Symbol symbol, int shortRocPeriod = 11, int longRocPeriod = 14, int lwmaPeriod = 10, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CC({shortRocPeriod},{longRocPeriod},{lwmaPeriod})", resolution); var coppockCurve = new CoppockCurve(name, shortRocPeriod, longRocPeriod, lwmaPeriod); InitializeIndicator(coppockCurve, resolution, selector, symbol); return coppockCurve; } /// /// Creates a Correlation indicator for the given target symbol in relation with the reference used. /// The indicator will be automatically updated on the given resolution. /// /// The target symbol of this indicator /// The reference symbol of this indicator /// The period of this indicator /// Correlation type /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Correlation indicator for the given parameters [DocumentationAttribute(Indicators)] public Correlation C(Symbol target, Symbol reference, int period, CorrelationType correlationType = CorrelationType.Pearson, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"C({period})", resolution); var correlation = new Correlation(name, target, reference, period, correlationType); InitializeIndicator(correlation, resolution, selector, target, reference); return correlation; } /// /// Creates a Covariance indicator for the given target symbol in relation with the reference used. /// The indicator will be automatically updated on the given resolution. /// /// The target symbol whose Covariance value we want /// The reference symbol to compare with the target symbol /// The period of the Covariance indicator /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Covariance indicator for the given parameters [DocumentationAttribute(Indicators)] public Covariance COV(Symbol target, Symbol reference, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"COV({period})", resolution); var covariance = new Covariance(name, target, reference, period); InitializeIndicator(covariance, resolution, selector, target, reference); return covariance; } /// /// Creates a new CommodityChannelIndex indicator. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose CCI we want /// The period over which to compute the CCI /// The type of moving average to use in computing the typical price average /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The CommodityChannelIndex indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public CommodityChannelIndex CCI(Symbol symbol, int period, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CCI({period})", resolution); var commodityChannelIndex = new CommodityChannelIndex(name, period, movingAverageType); InitializeIndicator(commodityChannelIndex, resolution, selector, symbol); return commodityChannelIndex; } /// /// Creates a new ChoppinessIndex indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose CHOP we want /// The input window period used to calculate max high and min low /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new ChoppinessIndex indicator with the window period [DocumentationAttribute(Indicators)] public ChoppinessIndex CHOP(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CHOP({period})", resolution); var indicator = new ChoppinessIndex(name, period); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new Chande Kroll Stop indicator which will compute the short and lower stop. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Chande Kroll Stop we seek. /// The period over which to compute the average true range. /// The ATR multiplier to be used to compute stops distance. /// The period over which to compute the max of high stop and min of low stop. /// The resolution. /// The type of smoothing used to smooth the true range values /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Chande Kroll Stop indicator for the requested symbol. [DocumentationAttribute(Indicators)] public ChandeKrollStop CKS(Symbol symbol, int atrPeriod, decimal atrMult, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CKS({atrPeriod},{atrMult},{period})", resolution); var indicator = new ChandeKrollStop(name, atrPeriod, atrMult, period, movingAverageType); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new ChaikinMoneyFlow indicator. /// /// The symbol whose CMF we want /// The period over which to compute the CMF /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The ChaikinMoneyFlow indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ChaikinMoneyFlow CMF(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CMF({period})", resolution); var chaikinMoneyFlow = new ChaikinMoneyFlow(name, period); InitializeIndicator(chaikinMoneyFlow, resolution, selector, symbol); return chaikinMoneyFlow; } /// /// Creates a new Chaikin Oscillator indicator. /// /// The symbol whose CO we want /// The fast moving average period /// The slow moving average period /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Chaikin Oscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ChaikinOscillator CO(Symbol symbol, int fastPeriod, int slowPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CO({fastPeriod},{slowPeriod})", resolution); var chaikinOscillator = new ChaikinOscillator(name, fastPeriod, slowPeriod); InitializeIndicator(chaikinOscillator, resolution, selector, symbol); return chaikinOscillator; } /// /// Creates a new ChandeMomentumOscillator indicator. /// /// The symbol whose CMO we want /// The period over which to compute the CMO /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ChandeMomentumOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ChandeMomentumOscillator CMO(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CMO({period})", resolution); var chandeMomentumOscillator = new ChandeMomentumOscillator(name, period); InitializeIndicator(chandeMomentumOscillator, resolution, selector, symbol); return chandeMomentumOscillator; } /// /// Creates a new Connors Relative Strength Index (CRSI) indicator, which combines the traditional Relative Strength Index (RSI), /// Streak RSI (SRSI), and Percent Rank to provide a more robust measure of market strength. /// This indicator oscillates based on momentum, streak behavior, and price change over the specified periods. /// /// The symbol whose CRSI is to be calculated. /// The period for the traditional RSI calculation. /// The period for the Streak RSI calculation (SRSI). /// The look-back period for calculating the Percent Rank. /// The resolution of the data (optional). /// Function to select a value from the BaseData to input into the indicator. Defaults to using the 'Value' property of BaseData if null. /// The Connors Relative Strength Index (CRSI) for the specified symbol and periods. [DocumentationAttribute(Indicators)] public ConnorsRelativeStrengthIndex CRSI(Symbol symbol, int rsiPeriod, int rsiPeriodStreak, int lookBackPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"CRSI({rsiPeriod},{rsiPeriodStreak},{lookBackPeriod})", resolution); var connorsRelativeStrengthIndex = new ConnorsRelativeStrengthIndex(name, rsiPeriod, rsiPeriodStreak, lookBackPeriod); InitializeIndicator(connorsRelativeStrengthIndex, resolution, selector, symbol); return connorsRelativeStrengthIndex; } /// /// Creates a new DeMarker Indicator (DEM), an oscillator-type indicator measuring changes in terms of an asset's /// High and Low tradebar values. /// /// The symbol whose DEM we seek. /// The period of the moving average implemented /// Specifies the type of moving average to be used /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The DeMarker indicator for the requested symbol. [DocumentationAttribute(Indicators)] public DeMarkerIndicator DEM(Symbol symbol, int period, MovingAverageType type, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"DEM({period},{type})", resolution); var deMarkerIndicator = new DeMarkerIndicator(name, period, type); InitializeIndicator(deMarkerIndicator, resolution, selector, symbol); return deMarkerIndicator; } /// /// Creates a new Donchian Channel indicator which will compute the Upper Band and Lower Band. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Donchian Channel we seek. /// The period over which to compute the upper Donchian Channel. /// The period over which to compute the lower Donchian Channel. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Donchian Channel indicator for the requested symbol. [DocumentationAttribute(Indicators)] public DonchianChannel DCH(Symbol symbol, int upperPeriod, int lowerPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"DCH({upperPeriod},{lowerPeriod})", resolution); var donchianChannel = new DonchianChannel(name, upperPeriod, lowerPeriod); InitializeIndicator(donchianChannel, resolution, selector, symbol); return donchianChannel; } /// /// Overload shorthand to create a new symmetric Donchian Channel indicator which /// has the upper and lower channels set to the same period length. /// /// The symbol whose Donchian Channel we seek. /// The period over which to compute the Donchian Channel. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a IBaseDataBar /// The Donchian Channel indicator for the requested symbol. [DocumentationAttribute(Indicators)] public DonchianChannel DCH(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return DCH(symbol, period, period, resolution, selector); } /// /// Creates a new Delta indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Delta /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Delta indicator for the specified symbol [DocumentationAttribute(Indicators)] public Delta D(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var delta = new Delta(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel); InitializeOptionIndicator(delta, resolution, symbol, mirrorOption); return delta; } /// /// Creates a new Delta indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Delta /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Delta indicator for the specified symbol [DocumentationAttribute(Indicators)] public Delta Δ(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { return D(symbol, mirrorOption, riskFreeRate, dividendYield, optionModel, ivModel, resolution); } /// /// Creates a new DoubleExponentialMovingAverage indicator. /// /// The symbol whose DEMA we want /// The period over which to compute the DEMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The DoubleExponentialMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public DoubleExponentialMovingAverage DEMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"DEMA({period})", resolution); var doubleExponentialMovingAverage = new DoubleExponentialMovingAverage(name, period); InitializeIndicator(doubleExponentialMovingAverage, resolution, selector, symbol); return doubleExponentialMovingAverage; } /// /// Creates a new DerivativeOscillator indicator. /// /// The symbol whose DO we want /// The period over which to compute the RSI /// The period over which to compute the smoothing RSI /// The period over which to compute the double smoothing RSI /// The period over which to compute the signal line /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The DerivativeOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public DerivativeOscillator DO(Symbol symbol, int rsiPeriod, int smoothingRsiPeriod, int doubleSmoothingRsiPeriod, int signalLinePeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"DO({rsiPeriod},{smoothingRsiPeriod},{doubleSmoothingRsiPeriod},{signalLinePeriod})", resolution); var derivativeOscillator = new DerivativeOscillator(name, rsiPeriod, smoothingRsiPeriod, doubleSmoothingRsiPeriod, signalLinePeriod); InitializeIndicator(derivativeOscillator, resolution, selector, symbol); return derivativeOscillator; } /// /// Creates a new indicator. /// /// The symbol whose DPO we want /// The period over which to compute the DPO /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// A new registered DetrendedPriceOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public DetrendedPriceOscillator DPO(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"DPO({period})", resolution); var detrendedPriceOscillator = new DetrendedPriceOscillator(name, period); InitializeIndicator(detrendedPriceOscillator, resolution, selector, symbol); return detrendedPriceOscillator; } /// /// Creates an ExponentialMovingAverage indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose EMA we want /// The period of the EMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ExponentialMovingAverage for the given parameters [DocumentationAttribute(Indicators)] public ExponentialMovingAverage EMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return EMA(symbol, period, ExponentialMovingAverage.SmoothingFactorDefault(period), resolution, selector); } /// /// Creates an ExponentialMovingAverage indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose EMA we want /// The period of the EMA /// The percentage of data from the previous value to be carried into the next value /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ExponentialMovingAverage for the given parameters [DocumentationAttribute(Indicators)] public ExponentialMovingAverage EMA(Symbol symbol, int period, decimal smoothingFactor, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"EMA({period})", resolution); var exponentialMovingAverage = new ExponentialMovingAverage(name, period, smoothingFactor); InitializeIndicator(exponentialMovingAverage, resolution, selector, symbol); return exponentialMovingAverage; } /// /// Creates an EaseOfMovementValue indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose EMV we want /// The period of the EMV /// The length of the outputed value /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The EaseOfMovementValue indicator for the given parameters [DocumentationAttribute(Indicators)] public EaseOfMovementValue EMV(Symbol symbol, int period = 1, int scale = 10000, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"EMV({period}, {scale})", resolution); var easeOfMovementValue = new EaseOfMovementValue(name, period, scale); InitializeIndicator(easeOfMovementValue, resolution, selector, symbol); return easeOfMovementValue; } /// /// Creates a new FilteredIdentity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// Filters the IBaseData send into the indicator, if null defaults to true (x => true) which means no filter /// The name of the field being selected /// A new FilteredIdentity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public FilteredIdentity FilteredIdentity(Symbol symbol, Func selector = null, Func filter = null, string fieldName = null) { var resolution = GetSubscription(symbol).Resolution; return FilteredIdentity(symbol, resolution, selector, filter, fieldName); } /// /// Creates a new FilteredIdentity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// The desired resolution of the data /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// Filters the IBaseData send into the indicator, if null defaults to true (x => true) which means no filter /// The name of the field being selected /// A new FilteredIdentity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public FilteredIdentity FilteredIdentity(Symbol symbol, Resolution resolution, Func selector = null, Func filter = null, string fieldName = null) { var name = CreateIndicatorName(symbol, fieldName ?? "close", resolution); var filteredIdentity = new FilteredIdentity(name, filter); RegisterIndicator(symbol, filteredIdentity, resolution, selector); return filteredIdentity; } /// /// Creates a new FilteredIdentity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// The desired resolution of the data /// Selects a value from the BaseData, if null defaults to the .Value property (x => x.Value) /// Filters the IBaseData send into the indicator, if null defaults to true (x => true) which means no filter /// The name of the field being selected /// A new FilteredIdentity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public FilteredIdentity FilteredIdentity(Symbol symbol, TimeSpan resolution, Func selector = null, Func filter = null, string fieldName = null) { var name = Invariant($"{symbol}({fieldName ?? "close"}_{resolution})"); var filteredIdentity = new FilteredIdentity(name, filter); RegisterIndicator(symbol, filteredIdentity, ResolveConsolidator(symbol, resolution), selector); return filteredIdentity; } /// /// Creates a new ForceIndex indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose ForceIndex we want /// The smoothing period used to smooth the computed ForceIndex values /// The type of smoothing to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new ForceIndex indicator with the specified smoothing type and period [DocumentationAttribute(Indicators)] public ForceIndex FI(Symbol symbol, int period, MovingAverageType type = MovingAverageType.Exponential, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"FI({period})", resolution); var indicator = new ForceIndex(name, period, type); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates an FisherTransform indicator for the symbol. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose FisherTransform we want /// The period of the FisherTransform /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The FisherTransform for the given parameters [DocumentationAttribute(Indicators)] public FisherTransform FISH(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"FISH({period})", resolution); var fisherTransform = new FisherTransform(name, period); InitializeIndicator(fisherTransform, resolution, selector, symbol); return fisherTransform; } /// /// Creates an FractalAdaptiveMovingAverage (FRAMA) indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose FRAMA we want /// The period of the FRAMA /// The long period of the FRAMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The FRAMA for the given parameters [DocumentationAttribute(Indicators)] public FractalAdaptiveMovingAverage FRAMA(Symbol symbol, int period, int longPeriod = 198, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"FRAMA({period},{longPeriod})", resolution); var fractalAdaptiveMovingAverage = new FractalAdaptiveMovingAverage(name, period, longPeriod); InitializeIndicator(fractalAdaptiveMovingAverage, resolution, selector, symbol); return fractalAdaptiveMovingAverage; } /// /// Creates a new Gamma indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Gamma /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Gamma indicator for the specified symbol [DocumentationAttribute(Indicators)] public Gamma G(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var gamma = new Gamma(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel); InitializeOptionIndicator(gamma, resolution, symbol, mirrorOption); return gamma; } /// /// Creates a new Gamma indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Gamma /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Gamma indicator for the specified symbol [DocumentationAttribute(Indicators)] public Gamma Γ(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { return G(symbol, mirrorOption, riskFreeRate, dividendYield, optionModel, ivModel, resolution); } /// /// Creates a new Heikin-Ashi indicator. /// /// The symbol whose Heikin-Ashi we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Heikin-Ashi indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public HeikinAshi HeikinAshi(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "HA", resolution); var heikinAshi = new HeikinAshi(name); InitializeIndicator(heikinAshi, resolution, selector, symbol); return heikinAshi; } /// /// Creates a new Hurst Exponent indicator for the specified symbol. /// The Hurst Exponent measures the long-term memory or self-similarity in a time series. /// The default maxLag value of 20 is chosen for reliable and accurate results, but using a higher lag may reduce precision. /// /// The symbol for which the Hurst Exponent is calculated. /// The number of data points used to calculate the indicator at each step. /// The maximum time lag used to compute the tau values for the Hurst Exponent calculation. /// The resolution /// Function to select a value from the BaseData to input into the indicator. Defaults to using the 'Value' property of BaseData if null. /// The Hurst Exponent indicator for the specified symbol. [DocumentationAttribute(Indicators)] public HurstExponent HE(Symbol symbol, int period, int maxLag = 20, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"HE({period},{maxLag})", resolution); var hurstExponent = new HurstExponent(name, period, maxLag); InitializeIndicator(hurstExponent, resolution, selector, symbol); return hurstExponent; } /// /// Creates a new Hilbert Transform indicator /// /// The symbol whose Hilbert transform we want /// The length of the FIR filter used in the calculation of the Hilbert Transform. /// This parameter determines the number of filter coefficients in the FIR filter. /// The multiplication factor used in the calculation of the in-phase component /// of the Hilbert Transform. This parameter adjusts the sensitivity and responsiveness of /// the transform to changes in the input signal. /// The multiplication factor used in the calculation of the quadrature component of /// the Hilbert Transform. This parameter also adjusts the sensitivity and responsiveness of the /// transform to changes in the input signal. /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(Indicators)] public HilbertTransform HT(Symbol symbol, int length, decimal inPhaseMultiplicationFactor, decimal quadratureMultiplicationFactor, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"HT({length}, {inPhaseMultiplicationFactor}, {quadratureMultiplicationFactor})", resolution); var hilbertTransform = new HilbertTransform(length, inPhaseMultiplicationFactor, quadratureMultiplicationFactor); InitializeIndicator(hilbertTransform, resolution, selector, symbol); return hilbertTransform; } /// /// Creates a new HullMovingAverage indicator. The Hull moving average is a series of nested weighted moving averages, is fast and smooth. /// /// The symbol whose Hull moving average we want /// The period over which to compute the Hull moving average /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// [DocumentationAttribute(Indicators)] public HullMovingAverage HMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"HMA({period})", resolution); var hullMovingAverage = new HullMovingAverage(name, period); InitializeIndicator(hullMovingAverage, resolution, selector, symbol); return hullMovingAverage; } /// /// Creates a new InternalBarStrength indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose IBS we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new InternalBarStrength indicator [DocumentationAttribute(Indicators)] public InternalBarStrength IBS(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "IBS", resolution); var indicator = new InternalBarStrength(name); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new IchimokuKinkoHyo indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose ICHIMOKU we want /// The period to calculate the Tenkan-sen period /// The period to calculate the Kijun-sen period /// The period to calculate the Tenkan-sen period /// The period to calculate the Tenkan-sen period /// The period to calculate the Tenkan-sen period /// The period to calculate the Tenkan-sen period /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new IchimokuKinkoHyo indicator with the specified periods and delays [DocumentationAttribute(Indicators)] public IchimokuKinkoHyo ICHIMOKU(Symbol symbol, int tenkanPeriod, int kijunPeriod, int senkouAPeriod, int senkouBPeriod, int senkouADelayPeriod, int senkouBDelayPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ICHIMOKU({tenkanPeriod},{kijunPeriod},{senkouAPeriod},{senkouBPeriod},{senkouADelayPeriod},{senkouBDelayPeriod})", resolution); var ichimokuKinkoHyo = new IchimokuKinkoHyo(name, tenkanPeriod, kijunPeriod, senkouAPeriod, senkouBPeriod, senkouADelayPeriod, senkouBDelayPeriod); InitializeIndicator(ichimokuKinkoHyo, resolution, selector, symbol); return ichimokuKinkoHyo; } /// /// Creates a new Identity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// Selects a value from the BaseData, if null defaults to the .Value property (x => x.Value) /// The name of the field being selected /// A new Identity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public Identity Identity(Symbol symbol, Func selector = null, string fieldName = null) { var resolution = GetSubscription(symbol).Resolution; return Identity(symbol, resolution, selector, fieldName); } /// /// Creates a new Identity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// The desired resolution of the data /// Selects a value from the BaseData, if null defaults to the .Value property (x => x.Value) /// The name of the field being selected /// A new Identity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public Identity Identity(Symbol symbol, Resolution resolution, Func selector = null, string fieldName = null) { var name = CreateIndicatorName(symbol, fieldName ?? "close", resolution); var identity = new Identity(name); InitializeIndicator(identity, resolution, selector, symbol); return identity; } /// /// Creates a new Identity indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The symbol whose values we want as an indicator /// The desired resolution of the data /// Selects a value from the BaseData, if null defaults to the .Value property (x => x.Value) /// The name of the field being selected /// A new Identity indicator for the specified symbol and selector [DocumentationAttribute(Indicators)] public Identity Identity(Symbol symbol, TimeSpan resolution, Func selector = null, string fieldName = null) { var name = Invariant($"{symbol}({fieldName ?? "close"},{resolution})"); var identity = new Identity(name); RegisterIndicator(symbol, identity, ResolveConsolidator(symbol, resolution), selector); return identity; } /// /// Creates a new ImpliedVolatility indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option contract used for parity type calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new ImpliedVolatility indicator for the specified symbol [DocumentationAttribute(Indicators)] public ImpliedVolatility IV(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var iv = new ImpliedVolatility(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel); InitializeOptionIndicator(iv, resolution, symbol, mirrorOption); return iv; } /// /// Creates a new KaufmanAdaptiveMovingAverage indicator. /// /// The symbol whose KAMA we want /// The period of the Efficiency Ratio (ER) of KAMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The KaufmanAdaptiveMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public KaufmanAdaptiveMovingAverage KAMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return KAMA(symbol, period, 2, 30, resolution, selector); } /// /// Creates a new KaufmanAdaptiveMovingAverage indicator. /// /// The symbol whose KAMA we want /// The period of the Efficiency Ratio (ER) /// The period of the fast EMA used to calculate the Smoothing Constant (SC) /// The period of the slow EMA used to calculate the Smoothing Constant (SC) /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The KaufmanAdaptiveMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public KaufmanAdaptiveMovingAverage KAMA(Symbol symbol, int period, int fastEmaPeriod, int slowEmaPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"KAMA({period},{fastEmaPeriod},{slowEmaPeriod})", resolution); var kaufmanAdaptiveMovingAverage = new KaufmanAdaptiveMovingAverage(name, period, fastEmaPeriod, slowEmaPeriod); InitializeIndicator(kaufmanAdaptiveMovingAverage, resolution, selector, symbol); return kaufmanAdaptiveMovingAverage; } /// /// Creates an KaufmanEfficiencyRatio indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose EF we want /// The period of the EF /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The KaufmanEfficiencyRatio indicator for the given parameters [DocumentationAttribute(Indicators)] public KaufmanEfficiencyRatio KER(Symbol symbol, int period = 2, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"KER({period})", resolution); var kaufmanEfficiencyRatio = new KaufmanEfficiencyRatio(name, period); InitializeIndicator(kaufmanEfficiencyRatio, resolution, selector, symbol); return kaufmanEfficiencyRatio; } /// /// Creates a new Keltner Channels indicator. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Keltner Channel we seek /// The period over which to compute the Keltner Channels /// The number of multiples of the from the middle band of the Keltner Channels /// Specifies the type of moving average to be used as the middle line of the Keltner Channel /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Keltner Channel indicator for the requested symbol. [DocumentationAttribute(Indicators)] public KeltnerChannels KCH(Symbol symbol, int period, decimal k, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"KCH({period},{k})", resolution); var keltnerChannels = new KeltnerChannels(name, period, k, movingAverageType); InitializeIndicator(keltnerChannels, resolution, selector, symbol); return keltnerChannels; } /// /// Creates a new KnowSureThing indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose KST we want /// The period over which to compute ROC1 /// The smoothing period used to smooth the computed ROC1 values /// The period over which to compute ROC2 /// The smoothing period used to smooth the computed ROC2 values /// The period over which to compute ROC3 /// The smoothing period used to smooth the computed ROC3 values /// The period over which to compute ROC4 /// The smoothing period used to smooth the computed ROC4 values /// The smoothing period used to smooth the signal values /// Specifies the type of moving average to be used as smoother for KnowSureThing values /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new KnowSureThing indicator with the specified smoothing type and period [DocumentationAttribute(Indicators)] public KnowSureThing KST(Symbol symbol, int roc1Period = 10, int roc1MaPeriod = 10, int roc2Period = 15, int roc2MaPeriod = 10, int roc3Period = 20, int roc3MaPeriod = 10, int roc4Period = 30, int roc4MaPeriod = 15, int signalPeriod = 9, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"KST({roc1Period},{roc1MaPeriod},{roc2Period},{roc2MaPeriod},{roc3Period},{roc3MaPeriod},{roc4Period},{roc4MaPeriod},{signalPeriod},{movingAverageType})", resolution); var indicator = new KnowSureThing(name, roc1Period, roc1MaPeriod, roc2Period, roc2MaPeriod, roc3Period, roc3MaPeriod, roc4Period, roc4MaPeriod, signalPeriod, movingAverageType); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new Klinger Volume Oscillator (KVO) indicator /// /// The symbol whose KVO we want /// The period of the fast EMA used to calculate KVO /// The period of the slow EMA used to calculate KVO, default to 13 /// The period of the signal EMA of the raw KVO value /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Klinger Volume Oscillator indicator for the requested symbol. [DocumentationAttribute(Indicators)] public KlingerVolumeOscillator KVO(Symbol symbol, int fastPeriod, int slowPeriod, int signalPeriod = 13, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"KVO({fastPeriod},{slowPeriod},{signalPeriod})", resolution); var klingerVolumeOscillator = new KlingerVolumeOscillator(name, fastPeriod, slowPeriod, signalPeriod); InitializeIndicator(klingerVolumeOscillator, resolution, selector, symbol); return klingerVolumeOscillator; } /// /// Creates a new LogReturn indicator. /// /// The symbol whose log return we seek /// The period of the log return. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar. /// log return indicator for the requested symbol. [DocumentationAttribute(Indicators)] public LogReturn LOGR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"LOGR({period})", resolution); var logReturn = new LogReturn(name, period); InitializeIndicator(logReturn, resolution, selector, symbol); return logReturn; } /// /// Creates and registers a new Least Squares Moving Average instance. /// /// The symbol whose LSMA we seek. /// The LSMA period. Normally 14. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar. /// A LeastSquaredMovingAverage configured with the specified period [DocumentationAttribute(Indicators)] public LeastSquaresMovingAverage LSMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"LSMA({period})", resolution); var leastSquaresMovingAverage = new LeastSquaresMovingAverage(name, period); InitializeIndicator(leastSquaresMovingAverage, resolution, selector, symbol); return leastSquaresMovingAverage; } /// /// Creates a new LinearWeightedMovingAverage indicator. This indicator will linearly distribute /// the weights across the periods. /// /// The symbol whose LWMA we want /// The period over which to compute the LWMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// [DocumentationAttribute(Indicators)] public LinearWeightedMovingAverage LWMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"LWMA({period})", resolution); var linearWeightedMovingAverage = new LinearWeightedMovingAverage(name, period); InitializeIndicator(linearWeightedMovingAverage, resolution, selector, symbol); return linearWeightedMovingAverage; } /// /// Creates a MACD indicator for the symbol. The indicator will be automatically updated on the given resolution. /// /// The symbol whose MACD we want /// The period for the fast moving average /// The period for the slow moving average /// The period for the signal moving average /// The type of moving average to use for the MACD /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The moving average convergence divergence between the fast and slow averages [DocumentationAttribute(Indicators)] public MovingAverageConvergenceDivergence MACD(Symbol symbol, int fastPeriod, int slowPeriod, int signalPeriod, MovingAverageType type = MovingAverageType.Exponential, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MACD({fastPeriod},{slowPeriod},{signalPeriod})", resolution); var movingAverageConvergenceDivergence = new MovingAverageConvergenceDivergence(name, fastPeriod, slowPeriod, signalPeriod, type); InitializeIndicator(movingAverageConvergenceDivergence, resolution, selector, symbol); return movingAverageConvergenceDivergence; } /// /// Creates a new MeanAbsoluteDeviation indicator. /// /// The symbol whose MeanAbsoluteDeviation we want /// The period over which to compute the MeanAbsoluteDeviation /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The MeanAbsoluteDeviation indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MeanAbsoluteDeviation MAD(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MAD({period})", resolution); var meanAbsoluteDeviation = new MeanAbsoluteDeviation(name, period); InitializeIndicator(meanAbsoluteDeviation, resolution, selector, symbol); return meanAbsoluteDeviation; } /// /// Creates a new Mesa Adaptive Moving Average (MAMA) indicator. /// The MAMA adjusts its smoothing factor based on the market's volatility, making it more adaptive than a simple moving average. /// /// The symbol for which the MAMA indicator is being created. /// The fast limit for the adaptive moving average. /// The slow limit for the adaptive moving average. /// The resolution /// Optional function to select a value from the BaseData. Defaults to casting the input to a TradeBar. /// The Mesa Adaptive Moving Average (MAMA) indicator for the requested symbol with the specified limits. [DocumentationAttribute(Indicators)] public MesaAdaptiveMovingAverage MAMA(Symbol symbol, decimal fastLimit = 0.5m, decimal slowLimit = 0.05m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MAMA({fastLimit},{slowLimit})", resolution); var mesaAdaptiveMovingAverage = new MesaAdaptiveMovingAverage(name, fastLimit, slowLimit); InitializeIndicator(mesaAdaptiveMovingAverage, resolution, selector, symbol); return mesaAdaptiveMovingAverage; } /// /// Creates an Market Profile indicator for the symbol with Volume Profile (VOL) mode. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose VP we want /// The period of the VP /// The percentage of volume contained in the value area /// How many digits you want to round and the precision. i.e 0.01 round to two digits exactly. /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Volume Profile indicator for the given parameters [DocumentationAttribute(Indicators)] public VolumeProfile VP(Symbol symbol, int period = 2, decimal valueAreaVolumePercentage = 0.70m, decimal priceRangeRoundOff = 0.05m, Resolution resolution = Resolution.Daily, Func selector = null) { var name = CreateIndicatorName(symbol, $"VP({period},{valueAreaVolumePercentage},{priceRangeRoundOff})", resolution); var marketProfile = new VolumeProfile(name, period, valueAreaVolumePercentage, priceRangeRoundOff); InitializeIndicator(marketProfile, resolution, selector, symbol); return marketProfile; } /// /// Creates an Market Profile indicator for the symbol with Time Price Opportunity (TPO) mode. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose TP we want /// The period of the TP /// The percentage of volume contained in the value area /// How many digits you want to round and the precision. i.e 0.01 round to two digits exactly. /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Time Profile indicator for the given parameters [DocumentationAttribute(Indicators)] public TimeProfile TP(Symbol symbol, int period = 2, decimal valueAreaVolumePercentage = 0.70m, decimal priceRangeRoundOff = 0.05m, Resolution resolution = Resolution.Daily, Func selector = null) { var name = CreateIndicatorName(symbol, $"TP({period},{valueAreaVolumePercentage},{priceRangeRoundOff})", resolution); var marketProfile = new TimeProfile(name, period, valueAreaVolumePercentage, priceRangeRoundOff); InitializeIndicator(marketProfile, resolution, selector, symbol); return marketProfile; } /// /// Creates a new Time Series Forecast indicator /// /// The symbol whose TSF we want /// The period of the TSF /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to Value property of BaseData (x => x.Value) /// The TimeSeriesForecast indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public TimeSeriesForecast TSF(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TSF({period})", resolution); var timeSeriesForecast = new TimeSeriesForecast(name, period); InitializeIndicator(timeSeriesForecast, resolution, selector, symbol); return timeSeriesForecast; } /// /// Creates a new Maximum indicator to compute the maximum value /// /// The symbol whose max we want /// The look back period over which to compute the max value /// The resolution /// Selects a value from the BaseData to send into the indicator, if null and the symbol is of type TradeBar defaults to the High property, /// otherwise it defaults to Value property of BaseData (x => x.Value) /// A Maximum indicator that compute the max value and the periods since the max value [DocumentationAttribute(Indicators)] public Maximum MAX(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MAX({period})", resolution); var maximum = new Maximum(name, period); // assign a default value for the selector function if (selector == null) { var subscription = GetSubscription(symbol); if (typeof(TradeBar).IsAssignableFrom(subscription.Type)) { // if we have trade bar data we'll use the High property, if not x => x.Value will be set in RegisterIndicator selector = x => ((TradeBar)x).High; } } InitializeIndicator(maximum, resolution, selector, symbol); return maximum; } /// /// Creates a new MoneyFlowIndex indicator. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose MFI we want /// The period over which to compute the MFI /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The MoneyFlowIndex indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MoneyFlowIndex MFI(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MFI({period})", resolution); var moneyFlowIndex = new MoneyFlowIndex(name, period); InitializeIndicator(moneyFlowIndex, resolution, selector, symbol); return moneyFlowIndex; } /// /// Creates a new Mass Index indicator. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose Mass Index we want. /// The period used by both EMA. /// The sum period. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Mass Index indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MassIndex MASS(Symbol symbol, int emaPeriod = 9, int sumPeriod = 25, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MASS({emaPeriod},{sumPeriod})", resolution); var massIndex = new MassIndex(name, emaPeriod, sumPeriod); InitializeIndicator(massIndex, resolution, selector, symbol); return massIndex; } /// /// Creates a new MidPoint indicator. /// /// The symbol whose MIDPOINT we want /// The period over which to compute the MIDPOINT /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The MidPoint indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MidPoint MIDPOINT(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MIDPOINT({period})", resolution); var midPoint = new MidPoint(name, period); InitializeIndicator(midPoint, resolution, selector, symbol); return midPoint; } /// /// Creates a new MidPrice indicator. /// /// The symbol whose MIDPRICE we want /// The period over which to compute the MIDPRICE /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The MidPrice indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MidPrice MIDPRICE(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MIDPRICE({period})", resolution); var midPrice = new MidPrice(name, period); InitializeIndicator(midPrice, resolution, selector, symbol); return midPrice; } /// /// Creates a new Minimum indicator to compute the minimum value /// /// The symbol whose min we want /// The look back period over which to compute the min value /// The resolution /// Selects a value from the BaseData to send into the indicator, if null and the symbol is of type TradeBar defaults to the Low property, /// otherwise it defaults to Value property of BaseData (x => x.Value) /// A Minimum indicator that compute the in value and the periods since the min value [DocumentationAttribute(Indicators)] public Minimum MIN(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MIN({period})", resolution); var minimum = new Minimum(name, period); // assign a default value for the selector function if (selector == null) { var subscription = GetSubscription(symbol); if (typeof(TradeBar).IsAssignableFrom(subscription.Type)) { // if we have trade bar data we'll use the Low property, if not x => x.Value will be set in RegisterIndicator selector = x => ((TradeBar)x).Low; } } InitializeIndicator(minimum, resolution, selector, symbol); return minimum; } /// /// Creates a new Momentum indicator. This will compute the absolute n-period change in the security. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose momentum we want /// The period over which to compute the momentum /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The momentum indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public Momentum MOM(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MOM({period})", resolution); var momentum = new Momentum(name, period); InitializeIndicator(momentum, resolution, selector, symbol); return momentum; } /// /// Creates a new Momersion indicator. /// /// The symbol whose Momersion we want /// The minimum period over which to compute the Momersion. Must be greater than 3. If null, only full period will be used in computations. /// The full period over which to compute the Momersion /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Momersion indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public Momersion MOMERSION(Symbol symbol, int? minPeriod, int fullPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MOMERSION({minPeriod},{fullPeriod})", resolution); var momersion = new Momersion(name, minPeriod, fullPeriod); InitializeIndicator(momersion, resolution, selector, symbol); return momersion; } /// /// Creates a new MomentumPercent indicator. This will compute the n-period percent change in the security. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose momentum we want /// The period over which to compute the momentum /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The momentum indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public MomentumPercent MOMP(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MOMP({period})", resolution); var momentumPercent = new MomentumPercent(name, period); InitializeIndicator(momentumPercent, resolution, selector, symbol); return momentumPercent; } /// /// Creates a new NormalizedAverageTrueRange indicator. /// /// The symbol whose NATR we want /// The period over which to compute the NATR /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The NormalizedAverageTrueRange indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public NormalizedAverageTrueRange NATR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"NATR({period})", resolution); var normalizedAverageTrueRange = new NormalizedAverageTrueRange(name, period); InitializeIndicator(normalizedAverageTrueRange, resolution, selector, symbol); return normalizedAverageTrueRange; } /// /// Creates a new New Highs - New Lows indicator /// /// The symbols whose NHNL we want /// The period over which to compute the NHNL /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a IBaseDataBar /// The NewHighsNewLows indicator for the requested symbols over the specified period [DocumentationAttribute(Indicators)] public NewHighsNewLows NHNL(IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"NH/NL({period})", resolution ?? GetSubscription(symbols.First()).Resolution); var nhnlDifference = new NewHighsNewLows(name, period); foreach (var symbol in symbols) { nhnlDifference.Add(symbol); } InitializeIndicator(nhnlDifference, resolution, selector, symbols.ToArray()); return nhnlDifference; } /// /// Creates a new New Highs - New Lows Volume indicator /// /// The symbols whose NHNLV we want /// The period over which to compute the NHNLV /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The NewHighsNewLowsVolume indicator for the requested symbols over the specified period [DocumentationAttribute(Indicators)] public NewHighsNewLowsVolume NHNLV(IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"NH/NL Volume({period})", resolution ?? GetSubscription(symbols.First()).Resolution); var nhnlVolume = new NewHighsNewLowsVolume(name, period); foreach (var symbol in symbols) { nhnlVolume.Add(symbol); } InitializeIndicator(nhnlVolume, resolution, selector, symbols.ToArray()); return nhnlVolume; } /// /// Creates a new On Balance Volume indicator. This will compute the cumulative total volume /// based on whether the close price being higher or lower than the previous period. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose On Balance Volume we seek /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The On Balance Volume indicator for the requested symbol. [DocumentationAttribute(Indicators)] public OnBalanceVolume OBV(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "OBV", resolution); var onBalanceVolume = new OnBalanceVolume(name); InitializeIndicator(onBalanceVolume, resolution, selector, symbol); return onBalanceVolume; } /// /// Creates a new PivotPointsHighLow indicator which will compute the high and low pivot points based on the configurable surrounding bars count. /// /// The symbol whose PPHL we seek /// The number of surrounding bars whose high values should be less than the current bar's for the bar high to be marked as high pivot point /// The number of surrounding bars whose low values should be more than the current bar's for the bar low to be marked as low pivot point /// The number of last stored indicator values /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The PivotPointsHighLow indicator for the requested symbol. [DocumentationAttribute(Indicators)] public PivotPointsHighLow PPHL(Symbol symbol, int lengthHigh, int lengthLow, int lastStoredValues, Resolution? resolution, Func selector = null) { return PPHL(symbol, lengthHigh, lengthLow, lastStoredValues, strict: true, resolution, selector); } /// /// Creates a new PivotPointsHighLow indicator which will compute the high and low pivot points based on the configurable surrounding bars count. /// /// The symbol whose PPHL we seek /// The number of surrounding bars whose high values should be less than the current bar's for the bar high to be marked as high pivot point /// The number of surrounding bars whose low values should be more than the current bar's for the bar low to be marked as low pivot point /// The number of last stored indicator values /// When true (default), uses strict inequalities (greater than and less than). When false, uses relaxed inequalities (greater than or equal and less than or equal) allowing equal values to be detected as pivot points. /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The PivotPointsHighLow indicator for the requested symbol. [DocumentationAttribute(Indicators)] public PivotPointsHighLow PPHL(Symbol symbol, int lengthHigh, int lengthLow, int lastStoredValues = 100, bool strict = true, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"PPHL({lengthHigh},{lengthLow})", resolution); var pivotPointsHighLow = new PivotPointsHighLow(name, lengthHigh, lengthLow, lastStoredValues, strict); InitializeIndicator(pivotPointsHighLow, resolution, selector, symbol); return pivotPointsHighLow; } /// /// Creates a new PercentagePriceOscillator indicator. /// /// The symbol whose PPO we want /// The fast moving average period /// The slow moving average period /// The type of moving average to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The PercentagePriceOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public PercentagePriceOscillator PPO(Symbol symbol, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"PPO({fastPeriod},{slowPeriod})", resolution); var percentagePriceOscillator = new PercentagePriceOscillator(name, fastPeriod, slowPeriod, movingAverageType); InitializeIndicator(percentagePriceOscillator, resolution, selector, symbol); return percentagePriceOscillator; } /// /// Creates a new Parabolic SAR indicator /// /// The symbol whose PSAR we seek /// Acceleration factor start value. Normally 0.02 /// Acceleration factor increment value. Normally 0.02 /// Acceleration factor max value. Normally 0.2 /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A ParabolicStopAndReverse configured with the specified periods [DocumentationAttribute(Indicators)] public ParabolicStopAndReverse PSAR(Symbol symbol, decimal afStart = 0.02m, decimal afIncrement = 0.02m, decimal afMax = 0.2m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"PSAR({afStart},{afIncrement},{afMax})", resolution); var parabolicStopAndReverse = new ParabolicStopAndReverse(name, afStart, afIncrement, afMax); InitializeIndicator(parabolicStopAndReverse, resolution, selector, symbol); return parabolicStopAndReverse; } /// /// Creates a new RegressionChannel indicator which will compute the LinearRegression, UpperChannel and LowerChannel lines, the intercept and slope /// /// The symbol whose RegressionChannel we seek /// The period of the standard deviation and least square moving average (linear regression line) /// The number of standard deviations specifying the distance between the linear regression and upper or lower channel lines /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// A Regression Channel configured with the specified period and number of standard deviation [DocumentationAttribute(Indicators)] public RegressionChannel RC(Symbol symbol, int period, decimal k, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"RC({period},{k})", resolution); var regressionChannel = new RegressionChannel(name, period, k); InitializeIndicator(regressionChannel, resolution, selector, symbol); return regressionChannel; } /// /// Creates a new Relative Moving Average indicator for the symbol. The indicator will be automatically updated on the given resolution. /// /// The symbol whose relative moving average we seek /// The period of the relative moving average /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// A relative moving average configured with the specified period and number of standard deviation [DocumentationAttribute(Indicators)] public RelativeMovingAverage RMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"RMA({period})", resolution); var relativeMovingAverage = new RelativeMovingAverage(name, period); InitializeIndicator(relativeMovingAverage, resolution, selector, symbol); return relativeMovingAverage; } /// /// Creates a new RateOfChange indicator. This will compute the n-period rate of change in the security. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose RateOfChange we want /// The period over which to compute the RateOfChange /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The RateOfChange indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public RateOfChange ROC(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ROC({period})", resolution); var rateOfChange = new RateOfChange(name, period); InitializeIndicator(rateOfChange, resolution, selector, symbol); return rateOfChange; } /// /// Creates a new RateOfChangePercent indicator. This will compute the n-period percentage rate of change in the security. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose RateOfChangePercent we want /// The period over which to compute the RateOfChangePercent /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The RateOfChangePercent indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public RateOfChangePercent ROCP(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ROCP({period})", resolution); var rateOfChangePercent = new RateOfChangePercent(name, period); InitializeIndicator(rateOfChangePercent, resolution, selector, symbol); return rateOfChangePercent; } /// /// Creates a new RateOfChangeRatio indicator. /// /// The symbol whose ROCR we want /// The period over which to compute the ROCR /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The RateOfChangeRatio indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public RateOfChangeRatio ROCR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ROCR({period})", resolution); var rateOfChangeRatio = new RateOfChangeRatio(name, period); InitializeIndicator(rateOfChangeRatio, resolution, selector, symbol); return rateOfChangeRatio; } /// /// Creates a new RelativeStrengthIndex indicator. This will produce an oscillator that ranges from 0 to 100 based /// on the ratio of average gains to average losses over the specified period. /// /// The symbol whose RSI we want /// The period over which to compute the RSI /// The type of moving average to use in computing the average gain/loss values /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The RelativeStrengthIndex indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public RelativeStrengthIndex RSI(Symbol symbol, int period, MovingAverageType movingAverageType = MovingAverageType.Wilders, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"RSI({period},{movingAverageType})", resolution); var relativeStrengthIndex = new RelativeStrengthIndex(name, period, movingAverageType); InitializeIndicator(relativeStrengthIndex, resolution, selector, symbol); return relativeStrengthIndex; } /// /// Creates a new RelativeVigorIndex indicator. /// /// The symbol whose RVI we want /// The period over which to compute the RVI /// The type of moving average to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The RelativeVigorIndex indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public RelativeVigorIndex RVI(Symbol symbol, int period, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"RVI({period},{movingAverageType})", resolution); var relativeVigorIndex = new RelativeVigorIndex(name, period, movingAverageType); InitializeIndicator(relativeVigorIndex, resolution, selector, symbol); return relativeVigorIndex; } /// /// Creates an RelativeDailyVolume indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose RDV we want /// The period of the RDV /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Relative Volume indicator for the given parameters [DocumentationAttribute(Indicators)] public RelativeDailyVolume RDV(Symbol symbol, int period = 2, Resolution resolution = Resolution.Daily, Func selector = null) { var name = CreateIndicatorName(symbol, $"RDV({period})", resolution); var relativeDailyVolume = new RelativeDailyVolume(name, period); RegisterIndicator(symbol, relativeDailyVolume, resolution, selector); return relativeDailyVolume; } /// /// Creates a new Rho indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Rho /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Rho indicator for the specified symbol [DocumentationAttribute(Indicators)] public Rho R(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var rho = new Rho(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel); InitializeOptionIndicator(rho, resolution, symbol, mirrorOption); return rho; } /// /// Creates a new Rho indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Rho /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Rho indicator for the specified symbol [DocumentationAttribute(Indicators)] public Rho ρ(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { return R(symbol, mirrorOption, riskFreeRate, dividendYield, optionModel, ivModel, resolution); } /// /// Creates a new Stochastic RSI indicator which will compute the %K and %D /// /// The symbol whose Stochastic RSI we seek /// The period of the relative strength index /// The period of the stochastic indicator /// The smoothing period of K output /// The smoothing period of D output /// The type of moving average to be used /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// A StochasticRelativeStrengthIndex configured with the specified periods and moving average type [DocumentationAttribute(Indicators)] public StochasticRelativeStrengthIndex SRSI(Symbol symbol, int rsiPeriod, int stochPeriod, int kSmoothingPeriod, int dSmoothingPeriod, MovingAverageType movingAverageType = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SRSI({rsiPeriod},{stochPeriod},{kSmoothingPeriod},{dSmoothingPeriod})", resolution); var indicator = new StochasticRelativeStrengthIndex(name, rsiPeriod, stochPeriod, kSmoothingPeriod, dSmoothingPeriod, movingAverageType); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new SuperTrend indicator. /// /// The symbol whose SuperTrend indicator we want. /// The smoothing period for average true range. /// Multiplier to calculate basic upper and lower bands width. /// Smoother type for average true range, defaults to Wilders. /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar [DocumentationAttribute(Indicators)] public SuperTrend STR(Symbol symbol, int period, decimal multiplier, MovingAverageType movingAverageType = MovingAverageType.Wilders, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"STR({period},{multiplier})", resolution); var strend = new SuperTrend(name, period, multiplier, movingAverageType); InitializeIndicator(strend, resolution, selector, symbol); return strend; } /// /// Creates a new SharpeRatio indicator. /// /// The symbol whose RSR we want /// Period of historical observation for sharpe ratio calculation /// /// Risk-free rate for sharpe ratio calculation. If not specified, it will use the algorithms' /// /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The SharpeRatio indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public SharpeRatio SR(Symbol symbol, int sharpePeriod, decimal? riskFreeRate = null, Resolution? resolution = null, Func selector = null) { var baseBame = riskFreeRate.HasValue ? $"SR({sharpePeriod},{riskFreeRate})" : $"SR({sharpePeriod})"; var name = CreateIndicatorName(symbol, baseBame, resolution); IRiskFreeInterestRateModel riskFreeRateModel = riskFreeRate.HasValue ? new ConstantRiskFreeRateInterestRateModel(riskFreeRate.Value) // Make it a function so it's lazily evaluated: SetRiskFreeInterestRateModel can be called after this method : new FuncRiskFreeRateInterestRateModel((datetime) => RiskFreeInterestRateModel.GetInterestRate(datetime)); var sharpeRatio = new SharpeRatio(name, sharpePeriod, riskFreeRateModel); InitializeIndicator(sharpeRatio, resolution, selector, symbol); return sharpeRatio; } /// /// Creates a new Sortino indicator. /// /// The symbol whose Sortino we want /// Period of historical observation for Sortino ratio calculation /// Minimum acceptable return (eg risk-free rate) for the Sortino ratio calculation /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The SortinoRatio indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public SortinoRatio SORTINO(Symbol symbol, int sortinoPeriod, double minimumAcceptableReturn = 0.0, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SORTINO({sortinoPeriod},{minimumAcceptableReturn})", resolution); var sortinoRatio = new SortinoRatio(name, sortinoPeriod, minimumAcceptableReturn); InitializeIndicator(sortinoRatio, resolution, selector, symbol); return sortinoRatio; } /// /// Creates a new Parabolic SAR Extended indicator /// /// The symbol whose SAREXT we seek /// The starting value for the Stop and Reverse indicator /// The offset value to be applied on reverse /// The starting acceleration factor for short positions /// The increment value for the acceleration factor for short positions /// The maximum value for the acceleration factor for short positions /// The starting acceleration factor for long positions /// The increment value for the acceleration factor for long positions /// The maximum value for the acceleration factor for long positions /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A ParabolicStopAndReverseExtended configured with the specified periods [DocumentationAttribute(Indicators)] public ParabolicStopAndReverseExtended SAREXT(Symbol symbol, decimal sarStart = 0.0m, decimal offsetOnReverse = 0.0m, decimal afStartShort = 0.02m, decimal afIncrementShort = 0.02m, decimal afMaxShort = 0.2m, decimal afStartLong = 0.02m, decimal afIncrementLong = 0.02m, decimal afMaxLong = 0.2m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SAREXT({sarStart},{offsetOnReverse},{afStartShort},{afIncrementShort},{afMaxShort},{afStartLong},{afIncrementLong},{afMaxLong})", resolution); var parabolicStopAndReverseExtended = new ParabolicStopAndReverseExtended(name, sarStart, offsetOnReverse, afStartShort, afIncrementShort, afMaxShort, afStartLong, afIncrementLong, afMaxLong); InitializeIndicator(parabolicStopAndReverseExtended, resolution, selector, symbol); return parabolicStopAndReverseExtended; } /// /// Creates a Squeeze Momentum indicator to identify market squeezes and potential breakouts. /// Compares Bollinger Bands and Keltner Channels to signal low or high volatility periods. /// /// The symbol for which the indicator is calculated. /// The period for Bollinger Bands. /// The multiplier for the Bollinger Bands' standard deviation. /// The period for Keltner Channels. /// The multiplier for the Average True Range in Keltner Channels. /// The resolution of the data. /// Selects a value from the BaseData to send into the indicator. If null, defaults to the Value property of BaseData (x => x.Value). /// The configured Squeeze Momentum indicator. [DocumentationAttribute(Indicators)] public SqueezeMomentum SM(Symbol symbol, int bollingerPeriod = 20, decimal bollingerMultiplier = 2m, int keltnerPeriod = 20, decimal keltnerMultiplier = 1.5m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SM({bollingerPeriod}, {bollingerMultiplier}, {keltnerPeriod}, {keltnerMultiplier})", resolution); var squeezeMomentum = new SqueezeMomentum(name, bollingerPeriod, bollingerMultiplier, keltnerPeriod, keltnerMultiplier); InitializeIndicator(squeezeMomentum, resolution, selector, symbol); return squeezeMomentum; } /// /// Creates an SimpleMovingAverage indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose SMA we want /// The period of the SMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The SimpleMovingAverage for the given parameters [DocumentationAttribute(Indicators)] public SimpleMovingAverage SMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SMA({period})", resolution); var simpleMovingAverage = new SimpleMovingAverage(name, period); InitializeIndicator(simpleMovingAverage, resolution, selector, symbol); return simpleMovingAverage; } /// /// Creates a new Schaff Trend Cycle indicator /// /// The symbol for the indicator to track /// The fast moving average period /// The slow moving average period /// The signal period /// The type of moving average to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The SchaffTrendCycle indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public SchaffTrendCycle STC(Symbol symbol, int cyclePeriod, int fastPeriod, int slowPeriod, MovingAverageType movingAverageType = MovingAverageType.Exponential, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"STC({cyclePeriod},{fastPeriod},{slowPeriod})", resolution); var schaffTrendCycle = new SchaffTrendCycle(name, cyclePeriod, fastPeriod, slowPeriod, movingAverageType); InitializeIndicator(schaffTrendCycle, resolution, selector, symbol); return schaffTrendCycle; } /// /// Creates a new SmoothedOnBalanceVolume indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose SmoothedOnBalanceVolume we want /// The smoothing period used to smooth the computed OnBalanceVolume values /// The type of smoothing to use /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new SmoothedOnBalanceVolume indicator with the specified smoothing type and period [DocumentationAttribute(Indicators)] public SmoothedOnBalanceVolume SOBV(Symbol symbol, int period, MovingAverageType type = MovingAverageType.Simple, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SOBV({period})", resolution); var indicator = new SmoothedOnBalanceVolume(name, period, type); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new StandardDeviation indicator. This will return the population standard /// deviation of samples over the specified period. By default, it consumes the security's /// price, so the result is the dispersion of price levels, not the asset's volatility. /// To compute volatility, chain this indicator onto a or /// indicator using . /// /// The symbol whose STD we want /// The period over which to compute the STD /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The StandardDeviation indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public StandardDeviation STD(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"STD({period})", resolution); var standardDeviation = new StandardDeviation(name, period); InitializeIndicator(standardDeviation, resolution, selector, symbol); return standardDeviation; } /// /// Creates a new TargetDownsideDeviation indicator. The target downside deviation is defined as the root-mean-square, or RMS, of the deviations of the /// realized return’s underperformance from the target return where all returns above the target return are treated as underperformance of 0. /// /// The symbol whose TDD we want /// The period over which to compute the TDD /// The resolution /// Minimum acceptable return (MAR) for the target downside deviation calculation /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The TargetDownsideDeviation indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public TargetDownsideDeviation TDD(Symbol symbol, int period, double minimumAcceptableReturn = 0, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TDD({period},{minimumAcceptableReturn})", resolution); var targetDownsideDeviation = new TargetDownsideDeviation(name, period, minimumAcceptableReturn); InitializeIndicator(targetDownsideDeviation, resolution, selector, symbol); return targetDownsideDeviation; } /// /// Creates a new TomDemark Sequential candlestick indicator for the symbol. The indicator will be automatically /// updated on the symbol's subscription resolution. /// /// The symbol whose TomDemark Sequential we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a IBaseDataBar /// The TomDemark Sequential indicator for the requested symbol over the specified period public TomDemarkSequential TDS(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "TDS", resolution); var tdSequential = new TomDemarkSequential(name); InitializeIndicator(tdSequential, resolution, selector, symbol); return tdSequential; } /// /// Creates a new Stochastic indicator. /// /// The symbol whose stochastic we seek /// The period of the stochastic. Normally 14 /// The sum period of the stochastic. Normally 14 /// The sum period of the stochastic. Normally 3 /// The resolution. /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// Stochastic indicator for the requested symbol. [DocumentationAttribute(Indicators)] public Stochastic STO(Symbol symbol, int period, int kPeriod, int dPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"STO({period},{kPeriod},{dPeriod})", resolution); var stochastic = new Stochastic(name, period, kPeriod, dPeriod); InitializeIndicator(stochastic, resolution, selector, symbol); return stochastic; } /// /// Overload short hand to create a new Stochastic indicator; defaulting to the 3 period for dStoch /// /// The symbol whose stochastic we seek /// The resolution. /// The period of the stochastic. Normally 14 /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// Stochastic indicator for the requested symbol. [DocumentationAttribute(Indicators)] public Stochastic STO(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return STO(symbol, period, period, 3, resolution, selector); } /// /// Creates a new instance of the Premier Stochastic Oscillator for the specified symbol. /// /// The symbol for which the stochastic indicator is being calculated. /// The period for calculating the Stochastic K value. /// The period for the Exponential Moving Average (EMA) used to smooth the Stochastic K. /// The data resolution (e.g., daily, hourly) for the indicator /// Optional function to select a value from the BaseData. Defaults to casting the input to a TradeBar. /// A PremierStochasticOscillator instance for the specified symbol. [DocumentationAttribute(Indicators)] public PremierStochasticOscillator PSO(Symbol symbol, int period, int emaPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"PSO({period},{emaPeriod})", resolution); var premierStochasticOscillator = new PremierStochasticOscillator(name, period, emaPeriod); InitializeIndicator(premierStochasticOscillator, resolution, selector, symbol); return premierStochasticOscillator; } /// /// Creates a new Sum indicator. /// /// The symbol whose Sum we want /// The period over which to compute the Sum /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Sum indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public Sum SUM(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SUM({period})", resolution); var sum = new Sum(name, period); InitializeIndicator(sum, resolution, selector, symbol); return sum; } /// /// Creates Swiss Army Knife transformation for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol to use for calculations /// The period of the calculation /// The delta scale of the BandStop or BandPass /// The tool os the Swiss Army Knife /// The resolution /// elects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The calculation using the given tool [DocumentationAttribute(Indicators)] public SwissArmyKnife SWISS(Symbol symbol, int period, double delta, SwissArmyKnifeTool tool, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"SWISS({period},{delta},{tool})", resolution); var swissArmyKnife = new SwissArmyKnife(name, period, delta, tool); InitializeIndicator(swissArmyKnife, resolution, selector, symbol); return swissArmyKnife; } /// /// Creates a new Theta indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Theta /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Theta indicator for the specified symbol [DocumentationAttribute(Indicators)] public Theta T(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var theta = new Theta(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel); InitializeOptionIndicator(theta, resolution, symbol, mirrorOption); return theta; } /// /// Creates a new Theta indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Theta /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Theta indicator for the specified symbol [DocumentationAttribute(Indicators)] public Theta Θ(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType optionModel = OptionPricingModelType.BlackScholes, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { return T(symbol, mirrorOption, riskFreeRate, dividendYield, optionModel, ivModel, resolution); } /// /// Creates a new T3MovingAverage indicator. /// /// The symbol whose T3 we want /// The period over which to compute the T3 /// The volume factor to be used for the T3 (value must be in the [0,1] range, defaults to 0.7) /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The T3MovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public T3MovingAverage T3(Symbol symbol, int period, decimal volumeFactor = 0.7m, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"T3({period},{volumeFactor})", resolution); var t3MovingAverage = new T3MovingAverage(name, period, volumeFactor); InitializeIndicator(t3MovingAverage, resolution, selector, symbol); return t3MovingAverage; } /// /// Creates a new TripleExponentialMovingAverage indicator. /// /// The symbol whose TEMA we want /// The period over which to compute the TEMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The TripleExponentialMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public TripleExponentialMovingAverage TEMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TEMA({period})", resolution); var tripleExponentialMovingAverage = new TripleExponentialMovingAverage(name, period); InitializeIndicator(tripleExponentialMovingAverage, resolution, selector, symbol); return tripleExponentialMovingAverage; } /// /// Creates a TrueStrengthIndex indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose TSI we want /// Period used for the first price change smoothing /// Period used for the second (double) price change smoothing /// The signal period /// The type of moving average to use for the signal /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The TrueStrengthIndex indicator for the given parameters [DocumentationAttribute(Indicators)] public TrueStrengthIndex TSI(Symbol symbol, int longTermPeriod = 25, int shortTermPeriod = 13, int signalPeriod = 7, MovingAverageType signalType = MovingAverageType.Exponential, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TSI({longTermPeriod},{shortTermPeriod},{signalPeriod})", resolution); var trueStrengthIndex = new TrueStrengthIndex(name, longTermPeriod, shortTermPeriod, signalPeriod, signalType); InitializeIndicator(trueStrengthIndex, resolution, selector, symbol); return trueStrengthIndex; } /// /// Creates a new TrueRange indicator. /// /// The symbol whose TR we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The TrueRange indicator for the requested symbol. [DocumentationAttribute(Indicators)] public TrueRange TR(Symbol symbol, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, "TR", resolution); var trueRange = new TrueRange(name); InitializeIndicator(trueRange, resolution, selector, symbol); return trueRange; } /// /// Creates a new TriangularMovingAverage indicator. /// /// The symbol whose TRIMA we want /// The period over which to compute the TRIMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The TriangularMovingAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public TriangularMovingAverage TRIMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TRIMA({period})", resolution); var triangularMovingAverage = new TriangularMovingAverage(name, period); InitializeIndicator(triangularMovingAverage, resolution, selector, symbol); return triangularMovingAverage; } /// /// Creates a new Trix indicator. /// /// The symbol whose TRIX we want /// The period over which to compute the TRIX /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Trix indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public Trix TRIX(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"TRIX({period})", resolution); var trix = new Trix(name, period); InitializeIndicator(trix, resolution, selector, symbol); return trix; } /// /// Creates a new UltimateOscillator indicator. /// /// The symbol whose ULTOSC we want /// The first period over which to compute the ULTOSC /// The second period over which to compute the ULTOSC /// The third period over which to compute the ULTOSC /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The UltimateOscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public UltimateOscillator ULTOSC(Symbol symbol, int period1, int period2, int period3, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ULTOSC({period1},{period2},{period3})", resolution); var ultimateOscillator = new UltimateOscillator(name, period1, period2, period3); InitializeIndicator(ultimateOscillator, resolution, selector, symbol); return ultimateOscillator; } /// /// Creates a new Vega indicator for the symbol The indicator will be automatically /// updated on the symbol's subscription resolution /// /// The option symbol whose values we want as an indicator /// The mirror option for parity calculation /// The risk free rate /// The dividend yield /// The option pricing model used to estimate Vega /// The option pricing model used to estimate IV /// The desired resolution of the data /// A new Vega indicator for the specified symbol [DocumentationAttribute(Indicators)] public Vega V(Symbol symbol, Symbol mirrorOption = null, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, OptionPricingModelType? ivModel = null, Resolution? resolution = null) { var name = InitializeOptionIndicator(symbol, out var riskFreeRateModel, out var dividendYieldModel, riskFreeRate, dividendYield, optionModel, resolution); var vega = new Vega(name, symbol, riskFreeRateModel, dividendYieldModel, mirrorOption, optionModel, ivModel); InitializeOptionIndicator(vega, resolution, symbol, mirrorOption); return vega; } /// /// Creates a new Chande's Variable Index Dynamic Average indicator. /// /// The symbol whose VIDYA we want /// The period over which to compute the VIDYA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The VariableIndexDynamicAverage indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public VariableIndexDynamicAverage VIDYA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"VIDYA({period})", resolution); var variableIndexDynamicAverage = new VariableIndexDynamicAverage(name, period); InitializeIndicator(variableIndexDynamicAverage, resolution, selector, symbol); return variableIndexDynamicAverage; } /// /// Creates a new Variance indicator. This will return the population variance of samples over the specified period. /// /// The symbol whose VAR we want /// The period over which to compute the VAR /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Variance indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] [Obsolete("'VAR' is obsolete please use 'V' instead")] public Variance VAR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return V(symbol, period, resolution, selector); } /// /// Creates a new Variance indicator. This will return the population variance of samples over the specified period. /// /// The symbol whose variance we want /// The period over which to compute the variance /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The Variance indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public Variance V(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"V({period})", resolution); var variance = new Variance(name, period); InitializeIndicator(variance, resolution, selector, symbol); return variance; } /// /// Creates a new ValueAtRisk indicator. /// /// The symbol whose VAR we want /// The period over which to compute the VAR /// The confidence level for Value at risk calculation /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ValueAtRisk indicator for the requested Symbol, lookback period, and confidence level public ValueAtRisk VAR(Symbol symbol, int period, double confidenceLevel, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"VAR({period},{confidenceLevel})", resolution); var valueAtRisk = new ValueAtRisk(name, period, confidenceLevel); InitializeIndicator(valueAtRisk, resolution, selector, symbol); return valueAtRisk; } /// /// Creates an VolumeWeightedAveragePrice (VWAP) indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose VWAP we want /// The period of the VWAP /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The VolumeWeightedAveragePrice for the given parameters [DocumentationAttribute(Indicators)] public VolumeWeightedAveragePriceIndicator VWAP(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"VWAP({period})", resolution); var volumeWeightedAveragePriceIndicator = new VolumeWeightedAveragePriceIndicator(name, period); InitializeIndicator(volumeWeightedAveragePriceIndicator, resolution, selector, symbol); return volumeWeightedAveragePriceIndicator; } /// /// Creates the canonical VWAP indicator that resets each day. The indicator will be automatically /// updated on the security's configured resolution. /// /// The symbol whose VWAP we want /// The IntradayVWAP for the specified symbol [DocumentationAttribute(Indicators)] public IntradayVwap VWAP(Symbol symbol) { var name = CreateIndicatorName(symbol, "VWAP", null); var intradayVwap = new IntradayVwap(name); RegisterIndicator(symbol, intradayVwap); return intradayVwap; } /// /// Creates a new VolumeWeightedMovingAverage indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose VWMA we want /// The smoothing period used to smooth the computed VWMA values /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new VolumeWeightedMovingAverage indicator with the specified smoothing period [DocumentationAttribute(Indicators)] public VolumeWeightedMovingAverage VWMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"VWMA({period})", resolution); var indicator = new VolumeWeightedMovingAverage(name, period); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new Vortex indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose VWMA we want /// The smoothing period used to smooth the computed VWMA values /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new Vortex indicator with the specified smoothing period [DocumentationAttribute(Indicators)] public Vortex VTX(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"VTX({period})", resolution); var indicator = new Vortex(name, period); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new Williams %R indicator. This will compute the percentage change of /// the current closing price in relation to the high and low of the past N periods. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose Williams %R we want /// The period over which to compute the Williams %R /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Williams %R indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public WilliamsPercentR WILR(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"WILR({period})", resolution); var williamsPercentR = new WilliamsPercentR(name, period); InitializeIndicator(williamsPercentR, resolution, selector, symbol); return williamsPercentR; } /// /// Creates a WilderMovingAverage indicator for the symbol. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose WMA we want /// The period of the WMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The WilderMovingAverage for the given parameters /// WWMA for Welles Wilder Moving Average [DocumentationAttribute(Indicators)] public WilderMovingAverage WWMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"WWMA({period})", resolution); var wilderMovingAverage = new WilderMovingAverage(name, period); InitializeIndicator(wilderMovingAverage, resolution, selector, symbol); return wilderMovingAverage; } /// /// Creates a Wilder Swing Index (SI) indicator for the symbol. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose SI we want /// The maximum daily change in price for the SI /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The WilderSwingIndex for the given parameters /// SI for Wilder Swing Index [DocumentationAttribute(Indicators)] public WilderSwingIndex SI(Symbol symbol, decimal limitMove, Resolution? resolution = Resolution.Daily, Func selector = null) { var name = CreateIndicatorName(symbol, "SI", resolution); var si = new WilderSwingIndex(name, limitMove); InitializeIndicator(si, resolution, selector, symbol); return si; } /// /// Creates a Wilder Accumulative Swing Index (ASI) indicator for the symbol. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose ASI we want /// The maximum daily change in price for the ASI /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The WilderAccumulativeSwingIndex for the given parameters /// ASI for Wilder Accumulative Swing Index [DocumentationAttribute(Indicators)] public WilderAccumulativeSwingIndex ASI(Symbol symbol, decimal limitMove, Resolution? resolution = Resolution.Daily, Func selector = null) { var name = CreateIndicatorName(symbol, "ASI", resolution); var asi = new WilderAccumulativeSwingIndex(name, limitMove); InitializeIndicator(asi, resolution, selector, symbol); return asi; } /// /// Creates a new WaveTrend Oscillator (WTO) indicator for the symbol. /// The indicator will be automatically updated on the given resolution. /// /// The symbol whose WaveTrend Oscillator we want /// The smoothing period for the typical-price EMA and the deviation EMA /// The EMA period applied to the channel index to produce the WT1 line /// The SMA period applied to WT1 to produce the WT2 signal line /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The WaveTrendOscillator indicator for the requested symbol [DocumentationAttribute(Indicators)] public WaveTrendOscillator WTO(Symbol symbol, int channelPeriod, int averagePeriod, int signalPeriod, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"WTO({channelPeriod},{averagePeriod},{signalPeriod})", resolution); var waveTrendOscillator = new WaveTrendOscillator(name, channelPeriod, averagePeriod, signalPeriod); InitializeIndicator(waveTrendOscillator, resolution, selector, symbol); return waveTrendOscillator; } /// /// Creates a new Arms Index indicator /// /// The symbols whose Arms Index we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Arms Index indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ArmsIndex TRIN(IEnumerable symbols, Resolution? resolution = null, Func selector = null) { return TRIN(symbols.ToArray(), resolution, selector); } /// /// Creates a new Arms Index indicator /// /// The symbols whose Arms Index we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Arms Index indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public ArmsIndex TRIN(Symbol[] symbols, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, "TRIN", resolution ?? GetSubscription(symbols.First()).Resolution); var trin = new ArmsIndex(name); foreach (var symbol in symbols) { trin.Add(symbol); } InitializeIndicator(trin, resolution, selector, symbols); return trin; } /// /// Creates a new Advance/Decline Ratio indicator /// /// The symbols whose A/D Ratio we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Advance/Decline Ratio indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AdvanceDeclineRatio ADR(IEnumerable symbols, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, "A/D Ratio", resolution ?? GetSubscription(symbols.First()).Resolution); var adr = new AdvanceDeclineRatio(name); foreach (var symbol in symbols) { adr.Add(symbol); } InitializeIndicator(adr, resolution, selector, symbols.ToArray()); return adr; } /// /// Creates a new Advance/Decline Volume Ratio indicator /// /// The symbol whose A/D Volume Rate we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Advance/Decline Volume Ratio indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AdvanceDeclineVolumeRatio ADVR(IEnumerable symbols, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, "A/D Volume Rate", resolution ?? GetSubscription(symbols.First()).Resolution); var advr = new AdvanceDeclineVolumeRatio(name); foreach (var symbol in symbols) { advr.Add(symbol); } InitializeIndicator(advr, resolution, selector, symbols.ToArray()); return advr; } /// /// Creates a new Advance/Decline Difference indicator /// /// The symbols whose A/D Difference we want /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The Advance/Decline Difference indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public AdvanceDeclineDifference ADDIFF(IEnumerable symbols, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, "A/D Difference", resolution ?? GetSubscription(symbols.First()).Resolution); var adDiff = new AdvanceDeclineDifference(name); foreach (var symbol in symbols) { adDiff.Add(symbol); } InitializeIndicator(adDiff, resolution, selector, symbols.ToArray()); return adDiff; } /// /// Creates a new McGinley Dynamic indicator /// /// The symbol whose McGinley Dynamic indicator value we want /// The period of the McGinley Dynamic indicator /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The McGinley Dynamic indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public McGinleyDynamic MGD(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"MGD({period})", resolution); var indicator = new McGinleyDynamic(name, period); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a new McClellan Oscillator indicator /// /// The symbols whose McClellan Oscillator we want /// Fast period EMA of advance decline difference /// Slow period EMA of advance decline difference /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The McClellan Oscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public McClellanOscillator MOSC(IEnumerable symbols, int fastPeriod = 19, int slowPeriod = 39, Resolution? resolution = null, Func selector = null) { return MOSC(symbols.ToArray(), fastPeriod, slowPeriod, resolution, selector); } /// /// Creates a new McClellan Oscillator indicator /// /// The symbols whose McClellan Oscillator we want /// Fast period EMA of advance decline difference /// Slow period EMA of advance decline difference /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The McClellan Oscillator indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public McClellanOscillator MOSC(Symbol[] symbols, int fastPeriod = 19, int slowPeriod = 39, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"MO({fastPeriod},{slowPeriod})", resolution ?? GetSubscription(symbols.First()).Resolution); var mosc = new McClellanOscillator(name, fastPeriod, slowPeriod); foreach (var symbol in symbols) { mosc.Add(symbol); } InitializeIndicator(mosc, resolution, selector, symbols); return mosc; } /// /// Creates a new McClellan Summation Index indicator /// /// The symbols whose McClellan Summation Index we want /// Fast period EMA of advance decline difference /// Slow period EMA of advance decline difference /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The McClellan Summation Index indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public McClellanSummationIndex MSI(IEnumerable symbols, int fastPeriod = 19, int slowPeriod = 39, Resolution? resolution = null, Func selector = null) { return MSI(symbols.ToArray(), fastPeriod, slowPeriod, resolution, selector); } /// /// Creates a new McClellan Summation Index indicator /// /// The symbols whose McClellan Summation Index we want /// Fast period EMA of advance decline difference /// Slow period EMA of advance decline difference /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// The McClellan Summation Index indicator for the requested symbol over the specified period [DocumentationAttribute(Indicators)] public McClellanSummationIndex MSI(Symbol[] symbols, int fastPeriod = 19, int slowPeriod = 39, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(QuantConnect.Symbol.None, $"MSI({fastPeriod},{slowPeriod})", resolution ?? GetSubscription(symbols.First()).Resolution); var msi = new McClellanSummationIndex(name, fastPeriod, slowPeriod); foreach (var symbol in symbols) { msi.Add(symbol); } InitializeIndicator(msi, resolution, selector, symbols); return msi; } /// /// Creates a new RogersSatchellVolatility indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose RogersSatchellVolatility we want /// The period of the rolling window used to compute volatility /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to casting the input value to a TradeBar /// A new RogersSatchellVolatility indicator with the specified smoothing type and period [DocumentationAttribute(Indicators)] public RogersSatchellVolatility RSV(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"RSV({period})", resolution); var indicator = new RogersSatchellVolatility(name, period); InitializeIndicator(indicator, resolution, selector, symbol); return indicator; } /// /// Creates a ZeroLagExponentialMovingAverage indicator for the symbol. The indicator will be automatically /// updated on the given resolution. /// /// The symbol whose ZLEMA we want /// The period of the ZLEMA /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The ZeroLagExponentialMovingAverage for the given parameters [DocumentationAttribute(Indicators)] public ZeroLagExponentialMovingAverage ZLEMA(Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ZLEMA({period})", resolution); var zeroLagExponentialMovingAverage = new ZeroLagExponentialMovingAverage(name, period); InitializeIndicator(zeroLagExponentialMovingAverage, resolution, selector, symbol); return zeroLagExponentialMovingAverage; } /// /// Creates a ZigZag indicator for the specified symbol, with adjustable sensitivity and minimum trend length. /// /// The symbol for which to create the ZigZag indicator. /// The sensitivity for detecting pivots. /// The minimum number of bars required for a trend before a pivot is confirmed. /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) /// The configured ZigZag indicator. [DocumentationAttribute(Indicators)] public ZigZag ZZ(Symbol symbol, decimal sensitivity = 0.05m, int minTrendLength = 1, Resolution? resolution = null, Func selector = null) { var name = CreateIndicatorName(symbol, $"ZZ({sensitivity},{minTrendLength})", resolution); var zigZag = new ZigZag(name, sensitivity, minTrendLength); InitializeIndicator(zigZag, resolution, selector, symbol); return zigZag; } /// /// Creates a new name for an indicator created with the convenience functions (SMA, EMA, ect...) /// /// The symbol this indicator is registered to /// The indicator type, for example, 'SMA(5)' /// The resolution requested /// A unique for the given parameters [DocumentationAttribute(Indicators)] public string CreateIndicatorName(Symbol symbol, FormattableString type, Resolution? resolution) { return CreateIndicatorName(symbol, Invariant(type), resolution); } /// /// Creates a new name for an indicator created with the convenience functions (SMA, EMA, ect...) /// /// The symbol this indicator is registered to /// The indicator type, for example, 'SMA(5)' /// The resolution requested /// A unique for the given parameters [DocumentationAttribute(Indicators)] public string CreateIndicatorName(Symbol symbol, string type, Resolution? resolution) { var symbolIsNotEmpty = symbol != QuantConnect.Symbol.None && symbol != QuantConnect.Symbol.Empty; if (!resolution.HasValue && symbolIsNotEmpty) { resolution = GetSubscription(symbol).Resolution; } var res = string.Empty; switch (resolution) { case Resolution.Tick: res = "tick"; break; case Resolution.Second: res = "sec"; break; case Resolution.Minute: res = "min"; break; case Resolution.Hour: res = "hr"; break; case Resolution.Daily: res = "day"; break; case null: break; default: throw new ArgumentOutOfRangeException(nameof(resolution), resolution, "resolution parameter is out of range."); } var parts = new List(); if (symbolIsNotEmpty) { parts.Add(symbol.ToString()); } parts.Add(res); return Invariant($"{type}({string.Join("_", parts)})").Replace(")(", ","); } /// /// Gets the SubscriptionDataConfig for the specified symbol and tick type /// /// Thrown if no configuration is found for the requested symbol /// The symbol to retrieve configuration for /// The tick type of the subscription to get. If null, will use the first ordered by TickType /// The SubscriptionDataConfig for the specified symbol private SubscriptionDataConfig GetSubscription(Symbol symbol, TickType? tickType = null) { if (!TryGetSubscription(symbol, tickType, out var subscription)) { // The symbol was not manually subscribed to. Mirror the behavior of order submission // (see GetSecurityForOrder): add the security automatically so users can register // indicators and consolidators without a prior AddSecurity()/AddEquity() call. if (CanAutoAddSecurity(symbol)) { AddSecurity(symbol); TryGetSubscription(symbol, tickType, out subscription); } if (subscription == null) { // this will happen if we did not find the subscription, let's give the user a decent error message throw new Exception($"Please register to receive data for symbol \'{symbol}\' using the AddSecurity() function."); } } return subscription; } /// /// Gets the subscription for the given symbol and optional tick type /// /// True if a subscription was found for the symbol; false otherwise private bool TryGetSubscription(Symbol symbol, TickType? tickType, out SubscriptionDataConfig subscription) { // deterministic ordering is required here var subscriptions = SubscriptionManager.SubscriptionDataConfigService .GetSubscriptionDataConfigs(symbol) // make sure common lean data types are at the bottom .OrderByDescending(x => LeanData.IsCommonLeanDataType(x.Type)) .ThenBy(x => x.TickType) .ToList(); // find our subscription subscription = subscriptions.FirstOrDefault(x => tickType == null || tickType == x.TickType) // if we can't locate the exact subscription by tick type just grab the first one we find ?? subscriptions.FirstOrDefault(); return subscription != null; } /// /// Creates and registers a new consolidator to receive automatic updates at the specified resolution as well as configures /// the indicator to receive updates from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The resolution at which to send data to the indicator, null to use the same resolution as the subscription /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, Resolution? resolution = null, Func selector = null) { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution), selector ?? (x => x.Value)); } /// /// Creates and registers a new consolidator to receive automatic updates at the specified resolution as well as configures /// the indicator to receive updates from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The resolution at which to send data to the indicator, null to use the same resolution as the subscription /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, TimeSpan? resolution = null, Func selector = null) { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution), selector ?? (x => x.Value)); } /// /// Registers the consolidator to receive automatic updates as well as configures the indicator to receive updates /// from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The consolidator to receive raw subscription data /// Selects a value from the BaseData send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, IDataConsolidator consolidator, Func selector = null) { // default our selector to the Value property on BaseData selector = selector ?? (x => x.Value); RegisterConsolidator(symbol, consolidator, null, indicator); // attach to the DataConsolidated event so it updates our indicator consolidator.DataConsolidated += (sender, consolidated) => { var value = selector(consolidated); indicator.Update(new IndicatorDataPoint(consolidated.Symbol, consolidated.EndTime, value)); }; } /// /// Registers the consolidator to receive automatic updates as well as configures the indicator to receive updates /// from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The resolution at which to send data to the indicator, null to use the same resolution as the subscription [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, Resolution? resolution = null) where T : IBaseData { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution, typeof(T))); } /// /// Registers the consolidator to receive automatic updates as well as configures the indicator to receive updates /// from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The resolution at which to send data to the indicator, null to use the same resolution as the subscription /// Selects a value from the BaseData send into the indicator, if null defaults to a cast (x => (T)x) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, Resolution? resolution, Func selector) where T : IBaseData { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution, typeof(T)), selector); } /// /// Registers the consolidator to receive automatic updates as well as configures the indicator to receive updates /// from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The resolution at which to send data to the indicator, null to use the same resolution as the subscription /// Selects a value from the BaseData send into the indicator, if null defaults to a cast (x => (T)x) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, TimeSpan? resolution, Func selector = null) where T : IBaseData { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution, typeof(T)), selector); } /// /// Registers the consolidator to receive automatic updates as well as configures the indicator to receive updates /// from the consolidator. /// /// The symbol to register against /// The indicator to receive data from the consolidator /// The consolidator to receive raw subscription data /// Selects a value from the BaseData send into the indicator, if null defaults to a cast (x => (T)x) [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void RegisterIndicator(Symbol symbol, IndicatorBase indicator, IDataConsolidator consolidator, Func selector = null) where T : IBaseData { // assign default using cast var selectorToUse = selector ?? (x => (T)x); RegisterConsolidator(symbol, consolidator, null, indicator); // check the output type of the consolidator and verify we can assign it to T var type = typeof(T); if (!type.IsAssignableFrom(consolidator.OutputType)) { if (type == typeof(IndicatorDataPoint) && selector == null) { // if no selector was provided and the indicator input is of 'IndicatorDataPoint', common case, a selector with a direct cast will fail // so we use a smarter selector as in other API methods selectorToUse = consolidated => (T)(object)new IndicatorDataPoint(consolidated.Symbol, consolidated.EndTime, consolidated.Value); } else { throw new ArgumentException($"Type mismatch found between consolidator and indicator for symbol: {symbol}." + $"Consolidator outputs type {consolidator.OutputType.Name} but indicator expects input type {type.Name}" ); } } // attach to the DataConsolidated event so it updates our indicator consolidator.DataConsolidated += (sender, consolidated) => { var value = selectorToUse(consolidated); indicator.Update(value); }; } /// /// Will unregister an indicator and it's associated consolidator instance so they stop receiving data updates /// /// The indicator instance to unregister [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void UnregisterIndicator(IndicatorBase indicator) { DeregisterIndicator(indicator); } /// /// Will deregister an indicator and it's associated consolidator instance so they stop receiving data updates /// /// The indicator instance to deregister [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public void DeregisterIndicator(IndicatorBase indicator) { foreach (var consolidator in indicator.Consolidators) { SubscriptionManager.RemoveConsolidator(null, consolidator); } indicator.Consolidators.Clear(); } /// /// Warms up a given indicator with historical data /// /// The symbol whose indicator we want /// The indicator we want to warm up /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(Symbol symbol, IndicatorBase indicator, Resolution? resolution = null, Func selector = null) { WarmUpIndicator(new[] { symbol }, indicator, resolution, selector); } /// /// Warms up a given indicator with historical data /// /// The symbols whose indicator we want /// The indicator we want to warm up /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(IEnumerable symbols, IndicatorBase indicator, Resolution? resolution = null, Func selector = null) { if (AssertIndicatorHasWarmupPeriod(indicator)) { IndicatorHistory(indicator, symbols, 0, resolution, selector); } } /// /// Warms up a given indicator with historical data /// /// The symbol whose indicator we want /// The indicator we want to warm up /// The necessary period to warm up 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) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(Symbol symbol, IndicatorBase indicator, TimeSpan period, Func selector = null) { WarmUpIndicator([symbol], indicator, period, selector); } /// /// Warms up a given indicator with historical data /// /// The symbols whose indicator we want /// The indicator we want to warm up /// The necessary period to warm up 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) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(IEnumerable symbols, IndicatorBase indicator, TimeSpan period, Func selector = null) { var history = GetIndicatorWarmUpHistory(symbols, indicator, period, out var identityConsolidator); if (history == Enumerable.Empty()) return; // assign default using cast selector ??= (x => x.Value); Action onDataConsolidated = bar => { var input = new IndicatorDataPoint(bar.Symbol, bar.EndTime, selector(bar)); indicator.Update(input); }; WarmUpIndicatorImpl(symbols, period, onDataConsolidated, history, identityConsolidator); } /// /// Warms up a given indicator with historical data /// /// The symbol whose indicator we want /// The indicator we want to warm up /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(Symbol symbol, IndicatorBase indicator, Resolution? resolution = null, Func selector = null) where T : class, IBaseData { WarmUpIndicator(new[] { symbol }, indicator, resolution, selector); } /// /// Warms up a given indicator with historical data /// /// The symbols whose indicator we want /// The indicator we want to warm up /// The resolution /// Selects a value from the BaseData to send into the indicator, if null defaults to the Value property of BaseData (x => x.Value) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(IEnumerable symbols, IndicatorBase indicator, Resolution? resolution = null, Func selector = null) where T : class, IBaseData { if (AssertIndicatorHasWarmupPeriod(indicator)) { IndicatorHistory(indicator, symbols, 0, resolution, selector); } } /// /// Warms up a given indicator with historical data /// /// The symbols whose indicator we want /// The indicator we want to warm up /// The necessary period to warm up 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) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(IEnumerable symbols, IndicatorBase indicator, TimeSpan period, Func selector = null) where T : class, IBaseData { var history = GetIndicatorWarmUpHistory(symbols, indicator, period, out var identityConsolidator); if (history == Enumerable.Empty()) return; // assign default selector selector ??= GetDefaultSelector(); // we expect T type as input Action onDataConsolidated = bar => { indicator.Update(selector(bar)); }; WarmUpIndicatorImpl(symbols, period, onDataConsolidated, history, identityConsolidator); } /// /// Warms up a given indicator with historical data /// /// The symbol whose indicator we want /// The indicator we want to warm up /// The necessary period to warm up the indicator /// Selects a value from the BaseData send into the indicator, if null defaults to a cast (x => (T)x) [DocumentationAttribute(HistoricalData)] [DocumentationAttribute(Indicators)] public void WarmUpIndicator(Symbol symbol, IndicatorBase indicator, TimeSpan period, Func selector = null) where T : class, IBaseData { WarmUpIndicator([symbol], indicator, period, selector); } private Func GetDefaultSelector() where T : IBaseData { if (typeof(T) == typeof(IndicatorDataPoint)) { return x => { if (!(x is IndicatorDataPoint)) { return (T)(object)new IndicatorDataPoint(x.Symbol, x.EndTime, x.Price); } return (T)x; }; } return x => (T)x; } private IEnumerable GetIndicatorWarmUpHistory(IEnumerable symbols, IIndicator indicator, TimeSpan timeSpan, out bool identityConsolidator) { identityConsolidator = false; if (!AssertIndicatorHasWarmupPeriod(indicator)) { return Enumerable.Empty(); } var periods = ((IIndicatorWarmUpPeriodProvider)indicator).WarmUpPeriod; if (periods != 0) { var resolution = timeSpan.ToHigherResolutionEquivalent(false); // if they are the same, means we can use an identity consolidator identityConsolidator = resolution.ToTimeSpan() == timeSpan; var resolutionTicks = resolution.ToTimeSpan().Ticks; if (resolutionTicks != 0) { periods *= (int)(timeSpan.Ticks / resolutionTicks); } try { return History(symbols, periods, resolution, dataNormalizationMode: GetIndicatorHistoryDataNormalizationMode(indicator)); } catch (ArgumentException e) { Debug($"{indicator.Name} could not be warmed up. Reason: {e.Message}"); } } return Enumerable.Empty(); } private bool AssertIndicatorHasWarmupPeriod(IIndicator indicator) { if (indicator is not IIndicatorWarmUpPeriodProvider) { if (!_isEmitWarmupInsightWarningSent) { Debug($"Warning: the 'WarmUpIndicator' feature only works with indicators which inherit from '{nameof(IIndicatorWarmUpPeriodProvider)}'" + $" and define a warm up period, setting property 'WarmUpPeriod' with a value > 0." + $" The provided indicator of type '{indicator.GetType().Name}' will not be warmed up."); _isEmitWarmupInsightWarningSent = true; } return false; } return true; } private void WarmUpIndicatorImpl(IEnumerable symbols, TimeSpan period, Action handler, IEnumerable history, bool identityConsolidator) where T : class, IBaseData { var consolidators = symbols.ToDictionary(symbol => symbol, symbol => { IDataConsolidator consolidator; if (SubscriptionManager.SubscriptionDataConfigService.GetSubscriptionDataConfigs(symbol).Count > 0) { consolidator = Consolidate(symbol, period, handler); } else { if (identityConsolidator) { period = TimeSpan.Zero; } var providedType = typeof(T); if (providedType.IsAbstract) { var dataType = SubscriptionManager.LookupSubscriptionConfigDataTypes( symbol.SecurityType, Resolution.Daily, // order by tick type so that behavior is consistent with 'GetSubscription()' symbol.IsCanonical()) // make sure common lean data types are at the bottom .OrderByDescending(tuple => LeanData.IsCommonLeanDataType(tuple.Item1)) .ThenBy(tuple => tuple.Item2).First(); consolidator = CreateConsolidator(period, dataType.Item1, dataType.Item2); } else { // if the 'providedType' is not abstract we use it instead to determine which consolidator to use var tickType = LeanData.GetCommonTickTypeForCommonDataTypes(providedType, symbol.SecurityType); consolidator = CreateConsolidator(period, providedType, tickType); } consolidator.DataConsolidated += (s, bar) => handler((T)bar); } return consolidator; }); foreach (var slice in history) { foreach (var (symbol, consolidator) in consolidators) { var consolidatorInputType = consolidator.InputType; if (slice.TryGet(consolidatorInputType, symbol, out var data)) { consolidator.Update(data); } } } // Scan for time after we've pumped all the data through for this consolidator foreach (var (symbol, consolidator) in consolidators) { if (consolidator.WorkingData != null) { DateTime currentTime; if (Securities.TryGetValue(symbol, out var security)) { currentTime = security.LocalTime; } else { var exchangeHours = MarketHoursDatabase.GetExchangeHours(symbol.ID.Market, symbol, symbol.SecurityType); currentTime = UtcTime.ConvertFromUtc(exchangeHours.TimeZone); } consolidator.Scan(currentTime); } SubscriptionManager.RemoveConsolidator(symbol, consolidator); } } /// /// Gets the default consolidator for the specified symbol and resolution /// /// The symbol whose data is to be consolidated /// The resolution for the consolidator, if null, uses the resolution from subscription /// The data type for this consolidator, if null, uses TradeBar over QuoteBar if present /// The new default consolidator [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public IDataConsolidator ResolveConsolidator(Symbol symbol, Resolution? resolution, Type dataType = null) { var tickType = dataType != null ? LeanData.GetCommonTickTypeForCommonDataTypes(dataType, symbol.SecurityType) : (TickType?)null; return CreateConsolidator(symbol, null, tickType, null, resolution, null); } /// /// Gets the default consolidator for the specified symbol and resolution /// /// The symbol whose data is to be consolidated /// The requested time span for the consolidator, if null, uses the resolution from subscription /// The data type for this consolidator, if null, uses TradeBar over QuoteBar if present /// The new default consolidator [DocumentationAttribute(ConsolidatingData)] [DocumentationAttribute(Indicators)] public IDataConsolidator ResolveConsolidator(Symbol symbol, TimeSpan? timeSpan, Type dataType = null) { var tickType = dataType != null ? LeanData.GetCommonTickTypeForCommonDataTypes(dataType, symbol.SecurityType) : (TickType?)null; return CreateConsolidator(symbol, null, tickType, timeSpan, null, null); } /// /// Creates a new consolidator for the specified period, generating the requested output type. /// /// The consolidation period /// The desired input type of the consolidator, such as TradeBar or QuoteBar /// Trade or Quote. Optional, defaults to trade /// A new consolidator matching the requested parameters [DocumentationAttribute(ConsolidatingData)] public static IDataConsolidator CreateConsolidator(TimeSpan period, Type consolidatorInputType, TickType? tickType = null) { if (period.Ticks == 0) { return CreateIdentityConsolidator(consolidatorInputType); } // if our type can be used as a trade bar, then let's just make one of those // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to TradeBar if (typeof(TradeBar).IsAssignableFrom(consolidatorInputType)) { return new TradeBarConsolidator(period); } // if our type can be used as a quote bar, then let's just make one of those // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to QuoteBar if (typeof(QuoteBar).IsAssignableFrom(consolidatorInputType)) { return new QuoteBarConsolidator(period); } // if our type can be used as a tick then we'll use a consolidator that keeps the TickType // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to Tick if (typeof(Tick).IsAssignableFrom(consolidatorInputType)) { switch (tickType) { case TickType.OpenInterest: return new OpenInterestConsolidator(period); case TickType.Quote: return new TickQuoteBarConsolidator(period); default: return new TickConsolidator(period); } } // if our type can be used as a DynamicData then we'll use the DynamicDataConsolidator if (typeof(DynamicData).IsAssignableFrom(consolidatorInputType)) { return new DynamicDataConsolidator(period); } // no matter what we can always consolidate based on the time-value pair of BaseData return new BaseDataConsolidator(period); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation period /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Resolution period, Action handler) { return Consolidate(symbol, period, TickType.Trade, handler); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation period /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, TimeSpan period, Action handler) { return Consolidate(symbol, period, TickType.Trade, handler); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation period /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Resolution period, Action handler) { return Consolidate(symbol, period.ToTimeSpan(), TickType.Quote, handler); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation period /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, TimeSpan period, Action handler) { return Consolidate(symbol, period, TickType.Quote, handler); } /// /// Registers the to receive consolidated data for the specified symbol and tick type. /// The handler and tick type must match. /// /// The symbol who's data is to be consolidated /// The consolidation period /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, TimeSpan period, Action handler) where T : class, IBaseData { // only infer TickType from T if it's not abstract (for example IBaseData, BaseData), else if will end up being TradeBar let's not take that // decision here (default type), it will be taken later by 'GetSubscription' so we keep it centralized // This could happen when a user passes in a generic 'Action' handler var tickType = typeof(T).IsAbstract ? (TickType?)null : LeanData.GetCommonTickTypeForCommonDataTypes(typeof(T), symbol.SecurityType); return Consolidate(symbol, period, tickType, handler); } /// /// Registers the to receive consolidated data for the specified symbol and tick type. /// The handler and tick type must match. /// /// The symbol who's data is to be consolidated /// The consolidation period /// The tick type of subscription used as data source for consolidator. Specify null to use first subscription found. /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Resolution period, TickType? tickType, Action handler) where T : class, IBaseData { return Consolidate(symbol, null, tickType, handler, null, period); } /// /// Registers the to receive consolidated data for the specified symbol and tick type. /// The handler and tick type must match. /// /// The symbol who's data is to be consolidated /// The consolidation period /// The tick type of subscription used as data source for consolidator. Specify null to use first subscription found. /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, TimeSpan period, TickType? tickType, Action handler) where T : class, IBaseData { return Consolidate(symbol, null, tickType, handler, period, null); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation calendar /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Func calendar, Action handler) { return Consolidate(symbol, calendar, TickType.Quote, handler); } /// /// Registers the to receive consolidated data for the specified symbol /// /// The symbol who's data is to be consolidated /// The consolidation calendar /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Func calendar, Action handler) { return Consolidate(symbol, calendar, TickType.Trade, handler); } /// /// Registers the to receive consolidated data for the specified symbol and tick type. /// The handler and tick type must match. /// /// The symbol who's data is to be consolidated /// The consolidation calendar /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Func calendar, Action handler) where T : class, IBaseData { // only infer TickType from T if it's not abstract (for example IBaseData, BaseData), else if will end up being TradeBar let's not take that // decision here (default type), it will be taken later by 'GetSubscription' so we keep it centralized // This could happen when a user passes in a generic 'Action' handler var tickType = typeof(T).IsAbstract ? (TickType?)null : LeanData.GetCommonTickTypeForCommonDataTypes(typeof(T), symbol.SecurityType); return Consolidate(symbol, calendar, tickType, handler); } /// /// Registers the to receive consolidated data for the specified symbol and tick type. /// The handler and tick type must match. /// /// The symbol who's data is to be consolidated /// The consolidation calendar /// The tick type of subscription used as data source for consolidator. Specify null to use first subscription found. /// Data handler receives new consolidated data when generated /// A new consolidator matching the requested parameters with the handler already registered [DocumentationAttribute(ConsolidatingData)] public IDataConsolidator Consolidate(Symbol symbol, Func calendar, TickType? tickType, Action handler) where T : class, IBaseData { return Consolidate(symbol, calendar, tickType, handler, null, null); } /// /// 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 target indicator /// 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null) { return IndicatorHistory(indicator, new[] { symbol }, period, resolution, selector); } /// /// Gets the historical data of an indicator for the specified symbols. The exact number of bars will be returned. /// The symbol must exist in the Securities collection. /// /// The target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) { var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0; if (warmupPeriod > 0 && period > 0) { warmupPeriod -= 1; } var history = History(symbols, period + warmupPeriod, resolution, dataNormalizationMode: GetIndicatorHistoryDataNormalizationMode(indicator)); return IndicatorHistory(indicator, history, selector); } /// /// 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 target indicator /// 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, int period, Resolution? resolution = null, Func selector = null) where T : IBaseData { return IndicatorHistory(indicator, new[] { symbol }, period, resolution, selector); } /// /// Gets the historical data of a bar indicator for the specified symbols. The exact number of bars will be returned. /// The symbol must exist in the Securities collection. /// /// The target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, int period, Resolution? resolution = null, Func selector = null) where T : IBaseData { var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0; if (warmupPeriod > 0 && period > 0) { warmupPeriod -= 1; } var history = History(symbols, period + warmupPeriod, resolution, dataNormalizationMode: GetIndicatorHistoryDataNormalizationMode(indicator)); return IndicatorHistory(indicator, history, selector); } /// /// 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 target 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null) { return IndicatorHistory(indicator, new[] { symbol }, span, resolution, selector); } /// /// 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 target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null) { return IndicatorHistory(indicator, symbols, Time - span, Time, resolution, selector); } /// /// 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 target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, TimeSpan span, Resolution? resolution = null, Func selector = null) where T : IBaseData { return IndicatorHistory(indicator, symbols, Time - span, Time, resolution, selector); } /// /// 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 target 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, TimeSpan span, Resolution? resolution = null, Func selector = null) where T : IBaseData { return IndicatorHistory(indicator, new[] { symbol }, span, resolution, selector); } /// /// Gets the historical data of an indicator for the specified symbols. The exact number of bars will be returned. /// The symbol must exist in the Securities collection. /// /// The target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null) { var history = History(symbols, GetIndicatorAdjustedHistoryStart(indicator, symbols, start, end, resolution), end, resolution, dataNormalizationMode: GetIndicatorHistoryDataNormalizationMode(indicator)); return IndicatorHistory(indicator, history, selector); } /// /// 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 target 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null) { return IndicatorHistory(indicator, new[] { symbol }, start, end, resolution, selector); } /// /// 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 target 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, Symbol symbol, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null) where T : IBaseData { return IndicatorHistory(indicator, new[] { symbol }, start, end, resolution, selector); } /// /// Gets the historical data of a bar indicator for the specified symbols. The exact number of bars will be returned. /// The symbol must exist in the Securities collection. /// /// The target indicator /// The symbols 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 public IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null, Func selector = null) where T : IBaseData { var history = History(symbols, GetIndicatorAdjustedHistoryStart(indicator, symbols, start, end, resolution), end, resolution, dataNormalizationMode: GetIndicatorHistoryDataNormalizationMode(indicator)); return IndicatorHistory(indicator, history, selector); } /// /// Gets the historical data of an indicator and convert it into pandas.DataFrame /// /// The target indicator /// 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 IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Func selector = null) { selector ??= (x => x.Value); return IndicatorHistory(indicator, history, (bar) => indicator.Update(new IndicatorDataPoint(bar.Symbol, bar.EndTime, selector(bar))), GetDataTypeFromSelector(selector)); } /// /// Gets the historical data of an bar indicator and convert it into pandas.DataFrame /// /// Bar indicator /// 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 IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Func selector = null) where T : IBaseData { selector ??= GetDefaultSelector(); return IndicatorHistory(indicator, history, (bar) => indicator.Update(selector(bar))); } /// /// Adds the provided consolidator and asserts the handler T type is assignable from the consolidator output, /// if not will throw /// private IDataConsolidator Consolidate(Symbol symbol, Func calendar, TickType? tickType, Action handler, TimeSpan? period, Resolution? resolution) where T : class, IBaseData { var consolidator = CreateConsolidator(symbol, calendar, tickType, period, resolution, typeof(T)); if (handler != null) { // register user-defined handler to receive consolidated data events consolidator.DataConsolidated += (sender, consolidated) => handler((T)consolidated); // register the consolidator for automatic updates via SubscriptionManager RegisterConsolidator(symbol, consolidator, tickType, indicatorBase: null); } return consolidator; } /// /// Registers a Renko or VolumeRenko consolidator for the specified symbol and bar size, /// and subscribes the to receive consolidated data. /// /// The symbol whose data is to be consolidated /// The bar size used for consolidation /// The tick type of the data to be consolidated /// Handler to receive consolidated data /// A new Renko-based consolidator with the handler registered public IDataConsolidator Consolidate(Symbol symbol, decimal size, TickType? tickType, Action handler) where T : class, IBaseData { var consolidator = CreateConsolidator(symbol, size, typeof(T), tickType); if (handler != null) { // register user-defined handler to receive consolidated data events consolidator.DataConsolidated += (sender, consolidated) => handler((T)consolidated); // register the consolidator for automatic updates via SubscriptionManager RegisterConsolidator(symbol, consolidator, tickType, indicatorBase: null); } return consolidator; } private IDataConsolidator CreateConsolidator(Symbol symbol, decimal size, Type consolidatorType, TickType? tickType) { var subscription = GetSubscription(symbol); // Select consolidator based on the consolidator type // size attribute will be used as barSize or range if (consolidatorType == typeof(VolumeRenkoBar)) { return new VolumeRenkoConsolidator(size); } if (consolidatorType == typeof(RenkoBar)) { return new RenkoConsolidator(size); } if (consolidatorType == typeof(RangeBar)) { return new RangeConsolidator((int)size); } // size attribute will be used as maxCount // If the subscription uses Tick resolution, choose the consolidator based on TickType if (subscription.Resolution == Resolution.Tick) { switch (tickType) { case TickType.OpenInterest: return new OpenInterestConsolidator((int)size); case TickType.Quote: return new TickQuoteBarConsolidator((int)size); default: return new TickConsolidator((int)size); } } if (consolidatorType == typeof(TradeBar)) { return new TradeBarConsolidator((int)size); } if (consolidatorType == typeof(QuoteBar)) { return new QuoteBarConsolidator((int)size); } // no matter what, we can always consolidate using BaseData with a maxCount return new BaseDataConsolidator((int)size); } private IDataConsolidator CreateConsolidator(Symbol symbol, Func calendar, TickType? tickType, TimeSpan? period, Resolution? resolution, Type consolidatorType) { // resolve consolidator input subscription var subscription = GetSubscription(symbol, tickType); // verify this consolidator will give reasonable results, if someone asks for second consolidation but we have minute // data we won't be able to do anything good, we'll call it second, but it would really just be minute! if (period.HasValue && period.Value < subscription.Increment || resolution.HasValue && resolution.Value < subscription.Resolution) { throw new ArgumentException($"Unable to create {symbol} consolidator because {symbol} is registered for " + Invariant($"{subscription.Resolution.ToStringInvariant()} data. Consolidators require higher resolution data to produce lower resolution data.") ); } IDataConsolidator consolidator = null; if (calendar != null) { // create requested consolidator consolidator = CreateConsolidator(calendar, subscription.Type, subscription.TickType); } else { // if not specified, default to the subscription resolution if (!period.HasValue && !resolution.HasValue) { period = subscription.Increment; } if (period.HasValue && period.Value == subscription.Increment || resolution.HasValue && resolution.Value == subscription.Resolution) { consolidator = CreateIdentityConsolidator(subscription.Type); } else { if (resolution.HasValue) { if (resolution.Value == Resolution.Daily) { if (subscription.ExtendedMarketHours && !Settings.DailyConsolidationUseExtendedMarketHours) { // Show this warning only once if (!_hasShownDailyConsolidationWarning) { Debug($"Warning: The subscription for {symbol} has ExtendedMarketHours=true, " + $"but Settings.DailyConsolidationUseExtendedMarketHours=false. " + $"Daily consolidations will exclude extended market hours. " + $"Enable algorithm.Settings.DailyConsolidationUseExtendedMarketHours to include them." ); _hasShownDailyConsolidationWarning = true; } } consolidator = new MarketHourAwareConsolidator(Settings.DailyPreciseEndTime, resolution.Value, subscription.Type, subscription.TickType, Settings.DailyConsolidationUseExtendedMarketHours && subscription.ExtendedMarketHours); } period = resolution.Value.ToTimeSpan(); } consolidator ??= CreateConsolidator(period.Value, subscription.Type, subscription.TickType); } } if (consolidatorType != null && !consolidatorType.IsAssignableFrom(consolidator.OutputType)) { throw new ArgumentException( $"Unable to consolidate with the specified handler because the consolidator's output type " + $"is {consolidator.OutputType.Name} but the handler's input type is {subscription.Type.Name}."); } return consolidator; } private IDataConsolidator CreateConsolidator(Func calendar, Type consolidatorInputType, TickType tickType) { // if our type can be used as a trade bar, then let's just make one of those // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to TradeBar if (typeof(TradeBar).IsAssignableFrom(consolidatorInputType)) { return new TradeBarConsolidator(calendar); } // if our type can be used as a quote bar, then let's just make one of those // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to QuoteBar if (typeof(QuoteBar).IsAssignableFrom(consolidatorInputType)) { return new QuoteBarConsolidator(calendar); } // if our type can be used as a tick then we'll use a consolidator that keeps the TickType // we use IsAssignableFrom instead of IsSubclassOf so that we can account for types that are able to be cast to Tick if (typeof(Tick).IsAssignableFrom(consolidatorInputType)) { if (tickType == TickType.Quote) { return new TickQuoteBarConsolidator(calendar); } return new TickConsolidator(calendar); } // if our type can be used as a DynamicData then we'll use the DynamicDataConsolidator if (typeof(DynamicData).IsAssignableFrom(consolidatorInputType)) { return new DynamicDataConsolidator(calendar); } // no matter what we can always consolidate based on the time-value pair of BaseData return new BaseDataConsolidator(calendar); } /// /// Creates a new consolidator identity consolidator for the requested output type. /// private static IDataConsolidator CreateIdentityConsolidator(Type consolidatorInputType) { if (typeof(TradeBar).IsAssignableFrom(consolidatorInputType)) { return new IdentityDataConsolidator(); } else if (typeof(QuoteBar).IsAssignableFrom(consolidatorInputType)) { return new IdentityDataConsolidator(); } else if (typeof(Tick).IsAssignableFrom(consolidatorInputType)) { return new IdentityDataConsolidator(); } else if (typeof(DynamicData).IsAssignableFrom(consolidatorInputType)) { return new DynamicDataConsolidator(1); } return new IdentityDataConsolidator(); } /// /// Registers and warms up (if EnableAutomaticIndicatorWarmUp is set) the indicator /// private void InitializeIndicator(IndicatorBase indicator, Resolution? resolution = null, Func selector = null, params Symbol[] symbols) { var dataType = GetDataTypeFromSelector(selector); foreach (var symbol in symbols) { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution, dataType), selector); } if (Settings.AutomaticIndicatorWarmUp) { WarmUpIndicator(symbols, indicator, resolution, selector); } } private void InitializeIndicator(IndicatorBase indicator, Resolution? resolution = null, Func selector = null, params Symbol[] symbols) where T : class, IBaseData { foreach (var symbol in symbols) { RegisterIndicator(symbol, indicator, resolution, selector); } if (Settings.AutomaticIndicatorWarmUp) { WarmUpIndicator(symbols, indicator, resolution, selector); } } private void InitializeOptionIndicator(IndicatorBase indicator, Resolution? resolution, Symbol symbol, Symbol mirrorOption) { RegisterIndicator(symbol, indicator, ResolveConsolidator(symbol, resolution, typeof(QuoteBar))); RegisterIndicator(symbol.Underlying, indicator, ResolveConsolidator(symbol.Underlying, resolution)); var symbols = new List { symbol, symbol.Underlying }; if (mirrorOption != null) { RegisterIndicator(mirrorOption, indicator, ResolveConsolidator(mirrorOption, resolution, typeof(QuoteBar))); symbols.Add(mirrorOption); } if (Settings.AutomaticIndicatorWarmUp) { WarmUpIndicator(symbols, indicator, resolution); } } private string InitializeOptionIndicator(Symbol symbol, out IRiskFreeInterestRateModel riskFreeRateModel, out IDividendYieldModel dividendYieldModel, decimal? riskFreeRate = null, decimal? dividendYield = null, OptionPricingModelType? optionModel = null, Resolution? resolution = null) where T : OptionIndicatorBase { var name = CreateIndicatorName(symbol, $"{typeof(T).Name}({riskFreeRate},{dividendYield},{OptionIndicatorBase.GetOptionModel(optionModel, symbol.ID.OptionStyle)})", resolution); riskFreeRateModel = riskFreeRate.HasValue ? new ConstantRiskFreeRateInterestRateModel(riskFreeRate.Value) // Make it a function so it's lazily evaluated: SetRiskFreeInterestRateModel can be called after this method : new FuncRiskFreeRateInterestRateModel((datetime) => RiskFreeInterestRateModel.GetInterestRate(datetime)); if (dividendYield.HasValue) { dividendYieldModel = new ConstantDividendYieldModel(dividendYield.Value); } else { dividendYieldModel = DividendYieldProvider.CreateForOption(symbol); } return name; } private void RegisterConsolidator(Symbol symbol, IDataConsolidator consolidator, TickType? tickType, IndicatorBase indicatorBase) { // keep a reference of the consolidator so we can unregister it later using only a reference to the indicator indicatorBase?.Consolidators.Add(consolidator); // register the consolidator for automatic updates via SubscriptionManager SubscriptionManager.AddConsolidator(symbol, consolidator, tickType); } private DateTime GetIndicatorAdjustedHistoryStart(IndicatorBase indicator, IEnumerable symbols, DateTime start, DateTime end, Resolution? resolution = null) { var warmupPeriod = (indicator as IIndicatorWarmUpPeriodProvider)?.WarmUpPeriod ?? 0; if (warmupPeriod != 0) { warmupPeriod -= 1; 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.DataType, request.IncludeExtendedMarketHours); if (adjustedStart < start) { start = adjustedStart; } } } } return start; } private DataNormalizationMode? GetIndicatorHistoryDataNormalizationMode(IIndicator indicator) { DataNormalizationMode? dataNormalizationMode = null; if (indicator is OptionIndicatorBase optionIndicator && optionIndicator.OptionSymbol.Underlying.SecurityType == SecurityType.Equity) { // we use point in time raw data to warmup option indicators which use underlying prices and strikes dataNormalizationMode = DataNormalizationMode.ScaledRaw; } return dataNormalizationMode; } private IndicatorHistory IndicatorHistory(IndicatorBase indicator, IEnumerable history, Action updateIndicator, Type dataType = null) where T : IBaseData { // Reset the indicator indicator.Reset(); var properties = indicator.GetType() .GetProperties() .Where(p => !p.IsDefined(typeof(PandasIgnoreAttribute), true) && !_ignoredProperties.Contains(p.Name)) .ToLookup(p => typeof(IIndicator).IsAssignableFrom(p.PropertyType)); var indicatorProperties = properties[true]; var nonIndicatorProperties = properties[false]; var indicatorsDataPointPerProperty = indicatorProperties .Select(p => InternalIndicatorValues.Create(indicator, p)) .Append(InternalIndicatorValues.Create(indicator, "Current")) .ToList(); var nonIndicatorValues = new Dictionary>(); var indicatorsDataPointsByTime = new List(); var lastConsumedTime = DateTime.MinValue; IndicatorDataPoint lastPoint = null; void consumeLastPoint(IndicatorDataPoint newInputPoint) { if (newInputPoint == null || lastConsumedTime == newInputPoint.EndTime) { return; } lastConsumedTime = newInputPoint.EndTime; var IndicatorDataPoints = new IndicatorDataPoints { Time = newInputPoint.Time, EndTime = newInputPoint.EndTime }; indicatorsDataPointsByTime.Add(IndicatorDataPoints); for (var i = 0; i < indicatorsDataPointPerProperty.Count; i++) { var newPoint = indicatorsDataPointPerProperty[i].UpdateValue(); IndicatorDataPoints.SetProperty(indicatorsDataPointPerProperty[i].Name, newPoint); } foreach (var property in nonIndicatorProperties) { var propertyName = property.Name; var propertyValue = property.GetValue(indicator); if (!nonIndicatorValues.TryGetValue(propertyName, out var propertyHistory)) { propertyHistory = new List<(DateTime, object)>(); nonIndicatorValues[propertyName] = propertyHistory; } propertyHistory.Add((newInputPoint.EndTime, propertyValue)); } } IndicatorUpdatedHandler callback = (object _, IndicatorDataPoint newInputPoint) => { if (!indicator.IsReady) { return; } if (lastPoint == null || lastPoint.Time != newInputPoint.Time) { // if null, it's the first point, we transitions from not ready to ready // else when the time changes we fetch the indicators values, some indicators which consume data from multiple symbols might trigger the Updated event // even if their value has not changed yet consumeLastPoint(newInputPoint); } lastPoint = newInputPoint; }; // register the callback, update the indicator and unregister finally indicator.Updated += callback; if (typeof(T) == typeof(IndicatorDataPoint) || typeof(T).IsAbstract) { history.PushThrough(bar => updateIndicator(bar), dataType); } else { // if the indicator requires a specific type, like a QuoteBar for an equity symbol, we need to fetch it directly foreach (var dataDictionary in history.Get()) { foreach (var dataPoint in dataDictionary.Values) { updateIndicator(dataPoint); } } } // flush the last point, this will be useful for indicator consuming time from multiple symbols consumeLastPoint(lastPoint); indicator.Updated -= callback; return new IndicatorHistory(indicatorsDataPointsByTime, indicatorsDataPointPerProperty, new Lazy( () => PandasConverter.GetIndicatorDataFrame(indicatorsDataPointPerProperty.Select(x => new KeyValuePair>(x.Name, x.Values)), nonIndicatorValues), isThreadSafe: false)); } private Type GetDataTypeFromSelector(Func selector) { Type dataType = null; if (_quoteRequiredFields.Any(x => ReferenceEquals(selector, x))) { dataType = typeof(QuoteBar); } else if (ReferenceEquals(selector, Field.Volume)) { dataType = typeof(TradeBar); } return dataType; } } }