🚀 AI One-Click Generation of quantconnect Strategy Code

How to Get Historical Price Data for Your Trading Strategy in Python

quantconnect | Published on: 2025/11/27
The following content is generated by EasyQuant .

Problem Description

How do I get the last 30 days of daily closing prices for a stock in my code?

Solution

To retrieve the last 30 days of daily closing prices in QuantConnect, you use the self.history method. This method returns a pandas DataFrame indexed by Symbol and Time.

Here is the specific implementation using the PEP8 Python API.

Implementation Details

You can request history in two ways:

  1. By Bar Count: Request exactly 30 trading bars (most common).
  2. By Time Period: Request data covering the last 30 calendar days.

The example below demonstrates how to request the last 30 trading bars of daily data and extract the closing prices.

from AlgorithmImports import *

class HistoricalDataAlgorithm(QCAlgorithm):

    def initialize(self):
        self.set_start_date(2023, 1, 1)
        self.set_cash(100000)
        
        # 1. Add the equity and save the Symbol object
        self.spy = self.add_equity("SPY", Resolution.DAILY).symbol

    def on_data(self, data: Slice):
        # 2. Request history for the specific symbol
        # Arguments: Symbol, Length (30 bars), Resolution
        history_df = self.history(self.spy, 30, Resolution.DAILY)

        # 3. Check if data exists to avoid errors
        if history_df.empty or 'close' not in history_df.columns:
            return

        # 4. Extract the 'close' column
        # The result is a pandas Series
        closing_prices = history_df['close']

        # Example: Log the most recent closing price
        # .iloc[-1] gets the last element (most recent)
        # .iloc[0] gets the first element (oldest)
        current_close = closing_prices.iloc[-1]
        self.log(f"Most recent close: {current_close}")
        
        # Example: Calculate a simple moving average of the last 30 days
        average_price = closing_prices.mean()
        self.log(f"30-Day Average: {average_price}")

Key Concepts

  1. self.history(symbol, 30, Resolution.DAILY):

    • Symbol: The specific asset you want data for.
    • 30: The integer indicates the number of bars (trading days) to retrieve.
    • Resolution.DAILY: Ensures you get daily bars. If omitted, it defaults to the resolution set in add_equity.
  2. DataFrame Structure:
    The returned DataFrame has a MultiIndex of (symbol, time). When you access history_df['close'], you get a pandas Series containing the closing prices.

  3. Handling Multiple Symbols:
    If you pass a list of symbols to self.history, the DataFrame will contain data for all of them. You would then typically use .loc[symbol] to isolate the data for a specific stock.

Q&A

Q: What if I want the last 30 calendar days instead of 30 trading bars?
A: You can import timedelta and pass a time delta object instead of an integer.

from datetime import timedelta
# Gets data from the last 30 calendar days (might be fewer than 30 bars due to weekends)
history = self.history(self.spy, timedelta(days=30), Resolution.DAILY)

Q: Can I get this data inside initialize?
A: Yes. This is useful for "warming up" indicators or calculating initial thresholds. The syntax is exactly the same.

Q: Why is the data returned as a DataFrame?
A: QuantConnect uses pandas DataFrames because they are the standard for data analysis in Python. They allow for easy vectorization, calculation of moving averages (e.g., .mean()), and slicing.

Q: Does self.history include the current day's data?
A: In on_data, self.history typically returns the completed bars. If you are running at Resolution.DAILY, the bar for "today" is not complete until market close. Therefore, the last data point in history is usually yesterday's close, unless you are running this logic after market close or using a higher resolution (like Minute) rolled up to Daily.