Almgren-Chriss Tanpa Basa-Basi: Eksekusi Optimal yang Bisa Anda Implementasikan dalam Satu Sore
Almgren dan Chriss (2001), "Optimal execution of portfolio transactions" (Journal of Risk 3(2), 5–39), mungkin adalah paper yang paling sering dikutip dalam riset eksekusi sekaligus salah satu yang paling jarang diimplementasikan dengan benar. Kebanyakan kode "Almgren-Chriss" yang beredar hanyalah scheduler TWAP dengan blok komentar. Kebanyakan tulisan blog tentangnya melewatkan derivasinya, melambaikan tangan ke fungsi sinh, dan tidak pernah menyentuh bagian yang sebenarnya penting di produksi: dari mana parameternya berasal.
Artikel ini membahas semuanya secara utuh. Asumsi model, dinyatakan dengan jujur. Trajektori bentuk tertutup (closed-form), diturunkan, bukan sekadar diklaim. Efficient frontier dan cara memilih parameter penghindaran risiko (risk aversion). Serta kalibrasi ketiga input — dampak temporer , dampak permanen , volatilitas — dari data order book dan trade Binance, dengan Python yang siap pakai dan pembahasan jujur tentang mengapa fit-nya berisik (noisy). Inilah tulang punggung intelektual dari segala hal lain di eksekusi: TWAP, VWAP, dan POV adalah kasus khusus atau sepupu heuristik (lihat TWAP, VWAP, POV: algoritma eksekusi yang dijalankan semua orang), dan pendekatan ML modern — scheduler reinforcement learning dan model dampak neural — adalah upaya untuk melonggarkan justru asumsi-asumsi yang akan kita tuliskan berikut ini.
Penyusunan: apa yang sebenarnya diasumsikan model
Anda memegang unit sebuah aset (misalnya, 100 BTC) dan harus melikuidasi seluruhnya pada waktu . Bagi menjadi interval berpanjang . Variabel keputusan Anda adalah trajektori kepemilikan , dengan trade dieksekusi pada interval .
Tiga asumsi menopang keseluruhan model:
1. Random walk aritmetika. Harga tak terganggu (unperturbed) mengikuti
di mana adalah normal standar i.i.d. dan adalah volatilitas absolut (dolar per satuan waktu, bukan persen). Aritmetika, bukan geometrik — dalam rentang beberapa jam perbedaannya dapat diabaikan dan random walk aritmetika menjaga aljabar tetap linier-kuadratik. Tanpa drift: Almgren dan Chriss membahas suku drift, tetapi untuk likuidasi intraday estimasi alpha Anda selama 4 jam hampir selalu berupa noise, dan menetapkannya nol adalah default yang jujur.
2. Dampak permanen linier. : berdagang pada laju menggeser harga secara permanen, proporsional, dan pergeseran itu tak pernah meluruh. Setiap unit yang Anda jual mendorong mid turun sebesar selamanya. Ini tampak kasar, tetapi ada alasan mendalam untuk mempertahankannya linier: Huberman dan Stanzl (2004) membuktikan bahwa dampak permanen yang nonlinier terhadap ukuran trade memungkinkan strategi round-trip dengan ekspektasi keuntungan positif — manipulasi harga. Dampak permanen linier bukanlah penyederhanaan demi kemudahan; ia adalah satu-satunya pilihan bebas-arbitrase dalam kelas model ini.
3. Dampak temporer linier. Harga yang sebenarnya Anda terima pada interval adalah
menangkap separuh bid-ask spread ditambah fee; adalah kemiringan biaya marjinal untuk menuntut likuiditas pada laju . Dampak temporer hanya memengaruhi fill Anda sendiri dan lenyap seketika — order book terisi ulang sepenuhnya sebelum child order Anda berikutnya. Ketiga kata "linier", "seketika", "sepenuhnya" itu semuanya keliru di pasar nyata, dan bagian terakhir membahas seberapa keliru. Namun pertama-tama, imbalan dari menerima asumsi-asumsi tersebut.
Biaya dan varians sebuah trajektori
Jumlahkan seluruh fill, kurangkan dari mark awal , dan Anda memperoleh implementation shortfall. Ekspektasi dan variansnya terhadap noise adalah:
dengan (koreksi diskretisasi yang lenyap saat ).
Dua pengamatan yang terlewatkan oleh kebanyakan implementasi:
- Biaya permanen tidak bergantung pada trajektori. Dengan dampak permanen yang linier dan tak meluruh, Anda membayar ongkos permanen yang sama tak peduli bagaimana Anda menjadwalkannya. Optimisasi sepenuhnya merupakan pertarungan antara suku biaya temporer (yang menginginkan perdagangan lambat dan merata — diminimalkan oleh , yakni TWAP) dan suku varians (yang menginginkan inventaris Anda lenyap kemarin — diminimalkan oleh likuidasi seketika).
- Suku varians dibobot inventaris, bukan dibobot trade. Risiko terakumulasi pada apa yang masih Anda pegang, , bukan pada apa yang Anda perdagangkan. Inilah alasan urgensi membuat jadwal condong ke depan (front-loaded).
Bentuk tertutup: sinh, cosh, dan parameter urgensi
Almgren-Chriss meminimalkan fungsi objektif mean-variance
di mana adalah penghindaran risiko dalam satuan 1/dolar. Tetapkan untuk titik-titik interior. Suku temporer menyumbang selisih kedua (second differences) dari , suku varians menyumbang itu sendiri, dan Anda memperoleh persamaan selisih (difference equation) linier orde dua:
Ini adalah analog diskret dari , dan dengan syarat batas , solusinya berbentuk hiperbolik:
di mana memenuhi , yang untuk kecil hanyalah .

Seluruh isi strategi terkompresi menjadi satu angka:
adalah urgensi. Kebalikannya adalah waktu karakteristik trade: skala waktu di mana risiko inventaris masih layak ditanggung demi menghemat biaya dampak. Perhatikan apa yang tidak dipengaruhi : ukuran order dan tenggat . Apakah skala waktu intrinsik trade Anda 20 menit atau 6 jam ditentukan semata-mata oleh penghindaran risiko, volatilitas, dan likuiditas. Jika , tenggat Anda tak relevan — model melikuidasi menurut jadwalnya sendiri dan ekor horizon tak terpakai. Jika , tenggat mengikat dan efektifnya Anda menjalankan TWAP.
Limit risk-neutral adalah TWAP — inilah alasan TWAP ada
Ambil , sehingga . Maka dan
Trajektori optimal merosot menjadi garis lurus: kuantitas sama dalam interval waktu yang sama. TWAP bukanlah heuristik yang kebetulan berhasil; ia adalah optimum eksak dari model Almgren-Chriss untuk trader yang risk-neutral dengan dampak linier. Setiap kali seseorang menjalankan TWAP, ia secara implisit menyatakan : "Saya tidak peduli pada varians shortfall saya, hanya pada rata-ratanya." Itu posisi yang dapat dibenarkan untuk order kecil dan horizon pendek. Itu posisi yang aneh untuk melikuidasi 5% volume harian selama 8 jam pada aset dengan vol harian 4%, yang justru di situlah orang tetap menjalankannya. Limit sebaliknya memberikan untuk semua : buang semuanya pada interval pertama, bayar berapa pun ongkosnya. Di antara kedua ekstrem ini, menginterpolasi: nyaris tak terbedakan dari TWAP, sangat front-loaded secara agresif.
Efficient frontier dari eksekusi
Untuk setiap Anda memperoleh satu trajektori, satu biaya ekspektasi , dan satu varians . Menyapu menelusuri sebuah kurva di bidang — efficient frontier dari eksekusi, dalam analogi langsung dengan Markowitz. Kurva ini konveks dan menurun: varians yang lebih kecil selalu berongkos ekspektasi shortfall yang lebih besar, dengan imbal hasil yang menurun tajam (diminishing returns). Pada titik frontier yang dipilih oleh tertentu, penghindaran risiko adalah kemiringan (negatif) dari garis singgung: .

Frontier membingkai ulang pertanyaan "berapa ?" — yang tak seorang pun bisa jawab secara introspektif — menjadi "trade-off biaya/risiko mana yang saya inginkan?", yang sebuah desk sebenarnya bisa jawab. Tiga cara praktis untuk memilih titiknya:
- Penalaran biaya marjinal. Susuri frontier dan tanyakan: "berpindah dari titik ini ke berikutnya, saya membayar dolar biaya ekspektasi untuk menghilangkan dolar standar deviasi shortfall — apakah saya mengambil trade itu?" Lutut (knee) frontier biasanya jelas dalam faktor 2, dan trajektori tak sensitif terhadap pada resolusi tersebut.
- Anggaran risiko. Tetapkan std shortfall maksimum yang dapat diterima (misalnya "1-sigma satu hari dari posisi residual harus tetap di bawah 15 bps notional") lalu ambil trajektori termurah yang memenuhinya. Ini adalah masalah berkendala (constrained) yang pengganda Lagrange-nya adalah .
- Penargetan waktu karakteristik. Pilih secara langsung ("order ini seharusnya punya half-life 90 menit") lalu turunkan . Inilah yang secara implisit dilakukan kebanyakan praktisi ketika mereka menggeser slider "urgensi".
Sebuah contoh terselesaikan dengan angka-angka yang akan kita justifikasi di bagian kalibrasi. Jual BTC pada S_0 = \100{,}000T = 4\sigma = $600\sqrt{\text{h}}\eta = 1.0\ $\cdot\text{h}/\text{BTC}\lambda = 10^{-6}\ $^{-1}$. Maka
Jadwal optimal menjual 46.2 BTC pada jam pertama (TWAP: 25). Biaya temporer: \eta \int_0^T v(t)^2 dt \approx \3{,}290$2{,}500$53{,}000$69{,}300 untuk TWAP. Jadi dengan tambahan 0,8 bps biaya ekspektasi pada notional \10 juta, Anda memangkas risiko shortfall sebesar 23%. Itulah keseluruhan isi model dalam satu kalimat: ia memberi harga pada asuransinya, dan membiarkan Anda memutuskan apakah akan membelinya.
Trajektorinya sendiri hanyalah sepuluh baris Python:
import numpy as np
def almgren_chriss(X, T, N, sigma, eta, gamma, lam):
"""Optimal liquidation trajectory (discrete AC 2001)."""
tau = T / N
eta_t = eta - 0.5 * gamma * tau # tilde-eta
kappa_t2 = lam * sigma**2 / eta_t # tilde-kappa^2
kappa = np.arccosh(0.5 * kappa_t2 * tau**2 + 1) / tau
t = np.arange(N + 1) * tau
x = X * np.sinh(kappa * (T - t)) / np.sinh(kappa * T)
n = x[:-1] - x[1:] # child order sizes
E = 0.5 * gamma * X**2 + (eta_t / tau) * np.sum(n**2)
V = sigma**2 * tau * np.sum(x[1:]**2)
return x, n, E, V
x, n, E, V = almgren_chriss(X=100, T=4, N=48, sigma=600,
eta=1.0, gamma=0.3, lam=1e-6)
print(f"first-hour qty: {n[:12].sum():.1f} BTC, "
f"E=${E:,.0f}, std=${np.sqrt(V):,.0f}")
Sapu lam sepanjang np.logspace(-8, -4, 50) lalu plot terhadap — itulah frontier Anda, dan seluruh permukaan keputusan muat dalam satu grafik yang bisa Anda serahkan ke komite risiko.
Kalibrasi: , , dari data Binance
Di sinilah 90% implementasi mati diam-diam. Rumus trajektori itu sepele; parameternya tidak. Tiga kuantitas, tiga masalah estimasi yang berbeda.

: yang mudah
Volatilitas absolut per akar-jam, dari return mid-price. Gunakan bar 1 menit lalu skalakan; pada sampling yang lebih halus, noise mikrostruktur (bid-ask bounce) membiaskan realized variance ke atas. Estimasi ini kokoh — vol adalah satu parameter yang akan Anda dapatkan dengan tepat.
: dampak temporer dari order book dan dari trade
Dua rute yang saling melengkapi. Rute A — telusuri order book L2. Dari snapshot depth, hitung biaya sebuah sweep marketable hipotetis berukuran : VWAP dari level-level yang dikonsumsi dikurangi mid. Mem-fit memberikan dampak instan per BTC. Untuk mengonversinya menjadi berbasis laju dalam model, Anda harus mengasumsikan waktu pengisian ulang order book (orde 10–60 detik untuk BTCUSDT): berdagang pada laju mengonsumsi per siklus refresh, sehingga . Asumsi itu — pengisian ulang instan dan penuh menurut jam yang tetap — justru celah tempat Obizhaeva-Wang masuk; lebih lanjut di bawah. Rute B — regresikan realized slippage terhadap partisipasi. Kelompokkan aliran agresif (taker) ke dalam bin 1 menit; untuk setiap bin, regresikan VWAP sisi-taker-dikurangi-open-mid terhadap laju volume taker. Rute B mengukur apa yang sebenarnya dibebankan pasar kepada pihak agresif; Rute A mengukur apa yang akan dibebankan order book yang menetap saat ini juga. Ketika keduanya berbeda hingga faktor 3, percayai B untuk level dan A untuk bentuk intraday.
: dampak permanen via regresi gaya Kyle
Regresikan perubahan mid-price terhadap net taker flow bertanda pada jendela 5 menit:
Lalu periksa bahwa dampaknya tidak berbalik (revert) satu jendela kemudian — komponen yang tidak berbalik adalah "permanen" pada skala waktu perdagangan Anda. Ini adalah yang paling berisik di antara ketiganya dengan selisih yang lebar.
Kode siap pakai, hanya menggunakan endpoint REST publik Binance:
import requests, numpy as np, pandas as pd
B = "https://api.binance.com/api/v3"
sym = "BTCUSDT"
kl = requests.get(f"{B}/klines", params=dict(
symbol=sym, interval="1m", limit=1000)).json()
close = np.array([float(k[4]) for k in kl])
sigma = np.diff(close).std() * np.sqrt(60) # $/sqrt(h)
d = requests.get(f"{B}/depth",
params=dict(symbol=sym, limit=5000)).json()
bids = np.array(d["bids"], dtype=float) # [price, qty]
mid = (bids[0, 0] + float(d["asks"][0][0])) / 2
cq = np.cumsum(bids[:, 1]) # cum qty
cn = np.cumsum(bids[:, 0] * bids[:, 1]) # cum notional
sizes = np.linspace(0.5, 50, 40) # BTC probes
cost = [mid - np.interp(q, cq, cn) / q for q in sizes]
eps, eta_inst = np.polyfit(sizes, cost, 1)[::-1] # cost ~ eps + k*q
eta = eta_inst * (30 / 3600) # 30s refresh -> $*h/BTC
tr = requests.get(f"{B}/aggTrades",
params=dict(symbol=sym, limit=1000)).json()
df = pd.DataFrame(dict(
t=[t["T"] for t in tr],
p=[float(t["p"]) for t in tr],
q=[float(t["q"]) * (-1 if t["m"] else 1) for t in tr]))
df["bin"] = df.t // 300_000 # 5-min bins
g = df.groupby("bin").agg(dp=("p", lambda s: s.iloc[-1] - s.iloc[0]),
qn=("q", "sum"))
gamma = np.polyfit(g.qn, g.dp, 1)[0] # $/BTC
print(f"sigma={sigma:.0f} $/sqrt(h) eta={eta:.2f} $*h/BTC "
f"gamma={gamma:.3f} $/BTC")
Untuk produksi, ganti satu halaman aggTrades dengan beberapa hari dump historis dan jalankan regresi pada ribuan bin, bukan segelintir saja.
Mengapa kalibrasi crypto berisik, dan apa yang harus dilakukan
Jalankan regresi pada data nyata dan Anda akan memperoleh beberapa persen serta koefisien yang bergerak dengan faktor 2–5 antar-hari. Ini bukan bug pada kode Anda. Alasannya bersifat struktural:
- Endogenitas. Aliran merespons harga sebanyak harga merespons aliran. Trader momentum membeli karena harga naik; OLS naif dari return terhadap aliran menangkap reaksi mereka dan mengaitkannya dengan dampak. Perbaikan yang bersih adalah menggunakan fill Anda sendiri (eksogen secara konstruksi) — yang hanya Anda miliki setelah berdagang beberapa waktu.
- Kecekungan (concavity). Dampak nyata cekung terhadap ukuran — secara empiris mendekati akar-kuadrat (Almgren, Thum, Hauptmann dan Li, 2005, "Direct estimation of equity market impact", menemukan eksponen mendekati 0,6; kecekungan yang sama pun kokoh pada crypto). Mem-fit garis pada fungsi cekung berarti dan Anda bergantung pada rentang ukuran dalam sampel. Kalibrasikan pada participation rate yang benar-benar akan Anda perdagangkan.
- Fragmentasi dan kepemimpinan derivatif. Spot BTCUSDT di Binance adalah satu venue dari sekian banyak, dan price discovery kerap terjadi di perp. Aliran yang tak pernah Anda lihat menggerakkan harga yang Anda regresikan, mengembungkan suku noise.
- Ketergantungan rezim. yang diukur pada sesi Asia tidak menggambarkan pembukaan AS; dampak kira-kira berlipat dua saat volatilitas berlipat dua. Kalibrasikan per sesi, dan fit ulang setidaknya mingguan.
Penyelamatnya: trajektori itu pemaaf. , sehingga kesalahan faktor-2 pada hanya menggeser sebesar , dan fungsi biaya datar di dekat optimum. Mendapatkan dengan tepat dalam faktor 2 dan dengan tepat dalam satu orde besaran sudah menangkap sebagian besar peningkatan yang tersedia atas TWAP. Presisi penting untuk estimasi biaya pra-trade; ketahanan (robustness) sudah cukup untuk penjadwalan.
Di mana model runtuh, dan paper-paper yang memperbaikinya
Almgren-Chriss adalah kerangka (scaffold), dan mengetahui persis balok mana yang menopang beban memberi tahu Anda ekstensi mana yang perlu diraih.
Dampak nonlinier — Almgren (2003). "Optimal execution with nonlinear impact functions and trading-enhanced risk" (Applied Mathematical Finance 10, 1–18) mengulang program dengan dampak temporer power-law . Untuk yang secara empiris disukai — hukum akar-kuadrat — trajektori optimal berubah sifat: dampak cekung menghukum ledakan (bursts) lebih ringan ketimbang dampak linier, sehingga jadwal optimal menjadi lebih front-loaded pada yang sama. Struktur kualitatifnya (parameter urgensi, efficient frontier) bertahan; rumus sinh-nya tidak.
Resiliensi dan LOB — Obizhaeva dan Wang (2013). "Optimal trading strategy and supply/demand dynamics" (Journal of Financial Markets 16(1), 1–32; working paper-nya beredar sejak 2005) mengganti dikotomi temporer/permanen dengan limit order book yang berkedalaman terhingga dan dampak yang meluruh secara eksponensial: trade Anda memakan order book, dan order book terisi ulang pada laju resiliensi . Asumsi AC bahwa "dampak temporer lenyap seketika" adalah limit . Strategi optimalnya berubah bentuk secara dramatis: satu block trade di awal, satu block di akhir, dan laju perdagangan konstan di antaranya — block-block itu memanfaatkan pemulihan order book. Jika interval child-order Anda sebanding dengan waktu pengisian ulang venue (pada crypto, dari hitungan detik ke satu menit — sering kali memang begitu), Anda berada di wilayah Obizhaeva-Wang, bukan wilayah Almgren-Chriss, dan akal-akalan pada kalibrasi di atas adalah tanda peringatan Anda.
No-dynamic-arbitrage — Gatheral (2010). "No-dynamic-arbitrage and market impact" (Quantitative Finance 10(7), 749–759) menanyakan kombinasi mana antara fungsi dampak instan dan kernel peluruhan yang konsisten secara internal, yakni tak memungkinkan strategi round-trip berbiaya ekspektasi negatif. Hasilnya tajam: peluruhan eksponensial hanya kompatibel hanya dengan dampak linier — gabungkan peluruhan eksponensial dengan dampak akar-kuadrat maka model bisa diperah uang oleh barisan trade yang berosilasi; dampak nonlinier menuntut peluruhan power-law, dengan sebuah pertidaksamaan yang mengaitkan kedua eksponen (untuk dampak dan peluruhan , kira-kira ). Inilah paper yang harus dibaca sebelum Anda memasang kernel peluruhan yang canggih pada model dampak Anda: kebanyakan kombinasi ad-hoc diam-diam bisa diarbitrase, yang dalam praktik berarti optimizer Anda akan menemukan arbitrase itu dan menghasilkan jadwal berosilasi yang absurd. Jika trajektori "optimal" Anda menyelang-nyeling beli dan jual selama likuidasi murni, Anda telah melanggar Gatheral, bukan menemukan alpha.
Sekuel-sekuel ML. Dua utas dalam seri ini dibangun langsung di atas kerangka ini. Pertama, eksekusi reinforcement-learning: begitu Anda mengakui bahwa dampak itu nonlinier, bergantung-keadaan (state-dependent), dan teramati sebagian (partially observable), bentuk tertutupnya lenyap, dan RL (mulai dari paper Q-learning Nevmyvaka, Feng dan Kearns 2006 dan seterusnya) adalah cara alami untuk menelusuri ruang trajektori — tetapi setiap agen eksekusi RL yang serius di-benchmark terhadap, dan sering kali diinisialisasi dari, solusi AC. Kedua, model dampak-harga neural: mengganti dengan fungsional terpelajar dari keadaan order book, sembari mempertahankan logika penjadwalan mean-variance di atasnya. Kedua sekuel itu tak masuk akal tanpa mengetahui persis apa baseline linier-Gaussian itu dan mengapa ia berbentuk demikian.
Yang perlu dibawa pulang
Model ini adalah tiga asumsi, satu persamaan selisih, dan satu angka. Dampak permanen linier (dipaksakan oleh no-manipulation), dampak temporer linier (aproksimasi yang Anda kalibrasi di sekitarnya), noise Brownian aritmetika. Optimum-nya menukar (trade off) varians inventaris dengan biaya dampak, seluruh strategi runtuh menjadi urgensi , dan TWAP muncul sebagai kasus degenerat — yang merupakan fakta paling berguna dalam model, karena ia mengubah "haruskah kita meng-TWAP ini?" dari soal kebiasaan menjadi klaim yang dapat diperiksa tentang penghindaran risiko. Kalibrasi adalah pekerjaan sesungguhnya: itu mudah, adalah permainan faktor-2, adalah proyek riset, dan trajektori memaafkan ketiganya. Implementasikan dalam satu sore; habiskan sisa bulan itu untuk diagnostik regresi.
Referensi
- Almgren, R., Chriss, N. (2001). "Optimal execution of portfolio transactions." Journal of Risk, 3(2), 5–39.
- Almgren, R. (2003). "Optimal execution with nonlinear impact functions and trading-enhanced risk." Applied Mathematical Finance, 10(1), 1–18.
- Almgren, R., Thum, C., Hauptmann, E., Li, H. (2005). "Direct estimation of equity market impact." Risk, 18(7), 58–62.
- Huberman, G., Stanzl, W. (2004). "Price manipulation and quasi-arbitrage." Econometrica, 72(4), 1247–1275.
- Obizhaeva, A., Wang, J. (2013). "Optimal trading strategy and supply/demand dynamics." Journal of Financial Markets, 16(1), 1–32.
- Gatheral, J. (2010). "No-dynamic-arbitrage and market impact." Quantitative Finance, 10(7), 749–759.
- Nevmyvaka, Y., Feng, Y., Kearns, M. (2006). "Reinforcement learning for optimized trade execution." ICML 2006.
Penulis
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.