Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions benchmarks/perp-funding-stability.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -4,7 +4,7 @@ slug: perp-funding-stability
number: "043"
title: Perp DEX funding stability, 7-day stddev of ETH funding ranked
seo_title: "Perp DEX funding stability 2026: ETH funding stddev across 12 venues ranked"
seo_description: "Live 7-day standard deviation of ETH perpetual futures funding rate in bps across 12 major venues. Lower means more stable funding for carry traders."
seo_description: "Live 7-day standard deviation of ETH perpetual futures funding rate in bps across 12 major venues (Hyperliquid plus 11 CEX-style perp books). Lower means more stable funding for carry traders."
subtitle: 7-day standard deviation of ETH funding rate, in basis points per 24h, across the Mobula funding cohort. Lower means funding stays in a tight band, the carry trader's preferred signal.
category: Trading
status: live
Expand DownExpand Up@@ -44,7 +44,7 @@ methodology:
- "Source. Same upstream as perp-funding: each venue's public funding endpoint polled every 60 seconds, normalized to bps per hour and per 24h hold, sign preserved."
- "Metric. stddev_over_time(perp_venue_funding_24h_bps{asset=\"ETH\"}[7d]) per venue. The 7d window smooths intraday noise but reacts to regime shifts within a week."
- "Sign handling. The underlying series is signed (positive means longs pay). Stability measures the swing, so the ranking uses the unsigned stddev. Average direction and level are the perp-funding bench."
- "Cohort. 12 venues: Hyperliquid, Binance, Bybit, OKX, dYdX v4, Paradex, Aster on the CEX-plus-orderbook side; Drift, Vertex, EdgeX, Extended and Aevo on the onchain-perp side. All quote ETH funding with documented intervals."
- "Cohort. 12 venues from the Mobula funding aggregator: Hyperliquid (onchain), Binance, Bybit, OKX, Gate, Lighter, KuCoin, MEXC, Bitget, Kraken, Coinbase, Deribit. All publish normalized hourly ETH funding."
- "Cadence. The upstream funding harness polls every 60 seconds; Prometheus scrapes every 30 seconds. The 7 day stddev refreshes on every scrape."
- "Failures. A venue whose upstream funding feed errors keeps its last gauge value; the perp_venue_health gauge drops to 0 and the leaderboard tags the row stale."
- "Reproducibility. The harness emits perp_venue_funding_24h_bps with labels venue and asset; the bench query is the stddev over 7d on that series with asset=ETH pinned."
Expand Down
2 changes: 1 addition & 1 deletion src/app/perps/page.tsx
Original file line numberDiff line numberDiff line change
Expand Up@@ -24,7 +24,7 @@ import { SITE } from "@/data/site";
*/

const DESCRIPTION =
"Live volume, open interest, fees, all-in cost and funding rate across 15 perpetual DEXes. Reproducible methodology, refreshed every minute, sources public.";
"Live volume, open interest, fees, all-in cost and funding rate across 16 perpetual DEXes. Reproducible methodology, refreshed every minute, sources public.";

export const metadata: import("next").Metadata = pageMetadata({
path: "/perps",
Expand Down
2 changes: 1 addition & 1 deletion src/data/provider-registry.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -1304,7 +1304,7 @@ export const PROVIDER_REGISTRY: Record<string, ProviderRegistryEntry> = {
twitter: "@DriftProtocol",
},
vertex: {
url: "https://vertexprotocol.com",
url: "https://www.nado.xyz",
description:
"Arbitrum perp and spot orderbook DEX with off-chain matching and on-chain settlement. Migrating to Ink Foundation.",
twitter: "@vertex_protocol",
Expand Down
38 changes: 38 additions & 0 deletions src/lib/providers.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -344,6 +344,29 @@ async function buildProviders(): Promise<ProviderProfile[]> {
});
}

// Seed stub profiles for cohort venues that don't yet have a bench
// appearance. Without this, /products/<slug> renders 404 for every
// venue the harness tracks but no bench specifically ranks (e.g. the
// perp cohort venues drift, edgex, extended, aevo, pacifica,
// variational, ostium, grvt have no row in perp-fees or perp-funding,
// so getProvider() returned undefined). The stub carries name + type
// only; appearances stays empty so the product page still renders the
// PerpVenueSection from the cohort harness without falsely claiming
// bench coverage. PM cohort venues stay unaffected because every PM
// venue already appears in at least one PM bench.
for (const v of PERP_VENUE_SEED) {
const key = v.slug.toLowerCase();
if (byKey.has(key)) continue;
byKey.set(key, {
slug: v.slug,
name: v.name,
type: "protocol",
appearances: [],
wins: 0,
categories: [],
});
}

const profiles = Array.from(byKey.values());
profiles.sort((a, b) => {
if (a.wins !== b.wins) return b.wins - a.wins;
Expand All@@ -355,6 +378,21 @@ async function buildProviders(): Promise<ProviderProfile[]> {
return profiles;
}

// Cohort venues that should have a /products/<slug> page even when no
// bench in benchmarks/ ranks them. Imported as a flat list here to
// avoid a build-time cycle with the perp-stats module.
const PERP_VENUE_SEED = [
{ slug: "drift", name: "Drift" },
{ slug: "vertex", name: "Vertex" },
{ slug: "edgex", name: "EdgeX" },
{ slug: "extended", name: "Extended" },
{ slug: "aevo", name: "Aevo" },
{ slug: "pacifica", name: "Pacifica" },
{ slug: "variational", name: "Variational" },
{ slug: "ostium", name: "Ostium" },
{ slug: "grvt", name: "GRVT" },
];

/** Cross-request cache. The expensive part isn't `getBenchmarks()`
* itself (already wrapped in unstable_cache) but the per-provider
* ranking + wins + per-chain aggregation post-processing on top. A 60
Expand Down
Loading