book
Checkout our new book! Hands on AI Trading with Python, QuantConnect, and AWS Learn More arrow

Datasets

Equity Fundamental Data

Introduction

This page explains how to request, manipulate, and visualize historical Equity Fundamental data. Corporate fundamental data is available through the US Fundamental Data from Morningstar.

Create Subscriptions

Follow these steps to subscribe to an Equity security:

  1. Create a QuantBook.
  2. Select Language:
    qb = QuantBook()
  3. Call the add_equity method with a ticker and then save a reference to the Equity Symbol.
  4. Select Language:
    symbols = [
        qb.add_equity(ticker, Resolution.DAILY).symbol
        for ticker in [
            "AAL",   # American Airlines Group, Inc.
            "ALGT",  # Allegiant Travel Company
            "ALK",   # Alaska Air Group, Inc.
            "DAL",   # Delta Air Lines, Inc.
            "LUV",   # Southwest Airlines Company
            "SKYW",  # SkyWest, Inc.
            "UAL"    # United Air Lines
        ]
    ]

Get Historical Data

You need a subscription before you can request historical fundamental data for US Equities. On the time dimension, you can request an amount of historical data based on a trailing number of bars, a trailing period of time, or a defined period of time. On the security dimension, you can request historical data for a single US Equity, a set of US Equities, or all of the US Equities in the US Fundamental dataset. On the property dimension, you can call the history method to get all fundamental properties.

When you call the history method, you can request Fundamental or Fundamentals objects. If you use Fundamental, the method returns all fundamental properties for the Symbol object(s) you provide. If you use Fundamentals, the method returns all fundamental properties for all the US Equities in the US Fundamental dataset that were trading during that time period you request, including companies that no longer trade.

Trailing Number of Trading Days

To get historical data for a number of trailing trading days, call the history method with the number of trading days. If you didn't use Resolution.DAILY when you subscribed to the US Equities, pass it as the last argument to the history method.

Select Language:
# DataFrame of fundamental data
single_fundamental_df = qb.history(Fundamental, symbols[0], 10, flatten=True)
set_fundamental_df = qb.history(Fundamental, symbols, 10, flatten=True)
all_fundamental_df = qb.history(Fundamental, qb.securities.keys(), 10, flatten=True)
all_fundamentals_df = qb.history(Fundamentals, 10, flatten=True)

# Fundamental objects
single_fundamental_history = qb.history[Fundamental](symbols[0], 10)
set_fundamental_history = qb.history[Fundamental](symbols, 10)
all_fundamental_history = qb.history[Fundamental](qb.securities.keys(), 10)

# Fundamentals objects
all_fundamentals_history = qb.history[Fundamentals](qb.securities.keys(), 10)

The preceding calls return fundamental data for the 10 most recent trading days.

Trailing Period of Time

To get historical data for a trailing period of time, call the history method with a timedelta object.

Select Language:
# DataFrame of fundamental data
single_fundamental_df = qb.history(Fundamental, symbols[0], timedelta(days=10), flatten=True)
set_fundamental_df = qb.history(Fundamental, symbols, timedelta(days=10), flatten=True)
all_fundamental_df = qb.history(Fundamental, qb.securities.keys(), timedelta(days=10), flatten=True)
all_fundamentals_df = qb.history(Fundamentals, timedelta(5), flatten=True)

# Fundamental objects
single_fundamental_history = qb.history[Fundamental](symbols[0], timedelta(days=10))
set_fundamental_history = qb.history[Fundamental](symbols, timedelta(days=10))
all_fundamental_history = qb.history[Fundamental](qb.securities.keys(), timedelta(days=10))

# Fundamentals objects
all_fundamentals_history = qb.history[Fundamentals](timedelta(days=10))

The preceding calls return fundamental data for the most recent trading days.

Defined Period of Time

To get the historical data of all the fundamental properties over specific period of time, call the history method with a start datetime and an end datetime. To view the possible fundamental properties, see the Fundamental attributes in Data Point Attributes. The start and end times you provide to these methods are based in the notebook time zone.

Select Language:
start_date = datetime(2021, 1, 1)
end_date = datetime(2021, 2, 1)

# DataFrame of all fundamental properties
single_fundamental_df = qb.history(Fundamental, symbols[0], start_date, end_date, flatten=True)
set_fundamental_df = qb.history(Fundamental, symbols, start_date, end_date, flatten=True)
all_fundamental_df = qb.history(Fundamental, qb.securities.keys(), start_date, end_date, flatten=True)
all_fundamentals_df = qb.history(Fundamentals, start_date, end_date, flatten=True)

# Fundamental objects
single_fundamental_history = qb.history[Fundamental](symbols[0], start_date, end_date)
set_fundamental_history = qb.history[Fundamental](symbols, start_date, end_date)
all_fundamental_history = qb.history[Fundamental](qb.securities.keys(), start_date, end_date)

# Fundamentals objects
all_fundamentals_history = qb.history[Fundamentals](qb.securities.keys(), start_date, end_date)

The preceding method returns the fundamental property values that are timestamped within the defined period of time.

Wrangle Data

You need some historical data to perform wrangling operations. To display pandas objects, run a cell in a notebook with the pandas object as the last line. To display other data formats, call the print method.

DataFrame Objects

The history method returns a multi-index DataFrame where the first level is the Equity Symbol and the second level is the end_time of the trading day. The columns of the DataFrame are the names of the fundamental properties. The following image shows the first 4 columns of an example DataFrame:

Historical fundamental properties dataframe for US Equities

To access an attribute from one of the cells in the DataFrame, select the value in the cell and then access the object's property.

single_fundamental_df.iloc[0].companyprofile.share_class_level_shares_outstanding

Fundamental Objects

If you pass a Symbol to the history[Fundamental] method, run the following code to get the fundamental properties over time:

Select Language:
for fundamental in single_fundamental_history:
    symbol = fundamental.symbol
    end_time = fundamental.end_time
    pe_ratio = fundamental.valuation_ratios.pe_ratio

If you pass a list of Symbol objects to the history[Fundamental] method, run the following code to get the fundamental properties over time:

Select Language:
for fundamental_dict in set_fundamental_history: # Iterate trading days
    for symbol, fundamental in fundamental_dict.items(): # Iterate Symbols
        end_time = fundamental.end_time
        pe_ratio = fundamental.valuation_ratios.pe_ratio

Fundamentals Objects

If you request all fundamental properties for all US Equities with the history[Fundamentals] method, run the following code to get the fundamental properties over time:

Select Language:
for fundamentals_dict in all_fundamentals_history: # Iterate trading days
    fundamentals = list(fundamentals_dict.values)[0]
    end_time = fundamentals.end_time
    for fundamental in fundamentals.data: # Iterate Symbols
        if not fundamental.has_fundamental_data:
            continue
        symbol = fundamental.symbol
        pe_ratio = fundamental.valuation_ratios.pe_ratio

Plot Data

You need some historical Equity fundamental data to produce plots. You can use many of the supported plotting libraries to visualize data in various formats. For example, you can plot line charts.

Follow these steps to plot line charts using built-in methods:

  1. Get some historical data.
  2. Select Language:
    history = qb.history[Fundamental](symbols, datetime(2014, 1, 1), datetime(2015, 1, 1))
  3. Convert to pandas DataFrame.
  4. data = {}
    for fundamental_dict in history: # Iterate trading days
        for symbol, fundamental in fundamental_dict.items(): # Iterate Symbols
            datum = data.get(symbol, dict())
            datum['index'] = datum.get('index', [])
            datum['index'].append(fundamental.end_time)
            datum['pe_ratio'] = datum.get('pe_ratio', [])
            datum['pe_ratio'].append(fundamental.valuation_ratios.pe_ratio)
            data[symbol] = datum
    
    df = pd.DataFrame()
    for symbol, datum in data.items():
        df_symbol = pd.DataFrame({symbol: pd.Series(datum['pe_ratio'], index=datum['index'])})
        df = pd.concat([df, df_symbol], axis=1)
  5. Call the plot method on the history DataFrame.
  6. df.plot(title='PE Ratio Over Time', figsize=(15, 8))
  7. Show the plot.
  8. Select Language:
    plt.show()

    Line charts display the value of the property you selected in a time series.

Line plot of PE ratio of US Equities

Examples

The following examples demonstrate some common practices for applying the Equity Fundamental Data dataset.

Example 1: PE Ratio Line Chart

The following example studies the trend of PE Ratio of AAPL using a line chart.

Select Language:
# Create a QuantBook
qb = QuantBook()

# Request AAPL's fundamental historical data.
equity = qb.add_equity("AAPL")
history = qb.history(
    Fundamental,
    equity.symbol, 
    start=qb.time - timedelta(days=365), 
    end=qb.time, 
    resolution=Resolution.DAILY,
    flatten=True
)
    
# Select the PE Ratio to study.
pe_ratio = history.loc[equity.symbol].apply(lambda x: x.valuationratios.pe_ratio, axis=1)
# Plot the PE Ratio line chart.
pe_ratio.plot(title=f"PE Ratio by Time of {equity.symbol}", ylabel="PE Ratio")

You can also see our Videos. You can also get in touch with us via Discord.

Did you find this page helpful?

Contribute to the documentation: