Comparing Almgren-Chriss optimal scheduling and GLFT limit order placement for liquidating BTC/USDT positions, backtested on Binance Futures tick data with full L2 book reconstruction.
Personal project built alongside a market microstructure course. The goal was to go beyond the textbook Almgren-Chriss framework and actually test whether the GLFT model's limit orders improve execution quality on real crypto order book data. Everything runs on freely available Binance Futures tick data via hftbacktest.
The execution framework has two levels (following Rosenbaum 2023):
- Level 1 — Scheduling: decides how much to trade per time slice. Almgren-Chriss computes a risk-averse trajectory (front-loaded); TWAP is the baseline.
- Level 2 — Placement: decides how to execute each slice. Three tactics: market orders (walk the bid), pegging the best ask, or GLFT optimal quoting from the ODE solution (Guéant et al. 2012).
The backtest uses hftbacktest for L2 order book reconstruction with queue position modeling. Limit order fills depend on your position in the queue, not just price crossing. Parameters (sigma, A, k, gamma, eta) are calibrated from the data itself, with out-of-sample mode calibrating on day D-1 and executing on day D.
Tested on a 20 BTC liquidation over 1 hour (60 one-minute slices).
Out-of-sample (calibrated Dec 14, executed Dec 15), 20 BTC liquidation over 1 hour.
- AC outperforms TWAP by 2.3 bps, book-depth η gives αT ≈ 3.5, non-trivial front-loaded schedule
- GLFT saves 1.5 bps vs market orders under TWAP, filling 100% passively
- GLFT is self-scheduling: identical IS under AC and TWAP, the ODE already encodes the risk-time trade-off
Python, NumPy, Numba, SciPy (matrix exponential for the ODE), hftbacktest, matplotlib. Live module uses python-binance (async) for testnet deployment.
Data: Binance Futures BTC/USDT tick-level order book and trades (.npz via hftbacktest format).
pip install -r requirements.txt
# single day
python run_backtest.py --data-dir data/raw --date 20200201
# multi-day out-of-sample
python run_multiday.py --mode oos --data-dir data/raw --total-qty 20.0
# live calibration (dry run, no orders)
python live_runner.py --dry-runFull write-up: report/optimal_execution.pdf
- Almgren, R. and Chriss, N. (2001). Optimal Execution of Portfolio Transactions. J. Risk, 3, 5-39.
- Gueant, O., Lehalle, C.-A. and Fernandez-Tapia, J. (2012). Optimal Portfolio Liquidation with Limit Orders. SIAM J. Financial Mathematics, 3(1), 740-764.
- Rosenbaum, M. (2023). Optimal Portfolio Liquidation. Course HFT, Ecole Polytechnique.
- nkaz001. hftbacktest. https://github.com/nkaz001/hftbacktest