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 RegisterIndicatorregister_indicator method. The RegisterIndicatorregister_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 RegisterIndicatorregister_indicator method can accept a timedeltaTimeSpan, 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 CloseOPEN, HIGH, LOW, or CLOSE, provide a selector argument to the RegisterIndicatorregister_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 RegisterIndicatorregister_indicator method can accept a timedeltaTimeSpan, 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;
});

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: