Bar Indicators


This page explains how to create, update and visualize LEAN bar indicators.


Working knowledge of C#.

If you use Python, you must understand how to work with pandas DataFrames and Series. If you are not familiar with pandas, refer to the pandas documentation.

Get Historical Data

Get some historical market data to warm-up and create a historical record of indicator values. For example, to get data for SPY, run:

var qb = new QuantBook();
var symbol = qb.AddEquity("SPY").Symbol;
var history = qb.History(symbol, 70, Resolution.Daily);
qb = QuantBook()
symbol = qb.AddEquity("SPY").Symbol
history = qb.History(symbol, 70, Resolution.Daily).loc[symbol]

Create Indicator Timeseries

Follow these steps to create an indicator timeseries:

  1. Create a bar indicator (utilizing OHLC information). In this tutorial, we'll be using a 20-period AverageTrueRange indicator.
  2. var atr = new AverageTrueRange(20);
    atr = AverageTrueRange(20)
  3. Create a RollingWindow for each attribute of the indicator to hold their values.
  4. In this example, save 50 data points.

    var time = new RollingWindow<DateTime>(50);
    var window = new Dictionary<string, RollingWindow<decimal>>();
    window["averagetruerange"] = new RollingWindow<decimal>(50);
    window["truerange"] = new RollingWindow<decimal>(50);
    window = {}
    window['time'] = RollingWindow[DateTime](50)
    window['averagetruerange'] = RollingWindow[float](50)
    window["truerange"] = RollingWindow[float](50)
  5. Set handler methods to update the RollingWindows.
  6. atr.Updated += (sender, updated) => 
        var indicator = (AverageTrueRange)sender;
    def UpdateAverageTrueRangeWindow(sender: object, updated: IndicatorDataPoint) -> None:
        indicator = sender
    atr.Updated += UpdateAverageTrueRangeWindow

    When the indicators receive new data, the handler will add the new IndicatorDataPoints into the RollingWindows.

  7. Iterate the historical market data to update the indicators and the RollingWindows.
  8. foreach(var bar in history){
        // Update the indicators with the whole bar.
    for time, row in history.iterrows():
        # Create a TradeBar/QuoteBar to update the bar indicator.
        bar = TradeBar(time, symbol,, row.high, row.low, row.close, row.volume)
        # Update the indicator with TradeBar/QuoteBar.
  9. Display the data.
  10. Console.WriteLine($"time,{string.Join(',', window.Select(kvp => kvp.Key))}");
    foreach (var i in Enumerable.Range(0, 5).Reverse())
        var data = string.Join(", ", window.Select(kvp => Math.Round(kvp.Value[i],6)));
        Console.WriteLine($"{time[i]:yyyyMMdd}, {data}");
  11. Convert the RollingWindows' data into pandas.DataFrame.
  12. atr_dataframe = pd.DataFrame(window).set_index('time')

Indicator Helper Method

Call the qb.Indicator method to create an indicator timeseries.

var atrIndicator = qb.Indicator(atr, symbol, 50, Resolution.Daily);
atr_indicator = qb.Indicator(atr, symbol, 50, Resolution.Daily)

Plot Indicators

Jupyter Notebooks don't currently support libraries to plot historical data, but we are working on adding the functionality. Until the functionality is added, use Python to plot historical Equity Options data.

You can call the in-built plot method of pandas.DataFrame to plot the indicators.

  1. Call plot to plot the indicator.
  2. atr_indicator.plot(title="SPY ATR(20)", figsize=(15, 10))
  3. Show the plots.

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: