尚未收集仓库信息。
尚未检测到更新。GitHub 发布版本后会显示在这里。
Daily ETF holdings-change signals across 71 funds (ARK, YieldMax, Avantis, Roundhill and more): conviction-scored buy/sell signals, cross-fund divergences, sector flow. Free REST API + MCP server for AI agents, no auth required. TickerTrace, a TraderMatrix product.
翻译准备中
取自仓库 README
正在加载完整 README。
查看完整 README ↗Daily ETF holdings intelligence — what institutions bought, sold, and changed since yesterday. No 90-day 13F delay.
Live at: tickertrace.pro API: api.tickertrace.pro/docs — fully open, no key required · openapi.json · llms.txt
Actively-managed ETFs publish their full holdings daily. TickerTrace scrapes, normalizes, and diffs them every morning so you can see who's accumulating, who's reducing, and where conviction is moving — before the opening bell.
148 ETFs tracked across 15 providers (as of October 2026):
| Provider | # | Funds |
|---|---|---|
| Avantis | 10 | AVUV, AVLV, AVMV, AVUS, AVEM, AVDE, AVDV, AVIV, AVSC, AVES |
| ARK Invest | 6 | ARKK, ARKQ, ARKW, ARKG, ARKF, ARKX |
| Amplify | 18 | BLOK, DIVO, QDVO, IDVO, YYY, HACK, IBUY, IPAY, ITEQ, AIEQ, AWAY, BATT, CNBS, COWS, DRVR, ETHO, GAMR, SILJ |
| Corgi Funds | 16 | EUV, CMAG, CQTM, XA, EYES, KYC, GNMX, AV, DOCK, WATS, GLAM, NYNY, STYL, WNDR, FDRS, FDRX |
| Roundhill | 16 | MSTW, NVDW, COIW, TSLW, HOOW, PLTW, AMDW, TOPW, XPAY, WEEK, QDTE, XDTE, RDTE, YBTC, DRAM, CHAT |
| Capital Group | 5 | CGDV, CGGR, CGGO, CGUS, CGXU |
| First Trust | 7 | FTLS, WCME, WCMG, WCMI, CRPT, MMSC, EMLP |
| Kurv | 3 | KYLD, KQQQ, TSLP |
| YieldMax | 42 | ULTY, SLTY, MSTY, NVDY, CONY, TSLY, HOOY, PLTY, CHPY, YMAX, AMDY, AMZY, GOOY, GDXY, AIYY, BABO, BIGY, CRSH, CVNY, DIPS, FBY, FIAT, GPTY, LFGY, MARO, MRNY, MSFO, NFLY, OARK, PYPY, RDTY, SDTY, SMCY, SNOY, SOXY, TSMY, WNTR, XOMO, YQQQ, YMAG, MSST, NVIT |
| REX Shares | 6 | ULTI, NVII, TSII, FEPI, AIPI, CEPI |
| Neos | 6 | SPYI, QQQI, IWMI, BTCI, CSHI, IAUI |
| Global X | 8 | QYLD, XYLD, RYLD, QRMI, XRMI, QYLG, XYLG, DJIA |
| Tidal / NicholasX | 1 | BLOX |
| Tidal / NestYield | 3 | EGGQ, EGGY, EGGS |
| Sprott | 1 | GBUG |
REX's MSII, COII, HOII, and PLTI were liquidated on 2026-06-16 (trading halted 2026-06-09) and are no longer tracked. NVII and TSII were not part of that liquidation and remain live.
The live count is always fundsTracked on /api/v1/stats.
Holdings view — main equity table per fund:
Option Attendance — Put/Call ratios and contract-level detail for options-based funds:
Discord Daily Intel — auto-generated embed of top buys/sells and sector flow:
GitHub Actions (daily scraper) → CSV history ─┬─→ FastAPI REST → Vultr → tickertrace.pro
├─→ FastMCP server → AI agents (Claude Desktop, etc.)
└─→ Next.js dashboard (Vercel)
api/
├── server.py FastAPI — all endpoints (public, marketing, vestigial auth)
├── mcp_server.py FastMCP — same data, MCP tools for AI agents
├── data.py Shared data layer (CSV → signals, changes, divergences, sector flow)
└── auth.py Vestigial user/API-key management (unused in v2)
etf-dashboard/
├── app/ Next.js 14 pages (dashboard, changes, holdings, fund/[ticker], effectiveness)
├── components/ React + discord-webhook + auth-context
└── lib/
├── api.ts Typed TS client — every page fetches via this
└── holdings.ts Static reference (FUND_PROVIDERS, FUND_AUM, PROVIDER_ORDER)
scrape_avantis.py Daily scraper (runs via GitHub Actions)
cusip_lookup.py CUSIP → ticker resolver (cache + OpenFIGI fallback)
etf-dashboard/public/data/
├── holdings_latest.csv Current day
└── history/holdings_YYYY-MM-DD.csv Daily history — read by the API at runtime (mounted read-only)
The dashboard, changes page, and fund profile pages all fetch from the FastAPI server via lib/api.ts instead of recomputing in TypeScript. One source of truth.
Base URL: https://api.tickertrace.pro — no key, no auth, no rate caps beyond IP throttling.
| Endpoint | What it returns |
|---|---|
GET /health | Status + as-of date |
GET /api/v1/signals | Top buy/sell signals with conviction scores |
GET /api/v1/changes?provider=ARK&direction=buying | Filterable daily position changes |
GET /api/v1/fund/{ticker} | Fund detail — top holdings, options, AUM |
GET /api/v1/ticker/{ticker} | Cross-fund view — who's buying/selling this ticker |
GET /api/v1/sectors | Sector-level weight flows |
GET /api/v1/divergences | Cross-fund conflicts (same ticker, opposite directions) |
GET /api/v1/briefing | Pre-built dashboard payload (signals + sectors + activity) |
GET /api/v1/activity | Most-active tickers by net change |
GET /api/v1/holdings | Full holdings dump — option rows carry underlying, CALL/PUT, strike, expiry, signed contracts, FLEX flag; every row carries its file date and staleness |
GET /api/v1/funds | All tracked funds + AUM, with each fund's lastHoldingsDate and stale |
GET /api/v1/options/{underlying} | One underlying's option legs across funds, grouped into synthetics / spreads / collars / rolls |
GET /api/v1/stats | Global stats |
GET /api/v1/fund-effectiveness | Per-fund signal-vs-price scorecard |
GET /api/v1/tradermatrix | Marketing handoff payload |
GET /api/v1/traderdaddy | Deprecated alias for /api/v1/tradermatrix (same payload) |
GET /docs | Interactive Swagger |
All additive — no existing CSV column or JSON field was renamed, removed or
changed meaning. Background: docs/DATA_QUALITY_2026-09.md.
History CSVs (holdings_YYYY-MM-DD.csv) gain three columns. Files written
before 2026-09-27 don't have them; the API derives what it can for those.
| Column | Meaning |
|---|---|
Refreshed | True = fetched from the issuer this run. False = the fetch failed after retries and these rows were carried forward from the previous file, so the fund is marked instead of silently missing. |
Source_Date | Date the rows are really from (the issuer's own date). Survives repeated carry-forwards, so a fund failing for a week still shows the first day. |
Is_Flex | Option rows only: FLEX (non-listed) contract, from the OCC root's leading digit (2AMAT …) or a strike off the $0.25 grid (490.01). Blank on non-option rows. |
Option_Strike is unchanged and stays exact (490.01, never rounded). The file
name is still the run date; a fund's data date is Source_Date, else Date.
/api/v1/holdings: new on every row: marketValue, fileDate, refreshed
(null for pre-2026-09-27 files), stale. New on option rows: underlying,
optionType (uppercase CALL/PUT; the CSV stores Call/Put), strike,
expiry, contracts, isFlex (these are null on non-option rows). shares
keeps its existing meaning: on option rows it is the signed contract count
(negative = written). contracts repeats it under a clearer name.
/api/v1/funds: new per fund: lastHoldingsDate, stale (older than the
previous trading day; exchange holidays not modelled) and refreshed.
/api/v1/ticker/{ticker}: option legs already past expiry are no longer
listed. A frozen issuer file used to keep them there for weeks. Each holding
gains fileDate, stale and refreshed; optionDetails gains optionType,
contracts, isFlex and underlying, alongside the unchanged type.
api/mcp_server.py exposes the same data as MCP tools for AI agents:
python -m api.mcp_server
Tools: get_signals, get_changes, get_fund_detail, get_ticker_detail, get_sector_flow, get_divergences, get_market_summary.
Remote (from anywhere) — the same tools are live over streamable HTTP, no install, no key:
claude mcp add --transport http tickertrace https://api.tickertrace.pro/mcp
Or add https://api.tickertrace.pro/mcp as a custom connector in Claude / Cursor.
Claude Desktop integration (local) — add to your MCP config:
{
"mcpServers": {
"tickertrace": {
"command": "python",
"args": ["-m", "api.mcp_server"],
"cwd": "/path/to/TickerTrace"
}
}
}
TickerTrace tells an agent what institutions hold and how it's changing. For the next step — screening, technical analysis, options/IV, backtesting — pair it with Momentum MCP, a sister project that gives an AI agent a Bloomberg-style quant toolkit. The two MCP servers compose well side by side; clone Momentum and run your own instance.
/auth/register): Full signals, briefing, sector flow, divergences, heatmaps, Δ changes page, fund profiles.# API
pip install -r api/requirements.txt
uvicorn api.server:app --port 8100 --reload
# MCP server
python -m api.mcp_server
# Scraper (Python 3.10+)
pip install -r requirements.txt
python scrape_avantis.py
# Dashboard
cd etf-dashboard && npm install && npm run dev
Full pipeline reference:
docs/PIPELINE.md— the canonical scrape → normalize → ETL walkthrough, with function/line anchors.
7:00 AM CST GitHub Actions runs scrape_avantis.py
→ fetches all fund CSVs (NestYield: link discovered from each
fund page; non-CSV 200s rejected); failed funds retried in two
passes, then carried forward with Refreshed=False
→ resolves CUSIPs via cache + OpenFIGI fallback
→ writes normalized_holdings.csv
→ copies into etf-dashboard/public/data/history/
→ commits + pushes to main
7:30 AM CST Vercel rebuilds frontend; API picks up new CSV on next request
Manual scrape on Vultr (Python 3.6 on the host can't run our deps — use Docker):
ssh vultr "cd /home/mphinance/TickerTrace && docker run --rm \
-v /home/mphinance/TickerTrace:/app -w /app \
python:3.12-slim bash -c \
'pip install -q requests beautifulsoup4 pandas yfinance && python3 scrape_avantis.py'"
# Then copy output into history:
ssh vultr "cp /home/mphinance/TickerTrace/normalized_holdings.csv \
/home/mphinance/TickerTrace/etf-dashboard/public/data/history/holdings_\$(date +%Y-%m-%d).csv"
Frontend (Vercel): auto-deploys on push to main. Domain: tickertrace.pro.
API (Vultr):
ssh vultr "cd /home/mphinance/TickerTrace && git pull origin main && \
docker compose build --no-cache && docker compose up -d"
# Quick restart (no rebuild):
ssh vultr "cd /home/mphinance/TickerTrace && docker compose restart"
# Logs:
ssh vultr "docker logs tickertrace-api --tail 50"
# Verify:
curl -s https://api.tickertrace.pro/health
The VPS working tree is often dirty from scraper output. git stash && git clean -fd etf-dashboard/public/data/history/ before pulling if git pull complains.
.agents/workflows/add-fund.md has the full workflow. TL;DR:
FUNDS in scrape_avantis.pyFUND_PROVIDERS + FUND_AUM in api/data.py (and mirror in etf-dashboard/lib/holdings.ts)Common gotchas:
Account instead of ETF Ticker — the scraper now always forces ETF Ticker = config ticker912797RG4) are filtered from displaycusip_cache.json + OpenFIGIdocker exec tickertrace-api python3 scrape_avantis.py won't work. The container only has api/.api/ — if you add a root-level Python file that api/ imports, add a COPY line.api.tickertrace.pro works. api.tickertrace.mphinance.com has no Apache vhost (requests fall through to the default vhost and return wrong-cert + 503)./auth/* endpoints still exist but are unused; CORS has an explicit allowlist; per-IP rate limits on the public endpoints.api/ — FastAPI + FastMCP servers, shared data.py layeretf-dashboard/ — Next.js 14 app (App Router, TS, Tailwind, shadcn/ui)scrape_avantis.py — daily scraper (despite the name, scrapes all 148 funds across 15 providers)cusip_lookup.py — CUSIP → ticker resolver with persistent cachetests/ — pytest suite covering the data layer + 38 junk-ticker filter casesscreenshots/ — README assets.github/workflows/ — daily scrape + CI (pytest + next build + Python AST parse check)