---
title: "Bar Indicators"
description: "Learn how to create, update, and read bar indicators in the research environment in QuantConnect."
canonical: https://www.quantconnect.com/docs/v2/research-environment/indicators/bar-indicators
markdown: https://www.quantconnect.com/docs/v2/research-environment/indicators/bar-indicators.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/04%20Research%20Environment/06%20Indicators/03%20Bar%20Indicators
modified: 2026-10-30
index: https://www.quantconnect.com/llms.txt
---

# Bar Indicators

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Research Environment](https://www.quantconnect.com/docs/v2/research-environment.md) > [Indicators](https://www.quantconnect.com/docs/v2/research-environment/indicators.md) > Bar Indicators

> Code examples are shown in Python. Append `?lang=csharp` to this URL for the C# version of this page.

## Introduction

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

## Create Subscriptions

You need to [subscribe to some market data](https://www.quantconnect.com/docs/v2/research-environment/datasets/us-equity.md#03-Create-Subscriptions) in order to calculate indicator values.

```python
qb = QuantBook()
symbol = qb.add_equity("SPY").symbol
```

## Create Indicator Timeseries

You need to [subscribe to some market data](https://www.quantconnect.com/docs/v2/research-environment/indicators/bar-indicators.md#03-Create-Subscriptions) and create an indicator in order to calculate a timeseries of indicator values. In this example, use a 20-period `AverageTrueRange` indicator.

```python
atr = AverageTrueRange(20)
```

You can create the indicator timeseries with the `indicator_history` helper method or you can manually create the timeseries.

### IndicatorHistory Helper Method

To create an indicator timeseries with the helper method, call the `indicator_history` method.

```python
# Create a dataframe with a date index, and columns are indicator values.
atr_dataframe = qb.indicator_history(atr, symbol, 50, Resolution.DAILY).data_frame
```

![Historical average true range data](https://cdn.quantconnect.com/i/tu/indicator-bar-py-helper-atr.png)

### Manually Create the Indicator Timeseries

Follow these steps to manually create the indicator timeseries:

1. Get some [historical data](https://www.quantconnect.com/docs/v2/research-environment/datasets/key-concepts.md).
   ```python
   # Request historical trading data with the daily resolution.
   history = qb.history[TradeBar](symbol, 70, Resolution.DAILY)
   ```
2. Set the indicator `window.size` for each attribute of the indicator to hold their values.
   ```python
   # Set the window.size to the desired timeseries length
   atr.window.size = 50
   atr.true_range.window.size = 50
   ```
3. Iterate through the historical market data and update the indicator.
   ```python
   for bar in history:
       atr.update(bar)
   ```
4. Populate a `DataFrame` with the data in the `Indicator` object.
   ```python
   atr_dataframe = pd.DataFrame({
       "current": pd.Series({x.end_time: x.value for x in atr}),
       "truerange": pd.Series({x.end_time: x.value for x in atr.true_range})
   }).sort_index()
   ```
   ![Historical average true range data](https://cdn.quantconnect.com/i/tu/indicator-bar-py-classic-atr.png)

## Plot Indicators

You need to [create an indicator timeseries](https://www.quantconnect.com/docs/v2/research-environment/indicators/bar-indicators.md#04-Create-Indicator-Timeseries) to plot the indicator values.

Follow these steps to plot the indicator values:

1. Call the `plot` method.
   ```python
   atr_indicator.plot(title="SPY ATR(20)", figsize=(15, 10))
   ```
2. Show the plots.
   ```python
   plt.show()
   ```
   ![Line plot of average true range properties](https://cdn.quantconnect.com/i/tu/indicator-bar-py-plot.png)

## Examples

The following examples demonstrate some common practices for researching with bar indicators.

### Example 1: Quick Backtest On William Percent Ratio

The following example demonstrates a quick backtest to testify the effectiveness of a William Percent Ratio mean-reversal under the research enviornment.

```python
# Instantiate the QuantBook instance for researching.
qb = QuantBook()
# Request SPY data to work with the indicator.
symbol = qb.add_equity("SPY").symbol

# Get the historical data for trading.
history = qb.history(symbol, 252, Resolution.DAILY).close.unstack(0).iloc[:, 0]

# Create the William %R indicator with parameters to be studied.
indicator = WilliamsPercentR(20)

# Get the indicator history of the indicator.
indicator_dataframe = qb.indicator_history(indicator, symbol, 252, Resolution.DAILY).data_frame

# Create a order record and return column.
# Buy if the asset is underprice (below -80), sell if overpriced (above -20)
indicator_dataframe["position"] = indicator_dataframe.apply(lambda x: 1 if x.current < -80 else -1 if x.current > -20 else 0, axis=1)
# Get the 1-day forward return.
indicator_dataframe["return"] = history.pct_change().shift(-1).fillna(0)
indicator_dataframe["return"] = indicator_dataframe["position"] * indicator_dataframe["return"]

# Obtain the cumulative return curve as a mini-backtest.
equity_curve = (indicator_dataframe["return"] + 1).cumprod()
equity_curve.plot(title="Equity Curve", ylabel="Equity", xlabel="time");
```
