Lecture 2: Liquidity Measures
A practical series for the discerning retail trader and the quantitative alchemist on Market Microstructure
🕯️Greetings, esteemed reader!
In the previous lecture, we outlined robust Normalized Realized and Effective Bid-Ask Spread measures that work pretty well in practice, especially in HFT (overall, the higher the frequency, the more sense the spread makes).
In this second lecture of Zero Lag Club’s Market Microstructure series, we dive into measuring liquidity in practice on centralized limit order book (CLOB) exchanges.
Building on the foundations of Spread (Lecture 1), we’ll explore how quants and traders actually gauge liquidity using both theoretical models 🔬 and practical metrics 🛠️. The focus here is strictly on order-book markets – AMMs will be covered later (their liquidity is defined by explicit curves, a topic for another scroll).
The lecture is pretty extensive (I’d schedule 1 hr to study it), but I promise it contains only necessary information for understanding the further material and building trading models.
Markers
🔬 : theory-heavy concepts useful for context (less directly monetizable).
🛠️ : hands-on code, heuristics, or practical tips.
Required Knowledge
Basic order‐book vocabulary, high-school math, and a bit of Python/pandas for examples will help. If your curiosity pendulum swings into deeper research, check the references at the end, as usual.
Outcome
You’ll get a working toolkit to measure liquidity and understand which metrics matter:
Theoretical Models: Roll’s implied spread, Kyle & Obizhaeva’s impact invariance, Hasbrouck’s lambda (price impact).
Practical Metrics: Amihud’s illiquidity, VWAP, and slippage, Implementation Shortfall, Realized Spread.
Low-Frequency Proxies: Daily spread estimators (Corwin–Schultz, Abdi–Ranaldo) and others validated for crypto by recent research.
Use Cases: Which measures are production-grade for crypto trading vs. which are academic or obsolete?
Liquidity Measures 🧪
Theoretical Foundations of Liquidity Costs
Roll’s Model (1984) – Implied Bid/Ask Spread
Kyle’s Lambda and Square-Root Impact
Price Impact vs. Cost: Temporary and Permanent
Practical Liquidity Measures
Amihud’s Illiquidity (2002)
Volume-Weighted Average Price (VWAP) and Slippage
Implementation Shortfall (IS)
Realized Spread
Low-Frequency Liquidity Proxies
Corwin–Schultz estimator (2012)
Abdi–Ranaldo estimator (2017)
Production usage
🔥 Shall we commence?
Let’s start by mapping the theoretical foundations of liquidity costs, then roll up our sleeves for practical measures with some code-ready insights.
Again, can’t avoid theory, understanding classic models gives context to why specific liquidity measures work (or don’t) in crypto.
🔬 Theoretical Foundations of Liquidity Costs
Roll’s Model (1984) – Implied Bid/Ask Spread
One elegant idea by Richard Roll (1984) derives the effective spread from price time series alone. Measuring the bid-ask spread when only the price is known - sounds like magic! I believe earlier it was a highly useful solution when it was impossible or hard/expensive to get real orderbook data. Nowadays, the case is very different - the real-time feeds are available for free from the exchange, historical orderbooks can be relatively expensive but available, and hardware is cheap enough to handle all the tick data volume required.
Despite the 40 years of history, the model remains indispensable in modern quant finance, and it is still actively used, and shows good results in crypto as well (20bps error average and 50bps in volatile regimes), I’d see it primarily use is backtesting, because when it’s hard (or expensive) to get historical orderbook for an asset.
So, Roll observed that in an efficient market (with true value static short-term), alternating buys and sells cause negative autocorrelation in price changes – prices zigzag as trades flip between bid and ask. This means that the covariance of successive price changes, Cov(Δpt,Δpt−1), would be negative, and its magnitude is related to the bid-ask spread. In simple words, this means that if the price goes up in the previous period t-1, it will go up in the current period t, and vice versa.
Roll’s formula for spread (in its simplest form) is:
Assuming that the covariance is negative. Intuitively, if prices tend to revert by a small amount each trade, that amount is about the half-spread.
This basically says: the more the price bounces back and forth, the wider the spread must be.
The model makes lots of assumptions, the main of which are that bid-ask is mean-reverting (tx prices oscillate between bid and ask quotes) and there’s no serial correlation in trades: trade signs (buy/sell) are independent (no clustering of buys or sells).
Formally, the assumptions are as follows:
All trades have the same size. Trade direction d=1 is a buy, d=-1 is a sell.
Arriving orders are i.i.d. (identically independently distributed):
\(\mathbb{P}(d_t=1) = \mathbb{P}(d_t=-1) = \frac{1}{2}\)Midquote follows a random walk. If m is a midprice and ε - some innovation term, a i.i.d. price shock, then
\(m_t = m_{t-1} + \epsilon_t\)Market orders are not informative. This is somewhat the most questionable assumption, since a direction d in the next period doesn’t depend on how the price moved. Expectation of how the quote has moved equals to how it will move and it’s zero.
\(\mathbb{E}(d_t \epsilon_t) = \mathbb{E}(d_t \epsilon_{t+1}) = 0\)Spread is constant.
\(S = a_t - b_t\)
Let’s derive the Roll’s model now!
The price is midquote with the halfspread times the direction of the trade:
We know p, but not m. How to estimate S?
The key (and very neat!) idea of the Roll’s paper is the mean revertion of the price and direction of the trade, prices are pressured to return to the midquote:
It’s simple to understand it intuitively, if Δdt> 0 that means that we go from a sale to buy, and the next change Δdt+1 should be the opposite.
Now, since Cov is a linear operator, it’s just a variance of dt-1
Thus
Which gives us the estimator
These prices’ covariances can be computed from the price data.
That’s it!
🔬 Why it fails in crypto: crypto prices are trending very often and exhibit momentum (positive autocorrelation) very often, rather than mean-reversion at trade-to-trade frequency. In trending markets, Roll’s negative covariance assumption breaks down which breaks down the whole thing – you might get a positive or near-zero covariance, leading to a zero or undefined implied spread. In practice, Roll’s estimator often outputs zero for crypto assets. The model’s spherical-cow assumptions listed above rarely hold on volatile crypto markets.
I might clean up the code I have that tests the measure for the Binance feed and share it with you in a separate post. In short, it’s heavily off, but it’s not that bad for HFT, where trends and momentum are not that significant. In most cases, it underestimates liquidity costs in crypto.
Roll’s measure is still a cornerstone of the microstructure theory, and the idea that the effective spread can be backed out from price dynamics is just cool.
Kyle’s Lambda and Square-Root Impact
Kyle (1985) introduced the concept of lambda (λ) as the price impact per unit size in his insider trading model. In Kyle’s model, trades move the price linearly: Δp=λ⋅q+noise, where q is the signed trade size. Lambda reflects adverse selection costs – a larger λ means the asset’s price moves more when someone tries to buy/sell a given amount (low liquidity).
In practice, we can estimate Kyle’s lambda by regressing price changes on signed volume or order flow. For example, over many trades:
where mt is the midprice, dt∈{+1,−1} the trade direction (buy or sell), and Vt the trade size (perhaps in USD). The slope λ is an empirical price-impact metric (e.g., “$0.05 price move per 1 BTC traded”). Hasbrouck’s model (1991) is a close cousin: it uses a vector autoregression of trades and quotes to measure the information content of trades, yielding a similar notion of price impact (often also dubbed lambda). These regression-based lambdas are useful in research to compare assets or time periods. However, they can be noisy and require high-frequency data. A few crypto trading shops estimate Hasbrouck’s VAR in real-time. Instead, it’s often better to use simpler stats (like immediate slippage or beta to order flow) for on-the-fly impact tracking.
🛠️ Code Tip: You can estimate a simple lambda in Python by fitting a line:
price_diff ~ sign * volume
. Use trade tape data or one-minute bars. The R-squared will be low, but λ’s magnitude gives a ballpark of impact. Calibrate in basis points per $1M traded, for instance.
Now, empirical studies found Kyle’s linear model is too simplistic for large trades. Large meta-orders (series of trades) tend to have a nonlinear impact.
A famous result is the square-root impact law:
Obizhaeva & Wang (2013) and Kyle & Obizhaeva (2016) formalized this via market microstructure invariance theory. Without diving into dimensional analysis, the takeaway is that impact grows sub-linearly with size – doubling the trade size doesn’t double the impact, it increases by less (roughly √2). This is why slicing orders (“iceberging”) makes sense: ten 100 ETH buys throughout the day move the price less overall than one big 1000 ETH buy.
For us practitioners, the square-root law suggests using concave impact models for cost estimation. Many execution algos (TWAP, POV, etc.) implicitly assume this concavity. In crypto, the square-root law holds qualitatively, although the exact coefficient varies by asset and venue liquidity.
Price Impact vs. Cost: Temporary and Permanent
Not all price impact is permanent. Hasbrouck’s price impact can be thought of as the permanent price change resulting from information (e.g., informed trading). The remainder of the spread/impact is temporary (due to inventory pressure or bounce). Realized Spread vs Price Impact is a helpful distinction:
Price Impact (per Hasbrouck or others) measures how far the price stays moved after a trade.
Realized Spread measures the part of the spread captured by liquidity providers, i.e. the profit of a market maker if the price mean-reverts.
We’ll cover realized spread more shortly – it’s a resiliency metric (how quickly prices revert) - remember liquidity dimensions from the Spread lecture.
🔬 Bottom line: Theoretical models give us λ (lambda) and other intuition pumps. But to actually measure liquidity on crypto exchanges, we need practical formulas. Let’s now turn to hands-on liquidity measures you can compute from data.
🛠️ Practical Liquidity Measures
The following metrics are the bread-and-butter tools to quantify liquidity and trading costs on CLOBs. You can implement these with exchange data using any language with relative ease.
Amihud’s Illiquidity Ratio (2002)
One widely used measure in academia (and increasingly in crypto quant circles) is the Amihud Illiquidity Ratio. Proposed by Yakov Amihud, it captures the idea of price impact per volume. For a given day d, it’s defined as:
where R is the asset’s return (usually absolute return, in decimal) and Vol is the trading volume in dollar terms that day. If you average this across days in a period, you get an estimate of how much the price moves per unit of trading volume. A low Amihud value means high liquidity (you can push a lot of volume for little price change), while a high value means illiquidity.
Usage: Amihud’s metric is great for comparing assets or exchanges cross-sectionally. Brauneis et al. (2021) found that Amihud’s ratio, despite being simple, does well in ranking the liquidity levels of different crypto exchanges. For example, if Exchange A’s BTCUSD has half the Amihud value of Exchange B’s, A generally offers a tighter market with less slippage per trade dollar.
🛠️ Code Tip: Given daily OHLCV data, you can compute
amihud = (abs(return) / dollar_volume).resample('D').mean()
in Python. Make sure to use dollar volume (price * quantity) for consistency. Watch out for outliers on days of huge returns but low volume – consider median or winsorizing in those cases.
However, note that Amihud is less useful for time-series liquidity changes. In fast-moving markets, volume and volatility can spike together, making daily illiquidity noisy. For intraday use, a rolling version can be computed (e.g., hourly illiquidity); however, many practitioners prefer direct order book statistics intraday.
Volume-Weighted Average Price (VWAP) and Slippage
VWAP – Volume Weighted Average Price – is technically a benchmark price, not a liquidity metric in itself. But it’s crucial in execution. Traders commonly gauge slippage by how far their execution price is from the VWAP over the execution interval.
For example, say you need to buy 50 BTC over 10 minutes. The market’s VWAP in that 10-minute window (considering all trades) was $30,000. If your average execution price ended up $30,100, then you paid 0.33% above VWAP. That difference is slippage cost – a measure of liquidity immediacy and market impact during your execution.
VWAP is used as a benchmark for immediacy because an uninformed execution spread evenly in time should approximately achieve VWAP (assuming you’re a small part of the volume). If you trade too aggressively (demanding immediacy), you’ll push the price and end up worse than VWAP; if you trade too passively or slowly, you might chase a drifting price and also miss VWAP. Thus, VWAP is the bar to beat.
🛠️ Practical Use: Many crypto execution algos (TWAP, VWAP algos) aim to track or beat VWAP. As a trader, you measure execution performance as Implementation Shortfall (next section) or vs VWAP. Exchanges don’t give VWAP directly, but you can compute it from trades. In Python, given trades with price and size,
vwap_price = (price * size).sum() / size.sum()
for the interval.
Implementation Shortfall (IS)
The Implementation Shortfall is the Tradfi-s gold-standard metric for total trading cost which is adopted by crypto. Originally coined by André Perold (1988), IS is the difference between the paper price when you decide to trade and the actual average price you get. It captures both spread and market impact (and timing delays). It was used to measure the performance of a broker.
Let’s break it down: You decide to buy at 10:00 when the midprice is $100. By the time your order fully executes, you ended up paying an average price of $101. Meanwhile, the market mid moved to $100.5 during your execution (maybe due to other traders or your own impact). Your implementation shortfall can be decomposed as:
Spread cost: If you crossed the spread to buy, maybe half the spread (say $0.1) was lost right away.
Impact/timing cost: The mid moved up $0.5 while you were executing – that’s adverse movement against you.
Opportunity cost: If you didn’t complete the full order, any unfilled part has an implicit cost if price keeps rising.
In total, your IS = $101 – $100 = $1 (1%) on that trade. This is the real cost of trading beyond the ideal scenario. It’s crucial for algorithmic execution evaluation – you want to minimize IS.
Formally, one can write Implementation Shortfall for a buy order as:
where Pdecision is the price (mid or last) when the trading decision was made (or a benchmark like previous close), and Pavg fill is the volume-weighted execution price. For sells, the formula is analogous (you want to sell high; any average fill below decision price is cost).
🛠️ Code-Level Tip: To compute IS, you need to record a benchmark price at the start (decision time or arrival price). Then track all fills of the order and compute the size-weighted average fill price. The difference (with correct sign) is your IS. If working with historical data, you can simulate an execution (e.g., splitting into chunks) and compare with a baseline price path. Python’s pandas can help aggregate fills; just be careful to align timestamps for the benchmark price.
Implementation Shortfall vs VWAP: If you use VWAP of the period as your benchmark, that variant is often called VWAP slippage. For example, some traders say “We were 5 bps inside VWAP” meaning they beat the VWAP by 0.05% (a positive outcome). This is essentially a flavor of implementation shortfall using VWAP as the benchmark instead of the decision price.
Realized Spread
In Lecture on Spread we introduced Realized Spread (RS) – a metric particularly relevant for market makers and liquidity providers. While effective spread measures the cost paid by takers on a given trade (difference between trade price and midprice at that moment), the realized spread looks ahead: it’s the difference between the trade price and the midprice after some time Δ.
If I sell to a market maker at $100 (mid was $99.9, so effective spread paid ~$0.1), and 5 minutes later the midprice is $99.8, the market maker benefited – they sold higher than the new mid. The realized spread for that trade to the market maker is $100 – $99.8 = $0.2.
Conversely, if the mid jumps to $100.5 after, the market maker’s gain from the spread was eroded (negative realized spread, meaning the taker’s trade had information).
Mathematically, for a buy order (taker perspective, d=+1 for buy, −1 for sell):
Realized Spreadt,
where pt is the trade price and mt+Δ the midprice Δ time later. The choice of Δ (e.g. 1 minute, 5 minutes) is critical – too short and it’s mostly noise, too long and other factors move the price.
For a liquidity taker, a small realized spread (or negative) means you implicitly didn’t pay much extra beyond the true price impact. For a market maker, a large positive realized spread means you earned your quoted spread and the price didn’t run away on you – a good trade. Realized spread thus measures resiliency of the market: how quickly prices mean-revert after trades. A resilient market where liquidity replenishes quickly tends to have lower permanent impact (and higher realized spread for makers).
🛠️ How to estimate: Using trade and quote data, for each trade record the midprice some minutes later. Compute d(p−mfuture) and average over many trades (you might condition on trade size or time of day). In Python, you can do this by merging the trade tape with a delayed midprice series. This helps quantify how much of the spread is “real” vs just temporary. Low realized spread (relative to effective spread) means information-heavy trades (price moved against the maker), whereas high realized spread means mostly noise or inventory trading.
Low-Frequency Liquidity Proxies
Thus far, we discussed measures you’d compute if you have tick-level data. What if you only have daily or hourly bars? That’s not our typical trading case though - we usually operate hft or mid-frequency (minutes). But in some cases, you need that data - for example, in mid-low frequency strategies like funding arbitrage, you want to know what venues to trade if there are the same assets with almost the same funding rates, but the liquidity differs. There are clever spread estimators that use low-frequency data to infer liquidity. Interestingly, some of these have been tested on crypto and work quite well. Here are two notable ones:
Corwin–Schultz estimator (2012): Uses daily high and low prices to estimate the bid-ask spread. The intuition: high prices are usually buyer-initiated trades and lows are seller-initiated, so the ratio of highs/lows over two days contains information about the spread. The formula is a bit involved (it uses the difference between single-day and two-day ranges to back out the spread). Corwin-Schultz is cheap to compute – you just need High and Low for two days, making it handy for quick comparisons. Brauneis et al. (2021) found this estimator excels at tracking time-series liquidity changes in BTC and ETH markets. That means if liquidity is drying up, the C-S measure will rise, and vice versa, roughly in sync with true spreads.
Abdi–Ranaldo estimator (2017): An improvement over C-S, this uses Close, High, and Low prices to estimate spreadsaeaweb.org. It’s also designed for daily data but tends to be more accurate by incorporating closing price information (reducing bias from day gaps). Abdi–Ranaldo also performed very well in crypto, slightly outdoing C-S in some cases. If you have daily OHLC, this is a great proxy for average bid-ask spreads without needing tick data.
Both of these give an estimated percentage spread. For example, Abdi–Ranaldo might estimate that an exchange’s typical spread is 0.20%. They won’t capture depth or large-order costs, but they reflect top-of-book tightness over time.
Other proxies include “Number of Trades” or Dollar Volume (more volume often means more liquidity) and variants of high-low volatility measures. Brauneis et al. tested a bunch. Two highlights from their findings worth noting:
For time-series liquidity (dynamic changes): Corwin-Schultz and Abdi-Ranaldo were the best, indicating these high-low based measures track liquidity over time better than, say, Amihud or trade counts. This is likely because high-low ranges widen when volatility and trading costs spike, signaling illiquidity in turbulent times.
For cross-sectional and level estimates: Amihud’s illiquidity and a proxy from Kyle & Obizhaeva (2016) invariance were most reliable. The “Kyle-Obizhaeva estimator” they used is rooted in invariance theory – it scales volume and volatility to produce a liquidity metric (think of it as a predicted impact cost per trade). Those two measures were best at ranking exchanges by liquidity and even approximating absolute spread levels. So if you want to know which exchange is most liquid or what’s the typical cost on Exchange X vs Y, Amihud and invariance-based metrics give a good gauge.
🔬 Reality check: Low-frequency proxies are great for research and monitoring broad trends or doing comparative studies when tick data isn’t available. But if you do have order book data, you’ll always get a more precise read from direct measures (actual quoted spreads, depth, etc.). Use proxies when you must (e.g. analyzing hundreds of altcoins quickly, or historical periods where only daily data exists).
Which Metrics Matter in Production?
Let’s summarize from a practitioner’s perspective – what should you actually use when trading crypto?
Quoted Spread and Order Book Depth: These are still king for real-time decisions. A tight normalized spread and substantial depth at the top of book mean you can execute small trades cheap. For larger trades, look at impact – e.g., how much the price moves if you sweep X dollars of the book (we covered weighted spreads in Lecture 1 and will delve more into slippage in future). These are immediately usable via exchange APIs.
Implementation Shortfall: If you’re executing large orders or running an algorithm, track IS on each order or day. It’s the true bottom-line cost including all slippage. In a live trading system, you’d log the decision price and fills to compute this. If your IS starts creeping up, it might indicate deteriorating liquidity or an execution problem.
VWAP Slippage: This is often used in TCA (Transaction Cost Analysis) reports. Institutional traders will report “We executed at 5 bps worse than VWAP” for example. If you’re building execution algos, minimizing VWAP slippage (or beating VWAP) is a concrete goal.
Amihud Ratio: For strategy research or asset selection, Amihud’s illiquidity is handy to rank assets by liquidity. It’s simple to compute and has intuitive units (percent move per $ traded). It’s not something you’d compute intraday for signals, but good for filtering out illiquid coins or deciding how to allocate capital across venues.
Hasbrouck’s Lambda / Kyle’s Lambda: In high-frequency strategy dev, you might estimate these to understand impact. For example, if lambda for a coin is huge, you know even small trades will move it – be careful with order sizing. But these are diagnostic; we don’t plug Hasbrouck’s VAR into a live system due to complexity and noise. Instead, simpler real-time estimators (like moving average of effective cost per trade size) are preferred.
Roll’s Measure: Honestly, pretty obsolete for crypto. It’s elegant for teaching and for some stock datasets, but as we emphasized, it often gives false signals in crypto markets. Use it only if you suspect purely random trade directions and want a quick guess of spread – and be ready for it to output zero when there’s persistent trending.
Corwin-Schultz / Abdi-Ranaldo: These are great for analysis – e.g., if you’re writing a report on historical liquidity or can’t pull tick data for years of history. They aren’t something a trading algorithm would use on the fly (they’re too laggy and coarse for that). Think of them as research tools or for monitoring market health over time. For instance, you could plot a 30-day moving average of C-S estimator to visualize how an exchange’s liquidity is improving or worsening.
In crypto markets, latency and explicit order book info reign supreme. We have full Level-2 data available, unlike some traditional markets where proxies were invented due to data scarcity. This means our production-grade metrics lean toward direct measurements (spreads, depth, fill stats). However, the theoretical concepts and low-frequency proxies are still invaluable for validation and understanding. They can validate if your direct measures make sense, or help compare liquidity across venues without streaming all their data.
As a final note, we deliberately left out Automated Market Makers here. AMMs (like Uniswap) have explicit liquidity curves and different metrics (like pool depth, k-values, etc.), which deserve their own discussion. Fear not – we shall tackle AMM liquidity in a later lecture.
For now, you should be equipped to measure and monitor liquidity on any crypto exchange with a limit order book. May your order placements be swift and your spreads ever tight!
See you in the next lecture, we’ll start diving straight into market-making models.
References
Roll, R. (1984). A simple implicit measure of the effective bid–ask spread in an efficient market. Journal of Finance, 39(4), 1127–1139.
Kyle, A. S. (1985). Continuous auctions and insider trading. Econometrica, 53(6), 1315–1335. (Introduced Kyle’s lambda)
Kyle, A. S., & Obizheva, A. A. (2016). Market Microstructure Invariance: Empirical Hypotheses. Econometrica, 84(4), 1345–1404. (Foundation of the square-root impact law)
Hasbrouck, J. (1991). Measuring the information content of stock trades. Journal of Finance, 46(1), 179–207.
Amihud, Y. (2002). Illiquidity and stock returns: cross-section and time-series effects. Journal of Financial Markets, 5(1), 31–56.
Perold, A. (1988). The Implementation Shortfall: Paper vs Reality. Journal of Portfolio Management, 14(3), 4–9.
Corwin, S. A., & Schultz, P. (2012). A simple way to estimate bid-ask spreads from daily high and low prices. Journal of Finance, 67(2), 719–759.
Abdi, F., & Ranaldo, A. (2017). A simple estimation of bid-ask spreads from daily close, high, and low prices. Review of Financial Studies, 30(12), 4437–4480.
Brauneis, A., Mestel, R., Riordan, R., & Theissen, E. (2021). How to measure the liquidity of cryptocurrency markets? Journal of Banking & Finance, 122, 106198.