Consolidating Data
Updating Indicators
Introduction
You can use consolidators to automatically update indicators in your algorithms. The consolidators can update your indicators at each time step or with aggregated bars. By default, LEAN updates data point indicators with the close price of the consolidated bars, but you can change it to a custom data field.
Standard Indicator Periods
If your algorithm has a static universe, you can create automatic indicators in just one line of code. When you create an automatic indicator, LEAN creates a consolidator, hooks it up for automatic updates, and then updates the indicator with the consolidated bars.
// Consolidate minute SPY data into 14-bar daily indicators var ema = EMA("SPY", 14, Resolution.Daily); var sma = SMA("SPY", 14, Resolution.Daily);
# Consolidate minute SPY data into 14-bar daily indicators ema = self.ema("SPY", 14, Resolution.DAILY) sma = self.sma("SPY", 14, Resolution.DAILY)
If your algorithm has a dynamic universe, create a manual indicator and then create a time period consolidator that updates the indicator at each time step. Keep a reference to the consolidator so you can remove it when your algorithm removes the security from the universe.
public override void Initialize() { _ema = new ExponentialMovingAverage(14); _consolidator = new TradeBarConsolidator(1); _consolidator.DataConsolidated += OnDataConsolidated; SubscriptionManager.AddConsolidator(_symbol, _consolidator); } // Define consolidator handler function as a class method public void OnDataConsolidated(object sender, TradeBar bar) { _ema.Update(bar.EndTime, bar.Close); }
def initialize(self): self._ema = ExponentialMovingAverage(14) self._consolidator = TradeBarConsolidator(1) self._consolidator.data_consolidated += self._on_data_consolidated self.subscription_manager.add_consolidator(self._symbol, self._consolidator) # Define consolidator handler function as a class method def _on_data_consolidated(self, sender, bar): self._ema.update(bar.end_time, bar.close)
Custom Indicator Periods
It's common to update indicators with price data that spans a normal time period like one minute or one day. It's less common to update an indicator with exotic time periods (for example, a 7-minute consolidated bar), so these types of indicators may provide more opportunities for alpha. To update indicators with exotic data, create a manual indicator and then call the RegisterIndicator
register_indicator
method. The RegisterIndicator
register_indicator
method wires up the indicator for automatic updates at the time interval you provide.
// Calculate the SMA with 10 7-minute bars var symbol = AddEquity("SPY", Resolution.Minute).Symbol; var indicator = new SimpleMovingAverage(10); RegisterIndicator(symbol, indicator, TimeSpan.FromMinutes(7));
# Calculate the SMA with 10 7-minute bars self._symbol = self.add_equity("SPY", Resolution.MINUTE).symbol self._indicator = SimpleMovingAverage(10) self.register_indicator(self._symbol, self._indicator, timedelta(minutes=7))
The RegisterIndicator
register_indicator
method can accept a timedelta
TimeSpan
, Resolution
, or an unregistered consolidator. If you apply the indicator to a security in a dynamic universe, provide a consolidator so that you can remove it when your algorithm removes the security from the universe.
// TimeSpan RegisterIndicator(symbol, indicator, TimeSpan.FromMinutes(7)); // Resolution RegisterIndicator(symbol, indicator, Resolution.Hour); // Consolidator _consolidator = new TradeBarConsolidator(35); RegisterIndicator(symbol, indicator, _consolidator);
# timedelta self.register_indicator(self._symbol, self._indicator, timedelta(minutes=7)) # Resolution self.register_indicator(self._symbol, self._indicator, Resolution.HOUR) # Consolidator self._consolidator = TradeBarConsolidator(35) self.register_indicator(self._symbol, self._indicator, self._consolidator)
Custom Indicator Values
Data point indicators use only a single price data in their calculations. By default, those indicators use the closing price. For
assets with TradeBar
data, that price is the TradeBar
close price. For assets with QuoteBar
data, that price is the mid-price of the bid closing price and the ask closing price. To create an indicator with the other fields like the Open
, High
, Low
, or Close
OPEN
, HIGH
, LOW
, or CLOSE
, provide a selector
argument to the RegisterIndicator
register_indicator
method.
// Define a 10-period RSI with indicator the constructor _rsi = new RelativeStrengthIndex(10, MovingAverageType.Simple); // Register the daily High price data to automatically update the indicator RegisterIndicator(symbol, _rsi, Resolution.Daily, Field.High);
# Define a 10-period RSI with indicator constructor self._rsi = RelativeStrengthIndex(10, MovingAverageType.SIMPLE) # Register the daily High price data to automatically update the indicator self.register_indicator(self._symbol, self._rsi, Resolution.DAILY, Field.HIGH)
The RegisterIndicator
register_indicator
method can accept a timedelta
TimeSpan
, Resolution
, or an unregistered consolidator. If you apply the indicator to a security in a dynamic universe, provide a consolidator so that you can remove it when your algorithm removes the security from the universe.
The Field
class has the following selector
properties:
To create a custom selector
, define a function that calculates the value.
RegisterIndicator(_symbol, _rsi, Resolution.Daily, x => { var bar = x as IBaseDataBar; return (bar.Low + bar.High) / 2; });