Methodology
How GET /v1/aggregated_ohlcv combines per-exchange candles into one cross-exchange series, method omm_vwap_v1.
Overview
For a given interval/base/quote, every contributing exchange's raw candles are joined on their candle close timestamp. Any exchange that reported a candle for a given close_ts is "present" for that row; an exchange with no trade in that window is simply absent, not zero. The present exchanges' values are then combined field by field, as below, into a single aggregated candle.
One step comes first: when at least one present exchange traded on a candle (base_volume > 0), every present exchange with zero or unknown volume is treated as absent for that candle. Its candle is flat (open == high == low == close), a carried-over price that can sit well outside what the trading exchanges actually saw. If no present exchange traded, nobody is dropped. The exclusion happens before outlier detection and before every rule below.
Combine rules
OHLC consistency
A volume-weighted average can never leave the range spanned by the exchanges it combines, so mathematically open and close always fall between low and high. In floating-point arithmetic they can miss that range by a rounding error (on the order of 1e-16 relative) — for example two exchanges that both report open == high can average to a value marginally above high.
To guarantee low ≤ open ≤ high and low ≤ close ≤ high on every candle, open and close are clamped into [low, high] after the weighted average. The clamp applies the same way whatever the number of exchanges present, and it only ever acts on that rounding noise: high and low are never widened, and an average already inside the range is left untouched.
Outlier detection
When more than one exchange is present on a candle, each present exchange is checked against the cross-exchange median for open, high, low, and close. An exchange is flagged an outlier at that row if any of the four fields deviates from the median by more than the method's outlier threshold.
- If outlier exchanges are at most 30% of the exchanges present for that row, they're excluded from the combination for that row only — the candle is flagged
outlier_excluded. - Otherwise — outliers are more than 30% of what's present, not a safe minority to overrule — nobody is dropped, every present exchange still contributes, and the candle is flagged
outlier. - An exchange is never removed globally, only row by row, and only in the excluded case.
A candle with neither condition has flag: null.
The exchanges field
Every aggregated candle carries an exchanges array — the exchanges that actually contributed to that specific candle, after any outlier exclusion. It can differ from row to row for the same base/quote/interval series as exchanges come in and out of coverage.
Choosing a method
The aggregation methodology is versioned by name and passed as the method query parameter on aggregated_ohlcv. omm_vwap_v1 is the only method today and the default if you omit the parameter.