Skip to main content
By Fruit Stand Team · November 2, 2026 · Guides Trailing returns for every US fund and ETF in bulk come from three places: licensed data feeds from Morningstar and CRSP, the SEC’s free data files, which run months behind, or a Snowflake Marketplace listing. Fruit Stand’s Fund Returns listing has 1-day to 20-year returns for about 32,000 US mutual funds and ETFs in one table, for $250 a month. You can also calculate them in bulk from adjusted prices, pulled for free with the yfinance library or from a price dataset. That works for a handful of funds, but getting it right for tens of thousands takes more care than the formula suggests. This post covers each option and shows the SQL for both.
Fruit Stand publishes the Fund Returns listing. Details for the other sources come from their own pages as of November 1, 2026. For a listing-by-listing comparison of fund data on the Snowflake Marketplace, see Fund and ETF Returns Data on Snowflake, Compared.

The options at a glance

Licensed data: Morningstar and CRSP

Morningstar is the standard source for fund performance in the industry, and its trailing total returns are what most fact sheets and advisor tools show. Access comes through Morningstar Direct or a licensed data feed, priced by quote. CRSP’s mutual fund database is the standard in academic research. It’s survivorship-bias-free, with 64,000+ funds including delisted ones, but it publishes monthly returns, not trailing periods. You’d compound the monthly returns into 1-, 3- and 5-year figures yourself. Both make sense when you already have an enterprise data budget, or need the exact numbers a fund’s own fact sheet uses.

Free: the SEC’s prospectus data

Every mutual fund prospectus has a risk/return summary with an average annual total returns table: 1, 5 and 10 years, or since inception for younger funds. Funds tag it in XBRL, and the SEC publishes the extracted data as quarterly ZIP files going back to December 2010. ETFs that file the same prospectus form are included. It’s free and comes straight from the funds, but it doesn’t answer most questions about current performance:
  • Once a year. The table is as of the last calendar year end, updated when the fund files its annual prospectus. In November it can be ten months old.
  • Three periods. There’s no year-to-date, 3-year or 3-month figure.
  • Sales charges. For share classes with a front-end load, the table’s returns are after the maximum sales charge, so they’ll be lower than a load-waived return.
  • Identifiers. Rows are keyed by the SEC’s series and class IDs. You have to map them to tickers to join your other data.

Free: the SEC’s N-PORT monthly returns

Funds also report returns every month. Registered funds other than money market funds file Form N-PORT, which includes the fund’s total return for each of the previous three months, by share class and net of fees. The SEC publishes the public filings as quarterly data sets, with the returns in a MONTHLY_TOTAL_RETURN table, going back to late 2019. That makes N-PORT the most current free source for the whole universe, but it’s monthly returns, not trailing ones. You compound them yourself. With the returns loaded into a table of one row per share class per month, the 1-year return is:
Before you rely on it:
  • Months behind, not days. Only the quarter-end filing is public, and it appears 60 days after the quarter ends. The SEC then publishes the data sets quarterly, so the latest month can be three to five months old.
  • Short history. The data starts in late 2019, so there are no 10-year returns until late 2029.
  • Class IDs, not tickers. Returns are keyed by the SEC’s share class ID, so you map each class to its ticker before joining other data.
  • Month-end only. There’s no year-to-date or 1-week figure between month ends.
Free lookup tools aren’t bulk sources. FINRA’s Fund Analyzer, for example, shows current 1-, 3-, 5- and 10-year returns, but one fund at a time on a website, with no download.

Free but unofficial: yfinance

yfinance is an open-source Python library that downloads prices from Yahoo Finance. It’s the most common free way to get fund prices in bulk, and with adjusted prices you can calculate trailing returns yourself:
For three funds, that’s fine. For every US fund and ETF, Yahoo becomes the limit:
  • Throttling. Yahoo doesn’t publish rate limits, and it throttles by IP address. Pull tens of thousands of tickers and requests start failing with “Too Many Requests” (YFRateLimitError). Users report blocks lasting hours, sometimes more than a day. A full backfill means batching, caching and pacing requests over days.
  • Yahoo’s quirks. yfinance isn’t an official API. It reads Yahoo’s website endpoints, which change without notice, and each change breaks the library until a new release ships. Data quirks show up too: missing or repeated days, and adjusted history that shifts between pulls.
  • No fund list. There’s no call for “every US mutual fund”. You need your own list of ~32,000 tickers and have to keep it current as funds launch, close and merge.
  • Personal use only. yfinance says it isn’t affiliated with Yahoo and that Yahoo’s API is intended for personal use only. That rules it out for client work or a shared company warehouse.

Calculating trailing returns yourself

A trailing return is the change in adjusted price over a window ending on an as-of date:
With daily adjusted prices in Snowflake, for example from the Historical Stock Prices listing, an ASOF JOIN finds each window’s base price, the last trading day on or before the start of the window:
That’s correct for three funds. At 32,000 funds, these are the things that go wrong:
  • Adjusted prices change. Every dividend restates a fund’s entire adjusted history. Mutual funds that pay monthly restate it monthly, so stored returns go stale unless you recompute from a full reload. See Adjusted Close vs. Close for why.
  • Funds younger than the window. A fund launched 3 years ago has no 5-year return. Without a check, the ASOF JOIN finds no base price and the row quietly drops out.
  • Thinly traded funds. When a fund doesn’t trade for a few days, the base price comes from an earlier date than the window implies. Keep base_date next to the return so it’s visible.
  • When to annualize. By convention, periods under a year are never annualized. Annualizing a 3-month return turns a good quarter into an implausible annual figure.
  • NAV vs. market price. For mutual funds, the daily price is the NAV. For ETFs it’s the market close, so the return is a market-price return. An ETF’s fact sheet usually shows both, and they differ slightly.
  • Delisted funds. Funds close and merge every month. If your fund list only has today’s funds, any history you build has survivorship bias.

The ready-made version

Fund Returns does that work in its pipeline. A fund’s full price history reloads whenever it posts a dividend or split, returns are recalculated as new prices land, with a full rebuild twice a week, and delisted funds stay in the tables with their history. Every fund’s latest returns are one query:
Run on October 30, 2026, it returned: Returns are decimals, so 0.148737 is 14.87%. Periods of 2 years and longer are annualized, and shorter ones, including year-to-date, are cumulative. Remove the where clause and the same query returns every fund and ETF. Calendar-year returns are in a separate table, one row per fund per year. The full schema and the return formulas are in the Fund Returns docs.

How close are the numbers?

Every method here starts from adjusted prices, so it’s worth checking them against the funds’ own published returns. Here are Vanguard’s figures for two of its largest funds as of September 30, 2026, next to Fund Returns and a yfinance calculation for the same date: All three agree to within 0.04 percentage points. The small gaps come from rounding and from how each source picks the base date for a window. For VTI, compare against Vanguard’s market-price return: an ETF’s daily close is a market price, and its NAV return differs slightly (15.33% over 1 year).

Exporting the whole universe

If what you need is a file, for a spreadsheet, a notebook or another system, the listing gets you there with one statement. In your own Snowflake account, unload the latest row for every fund to a stage:
Download the files with GET from SnowSQL or the Snowflake CLI, or point the stage at your own S3, Azure or GCS bucket instead. Wrap the statement in a scheduled task and the export stays current after each refresh.

Which should you use?

  • You need the exact figures on a fund’s fact sheet: license Morningstar data.
  • You’re doing academic research on fund performance: CRSP, through your institution.
  • You need current trailing returns for the whole universe in SQL: a Marketplace listing such as Fund Returns.
  • You want free data for the whole universe and can wait a few months: the SEC’s N-PORT monthly returns, compounded yourself.
  • You’re running a personal project on a few dozen funds: yfinance, with caching, within Yahoo’s terms.
  • You need a custom period or benchmark: calculate from adjusted prices, such as the Historical Stock Prices listing’s, and plan for the issues above.

F.A.Q.

A trailing return covers a fixed window ending on a date, such as the 1-year return as of today. A calendar-year return covers January 1 to December 31 of a given year. Trailing returns change every day; calendar-year returns only change for the current year.
Periods of more than a year usually are, as a compound annual growth rate, so a 5-year and a 10-year return can be compared directly. Periods of a year or less, including year-to-date, are cumulative. Fund Returns annualizes periods of 2 years or longer.
They should. Returns calculated from adjusted prices include reinvested dividends and distributions, which makes them total returns. Returns from raw closing prices leave out the income and understate performance, especially for bond and dividend funds.
Small differences usually come from the as-of date, NAV versus market price for ETFs, whether sales charges are deducted, and how the provider handles distributions. A fact sheet’s standardized returns are often month-end or quarter-end, not today.
From the Fund Returns listing, yes. It’s a table in your Snowflake account, so COPY INTO a stage writes the whole universe to CSV or Parquet in one statement (see Exporting the whole universe), and a scheduled task can repeat it after each refresh. The SEC’s prospectus data is also downloadable, as quarterly ZIP files.
Not reliably. yfinance downloads one price history per ticker from Yahoo, and Yahoo throttles bulk requests by IP, so pulling ~32,000 funds runs into “Too Many Requests” errors and multi-hour blocks. It also needs your own list of fund tickers, and Yahoo’s API is for personal use only.
Not current data. The SEC’s N-PORT data sets have free monthly returns for every registered fund, but they run three to five months behind and you compound the trailing periods yourself. The SEC’s prospectus data only updates once a year, as of December 31, for 1, 5 and 10 years. FINRA’s Fund Analyzer is free and current, but you look up funds one at a time. The Fund Returns listing has a free 30-day trial.
To get trailing and calendar-year returns for every US fund and ETF in bulk, start a free 30-day trial of the Fund Returns listing on the Snowflake Marketplace. It covers about 32,000 US mutual funds and ETFs, including delisted funds, with 16 trailing periods, for $250/month after the trial. The schema and formulas are in the dataset docs. Questions? Reach out at contact@fruitstand.dev.