---
title: "History Requests"
description: "You can use a direct historical data request at any time throughout your algorithm. It returns all of the data you request as a single object."
canonical: https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-requests
markdown: https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-requests.md
language: python
source: https://github.com/QuantConnect/Documentation/tree/master/03%20Writing%20Algorithms/20%20Historical%20Data/02%20History%20Requests
modified: 2026-10-29
index: https://www.quantconnect.com/llms.txt
---

# History Requests

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

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

## Introduction

There are two ways to request historical data in your algorithms: direct historical data requests and indirect [algorithm warm up](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/warm-up-periods.md). You can use a direct historical data request at any time throughout your algorithm. It returns all of the data you request as a single object.

## Trailing Data Samples

To get historical data for a trailing time period, call `history` method with an an integer and a `Resolution`. For example, if you pass an asset `Symbol`, 5, and `Resolution.MINUTE` as the arguments, it returns the data of the asset during the most recent 5 minutes in the asset's [market hours](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/market-hours.md). These trailing minute bars can cross multiple trading days.

```python
class TrailingDataSamplesHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Get the Symbol of an asset.
        symbol = self.add_equity('SPY').symbol
        # Get the minute-resolution TradeBar data of the asset over the trailing 5 minutes.
        history = self.history(TradeBar, symbol, 5, Resolution.MINUTE)
```

| symbol | time | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- |
| SPY | 2024-12-18 15:56:00 | 588.63 | 590.390 | 588.57 | 590.39 | 1053414.0 |
| SPY | 2024-12-18 15:57:00 | 588.34 | 588.910 | 588.24 | 588.61 | 930643.0 |
| SPY | 2024-12-18 15:58:00 | 588.11 | 588.460 | 588.07 | 588.34 | 1138812.0 |
| SPY | 2024-12-18 15:59:00 | 587.92 | 588.325 | 587.70 | 588.10 | 1576391.0 |
| SPY | 2024-12-18 16:00:00 | 586.28 | 587.940 | 585.89 | 587.92 | 5865463.0 |

If you don't pass a `Resolution`, it defaults to the resolution of the security subscription. The following example returns 3 days of data for QQQ and 3 minutes of data for SPY:

```python
class TrailingDataSamplesForMulitpleAssetsHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 20)
        self.set_end_date(2024, 12, 31)
        # Add two assets with different resolutions.
        spy = self.add_equity('SPY', Resolution.MINUTE).symbol
        qqq = self.add_equity('QQQ', Resolution.DAILY).symbol
        # Get the trailing 3 bars of data for each asset.
        history = self.history(TradeBar, [spy, qqq], 3)
```

| symbol | time | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- |
| QQQ | 2024-12-17 16:00:00 | 535.80 | 537.49 | 534.130 | 536.410 | 25048673.0 |
| QQQ | 2024-12-18 16:00:00 | 516.47 | 536.87 | 515.010 | 535.110 | 47016560.0 |
| QQQ | 2024-12-19 16:00:00 | 514.17 | 521.75 | 513.830 | 521.110 | 42192908.0 |
| SPY | 2024-12-19 15:58:00 | 586.40 | 586.77 | 586.365 | 586.730 | 872817.0 |
| SPY | 2024-12-19 15:59:00 | 586.50 | 586.83 | 586.380 | 586.420 | 1524079.0 |
| SPY | 2024-12-19 16:00:00 | 586.10 | 586.53 | 585.850 | 586.495 | 4342748.0 |

If there is no data for the time period you request, the result has fewer samples. For instance, say an illiquid asset has no trading activity during the last 15 minutes of the trading day and you request the 10 most recent minute bars at market close, 4 PM Eastern Standard Time (ET). In this case, you won't get any data because LEAN will try to fetch data from 3:50 PM ET to 4 PM ET since [the market was open during that time](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/us-equity/market-hours.md#03-Regular-Trading-Hours), but there were no trades for the asset. For more information about missing data points, see [Missing Data Points](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-responses.md#05-Missing-Data-Points).

## Trailing Time Periods

To get historical data for a trailing time period, pass a `timedelta` to the `history` method. The days of the `timedelta` represent calendar days.

```python
class TrailingTimePeriodHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Get the Symbol of an asset.
        symbol = self.add_equity('SPY').symbol
        # Get the minute-resolution TradeBar data of the asset over the trailing 3 days.
        history = self.history(TradeBar, symbol, timedelta(3), Resolution.MINUTE)
```

| symbol | time | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- |
| SPY | 2024-12-16 09:31:00 | 606.02 | 606.400 | 605.89 | 606.00 | 612650.0 |
| SPY | 2024-12-16 09:32:00 | 606.01 | 606.305 | 605.94 | 605.99 | 132785.0 |
| SPY | ... | ... | ... | ... | ... | ... |
| SPY | 2024-12-18 15:59:00 | 587.92 | 588.325 | 587.70 | 588.10 | 1576391.0 |
| SPY | 2024-12-18 16:00:00 | 586.28 | 587.940 | 585.89 | 587.92 | 5865463.0 |

If there is no data in the time period, the result is empty. For more information about missing data points, see [Missing Data Points](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-responses.md#05-Missing-Data-Points).

## Date Ranges

To get historical data for a specific date range, call `history` method with start and end `datetime` objects. The `datetime` objects you provide are based in the [algorithm time zone](https://www.quantconnect.com/docs/v2/writing-algorithms/initialization.md#12-Set-Time-Zone).

```python
class DateRangeHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 1)
        self.set_end_date(2024, 12, 31)
        # Get the Symbol of an asset.
        symbol = self.add_equity('SPY').symbol
        # Get the daily-resolution TradeBar data of the asset during 2020.
        history = self.history(TradeBar, symbol, datetime(2020, 1, 1), datetime(2021, 1, 1), Resolution.DAILY)
```

| symbol | time | close | high | low | open | volume |
| --- | --- | --- | --- | --- | --- | --- |
| SPY | 2020-01-02 16:00:00 | 301.194352 | 301.194352 | 299.029520 | 299.998363 | 52757344.0 |
| SPY | 2020-01-03 16:00:00 | 298.913630 | 300.053991 | 297.708370 | 297.782540 | 65558742.0 |
| SPY | 2020-01-06 16:00:00 | 300.053991 | 300.137432 | 297.013028 | 297.087198 | 47199709.0 |
| SPY | 2020-01-07 16:00:00 | 299.210309 | 299.956643 | 298.756019 | 299.479175 | 37979987.0 |
| SPY | 2020-01-08 16:00:00 | 300.804960 | 302.038033 | 299.163953 | 299.451361 | 62265971.0 |
| SPY | ... | ... | ... | ... | ... | ... |
| SPY | 2020-12-24 13:00:00 | 348.496921 | 348.496921 | 347.033045 | 347.609151 | 22897100.0 |
| SPY | 2020-12-28 16:00:00 | 351.490783 | 351.887446 | 350.451904 | 351.150786 | 34765681.0 |
| SPY | 2020-12-29 16:00:00 | 350.820234 | 353.219101 | 350.225239 | 353.077436 | 48584327.0 |
| SPY | 2020-12-30 16:00:00 | 351.320785 | 352.350220 | 350.933566 | 351.689115 | 46030043.0 |
| SPY | 2020-12-31 16:00:00 | 353.105769 | 353.825429 | 350.612458 | 351.188564 | 58258603.0 |

If there is no data for the date range you request, the result is empty. For more information about missing data points, see [Missing Data Points](https://www.quantconnect.com/docs/v2/writing-algorithms/historical-data/history-responses.md#05-Missing-Data-Points).

## Flat Universe DataFrames

Most history requests return a flat DataFrame by default, where there is one column for each data point attribute. Universe history requests return a Series, where the values in the Series are lists of the universe data objects. For example, the following code snippet returns a Series where each value is a `List[ETFConstituentUniverse]`:

```python
class SeriesUniverseHistoryAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2024, 12, 19)
        self.set_end_date(2024, 12, 31)
        # Add an ETF constituents universe for SPY so you can get its historical data.
        universe = self.add_universe(self.universe.etf('SPY'))
        # Get the trailing 5 days of universe data.
        history = self.history(universe, 5, Resolution.DAILY)
```

![Pandas series where each value is a list of ETFConstituentsUniverse objects.](https://cdn.quantconnect.com/i/tu/history-request-series-of-lists.png)

To get the data into a DataFrame instead, set the `flatten` argument to `True`. In this case, the DataFrame has one column for each data point attribute.

```python
# Get the trailing 5 days of universe data in DataFrame format
# so you can perform DataFrame wrangling operations.
history = self.history(universe, 5, Resolution.DAILY, flatten=True)
```

| time | symbol | lastupdate | period | sharesheld | weight |
| --- | --- | --- | --- | --- | --- |
| 2024-12-13 | A RPTMYV3VC57P | 2024-12-11 | 1 days | 3667879.0 | 0.000799 |
| 2024-12-13 | AAPL R735QTJ8XC9X | 2024-12-11 | 1 days | 190881735.0 | 0.072612 |
| 2024-12-13 | ABBV VCY032R250MD | 2024-12-11 | 1 days | 22169383.0 | 0.005966 |
| 2024-12-13 | ABNB XK8H247DY6W5 | 2024-12-11 | 1 days | 5515085.0 | 0.001182 |
| 2024-12-13 | ABT R735QTJ8XC9X | 2024-12-11 | 1 days | 21833687.0 | 0.003846 |
| ... | ... | ... | ... | ... | ... |
| 2024-12-19 | XYL V18KR26TE3XH | 2024-12-17 | 1 days | 3065334.0 | 0.000572 |
| 2024-12-19 | YUM R735QTJ8XC9X | 2024-12-17 | 1 days | 3548979.0 | 0.000739 |
| 2024-12-19 | ZMH S6ZZPKTVDY05 | 2024-12-17 | 1 days | 2570208.0 | 0.000429 |
| 2024-12-19 | ZBRA R735QTJ8XC9X | 2024-12-17 | 1 days | 650402.0 | 0.000397 |
| 2024-12-19 | ZTS VDRJHVQ4FNFP | 2024-12-17 | 1 days | 5703558.0 | 0.001505 |

## Default Values

The following table describes the assumptions of the History API:

| Argument | Assumption |
| --- | --- |
| `resolution` | LEAN guesses the resolution you request by looking at the securities you already have in your algorithm. If you have a security subscription in your algorithm with a matching `Symbol`, the history request uses the same resolution as the subscription. If you don't have a security subscription in your algorithm with a matching `Symbol`, `Resolution.MINUTE` is the default. |

## Additional Options

The `history` method accepts the following additional arguments:

| Argument | Data Type | Description |
| --- | --- | --- |
| `fill_forward` | `bool/NoneType` | True to [fill forward](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/requesting-data.md#05-Fill-Forward) missing data. Otherwise, false. |
| `extended_market_hours` | `bool/NoneType` | True to include extended market hours data. Otherwise, false. |
| `data_mapping_mode` | `DataMappingMode/NoneType` | The [contract mapping mode](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts) to use for the security history request. |
| `data_normalization_mode` | `DataNormalizationMode/NoneType` | The price scaling mode to use for [US Equities](https://www.quantconnect.com/docs/v2/writing-algorithms/securities/asset-classes/us-equity/requesting-data.md#11-Data-Normalization) or [continuous Futures contracts](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts). |
| `contract_depth_offset` | `int/NoneType` | The desired offset from the current front month for [continuous Futures contracts](https://www.quantconnect.com/docs/v2/writing-algorithms/universes/futures.md#12-Continous-Contracts). |

If you don't provide a value for some of the preceding options, it uses the option value from the security subscription.

```python
self.future = self.add_future(Futures.Indices.SP_500_E_MINI)
history = self.history(
    symbols=[self.future.symbol],
    start=self.time - timedelta(days=15),
    end=self.time,
    resolution=Resolution.MINUTE,
    fill_forward=False,
    extended_market_hours=False,
    data_mapping_mode=DataMappingMode.LAST_TRADING_DAY,
    data_normalization_mode=DataNormalizationMode.RAW,
    contract_depth_offset=0
)
```

## Examples

The following examples demonstrate some common practices for trading using historical requests.

### Example 1: Mean-Variance Portfolio

The following algorithm constructs a monthly rebalance mean-variance portfolio using the top 20 liquid equities. The position sizing can be optimized by 1-year historical daily return of the universe members.

```python
from Portfolio.MaximumSharpeRatioPortfolioOptimizer import MaximumSharpeRatioPortfolioOptimizer

class HistoricalRequestAlgorithm(QCAlgorithm):
    # Instantiate the optimizer to perform mean-variance optimization.
    # Mean-variance optimization will not consider a risk-free rate, so we use 0.
    _optimizer = MaximumSharpeRatioPortfolioOptimizer(0.0, 1.0, 0.0)

    def initialize(self) -> None:
        self.set_start_date(2024, 9, 1)
        self.set_end_date(2024, 12, 31)

        # Seed the last price to set the initial price of the BTCUSDT holdings.
        self.settings.seed_initial_prices = True

        # Monthly renewal of the top 20 liquid universe to trade popular stocks.
        self.universe_settings.schedule.on(self.date_rules.month_start())
        self._universe = self.add_universe(self.universe.top(20))

        # Set a scheduled event to rebalance the portfolio at the start of every month.
        self.schedule.on(self.date_rules.month_start(), self.time_rules.at(9, 31), self.rebalance)

    def rebalance(self) -> None:
        # Historical data request to get 1-year data for optimization.
        symbols = self._universe.selected
        history = self.history(symbols, 253, Resolution.DAILY).close.unstack(0).dropna()
        # Daily return on the universe members to calculate the optimized weights.
        returns = history.pct_change().dropna()

        # Calculate the optimized weights.
        weights = self._optimizer.optimize(returns)

        # Rebalance the portfolio according to the optimized weights.
        targets = [PortfolioTarget(symbol, size if abs(size) > 0.01 else 0) for symbol, size in zip(symbols, weights)]
        self.set_holdings(targets, liquidate_existing_holdings=True)
```

### Other Examples

For more examples, see the following algorithms:

**Demonstration Algorithm**

- [HistoryAlgorithm.py](https://github.com/QuantConnect/Lean/blob/master/Algorithm.Python/HistoryAlgorithm.py) (Python)
