Illiquidity and Stock Returns — Phần Bù Thanh Khoản Trong Cross-Section
Tác giả: Yakov Amihud (2002) Nguồn: Journal of Financial Markets, Vol. 5, No. 1 Tag:
mới:2026-05-16#liquidity#microstructure#factor
Nội dung chính (Core Concept)
Trước Amihud, đo lường thanh khoản đòi hỏi dữ liệu intra-day order book — đắt và khó tiếp cận. Amihud đề xuất một proxy cực kỳ đơn giản chỉ cần daily OHLCV:
$$\text{ILLIQ}{i,t} = \frac{1}{D{i,t}} \sum_{d=1}^{D_{i,t}} \frac{|r_{i,d}|}{V_{i,d}}$$
trong đó $r_{i,d}$ là daily return và $V_{i,d}$ là daily dollar volume. Trực giác: tỉ số $|r|/V$ đo price impact per dollar traded — bao nhiêu phần trăm giá thay đổi cho mỗi đồng giao dịch. ILLIQ càng cao → cổ phiếu càng kém thanh khoản (1 đồng order đẩy giá mạnh).
Amihud chạy Fama-MacBeth cross-section regression trên NYSE 1964–1997, kết quả:
- Hệ số ILLIQ dương và significant ngay cả sau khi kiểm soát beta, size, book-to-market, momentum. Cổ phiếu kém thanh khoản kiếm illiquidity premium ~0.5-1% năm mỗi đơn vị ILLIQ.
- ILLIQ time-series có power giải thích market-wide expected returns: khi ILLIQ tăng (market dries up), expected stock returns tăng — phù hợp lý thuyết Pastor-Stambaugh.
- Negative contemporaneous effect: shock thanh khoản (ILLIQ tăng đột biến) đi kèm với giá giảm — flight to liquidity.
Đây là một trong những factor đơn giản nhất mà robust nhất — chỉ cần return và volume.
Ý tưởng chính cho giao dịch (Key Trading Insight)
Bài này có 3 implication trực tiếp cho quant:
- Cross-sectional liquidity premium: Long bottom-decile ILLIQ (kém thanh khoản), short top-decile (thanh khoản tốt). Strategy này hoạt động vì investors đòi premium ôm risk thanh khoản — đặc biệt mạnh trên small/mid-cap.
- Liquidity timing: Khi market-wide ILLIQ tăng (panic), expected returns tới sẽ cao → vào long market. Khi ILLIQ thấp (bull complacency), expected returns thấp → giảm leverage.
- Filter rủi ro thanh khoản: Tránh trade cổ phiếu có ILLIQ > P95 historical — slippage sẽ ăn hết alpha. Đây là execution filter, không phải alpha signal.
Kết hợp với [[hasbrouck-1991]] (information content of trades) và [[kyle-1985]] (Kyle's λ), ILLIQ là proxy "nghèo người" cho Kyle's lambda.
Ứng dụng trên VN30F
VN30F là một sản phẩm duy nhất nên không có cross-section, nhưng ILLIQ áp dụng được dạng time-series:
- Liquidity regime trên futures: Tính ILLIQ rolling 20 ngày trên VN30F. Khi ILLIQ tăng > 1.5× median 6 tháng → giảm position size (slippage cao).
- Spot equity universe (VN30 components): Áp dụng cross-sectional ranking ILLIQ cho 30 cổ phiếu trong rổ. Top illiquid (HVN, BVH thường) có thể có illiquidity premium nhưng cũng có execution risk.
- Macro liquidity timing: Market-wide ILLIQ aggregate (trung bình VN30 components) làm regime indicator — khi spike, giảm gross exposure VN30F.
Code minh họa (Python)
import numpy as np
import pandas as pd
def amihud_illiq(returns: pd.Series, dollar_volume: pd.Series,
window: int = 21) -> pd.Series:
"""
ILLIQ = mean(|r| / V_dollar) rolling.
returns: daily simple returns.
dollar_volume: daily volume × VWAP (USD or VND).
Scale: nhân 10^6 cho equity USD để dễ đọc; 10^9 cho VND.
"""
daily_impact = returns.abs() / dollar_volume.replace(0, np.nan)
return daily_impact.rolling(window).mean() * 1e9
def illiq_zscore_regime(illiq: pd.Series, lookback: int = 126) -> pd.Series:
"""Z-score of ILLIQ vs 6-month history for liquidity timing."""
return (illiq - illiq.rolling(lookback).mean()) / illiq.rolling(lookback).std()
def position_size_liquidity_adjusted(target_size: float, illiq_z: float,
max_z: float = 2.0) -> float:
"""Reduce size when ILLIQ z-score is high (market is illiquid)."""
if illiq_z > max_z:
return target_size * 0.3
elif illiq_z > 1.0:
return target_size * (1 - 0.5 * (illiq_z - 1.0))
return target_size
# Cross-sectional ranking
def cs_illiq_signal(panel_returns: pd.DataFrame,
panel_dollar_volume: pd.DataFrame) -> pd.DataFrame:
"""
panel_*: index=date, columns=tickers.
Output: rank-based long illiquid / short liquid.
"""
illiq = (panel_returns.abs() / panel_dollar_volume.replace(0, np.nan))
illiq_ranks = illiq.rolling(21).mean().rank(axis=1, pct=True)
signal = 2 * illiq_ranks - 1 # range [-1, 1]; +1 = top illiquid
return signalTài liệu tham khảo
- Amihud, Y. (2002). Illiquidity and stock returns: cross-section and time-series effects. J. of Financial Markets, 5(1), 31-56.
- Pastor, L., & Stambaugh, R. F. (2003). Liquidity risk and expected stock returns. J. of Political Economy, 111(3), 642-685.
- Acharya, V. V., & Pedersen, L. H. (2005). Asset pricing with liquidity risk. J. of Financial Economics, 77(2), 375-410.