All Posts
AnalysisETF Turnover Rate APIPortfolio Turnover RatioFund Holdings API

ETF Turnover Rate, From Daily Data

Compute portfolio turnover from daily ETF holdings via API, then see how it compares to each fund's own official, once-a-year reported figure.

Published September 8, 202611 min readStockFit Engineering
ETF Turnover Rate, From Daily Data

Portfolio turnover rate is a required fund disclosure: the lesser of a fund's purchases or sales divided by its average net assets, reported once a year in the prospectus. It answers a real question, how much does this fund actually trade, but by the time it is public it can describe activity from over a year ago. We pulled two real daily holdings snapshots for 6 funds, about a month apart, computed our own turnover estimate directly from the position deltas, and checked it against three of those funds' own most recently reported figures, straight from their SEC filings and fact sheets.

The two numbers tell a consistent story once you know why they differ. Below is the formula, what /api/fund/changes actually returns (a quarterly N-PORT diff, not a daily one), how to compute a from-holdings estimate yourself, and exactly how far that estimate runs from three funds' own reported numbers, and why the gap gets smaller the more a fund really trades.

What portfolio turnover rate actually measures

The definition is the same across the fund industry, set out in Item 3 of Form N-1A: the lesser of a fund's purchases or sales of securities over the year (short-term instruments excluded), divided by the average value of its portfolio over that same year. Buy $50 million and sell $40 million against a $200 million average portfolio, and turnover is 40 / 200, 20%, the smaller of the two sides, not 25%.

Funds disclose it once a year, next to the fee table in the prospectus. A higher number means more transaction costs and, in a taxable account, more realized capital gains passed through to the holder. Under 20% to 30% generally reads as a buy-and-hold fund; well above 100% (a monthly options-overlay income fund, for instance) means the book turns over more than once a year.

/api/fund/changes gives you N-PORT, not a daily number

/api/fund/changes is genuinely useful, it diffs a fund's two most recently filed N-PORT holdings and returns exactly what was added, removed, and reweighted. It is not, despite what the name suggests, a daily turnover feed. Call it for ARKK with no other parameters and this is what comes back, as of 2026-09-08:

json
{
  "latestDate": "2026-04-30",
  "previousDate": "2026-01-30",
  "added": [
    { "name": "FIGMA INC", "pctVal": 0.478938095812, "mappedSymbol": "FIG" },
    { "name": "X-ENERGY INC", "pctVal": 1.281176078808, "mappedSymbol": "XE" }
  ],
  "removed": [
    { "name": "DraftKings Inc", "prevPctVal": 1.033583561772, "mappedSymbol": "DKNG" },
    { "name": "Trade Desk Inc/The", "prevPctVal": 0.889747911648, "mappedSymbol": "TTD" }
  ]
}

latestDate and previousDate are three months apart, 2026-01-30 to 2026-04-30, because that is exactly how far apart ARKK's two most recent N-PORT filings are. Every one of the 6 funds we checked (SPY, QQQ, JEPI, ARKK, TQQQ, SOXL) showed the same quarterly cadence, each on its own fiscal calendar (three months apart for SPY, QQQ, JEPI, and ARKK, two for TQQQ, three for SOXL, offset by each fund's reporting period). If you need a turnover number that reflects last week and not last quarter, this endpoint is the wrong one to diff, you need /api/fund/holdings/daily instead, which is exactly what the rest of this post computes from.

Computing turnover from two daily holdings snapshots

The daily file has none of N-PORT's lag, it republishes every trading day, current to the prior close, but it does not hand you a turnover percentage, only a position list. Building one from it is a three-step diff: pull two snapshots, match every position across them, then classify.

bash
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.stockfit.io/v1/api/fund/holdings/daily?symbol=ARKK&reportDate=2026-08-10&pageSize=1000"
curl -H "Authorization: Bearer $TOKEN" \
  "https://api.stockfit.io/v1/api/fund/holdings/daily?symbol=ARKK&pageSize=1000"

Match positions the same way our holdings-cadence post does, by cusip, falling back to ticker, then name. A ticker that is new in the second snapshot counts its full value as a buy; one that disappears counts its full old value as a sell; a ticker held in both counts its positive value change as a buy and its negative change as a sell. Sum both sides, take the smaller, divide by the average of the two snapshots' total value, and annualize by (365 divided by the number of days between snapshots). It is the same formula as the official one, adapted for position snapshots instead of a trade blotter, which is an important difference we come back to below.

Running this across 6 funds surfaced two real data quirks worth knowing before trusting a number blindly. SPY's daily file carries no valueUsd field at all, only balance (shares) and pctVal (portfolio weight), unlike the other 5 funds. The fix is to compute turnover in weight terms instead of dollars, mathematically equivalent since weights already sum to about 100% of net assets on both sides (SPY summed to 99.97% and 99.94% in our two snapshots).

SOXL is the sharper trap. A naive diff shows 10 new positions and 9 removed, mostly entries named "ICE SEMICONDUCTOR INDEX SWAP" whose identifier changed between the two dates (ICESEMIML becomes ICESEMMLL, for example), the same reformatted-contract-code pattern our holdings-cadence post found for this fund's position count. Counted naively, that is 873.1% annualized turnover. Reconciling 8 of those 9 pairs as the same swap leg resizing under a new code, not a real close-and-reopen, brings it down to 47%, an almost 19x difference from one data-quality fix. One pair (an old position named "Semiconductor Bull 3x" and a new one named "ICESEMI SWAP ASSET LEG") uses different enough naming that this reconciliation could not match it automatically, and is left as a genuine add and remove. Read a swap-heavy leveraged fund's raw diff with real skepticism before charting it.

Turnover by fund type: index, active, and leveraged

Methodology note: every figure below is annualized from a 24 to 28 day window (2026-08-10 to early September 2026), not a full fiscal year, so treat it as directional, not as this fund's actual 12-month figure.

Annualized turnover from two daily-holdings snapshots, by fund
6 real funds, 2026-08-10 to early September 2026. SOXL shown after reconciling reformatted swap codes (873.1% before). Source: /api/fund/holdings/daily.

The two index trackers land lowest, SPY at 44.5% and QQQ at 37.4%, and QQQ is the cleanest case in the whole sample: zero tickers were added or removed across its 28-day window, every point of its computed turnover comes from existing positions simply changing value with the market, not a single trade. JEPI is highest by far at 248.7%, and it is not noise, its added and removed rows are literally named SPX_1 through SPX_27, the fund's rolling monthly S&P 500-linked notes that generate its option-premium income, resetting on schedule rather than tracking a stock-picking decision. ARKK sits at 89.2%, driven by real, individually named trades (Rocket Lab added, Deere and Roblox exited in this window). The leveraged funds land in between: TQQQ at 57.7%, mostly a Treasury-bill collateral roll into new maturities, and SOXL at 47% after the swap-code reconciliation above.

None of the specific holdings named above are a signal to buy, sell, or avoid anything, they illustrate what each kind of change looks like in the data. This is data, not investment advice.

How far our estimate runs from each fund's official number

We cross-checked three of these funds directly against their own primary disclosures, not a secondary aggregator: SPY's 485BPOS prospectus on SEC EDGAR states a 3% turnover rate for the fiscal year ended 2024-09-30. ARKK's summary prospectus, dated 2025-11-30, states 43% for its most recent fiscal year. JEPI's own fact sheet, dated 2026-07-31, states a trailing-12-month turnover ratio of 172.17% measured through 2025-06-30, meaning JPMorgan's own current fact sheet is displaying a figure that is already more than 13 months stale.

Our position-delta estimate versus each fund's own reported turnover ratio
The gap narrows as real trading activity rises: 15x for SPY, 2x for ARKK, 1.4x for JEPI. Sources: SEC EDGAR, ARK and JPMorgan's own fund documents.

The gap is not random, it shrinks in a straight line as a fund's real trading activity rises. SPY is off by roughly 15x (3% official versus 44.5% computed), ARKK by roughly 2x (43% versus 89.2%), and JEPI by only about 1.4x (172.17% versus 248.7%). The reason is the same mechanism that inflated QQQ's number above: our position-delta method cannot separate a real trade from a position simply changing value with the market, so it adds a roughly constant layer of price-drift "turnover" on top of whatever a fund actually trades. For a nearly static index fund, that noise floor is almost the entire number. For a fund that genuinely turns its book over multiple times a year, real trading activity dominates the noise, and the estimate converges toward the fund's own audited figure.

Treat a from-holdings estimate like ours as a directional, current-as-of-this-week signal for comparing funds or spotting a change in behavior, not a substitute for a fund's own once-a-year reported number. The two measure genuinely different things: ours is a value-weighted position diff over a few weeks, theirs is actual purchase and sale dollars over a full fiscal year, filed and public only after that year closes.

Daily holdings requires the ETF plan ($59/mo, $39/mo billed annually) or Professional ($99/mo, $69/mo billed annually). Portfolio changes is on the same two plans; the quarterly N-PORT holdings endpoint is included from Starter ($19/mo, $15/mo billed annually) up, and the supported-funds list is free tier. Full detail on the daily file itself, including the six formats issuers publish it in, is in our daily ETF holdings API walkthrough, and the position-count version of this same diff, with the S&P 500 rebalance event behind SPY's single add and remove above, is in how often ETF holdings actually change. The same quarterly-versus-daily lag shows up on the institutional-ownership side too, covered in detecting institutional position changes from 13F data. Full fund and ETF coverage is on the ETF and fund data page. to try the supported-funds list and quarterly holdings on the free and Starter tiers first.

FAQ

Q.What is a good portfolio turnover ratio for an ETF?
Under 20% to 30% is generally read as a buy-and-hold, low-cost fund. Above 100% means the fund's book turns over more than once a year, common for actively managed or options-overlay income funds. In this sample, JEPI's officially reported 172.17% is on the high end even for its category; SPY's 3% is close to the low end for any equity fund.
Q.How do I calculate ETF turnover rate from holdings data?
Pull two /api/fund/holdings/daily snapshots, match positions by cusip (falling back to ticker, then name), sum the value gained by new and increased positions as buys and the value lost by removed and decreased positions as sells, divide the smaller of the two by the average of the snapshots' total value, and annualize by 365 divided by the number of days between them. Note this measures value drift, not confirmed trades, so it overstates turnover for low-activity funds; see the comparison against three funds' own reported figures above.
Q.Does /api/fund/changes give daily ETF turnover?
No. It diffs a fund's two most recently filed N-PORT holdings, which land quarterly, offset by each fund's own fiscal calendar. All 6 funds checked for this post showed a two-to-three-month gap between previousDate and latestDate. For anything closer to real time, diff two /api/fund/holdings/daily calls instead.
Q.Why is my computed turnover higher than the fund's official turnover ratio?
Because a position-delta estimate cannot tell a real sale from a stock that simply went up or down in price between your two snapshots; both count as apparent turnover. That gap was roughly 15x for SPY (a low-turnover index fund, where price drift is nearly the whole number) and shrank to about 1.4x for JEPI (a genuinely high-turnover fund, where real trading activity swamps the price-drift noise).
Q.How often do funds report their official portfolio turnover rate?
Once a year, in the prospectus, alongside the fee table, covering the fund's prior fiscal year. JEPI's own fact sheet, dated 2026-07-31, was still showing a turnover figure measured only through 2025-06-30 at the time of writing, over 13 months old.
Q.What is the difference between N-PORT holdings and daily holdings for computing turnover?
N-PORT holdings come from the fund's SEC filing, land quarterly, and are what /api/fund/changes diffs. Daily holdings come straight from the issuer's own website, current to the prior close, with roughly 30 rolling days of history, but no endpoint turns them into a turnover percentage for you; that diff is on the caller.
Q.Which StockFit plan includes daily ETF holdings and portfolio changes data?
/api/fund/holdings/daily and /api/fund/changes both require the ETF plan ($59/mo, $39/mo billed annually) or Professional ($99/mo, $69/mo billed annually). The quarterly /api/fund/holdings endpoint is included from Starter ($19/mo, $15/mo billed annually) up, and the supported-funds list is free tier.

Ready to build?

Free API key, no credit card.