The fields nobody calculates for you.
Eight derived microstructure fields, computed from full-depth books and trades on our capture clock, published on a 100 ms grid and as events where that makes sense. Each one is defined exactly, tested out of sample before it ships, and documented down to the column name.
Every input is ordered by our capture timestamp, the clock you would have seen live. A field never uses a message we had not yet received.
Grid rows are stamped at the boundary and built only from data captured before it. Event-driven rows (a sweep, a closed VPIN bucket) carry emit = "event".
The streaming computation and the historical one share code and must match exactly on recorded data before a field is released.
Multi-level order flow imbalance
Net pressure on the book across the top 10 levels: size added on the bid and removed from the ask counts as buying pressure, the reverse as selling pressure. Top-of-book OFI misses liquidity that moves one or two ticks behind the touch; summing across levels catches it.
# for level m, between book updates n-1 and n
e(n,m) = qb(n,m)·1[Pb(n,m) ≥ Pb(n-1,m)] − qb(n-1,m)·1[Pb(n,m) ≤ Pb(n-1,m)]
− qa(n,m)·1[Pa(n,m) ≤ Pa(n-1,m)] + qa(n-1,m)·1[Pa(n,m) ≥ Pa(n-1,m)]
OFI_m(t) = Σ e(n,m) over updates in the 100 ms interval
ofi_ml_l10 = Σ OFI_m for m = 1..10
ofi_ml_norm = ofi_ml_l10 / mean depth of levels 1..10 over the last 60 s
Typical uses
Short-horizon mid-price prediction, execution timing, and lead-lag between venues listing the same contract.
- Source
book_l2, top 10 levels- Frequency
- 100 ms grid
- Unit
- Base asset;
ofi_ml_normis unitless - Wide columns
ofi_ml_l1ofi_ml_l5ofi_ml_l10ofi_ml_norm
Flow toxicity
Volume-synchronized probability of informed trading: the share of recent volume that was one-sided, measured in equal-volume buckets instead of clock time. We know the aggressor side of every trade, so buckets use the actual buy and sell volume and skip the bulk-classification approximation used when sides are unknown.
V = trailing 30-day average daily volume / 50 # bucket size
VB(τ), VS(τ) = aggressor buy and sell volume in bucket τ
vpin = Σ |VB(τ) − VS(τ)| / (50 · V) over the last 50 buckets
vpin_cdf = percentile of vpin over the trailing 30 days
Typical uses
Throttling market making when flow turns one-sided, spread and risk-limit adjustments, and conditioning other signals on toxicity regimes.
- Source
trades- Frequency
- Event on each closed bucket; last value carried on the 100 ms grid
- Unit
- 0 to 1
- Wide columns
vpinvpin_cdfvpin_bucket_sizevpin_bucket_seq
Queue dynamics
The state of the queue at the best bid and ask, rebuilt order by order: how many orders are resting, how long they have been there, how long orders tend to live, and the empirical chance that an order joining the back of the queue now is filled within one second.
queue_bid_size, queue_bid_count = resting size and order count at best bid
queue_age_p50_ms = median age of orders resting at the touch
queue_life_p50_ms = median lifetime (add → cancel or full fill), trailing 1 h
queue_fill_1s_bid = joins at best bid filled within 1 s
/ joins at best bid, trailing 1 h
Typical uses
Queue-position models for passive execution, fill-probability estimates in backtests, and spotting when resting liquidity turns over faster than usual.
- Source
book_l3- Frequency
- 100 ms grid, plus an event whenever the touch price changes
- Unit
- Size, count, milliseconds, probability
- Wide columns
queue_bid_sizequeue_bid_countqueue_ask_sizequeue_ask_countqueue_age_p50_msqueue_life_p50_msqueue_fill_1s_bidqueue_fill_1s_ask
Cancel-to-fill ratio
How much displayed liquidity is pulled before anyone can trade against it. Computed separately for the touch and for the top five levels, over a trailing 10-second window, so a book that looks deep but cancels on contact shows up as a high ratio.
cxl_fill_l1 = Σ cancelled size at level 1 / Σ filled size at level 1
cxl_fill_l5 = Σ cancelled size in levels 1..5 / Σ filled size in levels 1..5
# trailing 10 s window; null when no fills occurred (never infinite)
Typical uses
Discounting displayed depth in slippage models, monitoring quote quality, and flagging intervals with unusual cancel activity for review.
- Source
book_l3- Frequency
- 100 ms grid
- Unit
- Ratio of sizes; counts are integers
- Wide columns
cxl_fill_l1cxl_fill_l5cxl_count_10sfill_count_10s
Book resiliency
How fast depth comes back after it is taken. A sweep is any 100 ms interval in which aggressive volume removes at least half of the top-five depth on one side. For each sweep we measure the time until that depth is 90% restored and the share restored after one second.
D(t) = resting size in levels 1..5 on the swept side sweep at ts : D(ts) ≤ 0.5 · D(ts−) resil_refill_ms = first t − ts with D(t) ≥ 0.9 · D(ts−) resil_refill_1s = D(ts + 1 s) / D(ts−) resil_med_5m = median resil_refill_ms over sweeps in the last 5 min
Typical uses
Sizing child orders and spacing them in time, estimating how much market-maker capacity is present, and detecting thin regimes before they show up in spreads.
- Source
book_l2, top 5 levels, andtrades- Frequency
- Event per sweep;
resil_med_5mon the 100 ms grid - Unit
- Milliseconds, ratio, base asset
- Wide columns
resil_refill_msresil_refill_1sresil_sweep_sizeresil_med_5m
Price impact
A rolling estimate of how far the mid price moves per unit of signed volume, in the spirit of Kyle's lambda. Regressing one-second mid returns on one-second signed notional over the last five minutes gives a live impact coefficient, with its fit quality alongside so you know when to trust it.
# k = 1-second buckets, trailing 300 buckets r(k) = (mid(k) − mid(k−1)) / mid(k−1) × 10,000 # bps Q(k) = Σ side · price · size in bucket k, USD millions r(k) = λ · Q(k) + ε(k) # OLS, no intercept lambda_bps_per_musd = λ, lambda_r2 = R², lambda_n = buckets with trades
Typical uses
Pre-trade impact estimates, strategy capacity, and comparing liquidity for the same contract across venues in one unit.
- Source
trades, with mid fromquotes- Frequency
- Re-estimated every 1 s, carried on the 100 ms grid
- Unit
- bps per USD 1M signed notional
- Wide columns
lambda_bps_per_musdlambda_r2lambda_n
Markouts
Post-trade price drift at fixed horizons, split by aggressor side: where the mid went 100 ms, 1 s, 5 s, 30 s and 60 s after buys, and after sells. Positive values mean the aggressor was right. Grid values are volume-weighted over the last minute of trades whose horizon has already elapsed.
s = +1 for buy, −1 for sell markout(h) = s · (mid(t + h) − mid(t)) / mid(t) × 10,000 # bps h ∈ {100ms, 1s, 5s, 30s, 60s} # grid row at T: trades with t + h ≤ T and t > T − h − 60 s # per-trade event row: ts_available = t + 60 s
ts_available; join those on ts_available, never on the trade time.Typical uses
Adverse-selection measurement for makers, transaction cost analysis, and separating informed from uninformed flow by side and size.
- Source
trades, with mid fromquotes- Frequency
- 100 ms grid; per-trade event when the 60 s horizon closes
- Unit
- bps
- Wide columns
markout_buy_100msmarkout_sell_100msmarkout_buy_1smarkout_sell_1smarkout_{side}_{5s|30s|60s}ts_available
Participant flow
Aggregated behaviour of attributed participants, on venues where our coverage includes L4. We do not publish per-participant rows in this field. It reports how concentrated trading is, how much of it comes from the largest participants, and which way they are leaning.
# trailing 1-minute window; top 10 ranked by volume over the trailing 1 h
part_active = distinct participant_id with a fill
part_top10_share = top-10 volume / total volume
part_top10_net_flow = Σ side · size for top-10 taker fills
part_maker_hhi = Σ (maker share of each participant)²
part_new_share = volume from ids first seen in the last 24 h / total
Typical uses
Crowding and concentration monitors, tracking large-participant positioning, and measuring how many market makers are active at a given moment.
- Source
book_l4- Frequency
- 100 ms grid
- Unit
- Count, share, base asset, 0 to 1
- Wide columns
part_activepart_top10_sharepart_top10_net_flowpart_maker_hhipart_new_share
How we test a field before it ships.
A derived field is only worth publishing if it carries information that raw trades and top-of-book data do not. Each candidate goes through the same five steps, in this order, and fails out at the first one it does not pass.
Extended fields against a raw baseline, out of sample.
Internal research. BTC, ETH and SOL perpetuals on Hyperliquid, predicting the sign of the mid-price return over the next 500 ms, sampled every 100 ms. Trained Jan–Jun 2026, tested Jul–Sep 2026, walk-forward with no overlap. Same gradient-boosted model and hyperparameters; only the feature set differs. Results exclude fees and latency, may not generalize to other assets, venues or horizons, and are not investment advice.
Where each field is available.
A field is computed wherever its source data is part of our coverage. All eight ship for Hyperliquid in Phase 1. Other venues are planned, subject to a data agreement with each exchange. PART needs L4, so on those venues it depends on the agreement including participant-level data.
Full coverage matrixExtended fields next to the raw data.
Ask for the fields you need and join them to trades or books on the capture clock. Rows are stored and returned in long format (field, variant, value); pass wide=True in the SDK or layout=wide in REST to get the column names listed above.
import polars as pl
from fdc import Client
fdc = Client(api_key="fdc_live_...")
ext = fdc.extended(
venue="hyperliquid",
symbol="BTC-PERP",
fields=["ofi_ml", "vpin", "queue", "markout"],
start="2027-01-15",
end="2027-01-16",
).to_polars()
grid = ext.filter(pl.col("emit") == "grid") # one row per 100 ms, safe as-of
events = ext.filter(pl.col("emit") == "event") # sweeps, VPIN buckets, per-trade markouts
# per-trade markouts: use them only once they were knowable
cutoff = 1800000000000000000 # 2027-01-15 08:00 UTC, ns
known = events.filter(pl.col("ts_available") <= cutoff)curl -G https://api.financedatacloud.com/v1/extended \
-H "Authorization: Bearer fdc_live_..." \
-d venue=hyperliquid -d symbol=BTC-PERP \
-d fields=ofi_ml,vpin -d start=2027-01-15T00:00:00Z -d end=2027-01-15T00:10:00Z{"op":"subscribe","channel":"extended","venue":"hyperliquid","symbol":"BTC-PERP"}Skip the feature engineering.
Extended fields are included from the Researcher plan. Pre-register to get them for Hyperliquid first, with history from November 2025.
EARLY ACCESS · PRE-SALE PRICINGPre-register for early access → DANIEL GARCIA · CEO & FOUNDERdaniel@financedatacloud.com →