Data sources
Reference for where Forven's market data comes from — the Binance research series, the other venues in Get data, Binance Vision archives, CSV import — plus the research universe, symbol formats, enrichment streams, provenance, and the data API.
This is the source-by-source reference for Forven's market-data layer. The data manager page covers the /data screens and the day-to-day workflow; this page documents what each source provides, how symbols are formatted, the research universe, the enrichment streams that ride alongside candles, how data provenance protects verdicts, and the API.
It is written for developers and operators who need exact source names, symbol conventions, settings, and endpoints.
The sources at a glance
Data → Get data → A market downloads candles from one of these places, under Where from:
| Where from | Stored as | Notes |
|---|---|---|
| Binance USD-M perp | The research series (canonical) | The default, and the series every backtest, the gauntlet and paper trading read. If Binance lists only a spot market for a symbol, Binance spot is the research series instead. |
| OKX, Bybit, Coinbase, Kraken (spot) | A separate venue series | Never mixed into the research series. If Binance doesn't list the symbol at all, the download becomes its research series. Kraken history is rebuilt from every trade, which is slow. |
| Hyperliquid (perp) | A separate venue series | Hyperliquid serves only its latest 5,000 candles per timeframe. |
| Binance Vision archives | The research series | Bulk monthly and daily archives — the fastest way to seed years of history. Used by Extend history and the research-universe seed. |
| CSV file (Data → Import file) | A new series, or a patch to an existing one | Your own bars. Nothing is written until you click Import. |
None of these needs a key. Each venue row in Get data says whether that venue lists the market, and a download from a venue series never feeds a backtest unless it is the market's research series.
Polygon
A Polygon API key field remains in Settings → System → Data source API keys, and the backend still answers /api/data/polygon/tickers and /api/data/polygon/status. Get data doesn't offer Polygon as a source.
Binance and the research series
Crypto history is stored perp-canonical — with the perpetual-futures semantics Forven would trade — and every stored series carries a venue stamp. Paper trading reads Binance prices live (market_data_source, default binance), so paper and backtest judge a strategy on one venue's prices.
Binance Vision
Binance Vision is the bulk downloader for data.binance.vision. It probes for a symbol's true start date, tracks what it has covered, resumes interrupted runs, and parses the older header-less archives. It also supplies derivatives metrics — open interest, long/short ratio, and taker volume. On a series page or in the Catalog, Extend history uses it to reach further back.
CSV import
Upload a file on Data → Import file, map its columns, check the preview, then import it as a New series or Add bars to it (patch). Where the file and stored bars differ, you choose Keep the stored values or Use the file's values. Pick one canonical source per symbol and timeframe, and stick to it.
The research universe
The symbols you trade and the symbols you research are different sets. The research universe is a liquidity-ranked set of Binance USD-M perpetuals that Forven keeps deep history for, so ideas can be tested on more markets and more history than you trade:
- A symbol registry tracks every perp listed on the venue, with its listing and delisting dates.
- A timeframe ladder sets the depth: 1h, 4h and 1d for the whole universe, 15m and 5m for the top tier, and 1-minute bars for the top few.
- Delisted symbols keep their history, so research is not biased toward survivors.
Settings → Data → Research universe holds the plan:
| Setting | Default |
|---|---|
| Research universe | On |
| Instrument types | Crypto perps and TradFi perps (stocks, commodities, FX) |
| Universe size | 50 symbols |
| Intraday depth (15m and 5m) | Top 20 |
| 1-minute depth | Top 10 (about 80 MB each for full history) |
| Derivatives history | 365 days of OI, long/short and taker-volume history per symbol |
Downloads never start on their own. To fill the plan, open Data → Get data → A research universe and click Bring the universe up to plan (or Resume the seed). It runs as one job from Binance Vision archives and resumes where it stopped. Over the API: GET /api/data/universe, POST /api/data/universe/config, POST /api/data/universe/seed.
Symbol formats
The same instrument is spelled differently by each source. Forven normalizes at the import and export boundaries, and the symbol registry treats spelling variants of one market as the same market — SOLUSDT, SOL/USDT, and SOL-USDT all resolve to one pair.
| Context | Format | Example |
|---|---|---|
| Filesystem / canonical | BASE-QUOTE | BTC-USDT |
| CCXT | BASE/QUOTE (or :SETTLE) | BTC/USDT, BTC/USDT:USDT |
| Binance Vision | concatenated | BTCUSDT |
Asset class is detected from the symbol's shape, so you do not declare it.
Strategies, ideas and backtest requests share one symbol check. A dataset id where a symbol belongs (SUI/USDT-1h-ccxt, dataset-3-ETH/USDT-4h) is repaired to the pair, and something that isn't a market, such as 1/USDT, is refused with a reason that says why. 1INCH and 1000PEPE are real coins and pass.
Enrichment streams
Candles are the spine. Alongside them, Forven collects derivative and context streams and merges them onto bars for a backtest. In Get data, the Perp add-ons checkboxes choose which ones to fetch with a market (funding and open interest are ticked by default):
| Stream | What it measures | Source |
|---|---|---|
| Funding rates | Perp funding paid/received, normalized per hour by each print's own interval | Binance |
| Open interest | Outstanding contract notional | Binance / Binance Vision |
| Long/short ratio | Account or position skew | Binance / Binance Vision |
| Taker volume | Aggressive buy/sell flow | Binance / Binance Vision |
| Liquidations | Forced-close volume, captured live | OKX all-swaps stream |
| Basis | Perp premium over the index | Binance premium index |
| Implied volatility | BTC and ETH DVOL | Deribit |
| Fear/greed index | Sentiment proxy | Public index |
| Macro indicators | VIX, DXY, bonds, sector ETFs | Yahoo Finance (background collector) |
| BTC dominance | BTC share of crypto market cap | CoinGecko |
Enrichment happens on demand during a backtest: each bar is matched to the nearest prior value of each stream (a merge-asof join), so no future information leaks backward. Two further rules keep it honest:
- Bucket-aggregate streams are shifted to bucket close. Taker flow, liquidations, and basis summarize a forward window that is only known at its close, so their timestamps move to the close before merging.
- Missing stays missing. If a stream is unavailable for a symbol or window, its columns are still on the frame but empty (NaN) — never zero-filled into something a strategy might trade on. A strategy that reads one simply doesn't fire on those bars, instead of crashing. Each stream also has a maximum age based on its own cadence, so a stale print is not carried forward forever.
Funding and open interest for backtests and paper come from Binance, not HyperLiquid, so the enrichment matches the series the strategy is validated on.
Point-in-time reconstruction (as_of) is supported for OHLCV via the revision log, and gauntlet runs can pin a candidate's data to a fixed as-of point. Enrichment streams do not support as_of.
Keeping data fresh
Once a series is stored, the Data Collector (freshness SLA) job keeps it current: every 120 seconds it refreshes the most overdue series first, within a 90-second budget per run and 120 requests a minute per venue. How late a series may be depends on who reads it — live, paper, gauntlet, research universe, or nothing — as described in data freshness. A series that finds no newer data three refreshes in a row (a delisted or renamed symbol) is frozen. The settings are under Settings → Data → Freshness SLAs and Collection.
Going the other way, when a run needs older history than a stored series holds but a finer timeframe of the same symbol goes back further, the missing older bars are rebuilt from that finer series (complete buckets only) before anything is downloaded. Native bars win wherever both exist.
Data provenance
A verdict is only as good as the data it was scored on. Every persisted backtest is stamped with a compact fingerprint of its data's semantics: each enrichment stream's print cadence, value scale, and whether it existed. Appending new bars never changes the fingerprint; a cadence flip, a unit rescale, or a stream appearing or disappearing does.
When the fingerprint of today's data no longer matches the one a verdict was scored on, the verdict is treated as stale: the gauntlet reads it as missing evidence and re-runs through the normal flow. See promotion gates. This is what stops a transient data artifact — a funding file rewritten mid-day, say — from quietly "validating" a strategy.
The market calendar
Crypto trades around the clock, but equities and forex do not. Forven carries a market calendar — NYSE hours and holidays, forex session windows, always-on crypto — so a stock backtest does not treat an overnight gap as a missing bar.
How data lands on disk
Every persisted bar is a closed bar. Writes are atomic: Forven writes a temporary file, fsyncs it, then renames it into place (retrying the rename on Windows share-violation races). A crash leaves a stray .tmp that a background orphan scan cleans up. Before any bar enters the lake it passes an OHLC sanity check — high ≥ low, open and close within the bar's range, positive prices, non-negative volume — and a corrupt Parquet file is detected and skipped rather than crashing a read. Dataset paths are confined to the data directory.
Configuration
Where data is stored
| Variable | Meaning |
|---|---|
FORVEN_HOME | Base directory for all app state (default ~/.forven). Data lives under $FORVEN_HOME/data/. |
FORVEN_DATA_DIR | Explicit override for the data-lake root. If set, all streams live here. |
Keep FORVEN_DATA_DIR and FORVEN_HOME consistent. If they diverge, the candle lake and the enrichment streams can end up under different roots, and the app may read empty enrichment streams. Forven checks root consistency at startup and warns on mismatch.
The Data Engine
Settings → Data → Data Engine controls how data is read. Data Engine enabled is on by default: candles and enrichment are read through DuckDB over the Parquet lake. Turning it off falls back to a legacy read path that is kept only as a fallback and will be removed. The same section holds Point-in-time mode (latest, or an as-of pin for reproducible backtests) and the Source reconciliation gate, which holds a strategy out of paper and live when its backtest price source diverges from the live trade venue by more than Max source divergence (default 2%).
Remote engine (optional)
For a shared-server setup, Settings → System → Remote engine offloads backtests to a remote Forven engine process.
API surface
The data layer is served on the local backend (127.0.0.1:8003). The endpoints behind the Data screens:
| Method | Path | Purpose |
|---|---|---|
GET | /api/data/sla | The freshness census: every series with its tier, lag and state. |
POST | /api/data/sla/refresh | Refresh or repair selected series now. |
GET | /api/data/catalog | Every stored series, for the Catalog. |
GET | /api/data/series/{symbol}/{tf} | One series' detail (plus …/bars, …/gaps, …/rows). |
GET | /api/data/acquire/targets?symbol= | Where a market can be downloaded from, and where each download would be stored. |
POST | /api/data/acquire/estimate | Size and time estimate for a download plan. |
POST | /api/data/acquire/downloads | Start downloads as background jobs. |
POST | /api/data/acquire/import/preview · /api/data/acquire/import | Preview and import a CSV. |
POST | /api/data/history/extend | Extend a series' history from Binance Vision. |
GET | /api/data/jobs · /api/data/jobs/{id} | Data jobs and one job's detail. |
POST | /api/data/jobs/{id}/cancel · …/retry | Cancel or retry a job. |
GET | /api/data/storage · /api/data/trash | Disk use, reclaimable space, and the trash. |
POST | /api/data/readiness | Whether the data a strategy needs is present and fresh. |
GET | /api/data/universe | The research universe and symbol registry. |
GET | /api/datasets-export/{symbol}/{timeframe}/download | Download a dataset as CSV, Parquet, or JSON. |
The older endpoints — /api/datasets, /api/data/ingestion/submit and /api/data/ingestion/runs, /api/upload/csv — still answer, for scripts written against them.
See the API reference for the full router catalog and authentication.
Caveats
- Venue series don't feed backtests. Only the research series does, unless Binance doesn't list the market.
- Hyperliquid history is short. Only the latest 5,000 candles per timeframe are available there.
- Source metadata is last-write-wins. Pick one canonical source per symbol.
- Point-in-time is OHLCV-only. Enrichment streams cannot be reconstructed as-of a past date.
- Deep history is large. A big research universe with minute bars takes hours to download and gigabytes of disk. Get data and Set up data show an estimate before you start.
Forven is a research tool. Clean data improves the honesty of a backtest, but no dataset makes a result predictive of future performance, and nothing here is financial advice.
Related
- Managing market data — the
/datascreens, from download to delete. - Health monitoring — freshness tiers and data alerts.
- Promotion gates — how stale data provenance re-queues validation.
- Environment variables — every data and storage variable in detail.
Writing custom strategies
Author a custom Forven strategy in Python — the BaseStrategy contract, the Signal shape, the vectorized path, allowed imports and enrichment columns, trade modes, registration, and the safety guard.
Health monitoring
How Forven's health monitor tracks its long-running loops and judges data freshness by SLA tier, what green, amber, and red mean, where you see health in the app, and how health alerts are routed.