Sources

Built-in historical data sources: venue REST, mock walk, CSV upload — contracts, config, and fallbacks.

This page

Sources

Abstract

A source loads a finite window of OHLCV bars for the chart and engine. Sources live in src/sources/catalog.ts and register into the unified registry via ensureSourcesRegistered().

Conceptual model

Diagram

Rendering…

Built-in catalog

idNameNetworkNotes
binance-restBinance RESTyesPublic klines; synthetic walk fallback only when fallback: true (default off)
okx-restOKX RESTyesCandles; symbol BTCUSDTBTC-USDT; max 300 bars
bybit-restBybit RESTyesSpot v5 klines; newest-first reversed
coinbase-restCoinbase RESTyesExchange candles; USDT pair rewritten to USD product
kraken-restKraken RESTyesPublic OHLC; pairs with kraken-ws
mexc-restMEXC RESTyesPublic spot klines (api.mexc.com); 1h60m; pairs with mexc-ws
mock-walkMock WalknoOffline random walk; optional Mulberry-like seed
csv-uploadCSV / JSON UploadnoReads last upload from upload-store

UI order is BUILTIN_SOURCES array order (Binance first).

Interface surface

Every source implements SourcePlugin (contracts):

fetchHistorical({
  symbol,
  interval,
  limit?,
  startTime?,   // unix seconds (optional)
  endTime?,     // unix seconds (optional) — walk-back pagination
  signal?,      // AbortSignal for background jobs
  config?,
}): Promise<Bar[]>

One-shot Load vs Data Source Manager

PathBehavior
src/data/load-symbol.tsSingle fetchHistorical (limit from Settings historyBars) → chart
Data Source ManagerMulti-page walk-back with endTime only per page, then validate + gap-fill, durable IDB cache

Do not pass startTime + endTime together when paginating on Binance-style venues: they return the first N bars from startTime, which can falsely complete a multi-year job in one page.

Config highlights

binance-rest

KeyDefaultMeaning
baseUrlhttps://api.binance.comOverride for mirrors/proxies
limit50050–1000
fallbackfalseOn network error, synthesizeWalk (demo only)

When Settings → Data has a Binance key in the session vault, Load uses signed REST (higher weight) and falls back to the Worker /api/market/binance/signed/klines on CORS failure. Keys are never written to disk.

mock-walk

KeyDefaultMeaning
seed00 = non-deterministic; non-zero = deterministic PRNG
startPrice100Walk origin
limit500Bar count

csv-upload

  • No schema fields. User must Upload a CSV (time,open,high,low,close[,volume]) or JSON array first; otherwise throws a clear error.

Internals

PathRole
src/sources/catalog.tsDefinitions + register/list/get + sourcePageLimit
src/sources/upload-store.tsIn-memory last upload for csv-upload
src/data/load-symbol.tsOne-shot Load pipeline
src/data/data-source-manager.tsBackground backfill + validate + gaps
src/data/bars-cache.tsIDB OHLCV cache for manager
src/data/bars-gaps.tsCoverage / gap detection
src/data/parse-bars.tsCSV/JSON normalization

Interval → venue codes

Helpers map AXIS intervals (1m, 3m, 5m, 15m, 30m, 1h, 2h, 4h, 6h, 8h, 12h, 1d, 3d, 1w, 1M) to OKX bar, Bybit interval codes, Coinbase granularity seconds. Unmapped intervals fall back to daily-ish defaults — check venue docs if you add exotic TFs. Some venues omit a subset (MEXC has no 3m/2h/6h/8h/12h/3d; Kraken has no 3m/2h).

Dynamic registration

registerDynamicSource(plugin)  // from catalog / loader
unregisterDynamicSource(id)
listDynamicSourceIds()

Loader path: kind === 'source' + fetchHistorical required.

Invariants & edge cases

  1. Time unit — always seconds unix (Binance ms ÷ 1000).
  2. Binance fallback — offline demos “work” but are not real prices; disable fallback for strict desk research.
  3. CORS — browser → public venue APIs must allow CORS; corporate proxies may require a Worker /api/proxy (not shipped as a general proxy today — plan carefully).
  4. Newest-first venues (OKX, Bybit, Coinbase) — catalog reverses/sorts ascending by time for the chart.

Worked example

// Minimal custom source (ES module for loader)
export default {
  id: 'static-two',
  name: 'Two Bars',
  kind: 'source',
  async fetchHistorical() {
    return [
      { time: 1_700_000_000, open: 1, high: 2, low: 0.5, close: 1.5, volume: 10 },
      { time: 1_700_000_060, open: 1.5, high: 2, low: 1, close: 1.2, volume: 12 },
    ];
  },
};

Failure modes

Error / symptomFix
No uploaded file…Use Upload before selecting csv-upload
Empty chart + Binance downExpected synthetic walk if fallback on
OKX code !== '0'Symbol format / region block
CORS blockedProxy or different source

See also