Telemetry off
Documentation

Documentation

22. v0.10.0 — CSV data provider

Created
Aug 23, 2026
Updated
Aug 23, 2026

This release adds CSV as a sixth data provider — the first local one. Import CSV files of OHLCV bars and chart your own data like any other instrument: symbol search, watchlists, every timeframe you imported, indicators, Pine request.security, backtesting, and replay all work. The one deliberate difference: imported bars are static — there is no realtime feed, charts don't tick, and alerts on CSV symbols never trigger. Everything stays in your browser; nothing is uploaded.

Added

  • CSV import in Settings → Data provider. Drop many files in one gesture. Files named SYMBOL_tf.csv (MES_1m.csvMES_1w.csv) group automatically into one symbol with one series per timeframe, and an instruments.csv manifest (symbol,minQty,mintick) merges into symbol metadata. Other filenames import as a single series with a preview where you pick the symbol, timeframe, and asset class. Re-importing a file for an existing symbol + timeframe replaces that series — the flow for datasets you re-export over time.
  • A tolerant, fast streaming parser. Comma/semicolon/tab delimiters and RFC-4180 quoting are auto-detected; columns map by header synonyms (time|date|timestamp, o/h/l/c, vol; an adj close column is never auto-picked over close); times may be epoch seconds, epoch milliseconds, ISO-8601 datetimes, or plain dates — all interpreted as UTC. Rows are sorted, duplicate timestamps keep the last occurrence, high/low are clamped to contain open/close, unparseable rows are skipped, and the summary reports every count. A ~112 MB, 2.3-million-row minute file imports in about two seconds.
  • Per-timeframe series, served verbatim. Each imported timeframe is stored and served as its own series, so your exported bars render exactly as exported — including session-anchored weekly bars that UTC re-aggregation would shift. A timeframe you didn't import is aggregated from the best finer series; a timeframe finer than anything imported shows the normal empty state rather than fabricated data.
  • Chunked browser storage built for large files. Bars live in IndexedDB as fixed 32,768-row columnar chunks with windowed reads, so opening a chart touches a couple of chunks — never a whole multi-million-row series. Caps: 256 MB per file, 4M rows per series, 11 series per symbol, 32 symbols. The panel shows storage usage, and the app asks the browser to persist the data on first import.
  • CSV: addressing and full surfacing. CSV:MES (or CSV:FU:MES for a non-default asset class), ?provider=csv, CSV-badged rows in symbol search, a CSV watchlist badge with quotes from the imported bars (last close and change), a synthesized ticker overview, and a dataset manager (per-symbol and per-series delete) in the provider panel.
  • Dataset-aware chart windows. A dataset that ends in the past opens showing its most recent bars instead of an empty chart; scrolling left pages history back to the file's first row, stepping across any collection gaps inside the data, and stops cleanly at the first row. A class-less address (CSV:MES with no asset-class token) still finds the dataset when exactly one imported class holds that ticker.

Changed

  • Symbol resolution order is now Binance → OKX → Kraken → Massive → Alpaca → CSV (last) — an imported dataset never shadows a real exchange symbol; pin it with CSV: or pick it from search.
  • Watchlist quote routing treats CSV as self-quoting: CSV rows quote only from their own imported bars and never fall back to the equity providers.
  • Workspace market/exchange mapping returns exchange: "CSV" and market: "imported" for CSV instruments.
  • History loading is more robust for instant data sources. The chart's older-bars request pipeline now signals whether a request actually ran or was swallowed (e.g. issued while the initial load was still in flight), re-arms swallowed requests so the next scroll retries, and stops requesting entirely once a pane's history is exhausted. Previously, a swallowed request — or a cache-served load completing within one React batch — could permanently freeze scroll-back backfill for that pane. This hardening benefits all providers; CSV's instant loads made it visible.

Technical notes

  • A first-class "local provider" concept. CSV is declared in LOCAL_CHART_DATA_PROVIDERS: exempt from the endpoint-descriptor consistency assertion (it has no network endpoints), excluded from the symbol catalog's session cache (a fresh import appears immediately), always routed to the browser connector regardless of execution mode, and stubbed on the server — the browser owns the data, so server-side resolution simply never matches a CSV symbol.
  • No streaming, by omission. The connector declares no streamBars capability and the client layer's existing no-op degradation keeps historical bars rendered. Alerts on CSV symbols stay inert by design.
  • Cache-friendly serving. Bar loads yield one macrotask even on full cache hits, and decoded chunks are held in a small LRU (~50 MB ceiling), respecting the app's chart-memory discipline.
  • Local-only by design. Datasets live in this browser's IndexedDB (fractal-csv-datasets), are never uploaded, and don't sync across browsers or devices. Open tabs stay consistent with each other (imports and deletes broadcast across tabs). Clearing site data deletes the datasets.
  • No new dependencies. The parser, storage layer, and connector are dependency-free; tests cover the parser and serving core with property-based suites, plus an opt-in smoke suite against a real multi-timeframe export.

Next steps

Import your first dataset: Importing CSV Data.

Next: Release Notes