DNH20
How DNH Index 20 is built
A transparent, rules-based gauge of the largest crypto assets by US-dollar market capitalization.
Formula
Each name is weighted by its share of the basket’s combined US-dollar market capitalization.
Weight_i = MarketCap_i / Σ MarketCap Index = (Σ MarketCap / BaseMarketCap) × 1000
Eligibility
- Universe: the largest listed cryptoassets by market cap. The index holds exactly 20 names.
- Stablecoins (USDT, USDC, DAI, FDUSD, USDe and other fiat pegs) are excluded.
- Wrapped and liquid-staking IOUs (WBTC, cbBTC, stETH, wstETH) are dropped when the underlying is already a member, so the same cap is not counted twice.
- Manual denylist (symbol or vendor id, case-insensitive): FIGR_HELOC, figure-heloc, HELOC*, RAIN (rain / rain-protocol), CC / Canton, YLDS. Denied ids are never filled back from cache.
- When a vendor sends tags, drop stablecoin, wrapped-tokens, liquid-staking-tokens (if the underlying is already in the universe), tokenized-rwa, tokenized-products, tokenized-treasury, real-world-assets, private-credit, heloc, and mortgage.
- Liquidity screen when 24h volume is reported: at least $25M and volume / market cap of at least 0.40%. Missing volume does not fail the name.
- Pricing may refresh every 10 minutes on a locked 20. That updates prices, caps and weights — it does not reconstitute membership.
- Membership is reviewed once per UTC day at 00:00. Effective date and members_hash are persisted. Intra-day snapshots do not add or drop names except hygiene fails (denylist or missing quote).
- In: eligible rank ≤ 18 and market cap ≥ 115% of the current rank-20 cutoff. Out: eligible rank ≥ 23 or market cap ≤ 85% of cutoff. Ranks 19–22 keep the incumbent unless they fail hygiene.
Base & divisor
Genesis is 2025-01-01. The index is scaled to 1,000 points using a fixed divisor of $2.4T (combined basket capitalization at base).
Reconstitution
Pricing can refresh every 10 minutes on a locked 20 — weights drift with live caps; that is not a membership trade. Official membership is reviewed once per UTC day at 00:00 with an 85/115 band around the rank-20 cutoff (in at rank ≤ 18 and ≥ 115% of cutoff; out at rank ≥ 23 or ≤ 85%; ranks 19–22 keep the incumbent unless they fail hygiene). The lab’s 85/115 toggle is that same hysteresis on the twelve-month panel.
DCA into DNH20
What this simulator represents: DNH20 is a composite index, not a tradable security or financial product. "DCA into DNH20" refers to a hypothetical scenario of periodically allocating capital across the 20 constituent assets in their index-defined weights — no fund, contract, or product named "DNH20" exists to be bought or held directly. Results are based on historical index snapshots and do not account for transaction fees, slippage, rebalancing costs, or tax implications of actually executing this strategy. This tool is for illustrative and educational purposes only, does not constitute investment advice, and past performance is not indicative of future results.
Pipeline
- CoinMarketCap first (when a key is set). On timeout, 429 or 5xx the call retries three times with exponential backoff, then CoinGecko, then CoinPaprika.
- A 5-minute snapshot cache skips the vendors. A lock stops overlapping cron and manual refreshes from double-fetching.
- Filter stables, wrapped duplicates, the denylist, category tags and the liquidity screen. At 00:00 UTC review membership with the 85/115 band; otherwise reprice the locked 20. Hygiene fails (denylist, missing quote) may replace a name intra-day. Never fill from a denied id.
- Scheduler hits /api/cron/refresh every 10 minutes for prices on the locked 20. Membership does not move with that clock. Two consecutive live-source failures page Telegram / Discord when those webhooks are configured.
- Optional: Grok drafts a bilingual desk note; Telegram delivers it when bot credentials are set.
CMC ── retry×3 ──► quotes
│ fail / no key
▼
Gecko ── retry×3 ──► quotes
│ fail
▼
Paprika ── retry×3 ──► quotes
│ fail
▼
last snapshot (if any) ──► serve + alert
│
▼
stables out → wraps out → denylist / category / liquidity
│
▼
00:00 UTC? ──yes──► 85/115 review → persist effective_date + members_hash
│ no
▼
reprice locked 20 (hygiene replace only) → persist snapshot