---
title: "How do I calculate the holdings overlap between two ETFs?"
description: "Overlap is the sum over shared holdings of the smaller of the two weights. Compute it from data.topHoldings, or call GET /overlap?isins=A,B for a name-matched result. Formula, Python and the free tool."
canonical: https://fundfactsapi.com/answers/how-to-calculate-overlap-between-two-etfs
published: 2026-09-12
updated: 2026-10-06
publisher: FundFacts API
---

# How do I calculate the holdings overlap between two ETFs?

**Short answer:** Overlap = Σ over holdings present in both funds of min(weight in A, weight in B), in percent of portfolio. GET https://fundfactsapi.com/api/v1/overlap?isins=A,B (Starter and above) does the name matching and returns overlap, sharedCount and the shared list per pair; on any plan you can compute the same from each fund's data.topHoldings, which holds its largest positions only (ten for most funds, up to 50 for some issuers), so the figure is a lower bound unless both lists cover most of each portfolio. The free ETF overlap tool on this site runs the endpoint in the browser.

## The formula

For two funds A and B with holdings weights `wA[name]` and `wB[name]` in percent:

```text
overlap(A, B) = Σ_{name ∈ A ∩ B} min(wA[name], wB[name])
```

An overlap of 40 means 40% of each portfolio's weight sits in names the other fund also holds (at the smaller of the two weights). Two share classes of the same index fund overlap near 100; a world ETF and an emerging-markets ETF near 0.

## From the payload

```python
import os, requests
H = {"Authorization": f"Bearer {os.environ['FUNDFACTS_API_KEY']}"}
def holdings(isin):
    d = requests.get(f"https://fundfactsapi.com/api/v1/funds/{isin}", headers=H, timeout=300).json()["data"]
    return {h["name"].upper(): h["weight"] for h in d["topHoldings"]}

a, b = holdings("IE00B4L5Y983"), holdings("IE00B3RBWM25")
shared = {n: min(a[n], b[n]) for n in a.keys() & b.keys()}
print(round(sum(shared.values()), 2), "% overlap over published holdings;", len(shared), "shared names")
```

This is exact over the positions stored in `topHoldings` (the ten largest for most funds, up to 50 for some issuers, even where the issuer publishes a full holdings file) and is what the endpoint does, with better name matching. Over top lists it is a lower bound on the true overlap.

## The endpoint

```bash
curl -s "https://fundfactsapi.com/api/v1/overlap?isins=IE00B4L5Y983,IE00B3RBWM25" -H "Authorization: Bearer $FUNDFACTS_API_KEY"
```

```json
{ "pairs": [ { "a": "IE00B4L5Y983", "b": "IE00B3RBWM25", "overlap": 18.4, "sharedCount": 9, "disclosed": { "a": 24.9, "b": 21.7 }, "shared": [ { "label": "NVIDIA", "a": 5.48, "b": 4.61 } ] } ] }
```

`disclosed` states what share of each portfolio the stored holdings cover, so you can tell a near-complete comparison (both close to 100) from a top-ten lower bound like this one. Several ISINs return every pair. One request per ISIN; Starter and above. The MCP server's `fund_overlap` tool wraps it for assistants.

## Reading the number

Overlap is about names, not about risk: two funds with 30% overlap can still be 95% correlated because they hold the same sectors and countries. Pair it with the sector and geography tables, or with `POST /portfolio` for the aggregate view. [How to calculate ETF holdings overlap](https://fundfactsapi.com/blog/how-to-calculate-etf-holdings-overlap) goes deeper into matching and edge cases.

## FAQ

### Why is the free tool result different from my own calculation?

Name matching: the endpoint normalises issuer labels ("NVIDIA" vs "NVIDIA CORP"), while a quick script over topHoldings matches exact strings. Both work on the same stored topHoldings (each fund's largest positions), so neither sees the lines beyond them.

## About FundFacts API

FundFacts turns any fund or ETF ISIN into one dated factsheet (fees and KID costs, the 1–7 risk indicator, holdings, sector and country exposure, returns) read from the fund house's own documents: as a client-ready PDF under your firm's name for advisers and wealth managers, as JSON through its API for developers, or inside ChatGPT and Claude through its MCP server.

FundFacts works inside ChatGPT and Claude as a connector (a remote MCP server): ask about any fund or ETF by ISIN, ticker or name and the assistant answers from FundFacts' dated figures, fees, risk, holdings, exposure and returns, with fund cards, side-by-side comparisons, holdings overlap and portfolio look-through.

- Free API key, no card: https://fundfactsapi.com/signup
- Documentation: https://fundfactsapi.com/docs (OpenAPI: https://fundfactsapi.com/openapi.json)
- MCP server: https://fundfactsapi.com/api/mcp (set-up for every client: https://fundfactsapi.com/mcp-server)
- Pricing: https://fundfactsapi.com/pricing
- Site index for AI assistants: https://fundfactsapi.com/llms.txt
- Informational data, not investment advice.
