Skip to content

Optimal Execution of Portfolio Transactions

Authors: Robert Almgren, Neil Chriss (2000) Source: Journal of Risk Tag: moi:2026-05-16 #execution #market-impact #optimization #transaction-cost

Ý tưởng cốt lõi

Almgren và Chriss (AC 2000) giải bài toán kinh điển của trader định lượng: làm thế nào để bán (hoặc mua) một khối lượng lớn cổ phiếu/hợp đồng với chi phí kỳ vọng thấp nhất, có tính tới rủi ro? Trước AC 2000, giới thực hành chia làm hai trường phái cực đoan — VWAP-style (chia đều theo khối lượng thị trường, không quan tâm rủi ro) hoặc Implementation Shortfall (giao dịch càng nhanh càng tốt để giảm rủi ro giá biến động). AC 2000 hợp nhất hai trường phái này thành một bài toán trade-off rủi ro–chi phí.

Mô hình giả định giá có hai thành phần tác động: tác động tạm thời (temporary impact — chỉ ảnh hưởng lệnh đang đặt, do liquidity provider phải thoái vị thế ngay) và tác động vĩnh viễn (permanent impact — dịch chuyển mid-price do thông tin lệnh tiết lộ ra thị trường). Cả hai đều là hàm tuyến tính của tốc độ giao dịch trong phiên bản gốc, nhưng bản mở rộng có thể dùng dạng concave (square-root law).

Đầu ra là một đường cong execution tối ưu (trajectory) tham số hóa bởi mức độ ngại rủi ro λ của trader: λ thấp → giao dịch chậm, đều (giảm impact), chấp nhận rủi ro giá; λ cao → giao dịch nhanh (giảm rủi ro), chấp nhận impact lớn. Efficient frontier của AC 2000 vẽ ra mọi cặp (impact cost, variance) khả thi — giống Markowitz frontier nhưng cho execution.

Ứng dụng giao dịch chính

Phạm vi áp dụng:

  • Liquidating large positions: ví dụ quỹ cần thoái 500.000 cổ phiếu HPG hoặc 200 hợp đồng VN30F trong 1 ngày.
  • Algorithmic execution: cơ sở lý thuyết cho các thuật toán VWAP, TWAP, IS (Implementation Shortfall) — IS algorithm chính là AC 2000 với λ > 0.
  • Entry/exit cho strategy: khi tín hiệu báo long/short, AC trajectory cho biết nên gom đủ size trong bao lâu để tối thiểu hóa cost.

Công thức trajectory dạng đóng (giả định linear impact, constant volatility):

$$x(t) = X_0 \cdot \frac{\sinh(\kappa (T-t))}{\sinh(\kappa T)}$$

trong đó $X_0$ = size ban đầu, $T$ = horizon, $\kappa = \sqrt{\lambda \sigma^2 / \eta}$ với $\eta$ = hệ số temporary impact, $\sigma$ = volatility. Đường cong cong (convex) khi λ > 0 — giao dịch front-loaded; khi λ → 0 → tuyến tính (TWAP).

Áp dụng đa thị trường

VN30F (Hợp đồng tương lai chỉ số Việt Nam)

  • Microstructure: tick 0.1 điểm; thanh khoản 9:00-11:30 và 13:00-14:45 với nghỉ trưa — tách thành 2 phiên độc lập trong tối ưu hóa hoặc skip block midday.
  • Tham số ước lượng: η ≈ 0.5-1.5 tick per 1% ADV; σ intraday ~ 12-18% annualized; λ = 1e-6 retail, 1e-7 prop.
  • ADV front month ~ 250.000 contracts. Lệnh < 1% ADV nên dùng VWAP đơn giản; > 5% ADV cần AC trajectory đầy đủ.

US equity futures (ES, NQ, RTY, YM)

  • ES là môi trường lý tưởng cho AC vì microstructure rất "sạch": tick 0.25, spread bằng 1 tick gần như 100% thời gian, ADV $2T notional. Linear impact model fit cực tốt — η ước lượng ổn định.
  • NQ η cao hơn ES ~ 2x do depth nhỏ hơn. RTY cao hơn nữa ~ 5x (illiquid relative).
  • Tham số chuẩn industry: η = 1.5 bps × (Q/ADV)^0.6 cho NQ (theo Bouchaud square-root law extension, không phải linear thuần).
  • Calendar/event effect: tăng λ trước FOMC, NFP, CPI release để execution nhanh hơn — vol forecast tăng → cần giảm timing risk.

Crypto spot (BTC, ETH trên CEX major)

  • Microstructure khác đáng kể: order book trải dài, không có "official close", trading 24/7 — không có "phiên" để phân biệt urgency.
  • Square-root impact phù hợp hơn linear vì depth giảm nhanh khi đẩy xa best bid/ask. Mô hình của Gatheral-Schied 2011 (concave impact) là phiên bản AC chuẩn cho crypto.
  • BTC spot ADV ~ $5-15B trên Binance — lệnh < $1M có thể market order; > $10M cần TWAP 4-8 giờ.
  • Cross-venue execution là chìa khóa: smart order routing giữa Binance, OKX, Coinbase để tránh impact tập trung. AC trajectory cộng thêm lớp "venue allocation".

Crypto perpetual futures (BTC perp, ETH perp)

  • Funding rate là chi phí ẩn: AC cost classical chỉ tính impact + timing — perp phải thêm funding accrual nếu horizon spans funding window (mỗi 8h).
  • Liquidation cascade risk: trong vol spike, depth shrinks 80-90% — η effective tăng 10-20x. Phải có circuit breaker: hủy AC trajectory và switch sang "wait & restart" khi spread > 3x median.
  • AC extension thực tế: chia size theo funding period — front-load nếu funding negative (cost được trả cho mình), back-load nếu funding positive.

Cân nhắc cross-market chung

  • Calibration η: hồi quy thực nghiệm trên dữ liệu fill của chính mình ít nhất 3 tháng. Tham số industry chỉ là điểm khởi đầu.
  • σ realized vs implied: dùng implied khi có (ES có VIX, BTC có DVOL) — phản ánh kỳ vọng tốt hơn realized backward-looking.
  • Logic alpha vs cost universal: nếu signal alpha estimate là α bps, chấp nhận cost < α/2. AC frontier cho biết liệu execution feasibility hay không.
  • Triển khai child orders: 5-10 cho VN30F/ES, 20-30 cho crypto (do thanh khoản trải mỏng).

Minh họa Python

python
import numpy as np
import pandas as pd

def almgren_chriss_trajectory(X0: float,
                              T: float,
                              N: int,
                              sigma: float,
                              eta: float,
                              gamma: float,
                              lam: float) -> pd.DataFrame:
    """
    Tính trajectory thực thi tối ưu Almgren-Chriss.

    Tham số:
    - X0: tổng số lượng cần giao dịch (e.g. 500 contracts).
    - T: thời gian giao dịch (đơn vị: phiên hoặc giờ).
    - N: số khoảng chia (e.g. 20 → mỗi 20 phút nếu T=6.6h).
    - sigma: volatility per unit time (e.g. tick/sqrt(hour)).
    - eta: hệ số temporary impact (tick / contract per period).
    - gamma: hệ số permanent impact (tick / contract).
    - lam: risk-aversion (1e-6 = vừa phải, 1e-5 = rất ngại rủi ro).
    """
    tau = T / N
    kappa_sq = (lam * sigma ** 2) / (eta * (1 - gamma * tau / (2 * eta)))
    kappa = np.sqrt(kappa_sq)

    t = np.linspace(0, T, N + 1)
    # Trajectory: số lượng còn lại tại thời điểm t
    x = X0 * np.sinh(kappa * (T - t)) / np.sinh(kappa * T)
    # Số lượng giao dịch trong mỗi interval
    trades = -np.diff(x)

    # Expected cost & variance
    E_cost = 0.5 * gamma * X0 ** 2 + eta * np.sum(trades ** 2) / tau
    V_cost = sigma ** 2 * np.sum(x[:-1] ** 2) * tau

    df = pd.DataFrame({
        'time': t[:-1],
        'remaining': x[:-1],
        'trade_size': trades
    })
    df.attrs['expected_cost'] = E_cost
    df.attrs['variance_cost'] = V_cost
    df.attrs['kappa'] = kappa
    return df


# Ví dụ: bán 500 hợp đồng VN30F trong 1 phiên 6.6 giờ, chia 20 đợt
# traj = almgren_chriss_trajectory(X0=500, T=6.6, N=20,
#                                  sigma=0.15, eta=0.02, gamma=0.001, lam=1e-6)
# print(traj.head(), '\nExpected cost (ticks):', traj.attrs['expected_cost'])

Powered by dautu.tech