Almgren-Chriss Tanpa Berselindung: Pelaksanaan Optimum yang Boleh Anda Laksanakan dalam Satu Petang
Almgren dan Chriss (2001), "Optimal execution of portfolio transactions" (Journal of Risk 3(2), 5–39), mungkin merupakan kertas kerja yang paling banyak dipetik dalam penyelidikan pelaksanaan dan salah satu yang paling jarang dilaksanakan dengan betul. Kebanyakan kod "Almgren-Chriss" di luar sana hanyalah penjadual TWAP dengan blok komen. Kebanyakan catatan blog mengenainya melangkau terbitannya, melambai ke arah fungsi sinh, dan tidak pernah menyentuh bahagian yang benar-benar penting dalam pengeluaran: dari mana parameter itu datang.
Artikel ini melakukan keseluruhannya. Andaian model, dinyatakan dengan jujur. Trajektori bentuk tertutup, diterbitkan, bukan sekadar dinyatakan. Sempadan cekap dan cara memilih parameter penghindaran risiko. Dan penentukuran ketiga-tiga input — kesan sementara , kesan kekal , kemeruapan — daripada data buku pesanan dan dagangan Binance, dengan Python yang berfungsi dan perbincangan jujur tentang mengapa pemadanannya bising. Inilah tulang belakang intelektual segala yang lain dalam pelaksanaan: TWAP, VWAP dan POV ialah kes khas atau sepupu heuristik (lihat TWAP, VWAP, POV: algoritma pelaksanaan yang semua orang jalankan), dan pendekatan ML moden — penjadual pembelajaran pengukuhan dan model kesan neural — ialah percubaan untuk melonggarkan tepat andaian yang bakal kita tuliskan.
Persediaan: apa yang model sebenarnya andaikan
Anda memegang unit aset (katakan, 100 BTC) dan mesti melikuidasikan sepenuhnya menjelang masa . Bahagikan kepada selang dengan panjang . Pemboleh ubah keputusan anda ialah trajektori pegangan , dengan dagangan yang dilaksanakan dalam selang .
Tiga andaian membawa keseluruhan model:
1. Rawak berjalan aritmetik. Harga tanpa gangguan mengikut
di mana ialah normal piawai i.i.d. dan ialah kemeruapan mutlak (dolar per unit masa, bukan peratus). Aritmetik, bukan geometri — dalam beberapa jam perbezaannya boleh diabaikan dan rawak berjalan aritmetik mengekalkan algebra linear-kuadratik. Tiada hanyutan: Almgren dan Chriss membincangkan sebutan hanyutan, tetapi bagi likuidasi intrahari anggaran alfa anda dalam tempoh 4 jam hampir selalu hingar, dan menetapkannya kepada sifar ialah pilihan lalai yang jujur.
2. Kesan kekal linear. : berdagang pada kadar mengalihkan harga secara kekal, berkadaran, dan alihan itu tidak pernah reput. Setiap unit yang anda jual menolak pertengahan (mid) ke bawah sebanyak selama-lamanya. Ini kelihatan kasar, tetapi ada sebab mendalam untuk mengekalkannya linear: Huberman dan Stanzl (2004) membuktikan bahawa kesan kekal yang tidak linear dalam saiz dagangan membuka ruang untuk strategi pusingan-balik dengan keuntungan jangkaan positif — manipulasi harga. Kesan kekal linear bukan pemudahan demi kemudahan; ia satu-satunya pilihan bebas arbitraj dalam kelas model ini.
3. Kesan sementara linear. Harga yang sebenarnya anda terima dalam selang ialah
menangkap separuh daripada spread bid-ask ditambah yuran; ialah cerun kos marginal untuk menuntut kecairan pada kadar . Kesan sementara hanya mempengaruhi pengisian anda sendiri dan lenyap serta-merta — buku pesanan diisi semula sepenuhnya sebelum pesanan anak anda seterusnya. Setiap satu daripada tiga perkataan "linear", "serta-merta", "sepenuhnya" adalah salah dalam pasaran sebenar, dan bahagian terakhir membincangkan betapa salahnya. Tetapi pertama, ganjaran kerana menerimanya.
Kos dan varians sesuatu trajektori
Jumlahkan pengisian, tolak daripada tanda awal , dan anda memperoleh kekurangan pelaksanaan (implementation shortfall). Jangkaan dan variansnya terhadap hingar ialah:
dengan (pembetulan pendiskretan yang lenyap apabila ).
Dua pemerhatian yang terlepas oleh kebanyakan pelaksanaan:
- Kos kekal tidak bergantung pada trajektori. Dengan kesan kekal linear yang tidak reput, anda membayar tol kekal yang sama tidak kira bagaimana anda menjadualkannya. Pengoptimuman keseluruhannya ialah pertarungan antara sebutan kos sementara (yang mahukan dagangan perlahan dan sekata — ia diminimumkan oleh , iaitu TWAP) dan sebutan varians (yang mahukan inventori anda hilang semalam — ia diminimumkan oleh likuidasi serta-merta).
- Sebutan varians ditimbang mengikut inventori, bukan mengikut dagangan. Risiko terkumpul pada apa yang masih anda pegang, , bukan pada apa yang anda dagangkan. Inilah sebabnya kesegeraan membebankan jadual di bahagian awal (front-load).
Bentuk tertutup: sinh, cosh, dan parameter kesegeraan
Almgren-Chriss meminimumkan objektif min-varians
di mana ialah penghindaran risiko dalam unit 1/dolar. Tetapkan untuk titik dalaman. Sebutan sementara menyumbang perbezaan kedua bagi , sebutan varians menyumbang itu sendiri, dan anda memperoleh persamaan perbezaan tertib kedua linear:
Ini ialah analog diskret bagi , dan dengan syarat sempadan , penyelesaiannya adalah hiperbolik:
di mana menyelesaikan , yang untuk kecil hanyalah .

Segala-galanya tentang strategi ini dimampatkan ke dalam satu nombor:
ialah kesegeraan (urgency). Salingannya ialah masa ciri dagangan: skala masa yang mana berbaloi untuk menanggung risiko inventori demi menjimatkan kos kesan. Perhatikan apa yang tidak bergantung padanya: saiz pesanan dan tarikh akhir . Sama ada skala masa intrinsik dagangan anda ialah 20 minit atau 6 jam ditentukan oleh penghindaran risiko, kemeruapan dan kecairan sahaja. Jika , tarikh akhir anda tidak relevan — model melikuidasikan mengikut jadualnya sendiri dan ekor ufuk tidak digunakan. Jika , tarikh akhir mengikat dan anda secara berkesan sedang melakukan TWAP.
Had neutral-risiko ialah TWAP — inilah sebab TWAP wujud
Ambil , jadi . Maka dan
Trajektori optimum merosot menjadi garis lurus: kuantiti sama dalam selang masa yang sama. TWAP bukan heuristik yang kebetulan berfungsi; ia optimum tepat bagi model Almgren-Chriss untuk pedagang neutral-risiko dengan kesan linear. Setiap kali seseorang menjalankan TWAP, mereka secara tersirat menegaskan : "Saya tidak peduli tentang varians kekurangan saya, hanya minnya sahaja." Itu kedudukan yang boleh dipertahankan untuk pesanan kecil dan ufuk pendek. Ia kedudukan yang pelik untuk melikuidasikan 5% daripada volum harian selama 8 jam dalam aset yang mencatat kemeruapan harian 4%, yang justeru di situlah orang menjalankannya. Had bertentangan memberikan untuk semua : buang semuanya dalam selang pertama, bayar apa sahaja kosnya. Antara kedua-dua ekstrem ini, menginterpolasi: hampir tidak dapat dibezakan daripada TWAP, dibebankan secara agresif di bahagian awal.
Sempadan cekap pelaksanaan
Bagi setiap anda memperoleh satu trajektori, satu kos jangkaan , dan satu varians . Menyapu menjejaki satu lengkung dalam satah — sempadan cekap pelaksanaan, secara analogi langsung dengan Markowitz. Ia cembung dan menurun: varians yang lebih rendah sentiasa memerlukan kos jangkaan kekurangan yang lebih tinggi, dengan pulangan yang menyusut dengan curam. Pada titik sempadan yang dipilih oleh tertentu, penghindaran risiko ialah cerun (negatif) tangen: .

Sempadan itu membingkai semula soalan "apakah ?" — yang tiada siapa boleh jawab secara introspektif — menjadi "pertukaran kos/risiko manakah yang saya mahu?", yang meja dagangan sebenarnya boleh jawab. Tiga cara praktikal untuk memilih titik:
- Penaakulan kos marginal. Susuri sempadan dan tanya: "berpindah daripada titik ini ke titik seterusnya, saya membayar dolar kos jangkaan untuk menghapuskan dolar sisihan piawai kekurangan — adakah saya mengambil dagangan itu?" Lutut sempadan biasanya jelas dalam faktor 2, dan trajektori tidak sensitif terhadap pada resolusi itu.
- Belanjawan risiko. Tetapkan sisihan piawai kekurangan maksimum yang boleh diterima (cth. "1-sigma sehari bagi kedudukan baki mesti kekal di bawah 15 bps daripada nosional") dan ambil trajektori termurah yang memenuhinya. Ini masalah berkekangan yang pengganda Lagrange-nya ialah .
- Menyasar masa ciri. Pilih secara langsung ("pesanan ini sepatutnya mempunyai separuh hayat 90 minit") dan keluarkan . Inilah yang kebanyakan pengamal lakukan secara tersirat apabila mereka menetapkan gelangsar "kesegeraan".
Satu contoh dikerjakan dengan nombor yang akan kita wajarkan dalam bahagian penentukuran. Jual BTC pada S_0 = \100{,}000T = 4\sigma = $600\sqrt{\text{j}}\eta = 1.0\ $\cdot\text{j}/\text{BTC}\lambda = 10^{-6}\ $^{-1}$. Maka
Jadual optimum menjual 46.2 BTC pada jam pertama (TWAP: 25). Kos sementara: \eta \int_0^T v(t)^2 dt \approx \3{,}290$2{,}500$53{,}000$69{,}300 untuk TWAP. Jadi untuk tambahan 0.8 bps kos jangkaan pada nosional \10J anda mengurangkan risiko kekurangan sebanyak 23%. Itulah keseluruhan kandungan model dalam satu ayat: ia menetapkan harga insurans, dan membiarkan anda memutuskan sama ada hendak membelinya.
Trajektori itu 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 merentasi np.logspace(-8, -4, 50) dan plot terhadap — itulah sempadan anda, dan keseluruhan permukaan keputusan muat pada satu carta yang boleh anda serahkan kepada jawatankuasa risiko.
Penentukuran: , , daripada data Binance
Di sinilah 90% pelaksanaan mati secara senyap. Formula trajektori adalah remeh; parameternya tidak. Tiga kuantiti, tiga masalah anggaran yang berbeza.

: yang mudah
Kemeruapan mutlak per punca-jam, daripada pulangan harga pertengahan. Gunakan bar 1-minit dan skalakan; pada persampelan yang lebih halus, hingar mikrostruktur (lantunan bid-ask) memberat sebelahkan varians terealisasi ke atas. Anggaran ini kukuh — kemeruapan ialah satu-satunya parameter yang akan anda dapat dengan betul.
: kesan sementara daripada buku dan daripada dagangan
Dua laluan yang saling melengkapi. Laluan A — susuri buku L2. Daripada syot kilat kedalaman, kira kos sapuan boleh-dagang hipotetikal bersaiz : VWAP aras yang digunakan tolak pertengahan. Memadankan memberi kesan seketika per BTC. Untuk menukar kepada berasaskan kadar dalam model, anda mesti mengandaikan masa pengisian semula buku (dalam lingkungan 10–60 s untuk BTCUSDT): berdagang pada kadar menggunakan setiap kitaran penyegaran, jadi . Andaian itu — pengisian semula serta-merta dan penuh pada jam tetap — ialah tepat retakan yang melaluinya Obizhaeva-Wang masuk; lebih lanjut di bawah. Laluan B — regres gelinciran terealisasi terhadap penyertaan. Kelompokkan aliran agresif (pengambil/taker) ke dalam bin 1-minit; bagi setiap bin, regres VWAP sisi-taker-tolak-pertengahan-buka terhadap kadar volum taker. Laluan B mengukur apa yang pasaran sebenarnya kenakan kepada agresor; Laluan A mengukur apa yang buku berdiam akan kenakan sekarang. Apabila kedua-duanya tidak bersetuju dengan faktor 3, percaya B untuk paras dan A untuk bentuk intrahari.
: kesan kekal melalui regresi gaya Kyle
Regres perubahan harga pertengahan terhadap aliran taker bersih bertanda merentasi tetingkap 5-minit:
Kemudian semak bahawa kesan itu tidak berbalik satu tetingkap kemudian — komponen tidak-berbalik ialah "kekal" pada skala masa dagangan anda. Ini yang paling bising antara ketiga-tiganya dengan margin yang besar.
Kod yang berfungsi, menggunakan hanya titik hujung REST awam 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 pengeluaran, gantikan halaman aggTrades tunggal itu dengan beberapa hari longgokan sejarah dan jalankan regresi pada beribu-ribu bin, bukan segelintir sahaja.
Mengapa penentukuran kripto bising, dan apa yang perlu dilakukan mengenainya
Jalankan regresi pada data sebenar dan anda akan memperoleh beberapa peratus dan pekali yang bergerak dengan faktor 2–5 antara hari. Ini bukan pepijat dalam kod anda. Sebab-sebabnya berstruktur:
- Keendogenan. Aliran bertindak balas terhadap harga sebanyak harga bertindak balas terhadap aliran. Pedagang momentum membeli kerana harga naik; OLS naif bagi pulangan terhadap aliran menangkap reaksi mereka dan mengaitkannya dengan kesan. Penyelesaian bersih ialah menggunakan pengisian anda sendiri (eksogen secara binaan) — yang hanya anda miliki selepas berdagang untuk seketika.
- Kecekungan. Kesan sebenar adalah cekung dalam saiz — secara empirik hampir kepada punca-kuasa-dua (Almgren, Thum, Hauptmann dan Li, 2005, "Direct estimation of equity market impact", mendapati eksponen menghampiri 0.6; kecekungan yang sama teguh dalam kripto). Memadankan garis kepada fungsi cekung bermakna dan anda bergantung pada julat saiz dalam sampel. Tentukur pada kadar penyertaan yang anda benar-benar akan dagangkan.
- Pemecahan dan kepimpinan derivatif. BTCUSDT spot di Binance ialah satu tempat daripada banyak, dan penemuan harga kerap berlaku di perps. Aliran yang anda tidak pernah lihat menggerakkan harga yang anda regres, menaikkan sebutan hingar.
- Kebergantungan rejim. yang diukur dalam sesi Asia tidak menggambarkan pembukaan AS; kesan kira-kira berganda apabila kemeruapan berganda. Tentukur setiap sesi, dan padankan semula sekurang-kurangnya setiap minggu.
Penyelamatnya: trajektori itu bertimbang rasa. , jadi ralat faktor-2 dalam menggerakkan hanya sebanyak , dan fungsi kos mendatar berhampiran optimum. Mendapat betul dalam faktor 2 dan betul dalam satu magnitud sudah menangkap kebanyakan penambahbaikan yang tersedia berbanding TWAP. Ketepatan penting untuk anggaran kos pra-dagangan; keteguhan cukup untuk penjadualan.
Di mana model itu rosak, dan kertas kerja yang membaikinya
Almgren-Chriss ialah rangka, dan mengetahui dengan tepat rasuk mana yang menanggung beban memberitahu anda sambungan mana yang perlu dicapai.
Kesan tidak linear — Almgren (2003). "Optimal execution with nonlinear impact functions and trading-enhanced risk" (Applied Mathematical Finance 10, 1–18) mengulangi program dengan kesan sementara hukum-kuasa . Bagi yang disukai secara empirik — hukum punca-kuasa-dua — trajektori optimum berubah watak: kesan cekung menghukum lonjakan kurang berbanding kesan linear, jadi jadual optimum menjadi lebih dibebankan di bahagian awal pada yang sama. Struktur kualitatif (parameter kesegeraan, sempadan cekap) kekal; formula sinh tidak.
Ketahanan dan LOB — Obizhaeva dan Wang (2013). "Optimal trading strategy and supply/demand dynamics" (Journal of Financial Markets 16(1), 1–32; kertas kerja diedarkan sejak 2005) menggantikan dikotomi sementara/kekal dengan buku pesanan had yang mempunyai kedalaman terhingga dan kesan yang mereput secara eksponen: dagangan anda memakan buku, dan buku diisi semula pada kadar ketahanan . Andaian AC "kesan sementara lenyap serta-merta" ialah had . Strategi optimum berubah bentuk secara dramatik: dagangan blok pada permulaan, blok pada penghujung, dan kadar dagangan malar di antaranya — blok-blok itu mengeksploitasi pemulihan buku. Jika selang pesanan-anak anda setanding dengan masa pengisian semula tempat itu (dalam kripto, saat hingga seminit — selalunya begitu), anda berada dalam wilayah Obizhaeva-Wang, bukan wilayah Almgren-Chriss, dan penipuan dalam penentukuran di atas ialah tanda amaran anda.
Tiada-arbitraj-dinamik — Gatheral (2010). "No-dynamic-arbitrage and market impact" (Quantitative Finance 10(7), 749–759) bertanya kombinasi manakah bagi fungsi kesan seketika dan inti reputan yang konsisten secara dalaman, iaitu tidak membuka ruang untuk strategi pusingan-balik dengan kos jangkaan negatif. Keputusannya tajam: reputan eksponen serasi hanya dengan kesan linear — gabungkan reputan eksponen dengan kesan punca-kuasa-dua dan model boleh dipam untuk wang oleh jujukan dagangan berayun; kesan tidak linear memerlukan reputan hukum-kuasa, dengan satu ketaksamaan yang mengaitkan kedua-dua eksponen (untuk kesan dan reputan , secara kasar ). Inilah kertas kerja untuk dibaca sebelum anda memasang inti reputan yang mewah pada model kesan anda: kebanyakan kombinasi ad-hoc sebenarnya boleh diarbitraj secara rahsia, yang dalam amalan bermakna pengoptimum anda akan menemui arbitraj itu dan menghasilkan jadual berayun yang tidak masuk akal. Jika trajektori "optimum" anda berselang-seli beli dan jual semasa likuidasi tulen, anda telah melanggar Gatheral, bukan menemui alfa.
Sekuel ML. Dua benang dalam siri ini dibina secara langsung di atas rangka ini. Pertama, pelaksanaan pembelajaran pengukuhan: sebaik anda mengakui bahawa kesan itu tidak linear, bergantung keadaan, dan boleh diperhati secara separa, bentuk tertutup itu hilang, dan RL (dari kertas kerja Q-learning Nevmyvaka, Feng dan Kearns 2006 dan seterusnya) ialah cara semula jadi untuk mencari ruang trajektori — tetapi setiap ejen pelaksanaan RL yang serius ditanda aras terhadap, dan selalunya dimulakan daripada, penyelesaian AC. Kedua, model kesan-harga neural: menggantikan dengan fungsian terpelajar bagi keadaan buku pesanan, sambil mengekalkan logik penjadualan min-varians di atasnya. Kedua-dua sekuel tidak masuk akal tanpa mengetahui dengan tepat apa itu garis dasar linear-Gaussian dan mengapa ia mempunyai bentuk sedemikian.
Apa yang perlu diambil
Model itu ialah tiga andaian, satu persamaan perbezaan, dan satu nombor. Kesan kekal linear (dipaksa oleh tiada-manipulasi), kesan sementara linear (satu penghampiran yang anda tentukur di sekelilingnya), hingar Brownian aritmetik. Optimum itu mengimbangi varians inventori terhadap kos kesan, keseluruhan strategi runtuh menjadi kesegeraan , dan TWAP terhasil sebagai kes merosot — yang merupakan fakta paling berguna dalam model, kerana ia menukar "patutkah kita TWAP-kan ini?" daripada soal kebiasaan menjadi dakwaan yang boleh disemak tentang penghindaran risiko. Penentukuran ialah kerja sebenar: mudah, ialah permainan faktor-2, ialah projek penyelidikan, dan trajektori memaafkan ketiga-tiganya. Laksanakan dalam satu petang; habiskan baki bulan itu untuk diagnostik regresi.
Rujukan
- 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.
Pengarang
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.