Morningstar

US Fundamental Data

Introduction

The US Fundamental Data by Morningstar tracks US Equity fundamentals. The data covers 8,000 US Equities, starts in January 1998, and is delivered on a daily frequency. This dataset is created by using a combination of string matching, Regular Expressions, and Machine Learning to gather the fundamental data published by companies.

For older symbols, the file date is approximated 45 days after the as of date. When a filing date is present on the Morningstar data, it is used. As we are a quant platform, all the data is loaded using "As Original Reported" figures. If there was a mistake reporting the figure, this will not be fixed later. The market typically responds quickly to these initially reported figures. Data is available for multiple periods depending on the property. Periods available include: 1 mo, 2 mo, 3 mo, 6 mo, 9 mo, 12 mo, 1 Yr, 2 Yr, 3 Yr, and 5 Yr. Morningstar symbols cover the NYSE, NASDAQ, AMEX, and BATS exchanges.

In live trading, Morningstar data is delivered to your algorithm at approximately 6 am each day. The majority of the fundamental data update occurs once per month. This includes updates to all of the key information for each security Morningstar supports. On top of this monthly update, there are daily updates of the financial ratios.

As Morningstar data arrives, it updates the master copy and is passed into your algorithm, similar to how TradeBars are fill-forwarded in your data feed. If there have been no updates for a day, you'll receive the same fundamental data.

This dataset depends on the US Equity Security Master dataset because the US Equity Security Master dataset contains information on splits, dividends, and symbol changes.

QuantConnect/LEAN combines the data of this dataset with US Coarse Universe data in runtime.

For more information about the US Fundamental Data dataset, including CLI commands and pricing, see the dataset listing.

About the Provider

Morningstar was founded by Joe Mansueto in 1984 with the goal of empowering investors by connecting people to the investing information and tools they need. Morningstar provides access extensive line of products and services for individual investors, financial advisors, asset managers, and retirement plan providers. Morningstar provides data on approximately 525,000 investment offerings including stocks, mutual funds, and similar vehicles, along with real-time global market data on nearly 18 million equities, indexes, futures, options, commodities, and precious metals, in addition to foreign exchange and Treasury markets. Morningstar also offers investment management services through its investment advisory subsidiaries, with $244 billion in assets under advisement or management as of 2021.

Getting Started

The following snippets demonstrate how to request data from the US Fundamental dataset:

  • Direct Access using the Security object
equity = self.add_equity("IBM")
ibm_fundamental = equity.fundamentals
var equity = AddEquity("IBM");
var ibmFundamental = equity.Fundamentals;
  • Direct Access using the Symbol object
ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
ibm_fundamental = self.fundamentals(ibm)
var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
var ibmFundamental = Fundamentals(ibm);
  • Universe Selection
def initialize(self) -> None:
    self._universe = self.add_universe(self.fundamental_filter_function)

def fundamental_filter_function(self, fundamental: List[Fundamental]):
    filtered = [f for f in fundamental if f.has_fundamental_data and f.price > 10 and not np.isnan(f.valuation_ratios.pe_ratio)]
    sorted_by_pe_ratio = sorted(filtered, key=lambda f: f.valuation_ratios.pe_ratio)
    return [f.symbol for f in sorted_by_pe_ratio[:10]]
public override void Initialize()
{
    _universe = AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
}

public override List<Symbol> FundamentalFilterFunction(List<Fundamental> fundamental)
{
    return (from f in fundamental
            where f.HasFundamentalData && f.Price > 10 && !Double.IsNaN(f.ValuationRatios.PERatio)
            orderby f.ValuationRatios.PERatio
            select f.Symbol).Take(10);
}

Data Summary

The following table describes the dataset properties:

PropertyValue
Start DateJanuary 1998
Asset Coverage8,000 US Equities
Corporate Indicators / Tracked Fields900 Fields
Data DensitySparse
ResolutionDaily
TimezoneNew York

Example Applications

The US Fundamentals dataset enables you to design strategies harnessing fundamental data points. Examples include the following strategies:

  • Ranking a universe of securities by a value factor like the Piotroski F-score and buying a subset of the universe with the best factor ranking
  • Using the Morningstar asset classification to target specific industries or to ensure your strategy is diversified across several sectors
  • Trading securities that recently performed an IPO

For more example algorithms, see Examples.

Data Point Attributes

The US Fundamentals dataset provides Fundamental objects. To filter Fundamental objects, you can use the MorningstarSectorCode, MorningstarIndustryGroupCode, and MorningstarIndustryCode enumeration values.

Fundamental Attributes

Fundamental objects have the following attributes:

MorningstarSectorCode Enumeration

Sectors are large super categories of data. To access the sector of an Equity, use the MorningstarSectorCode property.

filteredFundamentals = fundamental.Where(x =>
    x.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology);
filtered_fundamentals = [x for x in fundamental
    if x.AssetClassification.MorningstarSectorCode == MorningstarSectorCode.Technology]

The MorningstarSectorCode enumeration has the following members:

MorningstarIndustryGroupCode Enumeration

Industry groups are clusters of related industries that tie together. To access the industry group of an Equity, use the MorningstarIndustryGroupCode property.

filteredFundamentals = fundamental.Where(x =>
    x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.ApplicationSoftware);
filtered_fundamentals = [x for x in fundamental
    if x.AssetClassification.MorningstarIndustryGroupCode == MorningstarIndustryGroupCode.ApplicationSoftware]

The MorningstarIndustryGroupCode enumeration has the following members:

MorningstarIndustryCode Enumeration

Industries are the finest classification level available and are the individual industries according to the Morningstar classification system. To access the industry group of an Equity, use the MorningstarIndustryCode property.

filteredFundamentals = fundamental.Where(x =>
    x.AssetClassification.MorningstarIndustryCode == MorningstarIndustryCode.SoftwareApplication);
filtered_fundamentals = [x for x in fundamental
    if x.AssetClassification.MorningstarIndustryCode == MorningstarIndustryCode.SoftwareApplication]

The MorningstarIndustryCode enumeration has the following members:

Exchange ID Values

The exchange ID represents the exchange that lists the Equity. To access the exchange ID of an Equity, use the PrimaryExchangeID property.

filteredFundamentals = fundamental.Where(x =>
    x.CompanyReference.PrimaryExchangeID == "NAS");
filtered_fundamentals = [x for x in fundamental
    if x.CompanyReference.PrimaryExchangeID == "NAS"]

The exchanges are represented by the following string values:

String RepresentationExchange
NYSNew York Stock Exchange (NYSE)
NASNASDAQ
ASEAmerican Stock Exchange (AMEX)
TSETokyo Stock Exchange
AMSAmsterdam Internet Exchange
SGOSantiago Stock Exchange
XMADMadrid Stock Exchange
ASXAustralian Securities Exchange
BVMFB3 (stock exchange)
LONLondon Stock Exchange
TKSIstanbul Stock Exchange Settlement and Custody Bank
SHGShanghai Exchange
LIMLima Stock Exchange
FRAFrankfurt Stock Exchange
JSEJohannesburg Stock Exchange
MILMilan Stock Exchange
TAETel Aviv Stock Exchange
STOStockholm Stock Exchange
ETRDeutsche Boerse Xetra Core
PARParis Stock Exchange
BUEBuenos Aires Stock Exchange
KRXKorea Exchange
SWXSIX Swiss Exchange
PINXPink Sheets (OTC)
CSECanadian Securities Exchange
PHSPhilippine Stock Exchange
MEXMexican Stock Exchange
TAITaiwan Stock Exchange
IDXIndonesia Stock Exchange
OSLOslo Stock Exchange
BOGColombia Stock Exchange
NSENational Stock Exchange of India
HELNasdaq Helsinki
MISXMoscow Exchange
HKGHong Kong Stock Exchange
ISTIstanbul Stock Exchange
BOMBombay Stock Exchange
TSXToronto Stock Exchange
BRUBrussels Stock Exchange
BATSBATS Global Markets
ARCXNYSE Arca
GREYGrey Market (OTC)
DUSDusseldorf Stock Exchange
BERBerlin Stock Exchange
ROCOTaipei Exchange
CNQCanadian Trading and Quotation System Inc.
BSPBangko Sentral ng Pilipinas
NEOENEO Exchange

Requesting Data

You don't need any special code to request US Fundamental Data. You can access the current and historical fundamental data for any of the US Equities that this dataset includes.

class MorningStarDataAlgorithm(QCAlgorithm):

    def initialize(self) -> None:
        self.set_start_date(2021, 1, 1)
        self.set_end_date(2021, 7, 1)
        self.set_cash(100000) 
        self.universe_settings.asynchronous = True

        # Option 1: Subscribe to individual US Equity assets
        self.add_equity("IBM")        

        # Option 2A: Create a fundamental universe (classic version)
        self._universe = self.add_universe(self.fundamental_function)

        # Option 2B: Create a fundamental universe (framework version)
        self.add_universe_selection(FundamentalUniverseSelectionModel(self.fundamental_function))
namespace QuantConnect
{
    private Universe _universe;
    public class MorningStarDataAlgorithm : QCAlgorithm
    {    	
        public override void Initialize()
        {
            SetStartDate(2021, 1, 1);
            SetEndDate(2021, 7, 1);
            SetCash(100000);
            UniverseSettings.Asynchronous = True;
            
            // Option 1: Subscribe to individual US Equity assets
            AddEquity("IBM");

            // Option 2A: Create a fundamental universe (classic version)
            _universe = AddUniverse(FundamentalFilterFunction);

            // Option 2B: Create a fundamental universe (framework version)
            AddUniverseSelection(new FundamentalUniverseSelectionModel(FundamentalFilterFunction));
        }
    }
}

For more information about universe settings, see Settings.

Accessing Data

If you add a fundamental universe to your algorithm, you can access fundamental data in the universe selection function.

def fundamental_function(self, fundamental: List[Fundamental]) -> List[Symbol]:
    return [f.symbol for f in fundamental if f.price > 10 f.valuation_ratios.pe_ratios > 30]
public IEnumerable<Symbol> FundamentalFunction(IEnumerable<Fundamental> fundamental)
{
    return fundamental.Where(f => f.Price > 10 && f.ValuationRatios.PERatios > 30).Select(f => f.Symbol);
}

To get fundamental data for Equities in your algorithm, use the Fundamentalsfundamentals property of the Equity objects. The fundamental data represent the corporate fundamentals for the current algorithm time.

fundamentals = self.securities[symbol].fundamentals
var fundamentals = Securities[symbol].Fundamentals;

To get fundamental data for Equities, regardless of whether or not you have subscribed to them in your algorithm, call the Fundamentalsfundamentals method. If you pass one Symbol, the method returns a Fundamental object. If you pass a list of Symbol objects, the method returns a list of Fundamental objects.

// Single asset 
var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);
var ibmFundamental = Fundamentals(ibm);

// Multiple assets
var nb = QuantConnect.Symbol.Create("NB", SecurityType.Equity, Market.USA);
var fundamentals = Fundamentals(new List<Symbol>{ nb, ibm }).ToList();
# Single asset
ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)
ibm_fundamental = self.fundamentals(ibm)

# Multiple assets
nb = Symbol.create("NB", SecurityType.EQUITY, Market.USA)
fundamentals = self.fundamentals([ nb, ibm ])

Historical Data

You can get historical fundamental data in an algorithm and in the Research Environment.

Historical Data in Algorithms

To get historical fundamental data in an algorithm, call the Historyhistory method with Fundamental type and the Equity Symbol or the Universe object. If there is no data in the period you request, the history result is empty.

var ibm = QuantConnect.Symbol.Create("IBM", SecurityType.Equity, Market.USA);

// Fundamental objects
var fundamentalHistory = History<Fundamental>(ibm, TimeSpan.FromDays(30));

// Fundamentals objects for all US Equities (including delisted companies)
var fundamentalsHistory = History<Fundamentals>(TimeSpan.FromDays(30));

// Collection of Fundamental objects for all US Equities (including delisted companies)
var collectionHistory = History(_universe, 30, Resolution.Daily);
foreach (var fundamental in collectionHistory)
{
    // Cast to Fundamental is required
    var highestMarketCap = fundamental.OfType<Fundamental>().OrderByDescending(x => x.MarketCap).Take(5);
}
ibm = Symbol.create("IBM", SecurityType.EQUITY, Market.USA)

# DataFrame object where the columns are the Fundamental attributes
asset_df_history = self.history(Fundamental, ibm, timedelta(30), flatten=True)

# Fundamental objects
fundamental_history= self.history[Fundamental](ibm, timedelta(30))

# Fundamentals objects for all US Equities (including delisted companies)
fundamentals_history = self.history[Fundamentals](timedelta(30))

# Multi-index Series objects where the values are lists of Fundamental objects
series_history = self.history(self.universe, 30, Resolution.DAILY)
for (universe_symbol, time), fundamentals in series_history.items():
    highest_market_cap = sorted(fundamentals, key=lambda x: x.market_cap)[-5:]

Historical Data in the Research Environment

To get historical data in the Research Environment, call any of the preceding methods or call the UniverseHistoryuniverse_history method with the Universe object, a start date, and an end date. This method returns the filtered universe. Alternatively, call the GetFundamentalget_fundamental method with the Equity Symbol, a Fundamental property, a start date, and an end date. If there is no data in the period you request, the history result is empty.

# DataFrame object where the columns are the Fundamental attributes
universe_history_df = qb.universe_history(universe, qb.time-timedelta(30), qb.time, flatten=True)

# Multi-index Series objects where the values are lists of Fundamental objects
universe_history = qb.universe_history(universe, qb.time-timedelta(30), qb.time)
for (universe_symbol, time), fundamentals in universe_history.items():
    for fundamental in fundamentals:
        print(f"{fundamental.symbol} market cap at {fundamental.end_time}: {fundamental.market_cap}")

# DataFrame of a single Fundamental attribute
history = qb.get_fundamental(symbol, "ValuationRatios.pe_ratios", datetime(2021, 1, 1), datetime(2021, 7, 1))
var universeHistory = qb.UniverseHistory(universe, qb.Time.AddDays(-30), qb.Time);foreach (var fundamentals in universeHistory)
{
    foreach (Fundamental fundamental in fundamentals)
    {
        Console.WriteLine($"{fundamental.Symbol} market cap at {fundamental.EndTime}: {fundamental.MarketCap}");
    }
}

var history = qb.GetFundamental(symbol, "ValuationRatios.PERatios", new DateTime(2021, 1, 1), new DateTime(2021, 7, 1));

For more information about historical US Equity fundamental data, see Equity Fundamental Data.

Example Applications

The US Fundamentals dataset enables you to design strategies harnessing fundamental data points. Examples include the following strategies:

  • Ranking a universe of securities by a value factor like the Piotroski F-score and buying a subset of the universe with the best factor ranking
  • Using the Morningstar asset classification to target specific industries or to ensure your strategy is diversified across several sectors
  • Trading securities that recently performed an IPO

For more example algorithms, see Examples.

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: