---
title: "Index"
description: "This page explains how to get historical price and indicator data for Indices."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/asset-classes/index
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/asset-classes/index.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/20%20Historical%20Data/04%20Asset%20Classes/08%20Index
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# Index

[Documentation](https://www.quantconnect.com/docs/v2.md) > [Writing Algorithms](https://www.quantconnect.com/docs/v2/writing-algorithms.md) > Historical Data > Asset Classes > Index

> 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 get historical price and indicator data for Indices.

## Bars

To get historical [price data](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/index/handling-data.md#02-Bars), call the `history` method with an Index `Symbol`. This method returns a DataFrame with columns for the open, high, low, and close.

```python
class IndexPriceHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Get the Symbol of an Index.
        symbol = self.add_index('SPX').symbol
        # Get the 5 trailing daily bars of the Index in DataFrame format.
        history = self.history(symbol, 5, Resolution.DAILY)
```

| symbol | time | close | high | low | open |
| --- | --- | --- | --- | --- | --- |
| SPX | 2024-12-12 15:15:00 | 6051.70 | 6079.68 | 6051.70 | 6074.05 |
| SPX | 2024-12-13 15:15:00 | 6050.83 | 6078.58 | 6035.77 | 6068.48 |
| SPX | 2024-12-16 15:15:00 | 6074.48 | 6085.19 | 6059.14 | 6064.04 |
| SPX | 2024-12-17 15:15:00 | 6050.31 | 6057.68 | 6035.19 | 6046.33 |
| SPX | 2024-12-18 15:15:00 | 5869.22 | 6070.67 | 5867.79 | 6048.69 |

```python
# Calculate the daily growth.
daily_growth = history.close.pct_change().iloc[1:]
```

```python
symbol  time
SPX     2024-12-13 15:15:00   -0.000144
        2024-12-16 15:15:00    0.003909
        2024-12-17 15:15:00   -0.003979
        2024-12-18 15:15:00   -0.029931
Name: close, dtype: float64
```

If you intend to use the data in the DataFrame to create `TradeBar` objects, request that the history request returns the data type you need. Otherwise, LEAN consumes unnecessary computational resources populating the DataFrame. To get a list of `TradeBar` objects instead of a DataFrame, call the `history[TradeBar]` method.

```python
# Get the 5 trailing daily bars of the Index in TradeBar format.
history = self.history[TradeBar](symbol, 5, Resolution.DAILY)
# Iterate through the TradeBar objects and access their prices.
for trade_bar in history:
    price = trade_bar.price
```

Request minute, hour, or daily resolution data. Otherwise, the history request won't return any data.

## Slices

To get historical [Slice](https://www.quantconnect.com/docs/v2/writing-algorithms/key-concepts/time-modeling/timeslices.md) data, call the `history` method without passing any `Symbol` objects. This method returns `Slice` objects, which contain data points from all the datasets in your algorithm. If you omit the `resolution` argument, it uses the resolution that you set for each security and dataset when you created the subscriptions.

```python
class SliceHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 1)
        self.set_end_date(2024, 12, 31)
        # Add some securities and datasets.
        self.add_index('SPX')
        # Get the historical Slice objects over the last 5 days for all the subcriptions in your algorithm.
        history = self.history(5, Resolution.DAILY)
        # Iterate through each historical Slice.
        for slice_ in history:
            # Iterate through each TradeBar in this Slice.
            for symbol, trade_bar in slice_.bars.items():
                close = trade_bar.close
```

## Indicators

To get historical [indicator](https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/key-concepts.md) values, call the `indicator_history` method with an indicator and the security's `Symbol`.

```python
class IndexIndicatorHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Get the Symbol of a security.
        symbol = self.add_index('SPX').symbol
        # Get the 21-day SMA values of the security for the last 5 trading days.
        history = self.indicator_history(SimpleMovingAverage(21), symbol, 5, Resolution.DAILY)
```

To organize the data into a DataFrame, use the `data_frame` property of the result.

```python
# Organize the historical indicator data into a DataFrame to enable pandas wrangling.
history_df = history.data_frame
```

|  | current | rollingsum |
| --- | --- | --- |
| 2024-12-12 15:15:00 | 6003.055714 | 126064.17 |
| 2024-12-13 15:15:00 | 6006.096667 | 126128.03 |
| 2024-12-16 15:15:00 | 6012.036190 | 126252.76 |
| 2024-12-17 15:15:00 | 6020.634286 | 126433.32 |
| 2024-12-18 15:15:00 | 6019.442381 | 126408.29 |

```python
# Get the maximum of the SMA values.
sma_max = history_df.current.max()
```

The `indicator_history` method resets your indicator, makes a history request, and updates the indicator with the historical data. Just like with regular history requests, the `indicator_history` method supports time periods based on a trailing number of bars, a trailing period of time, or a defined period of time. If you don't provide a `resolution` argument, it defaults to match the resolution of the security subscription.

To make the `indicator_history` method update the indicator with an [alternative price field](https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/automatic-indicators.md#07-Alternative-Price-Fields) instead of the close (or mid-price) of each bar, pass a `selector` argument.

```python
# Get the historical values of an indicator over the last 30 days, applying the indicator to the security's high price.
history = self.indicator_history(indicator, symbol, timedelta(30), selector=Field.HIGH)
```

Some indicators require the prices of two securities to compute their value (for example, [Beta](https://www.quantconnect.com/docs/v2/writing-algorithms/indicators/supported-indicators/beta.md)). In this case, pass a list of the `Symbol` objects to the method.

```python
class IndexMultiAssetIndicatorHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Add the target and reference securities.
        target_symbol = self.add_index('NDX').symbol
        reference_symbol = self.add_index('SPX').symbol
        # Create a 21-period Beta indicator.
        beta = Beta("", target_symbol, reference_symbol, 21)
        # Get the historical values of the indicator over the last 10 trading days.
        history = self.indicator_history(beta, [target_symbol, reference_symbol], 10, Resolution.DAILY)
        # Get the average Beta value.
        beta_avg = history.data_frame.mean()
```

## Examples

The following examples demonstrate some common practices for trading with Index historical data.

### Example 1: Replicating Portfolio

The example below constructed a replicating SGX portfolio using the top 100 weighted SPY constituents. It provides an alternative way for retail investors to invest in SGX without access to certain financial instruments and a hedging idea on SGX close hours.

```python
from sklearn.linear_model import LinearRegression

class SGXMatchingTradingAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)
        self.set_cash(100000)
        self.set_warm_up(timedelta(7))

        # Request SGX Index data for matching.
        self._sgx = self.add_index("SGX").symbol
        self._spy = Symbol.create('SPY', SecurityType.EQUITY, Market.USA)
        # We will try to use SPY constituents to reproduce the SGX index.
        self._universe = self.add_universe(
            self.universe.etf(
                self._spy,
                universe_filter_func=lambda x: [
                    y.symbol for y in sorted(
                        [y for y in x if y.weight],
                        key=lambda x: x.weight, reverse=True
                    )[:100]
                ]
            )
        )

        # Schedule an event to rebalance the portfolio.
        self.schedule.on(
            self.date_rules.every_day(self._spy),
            self.time_rules.after_market_open(self._spy, 1),
            self.rebalance
        )

    def rebalance(self) -> None:
        if self.is_warming_up or not self._universe.selected:
            return
        symbols = list(self._universe.selected)
        # Obtain the historical data.
        history = self.history([self._sgx] + symbols, 252, Resolution.DAILY).unstack(0).close
        history = history.groupby(history.index.date).last().dropna()
        # Obtain the weights of SPY constituents that best reproduce SGX.
        weights = self.calculate_weights(history[symbols], history[self._sgx])
        self.set_holdings(
            [PortfolioTarget(symbol, weight) for symbol, weight in zip(symbols, weights)],
            liquidate_existing_holdings=True
        )

    def calculate_weights(self, history: pd.DataFrame, benchmark: pd.Series) -> pd.Series:
        # Use log price to eliminate the compounding effect.
        # Perform regression to obtain the best-replicating portfolio of SGX.
        lr = LinearRegression(fit_intercept=False).fit(np.log(history), np.log(benchmark))
        sum_ = sum(abs(lr.coef_))
        return [c/sum_ for c in lr.coef_]
```
