vike
Data providers

Funding rates

Two collectors that look alike and write different things — the venue-wide market funding rate a strategy trades on, and one account's realized funding payments.

Two bins in crates/vike-backfill carry "funding" in their name, and crates/vike-backfill/src/funding_rate.rs's header draws the line between them before anything else. funding_rate_backfill writes the market rate: the venue-wide, position-independent funding schedule for a symbol — keyless, available for every perpetual whether or not you hold it, and the signal a funding-capture strategy trades on. hyperliquid_funding_backfill writes an account's realized funding: a wallet's userFunding payments, which is a different series with a different store kind. Both sit behind the venue-backfill feature, and the second reason is not obvious: crates/vike-backfill/Cargo.toml notes that funding_rate_backfill looks bridge-free but routes through crate::funding_rate, which calls vike-hyperliquid.

The market rate: funding_rate_backfill

The collector fetches a venue's public funding-rate schedule and ingests it as kind=bar, the rate riding on vike_model::Bar::funding with OHLCV and volume left 0.0 — so a backtest's funding_source seam can replay the real per-interval rate off the stored column (funding_rate.rs header). Two venues ship, each as an impl of the FundingRateSource trait — a pure, fixture-tested parser over the venue's JSON plus a paged fetch:

  • Binance — GET https://fapi.binance.com/fapi/v1/fundingRate with symbol, startTime, endTime and limit=1000; 8-hour cadence; a keyless GET over the crate's shared HTTP client.
  • Hyperliquid — POST /info with {"type":"fundingHistory", ...}; 1-hour cadence; a keyless mainnet read over the bridge's own HyperliquidTransport.

Both venues cap responses at roughly 500–1000 rows, so fetch pages startTime forward until a page comes back short or the cursor passes the end (page_forward, shared by both impls). The run is idempotent per (venue, symbol, [start, end]) window through funding_rate_commit_key.

From crates/vike-backfill/src/bin/funding_rate_backfill.rs's usage: --venue selects the source and names the store partition (binance | hyperliquid); --symbols is a comma list of vikeSymbol=sourceSymbol pairs, bare SYM meaning the two coincide (Binance BTCUSDT, Hyperliquid BTC); --start/--end are each an epoch-ms integer or a YYYY-MM-DD UTC date, --end defaulting to now; --interval is the series interval label and defaults, for both venues, to the cadence-agnostic namespace funding — FundingRateSource::default_interval is deliberately not a cadence (8h/1h), because funding spacing varies by venue and by symbol, so the true cadence lives in the data, in the spacing of the stored Bar.ts, and one stable label keeps this series in its own keyspace where an OHLCV kline series can never interleave with it. An operator who wants a cadence-tagged series passes --interval, as the second example below does. --store resolves through the store's ladder: $VIKE_HIST_STORE, then a project declared by $VIKE_SETTINGS_DIR, then <repo>/market_data/hist.

funding_rate_backfill --venue binance --symbols BTCUSDT,ETHUSDT --start 2024-01-01
funding_rate_backfill --venue hyperliquid --symbols BTC=BTC,ETH=ETH --start 1704067200000 --interval 1h

Hyperliquid's response carries a second number, and it is kept

The funding_rate.rs header records that premium was parsed and discarded for as long as the file existed. It is the venue's funding premium for the same interval, not derivable from fundingRate (the venue folds an interest-rate term in and then clamps), and it is the input the cohort study's premium_z_24h feature needs. It is stored as its own kind — kind=perp_metrics, one PerpMetricRow per interval that had one — rather than on the funding Bar, which has no field for it. Binance sends no premium and therefore writes none. Open interest is deliberately not beside it: Hyperliquid serves OI only as a current snapshot, never as history, so no backfill can reconstruct a past value. The one producer that does fill open_interest is the vike.io hourly panel, on the Data API page.

The account's payments: hyperliquid_funding_backfill

crates/vike-backfill/src/bin/hyperliquid_funding_backfill.rs fetches a master account's keyless userFunding /info history on mainnet — no credentials, just the address — over [--start, --end] and ingests it as kind=funding/venue=hyperliquid/symbol=<coin>, split by coin and idempotent per (account, coin, window). It is the funding analog of hyperliquid_backfill, and crates/vike-backfill/src/hyperliquid.rs owns both: the candle backfill and backfill_hyperliquid_funding with its pure funding_rows_by_coin, persisting through vike_data::HistStore::append_funding.

--account is the master account address funding is read against. The bin header is explicit about the agent-wallet pitfall the bridge guards against elsewhere: it does not apply here, because funding reads are keyless — pass the master address. --start/--end take the same epoch-ms-or-date forms as the market-rate bin, and --store resolves the same way.

hyperliquid_funding_backfill --account 0x8f0a3e01d916486735a8f6a2ffc0685a3fa57bf5 --start 2024-01-01

Which one you want

A funding-carry strategy backtest wants the market rate, on Bar.funding, from funding_rate_backfill — that is the number the position would have paid or received per interval regardless of who held it. A reconstruction of what one wallet actually received wants kind=funding from hyperliquid_funding_backfill. crates/vike-backfill/src/caps.rs tracks the first as bars and does not track the second at all, with the reason on the Hyperliquid row: realized funding payments are not market data, and no coverage report asks for them. The kinds themselves are documented under concepts/data; the tutorial that consumes the market rate is funding carry across two venues.

Two producers of one series double its hours

vikedata_backfill --panel-funding also writes funding-rate hours, and its usage text states that the panel's rate and fundingHistory's settled rate are different series — a snapshot aggregate versus a settled interval rate, measured roughly 4× apart. The store's idempotency is batch-level on the commit key, two producers are two keys, and the hours they share land twice. One store takes one producer for a window.

On this page