vike
Data providers

Venue-direct

The seven collectors that page a venue's own keyless history endpoint into the store — five klines bins sharing one CLI body, plus Dukascopy ticks and Hyperliquid candles.

Seven bins in crates/vike-backfill talk to a venue directly, and all seven sit behind the venue-backfill feature (crates/vike-backfill/Cargo.toml): binance_backfill, bybit_backfill, okx_backfill, aster_backfill, deribit_backfill, dukascopy_backfill and hyperliquid_backfill. A default build has neither the module nor the bridge dependency, so the invocation is cargo run -p vike-backfill --features venue-backfill --bin <name>. What they have in common, from crates/vike-backfill/src/caps.rs: every one of them writes kind=bar, and Dukascopy is the only venue-direct source that also serves a tick kind — quotes, never trades, because .bi5 is a quote feed. None of them can repair a recorded trade or book gap.

The five klines bins

binance, bybit, okx, aster and deribit differ in nothing but the venue. crates/vike-backfill/src/klines.rs is the one place their shape lives: commit_key is the idempotency format, backfill_klines the fetch→ingest orchestration each venue binds with its own VENUE constant and bridge fetcher, and run_klines_backfill_cli the CLI body every bin calls. Its klines_usage text is what --help prints, and it is exact about the arguments:

<venue>_backfill <ROOT_DIR> <SYMBOL> <INTERVAL> <START_MS> <END_MS>

All five are required and positional, in that order, and the window is in epoch milliseconds — the usage names seconds as the mistake that silently backfills 1970. Bars land under kind=bar/venue={venue}/symbol=SYMBOL/interval=INTERVAL, re-running the same window writes 0 rows, and a still-forming final candle is dropped. The crates/vike-backfill/src/lib.rs header gives the key's shape: {venue}:{symbol}:{interval}:{start}-{end}. There is no resample step — klines are already bars.

Per venue, from each bin's own header:

  • Binance (crates/vike-backfill/src/bin/binance_backfill.rs) pages the public REST endpoint at 1000 rows per request. It is the one bin of the family whose persisted pace actually steers, because Binance is the only venue of the five that publishes a REQUEST_WEIGHT budget for the pager to discover; the record is keyed (binance, spot|perp) because the two hosts publish different budgets (6000 vs 2400 weight per minute) and price /klines differently (weight 2 vs 5).
  • Bybit (bybit_backfill.rs) pages 1000 rows per request, newest-first and reversed by the fetcher. crates/vike-backfill/src/bybit.rs warns that the endpoint is end-anchored — it ignores start once the window exceeds the cap and answers the newest 1000 rows with retCode: 0 — so the bridge pages backward and a window wider than 1000 intervals is normal here, never silently clipped.
  • OKX (okx_backfill.rs) pages the history-candles endpoint backward through its 100-row cap via the after cursor. Its per-page cost was measured on prod2 on 2026-08-04 at 476–486 ms, against a 200 ms delay nobody had ever checked.
  • Aster (aster_backfill.rs) reads keyless public mainnet REST; a symbol carrying the .P suffix (BTCUSDT.P) fetches the USDⓈ-M perpetual and is stored under that suffixed key, a bare symbol fetches spot. crates/vike-backfill/src/aster.rs says why mainnet is not a risk decision here: klines are a keyless public read, so the standing rule to exclude Aster from validation runs — which is about authenticated account calls — does not reach this path.
  • Deribit (deribit_backfill.rs) pages the venue's public, keyless chart-data JSON-RPC endpoint. SYMBOL is a Deribit instrument name passed through verbatim (BTC-PERPETUAL, a dated future) — there is no .P suffix on this venue, because the name is already unambiguous. The endpoint is end-anchored like Bybit's and is paged backward.

A 24-month 1m pull on Deribit is a lot of requests and a lot of log

deribit_backfill.rs's header: set VIKE_LOG_FILE_LEVEL=warn for it — the file layer is trace by default and does not listen to RUST_LOG. The rule for every long run is on log volume.

The pace book

crates/vike-backfill/src/pace_book.rs explains what the klines bins persist and why: every backfill measures its own pace — the wall clock of a request, the weight one request costs — and used to discard it at exit, so run N+1 opened on a pessimistic constant (on Binance spot, where a page costs weight 2, the pacer's seed of 5 paced the first pages 2.5× slower than the venue permits). The record is written down and the next run reads it. run_klines_backfill_cli resolves the file through crates/vike-backfill/src/cli.rs's pace_book_path: $VIKE_PACE_BOOK, then <project>/settings/state/pace.json, then <ROOT_DIR>/pace.json for a binary with no project above its working directory.

The file is a cache and follows a never-brick law: a missing, unreadable or unparseable file is "no record", deleting it costs one run's opening pages and nothing else. And a record does not mean a faster backfill. run_klines_backfill_cli's doc is blunt: Binance's genuinely re-paces the first page, while Bybit, OKX and Deribit's pagers answer their hardcoded PAGE_DELAY whatever is stored — for them the record buys an ETA line from page zero and an operator-readable per-page cost. Aster is the one bin that persists nothing at all, because its host is environment-resolved and the bridge exposes no paced fetch to plumb a sample through (aster_backfill.rs).

Dukascopy ticks

crates/vike-backfill/src/bin/dukascopy_backfill.rs takes a different argument shape:

dukascopy_backfill <ROOT_DIR> <SYMBOL> <START_MS> <END_MS> [INTERVAL]

It fetches tick history for a symbol such as EURUSD from Dukascopy's keyless .bi5 datafeed, appends the quotes, then — if INTERVAL is given — resamples the stored quotes into OHLCV bars. crates/vike-backfill/src/dukascopy.rs names the pipeline: fetch_ticks_range → tick_to_quote → append_quotes → resample_quotes_to_bars, the last being the parity-tested vike_model::consolidate_quotes. It is history-only: Dukascopy publishes with a T+1 lag. This was the crate's first collector, and crates/vike-backfill/src/lib.rs's header still introduces it that way — the first collector, keyless .bi5 tick history to QuoteTicks to the store, plus a quote-to-bar resample.

Hyperliquid candles

crates/vike-backfill/src/bin/hyperliquid_backfill.rs pages the keyless candleSnapshot /info endpoint on mainnet with named flags rather than positionals: --symbols is a comma list of vikeSymbol=coin pairs (bare SYM means coin equals symbol — HL perps use the coin as the symbol, BTC/HYPE), --interval is one of 1d, 1h, 5m, 1m, and --start/--end are each an epoch-ms integer or a YYYY-MM-DD UTC date with --end defaulting to now. The fetcher pages forward by advancing startTime past each page's last candle close (crates/vike-backfill/src/hyperliquid.rs), and the one wrinkle is that the store symbol may differ from the coin the fetch pages, so the commit key and append key on the symbol. Series land as kind=bar/venue=hyperliquid, idempotent per window. The same module owns the realized-funding backfill, which is on funding rates.

The klines trio backfill_{binance,bybit,okx}_klines is also what the desktop app's bulk Backfill action and vike-datahub's backfill-on-demand call (lib.rs header) — see Backfill from the GUI.

On this page