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

# Data Point 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) > Data Point 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 data-point 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/data-point-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 2-standard-deviation `BollingerBands` indicator.

```python
bb = BollingerBands(20, 2)
```

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.
bb_dataframe = qb.indicator_history(bb, symbol, 50, Resolution.DAILY).data_frame
```

![Historical bollinger band data](https://cdn.quantconnect.com/i/tu/indicator-datapoint-py-helper-bb.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
   bb.window.size=50
   bb.lower_band.window.size=50
   bb.middle_band.window.size=50
   bb.upper_band.window.size=50
   bb.band_width.window.size=50
   bb.percent_b.window.size=50
   bb.standard_deviation.window.size=50
   bb.price.window.size=50
   ```
3. Iterate through the historical market data and update the indicator.
   ```python
   for bar in history:
       bb.update(bar.end_time, bar.close)
   ```
4. Populate a `DataFrame` with the data in the `Indicator` object.
   ```python
   bb_dataframe = pd.DataFrame({
       "current": pd.Series({x.end_time: x.value for x in bb}),
       "lowerband": pd.Series({x.end_time: x.value for x in bb.lower_band}),
       "middleband": pd.Series({x.end_time: x.value for x in bb.middle_band}),
       "upperband": pd.Series({x.end_time: x.value for x in bb.upper_band}),
       "bandwidth": pd.Series({x.end_time: x.value for x in bb.band_width}),
       "percentb": pd.Series({x.end_time: x.value for x in bb.percent_b}),
       "standarddeviation": pd.Series({x.end_time: x.value for x in bb.standard_deviation}),
       "price": pd.Series({x.end_time: x.value for x in bb.price})
   }).sort_index()
   ```
   ![Historical bollinger band data](https://cdn.quantconnect.com/i/tu/indicator-datapoint-py-classic-bb.png)

## Plot Indicators

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

Follow these steps to plot the indicator values:

1. Select the columns/features to plot.
   ```python
   bb_plot = bb_indicator[["upperband", "middleband", "lowerband", "price"]]
   ```
2. Call the `plot` method.
   ```python
   bb_plot.plot(figsize=(15, 10), title="SPY BB(20,2)"))
   ```
3. Show the plots.
   ```python
   plt.show()
   ```
   ![Line plot of bollinger band properties](https://cdn.quantconnect.com/i/tu/indicator-datapoint-py-plot.png)

## Examples

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

### Example 1: Quick Backtest On Bollinger Band

The following example demonstrates a quick backtest to testify the effectiveness of a Bollinger Band 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

# Create the Bollinger Band indicator with parameters to be studied.
bb = BollingerBands(20, 2)

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

# Create a order record and return column.
# Buy if the asset is underprice (below the lower band), sell if overpriced (above the upper band)
bb_dataframe["position"] = bb_dataframe.apply(lambda x: 1 if x.price < x.lowerband else -1 if x.price > x.upperband else 0, axis=1)
# Get the 1-day forward return.
bb_dataframe["return"] = bb_dataframe["price"].pct_change().shift(-1).fillna(0)
bb_dataframe["return"] = bb_dataframe["position"] * bb_dataframe["return"]

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