Crypto Market Data Lake: Faster Backtests, No More Re-Downloads
You configure a backtest, click run, and then watch a progress bar crawl while the engine re-downloads the same BTC/USDT 1h candles you've fetched a dozen times before. Multiply that wait by 200 hyperopt epochs and the I/O alone burns half your afternoon. VolatiCloud's centralized market data lake removes that step entirely — historical OHLCV is fetched once, stored centrally, and made available instantly to every backtest, hyperopt run, and bot warm-up in your organization.
The Problem with Per-Runner Data Downloads
Self-hosted Freqtrade setups follow a straightforward but inefficient workflow: each backtest checks for local data, downloads whatever's missing, and only then begins the simulation. Switch runners, change pairs, or extend the date range — and the download cycle starts over.
At small scale this is annoying. At scale, it's a hard bottleneck:
- Hyperparameter optimization can require 200–500 individual backtest iterations. If each one waits on data, a meaningful fraction of total optimization time is pure I/O.
- Walk-forward optimization rolls the same date range across N windows. Without shared data, each window risks re-downloading what it already had.
- Multi-pair, multi-timeframe testing explodes the data requirement: 15 pairs × 4 timeframes = 60 datasets you'd otherwise download per runner.
Three additional problems compound the pain:
- No visibility into what data you have. Without a dedicated inventory, you don't know whether your runner has 90 days or 2 years of ETH/USDT data until you try to run a backtest.
- Data gaps are silent. A missing month produces results that look plausible but are statistically compromised. Without tracking completeness, gaps slip through.
- Exchange rate limits punish repeated downloads. Major exchanges throttle their historical data APIs. Re-fetching the same candles burns through those limits and slows your next genuine download.
How VolatiCloud's Data Lake Works
The data lake is a shared OHLCV store that sits outside any individual runner. Instead of each runner managing its own history, a central pool of workers downloads market data from supported exchanges and stores it in a shared location every runner in your organization can access.
The data flow:
- Configuration — You specify which exchange, pairs, and timeframes to maintain in your runner's data download settings.
- Backfill — A worker claims the job and fetches historical candles, working backward from the present to fill in the requested history.
- Upfill — Once initial history is loaded, the system monitors for new candles and keeps the dataset current.
- Availability — When you run a backtest, the data is already present. The runner reads from the shared store rather than triggering a fresh exchange API call.
Workers run concurrently across multiple exchanges with exchange-aware rate limiting — Binance, OKX, Bybit, BingX, Bitget, and the rest each have different API constraints, and the downloader respects them without any configuration on your part. A lease and renewal mechanism ensures that if a worker fails mid-download, another picks up the job rather than leaving data permanently incomplete.
Backfill and Upfill: Two Distinct Processes
Backfill is the initial historical download. When you add a new pair and timeframe, a backfill job is created to fetch all available history. For major pairs like BTC/USDT, this can mean years of 1h candles — substantial, but only paid once.
Upfill is the ongoing maintenance process. After backfill completes, upfill takes over, checking for new candles and appending them. The system tracks the most recent candle and requests only the delta since the last update. Subsequent updates are near-instant.
The separation matters for planning. When you add a new pair, expect a one-time backfill that might take minutes (or longer for multi-year history on frequent timeframes). After that, you're paying only the trickle cost of upfill.
Add pairs you're actively backtesting to your runner's data download config as soon as you know you'll be testing them. A backfill running in the background while you build your strategy means data is ready by the time you run your first backtest.