OHLCV Candles for Backtesting: A Practical Guide

OHLCV Candles for Backtesting: A Practical Guide

Backtests fail when the data is messy

A strategy can be “perfect” on paper but collapse in production if your historical candles are inconsistent across exchanges. Mila-ex standardizes OHLCV candles so your pipeline can backtest, compare venues, and validate assumptions without rewriting parsers for every exchange.

The endpoint: OHLCV in one call

Mila-ex exposes normalized candles via:

GET https://api.milaex.com/api/v1/exchange/ohlcv?exchange=binance&base_name=BTC&quote_name=USDT
Don’t forget the header:

x-api-key: YOUR_API_KEY

What you get back

The response returns an array of candle objects (timestamp \+ open/high/low/close \+ volume). That’s all most backtesting engines need.

Python example: fetch candles and compute returns

import requests
API_KEY = "YOUR_API_KEY"
URL = "https://api.milaex.com/api/v1/exchange/ohlcv"
def fetch_ohlcv(exchange: str, base: str, quote: str):
    res = requests.get(
        URL,
        headers={"x-api-key": API_KEY},
        params={"exchange": exchange, "base_name": base, "quote_name": quote},
        timeout=20,
    )
    res.raise_for_status()
    return res.json()["Data"]
candles = fetch_ohlcv("binance", "BTC", "USDT")
closes = [c["closePrice"] for c in candles if c.get("closePrice") is not None]
# Simple daily returns
returns = [(closes[i] / closes[i-1]) \- 1 for i in range(1, len(closes))]
print("Candles:", len(closes), "Avg return:", sum(returns)/max(1, len(returns)))

How to keep your backtests honest

  • Normalize by pair: use the same base_name and quote_name across venues.
  • Check gaps: compare candle timestamps for missing periods.
  • Compare liquidity: high volume exchanges behave differently; validate using order books too.

Bonus: add market microstructure context

For strategies sensitive to slippage, pull depth snapshots and recent prints:

  • /api/v1/exchange/orderbook for bids/asks depth
  • /api/v1/exchange/orderbook/complete for completed trades

Related reading

Rate limit note

OHLCV is intentionally rate-limited (typically \~1 request per 10 seconds). Cache results and request only the pairs you need.

Reference

Full endpoint details are available in the Mila-ex API Docs.