← Torna agli articoli
July 14, 2026
5 min di lettura

Almgren-Chriss senza fumo negli occhi: esecuzione ottimale implementabile in un pomeriggio

Almgren-Chriss senza fumo negli occhi: esecuzione ottimale implementabile in un pomeriggio
#esecuzione
#almgren-chriss
#market impact
#esecuzione ottimale
#twap
#quant
#python
#crypto

Almgren e Chriss (2001), "Optimal execution of portfolio transactions" (Journal of Risk 3(2), 5–39), è probabilmente l'articolo più citato nella ricerca sull'esecuzione e uno dei meno implementati correttamente. Buona parte del codice "Almgren-Chriss" in circolazione è in realtà uno scheduler TWAP con un blocco di commenti. Buona parte dei post che ne parlano saltano la derivazione, agitano le mani davanti a una funzione sinh e non toccano mai la parte che conta davvero in produzione: da dove vengono i parametri.

Questo articolo fa tutto per intero. Le assunzioni del modello, dichiarate onestamente. La traiettoria in forma chiusa, derivata, non asserita. La frontiera efficiente e come scegliere il parametro di avversione al rischio. E la calibrazione dei tre input — impatto temporaneo η\eta, impatto permanente γ\gamma, volatilità σ\sigma — a partire da dati dell'order book e dei trade di Binance, con Python funzionante e una discussione onesta sul perché il fit sia rumoroso. Questa è la spina dorsale intellettuale di tutto il resto in materia di esecuzione: TWAP, VWAP e POV sono casi particolari o cugini euristici (vedi TWAP, VWAP, POV: gli algoritmi di esecuzione che tutti usano), e i moderni approcci basati su ML — scheduler a reinforcement learning e modelli di impatto neurali — sono tentativi di rilassare esattamente le assunzioni che stiamo per scrivere.

L'impostazione: cosa assume davvero il modello

Detenete XX unità di un asset (diciamo, 100 BTC) e dovete liquidarle completamente entro il tempo TT. Dividete [0,T][0, T] in NN intervalli di lunghezza τ=T/N\tau = T/N. La vostra variabile di decisione è la traiettoria delle posizioni x0=X,x1,,xN=0x_0 = X, x_1, \dots, x_N = 0, con i trade nk=xk1xkn_k = x_{k-1} - x_k eseguiti nell'intervallo kk.

Tre assunzioni reggono l'intero modello:

1. Random walk aritmetico. Il prezzo non perturbato segue

Sk=Sk1+στξkτg ⁣(nkτ),S_k = S_{k-1} + \sigma \sqrt{\tau}\, \xi_k - \tau\, g\!\left(\frac{n_k}{\tau}\right),

dove ξk\xi_k sono normali standard i.i.d. e σ\sigma è la volatilità assoluta (dollari per unità di tempo1/2^{1/2}, non percentuale). Aritmetico, non geometrico — su un arco di poche ore la differenza è trascurabile e il random walk aritmetico mantiene l'algebra lineare-quadratica. Nessun drift: Almgren e Chriss discutono il termine di drift, ma per una liquidazione intraday la vostra stima di alpha su 4 ore è quasi sempre rumore, e porla a zero è l'opzione di default onesta.

2. Impatto permanente lineare. g(v)=γvg(v) = \gamma v: negoziare al ritmo vv sposta il prezzo in modo permanente, proporzionale, e lo spostamento non decade mai. Ogni unità venduta spinge il mid verso il basso di γ\gamma per sempre. Sembra rozzo, ma c'è una ragione profonda per mantenerlo lineare: Huberman e Stanzl (2004) hanno dimostrato che un impatto permanente non lineare nella dimensione del trade ammette strategie di round-trip con profitto atteso positivo — manipolazione del prezzo. L'impatto permanente lineare non è una semplificazione di comodo; è l'unica scelta arbitrage-free in questa classe di modelli.

3. Impatto temporaneo lineare. Il prezzo effettivamente ricevuto nell'intervallo kk è

S~k=Sk1h ⁣(nkτ),h(v)=ϵsgn(v)+ηv.\tilde{S}_k = S_{k-1} - h\!\left(\frac{n_k}{\tau}\right), \qquad h(v) = \epsilon\, \mathrm{sgn}(v) + \eta v.

ϵ\epsilon cattura metà dello spread bid-ask più le commissioni; η\eta è la pendenza del costo marginale di richiedere liquidità al ritmo vv. L'impatto temporaneo influisce solo sul proprio fill e svanisce istantaneamente — il book si ricostituisce completamente prima del child order successivo. Ognuna delle tre parole "lineare", "istantaneamente", "completamente" è sbagliata nei mercati reali, e l'ultima sezione tratta di quanto lo sia. Ma prima, il payoff per averle accettate.

Costo e varianza di una traiettoria

Sommate i fill, sottraeteli dal mark iniziale XS0X S_0, e ottenete l'implementation shortfall. Il suo valore atteso e la sua varianza rispetto al rumore ξk\xi_k sono:

E[C]=12γX2permanente+ϵXspread+η~τk=1Nnk2temporaneo,V[C]=σ2τk=1Nxk2,E[C] = \underbrace{\tfrac{1}{2}\gamma X^2}_{\text{permanente}} + \underbrace{\epsilon X}_{\text{spread}} + \underbrace{\frac{\tilde{\eta}}{\tau} \sum_{k=1}^{N} n_k^2}_{\text{temporaneo}}, \qquad V[C] = \sigma^2 \tau \sum_{k=1}^{N} x_k^2,

con η~=η12γτ\tilde{\eta} = \eta - \tfrac{1}{2}\gamma\tau (una correzione di discretizzazione che svanisce quando τ0\tau \to 0).

Due osservazioni che la maggior parte delle implementazioni si perde:

  • Il costo permanente 12γX2\tfrac{1}{2}\gamma X^2 non dipende dalla traiettoria. Con impatto permanente lineare e non decadente, si paga lo stesso pedaggio permanente indipendentemente da come si pianifica l'esecuzione. L'ottimizzazione è interamente una lotta tra il termine di costo temporaneo (che vuole un trading lento e uniforme — è minimizzato da nk=X/Nn_k = X/N, cioè TWAP) e il termine di varianza (che vuole che il vostro inventario sparisca il prima possibile — è minimizzato dalla liquidazione immediata).
  • Il termine di varianza è pesato per l'inventario, non per il trade. Il rischio matura su ciò che ancora detenete, xkx_k, non su ciò che negoziate. Questo è il motivo per cui l'urgenza sposta il carico dello schedule verso l'inizio.

La forma chiusa: sinh, cosh e il parametro di urgenza

Almgren-Chriss minimizzano l'obiettivo media-varianza

U(x)=E[C]+λV[C],U(x) = E[C] + \lambda V[C],

dove λ0\lambda \geq 0 è l'avversione al rischio in unità di 1/dollari. Ponendo U/xj=0\partial U / \partial x_j = 0 per i punti interni. Il termine temporaneo contribuisce con le differenze seconde di xx, il termine di varianza contribuisce con xjx_j stesso, e si ottiene un'equazione alle differenze lineare del secondo ordine:

xj12xj+xj+1τ2=κ~2xj,κ~2=λσ2η~.\frac{x_{j-1} - 2x_j + x_{j+1}}{\tau^2} = \tilde{\kappa}^2 x_j, \qquad \tilde{\kappa}^2 = \frac{\lambda \sigma^2}{\tilde{\eta}}.

Questo è l'analogo discreto di x=κ2xx'' = \kappa^2 x, e con le condizioni al contorno x0=Xx_0 = X, xN=0x_N = 0 la soluzione è iperbolica:

  xj=Xsinh ⁣(κ(Ttj))sinh(κT)  nj=2sinh(κτ/2)sinh(κT)cosh ⁣(κ(Ttj1/2))X,\boxed{\;x_j = X\, \frac{\sinh\!\big(\kappa\,(T - t_j)\big)}{\sinh(\kappa T)}\;} \qquad n_j = \frac{2\sinh(\kappa\tau/2)}{\sinh(\kappa T)}\, \cosh\!\big(\kappa (T - t_{j-1/2})\big)\, X,

dove κ\kappa risolve 2τ2(cosh(κτ)1)=κ~2\tfrac{2}{\tau^2}\left(\cosh(\kappa\tau) - 1\right) = \tilde{\kappa}^2, che per τ\tau piccolo è semplicemente κκ~=λσ2/η\kappa \approx \tilde{\kappa} = \sqrt{\lambda\sigma^2/\eta}.

Traiettorie ottimali delle posizioni per diversi valori di kappa, dalla linea retta del TWAP alle curve aggressive con carico anticipato

Tutto ciò che riguarda la strategia è compresso in un unico numero:

κ=λσ2η[unitaˋ1/tempo].\kappa = \sqrt{\frac{\lambda \sigma^2}{\eta}} \qquad [\text{unità: } 1/\text{tempo}].

κ\kappa è l'urgenza. Il suo reciproco θ=1/κ\theta = 1/\kappa è il tempo caratteristico del trade: la scala temporale su cui conviene mantenere il rischio di inventario per risparmiare sul costo di impatto. Notate cosa κ\kappa non dipende: dalla dimensione dell'ordine XX e dalla scadenza TT. Se la scala temporale intrinseca del vostro trade è 20 minuti o 6 ore è determinato solo da avversione al rischio, volatilità e liquidità. Se θT\theta \ll T, la vostra scadenza è irrilevante — il modello liquida secondo il proprio schedule e la coda dell'orizzonte resta inutilizzata. Se θT\theta \gg T, la scadenza diventa vincolante e state effettivamente facendo TWAP.

Il limite risk-neutral è il TWAP — ecco perché il TWAP esiste

Prendete λ0\lambda \to 0, quindi κ0\kappa \to 0. Allora sinh(z)z\sinh(z) \to z e

x(t)=Xsinh(κ(Tt))sinh(κT)    XTtT.x(t) = X\,\frac{\sinh(\kappa(T-t))}{\sinh(\kappa T)} \;\longrightarrow\; X\,\frac{T-t}{T}.

La traiettoria ottimale degenera nella linea retta: quantità uguali in intervalli di tempo uguali. Il TWAP non è un'euristica che per caso funziona; è l'ottimo esatto del modello Almgren-Chriss per un trader risk-neutral con impatto lineare. Ogni volta che qualcuno esegue un TWAP, sta implicitamente asserendo λ=0\lambda = 0: "non mi interessa la varianza del mio shortfall, solo la sua media". È una posizione difendibile per ordini piccoli e orizzonti brevi. È una posizione strana per liquidare il 5% del volume giornaliero in 8 ore su un asset con il 4% di vol giornaliera, che è esattamente dove le persone lo eseguono comunque. Il limite opposto λ\lambda \to \inftyxj0x_j \to 0 per ogni j>0j > 0: scaricare tutto nel primo intervallo, pagando qualsiasi costo. Tra questi estremi, κT\kappa T interpola: κT0.5\kappa T \lesssim 0.5 è a malapena distinguibile dal TWAP, κT3\kappa T \gtrsim 3 è aggressivamente front-loaded.

La frontiera efficiente dell'esecuzione

Per ogni λ\lambda si ottiene una traiettoria, un costo atteso E(λ)E(\lambda) e una varianza V(λ)V(\lambda). Facendo variare λ[0,)\lambda \in [0, \infty) si traccia una curva nel piano (V,E)(V, E) — la frontiera efficiente dell'esecuzione, in diretta analogia con Markowitz. È convessa e decrescente: meno varianza costa sempre più shortfall atteso, con rendimenti marginali fortemente decrescenti. Nel punto della frontiera selezionato da un dato λ\lambda, l'avversione al rischio è la pendenza (negativa) della tangente: λ=E/V\lambda = -\partial E / \partial V.

Frontiera efficiente del costo di esecuzione rispetto alla varianza, con la linea tangente che mostra lambda come pendenza

La frontiera riformula la domanda "quanto vale λ\lambda?" — a cui nessuno sa rispondere per introspezione — in "quale trade-off costo/rischio voglio?", a cui un desk può effettivamente rispondere. Tre modi pratici per scegliere il punto:

  1. Ragionamento a costo marginale. Percorrete la frontiera e chiedetevi: "spostandomi da questo punto al successivo, pago ΔE\Delta E dollari di costo atteso in più per rimuovere Δstd\Delta\text{std} dollari di deviazione standard dello shortfall — accetto questo scambio?" Il ginocchio della frontiera è di solito evidente entro un fattore 2, e la traiettoria è insensibile a λ\lambda a quella risoluzione.
  2. Budget di rischio. Fissate una deviazione standard massima accettabile dello shortfall (ad es. "l'1-sigma giornaliero della posizione residua deve restare sotto i 15 bps del nozionale") e prendete la traiettoria più economica che la soddisfa. Questo è un problema vincolato il cui moltiplicatore di Lagrange è λ\lambda.
  3. Targeting del tempo caratteristico. Scegliete direttamente θ=1/κ\theta = 1/\kappa ("questo ordine dovrebbe avere un'emivita di 90 minuti") e ricavate λ=η/(σ2θ2)\lambda = \eta/(\sigma^2\theta^2). È ciò che la maggior parte dei practitioner fa implicitamente quando imposta uno slider di "urgenza".

Un esempio numerico con valori che giustificheremo nella sezione di calibrazione. Vendete X=100X = 100 BTC a S_0 = \100{,}000,orizzonte, orizzonte T = 4h,h,\sigma = $600perBTCperper BTC per\sqrt{\text{h}}(circail3(circa il 3% di vol giornaliera),\eta = 1.0\ $\cdot\text{h}/\text{BTC},, \lambda = 10^{-6}\ $^{-1}$. Allora

κ=106×3.6×1051.0=0.6 h1,κT=2.4,θ1.7 h.\kappa = \sqrt{\frac{10^{-6} \times 3.6\times 10^{5}}{1.0}} = 0.6\ \text{h}^{-1}, \qquad \kappa T = 2.4, \qquad \theta \approx 1.7\ \text{h}.

Lo schedule ottimale vende 46.2 BTC nella prima ora (TWAP: 25). Costo temporaneo: \eta \int_0^T v(t)^2 dt \approx \3{,}290controcontro$2{,}500perilTWAP.Deviazionestandarddelloshortfall:per il TWAP. Deviazione standard dello shortfall:$53{,}000controcontro$69{,}300 per il TWAP. Quindi per 0.8 bps in più di costo atteso su un nozionale da \10M si riduce il rischio di shortfall del 23%. Questo è l'intero contenuto del modello in una frase: prezza l'assicurazione e vi lascia decidere se comprarla.

La traiettoria stessa è dieci righe di 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}")

Fate variare lam su np.logspace(-8, -4, 50) e plottate EE rispetto a V\sqrt{V} — quella è la vostra frontiera, e l'intera superficie decisionale sta su un unico grafico che potete consegnare a un risk committee.

Calibrazione: η\eta, γ\gamma, σ\sigma da dati Binance

Qui è dove il 90% delle implementazioni muore in silenzio. La formula della traiettoria è banale; i parametri no. Tre grandezze, tre problemi di stima diversi.

Grafici a dispersione di calibrazione: slippage rispetto al participation rate e variazione di prezzo rispetto al flusso netto degli ordini, da dati Binance

σ\sigma: quello facile

Volatilità assoluta per radice-ora, dai rendimenti del mid-price. Usate barre a 1 minuto e riscalate; a campionamenti più fini, il rumore di microstruttura (bid-ask bounce) distorce verso l'alto la varianza realizzata. Questa stima è solida — la vol è l'unico parametro che otterrete correttamente.

η\eta: impatto temporaneo dal book e dai trade

Due strade complementari. Strada A — percorrere il book L2. Dagli snapshot di profondità, calcolate il costo di uno sweep marketable ipotetico di dimensione qq: il VWAP dei livelli consumati meno il mid. Il fit di cost(q)ϵ+ηinstq\text{cost}(q) \approx \epsilon + \eta_{\text{inst}}\, q dà l'impatto istantaneo per BTC. Per convertirlo nell'η\eta basato sul ritmo del modello dovete assumere un tempo di ricostituzione del book Δtr\Delta t_r (dell'ordine di 10–60 s per BTCUSDT): negoziare al ritmo vv consuma vΔtrv \Delta t_r per ciclo di refresh, quindi ηηinstΔtr\eta \approx \eta_{\text{inst}} \Delta t_r. Questa assunzione — ricostituzione istantanea e completa su un orologio fisso — è esattamente la crepa da cui entra Obizhaeva-Wang; ne parliamo più avanti. Strada B — regredire lo slippage realizzato sul participation rate. Raggruppate il flusso aggressivo (taker) in bin da 1 minuto; per ogni bin, regredite il VWAP lato taker meno l'open-mid sul tasso di volume taker. La strada B misura ciò che il mercato ha effettivamente addebitato agli aggressori; la strada A misura ciò che il book in attesa addebiterebbe in questo momento. Quando differiscono di un fattore 3, fidatevi di B per il livello e di A per la forma intraday.

γ\gamma: impatto permanente tramite regressione in stile Kyle

Regredite le variazioni del mid-price sul flusso taker netto firmato su finestre di 5 minuti:

ΔS5m=γQnet+noise,Qnet=acquisti takervendite taker.\Delta S_{5m} = \gamma\, Q_{\text{net}} + \text{noise}, \qquad Q_{\text{net}} = \text{acquisti taker} - \text{vendite taker}.

Poi verificate che l'impatto non sia rientrato una finestra dopo — la componente non revertente è "permanente" alla vostra scala temporale di trading. Questa è di gran lunga la più rumorosa delle tre.

Codice funzionante, usando solo endpoint pubblici REST di 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")

Per la produzione, sostituite la singola pagina di aggTrades con qualche giorno di dump storici ed eseguite la regressione di γ\gamma su migliaia di bin, non su una manciata.

Perché la calibrazione su crypto è rumorosa, e cosa farci

Eseguite la regressione di γ\gamma su dati reali e otterrete un R2R^2 di pochi punti percentuali e un coefficiente che si sposta di un fattore 2–5 tra un giorno e l'altro. Non è un bug nel vostro codice. Le ragioni sono strutturali:

  • Endogeneità. Il flusso risponde al prezzo tanto quanto il prezzo risponde al flusso. I trader momentum comprano perché il prezzo è salito; una regressione OLS ingenua dei rendimenti sul flusso cattura la loro reazione e la attribuisce all'impatto. La soluzione pulita è usare i propri fill (esogeni per costruzione) — che si hanno solo dopo aver negoziato per un po'.
  • Concavità. L'impatto reale è concavo nella dimensione — empiricamente vicino a una radice quadrata (Almgren, Thum, Hauptmann e Li, 2005, "Direct estimation of equity market impact", hanno trovato un esponente vicino a 0.6; la stessa concavità è robusta anche nelle crypto). Fittare una retta a una funzione concava significa che η\eta e γ\gamma dipendono dall'intervallo di dimensioni nel campione. Calibrate ai participation rate a cui negozierete effettivamente.
  • Frammentazione e leadership dei derivati. BTCUSDT spot su Binance è una venue tra molte, e la price discovery avviene spesso sui perpetual. Il flusso che non vedete muove il prezzo su cui regredite, gonfiando il termine di rumore.
  • Dipendenza dal regime. L'η\eta misurato nella sessione asiatica non descrive l'apertura USA; l'impatto raddoppia più o meno quando la volatilità raddoppia. Calibrate per sessione, e ri-fittate almeno settimanalmente.

L'aspetto salvifico: la traiettoria è indulgente. κ1/η\kappa \propto \sqrt{1/\eta}, quindi un errore di un fattore 2 su η\eta sposta κ\kappa solo di 2\sqrt{2}, e la funzione di costo è piatta vicino all'ottimo. Ottenere η\eta corretto entro un fattore 2 e λ\lambda corretto entro un ordine di grandezza cattura già la maggior parte del miglioramento disponibile rispetto al TWAP. La precisione conta per le stime di costo pre-trade; la robustezza è sufficiente per la pianificazione.

Dove il modello si rompe, e gli articoli che lo correggono

Almgren-Chriss è un'impalcatura, e sapere esattamente quale trave è portante indica a quale estensione rivolgersi.

Impatto non lineare — Almgren (2003). "Optimal execution with nonlinear impact functions and trading-enhanced risk" (Applied Mathematical Finance 10, 1–18) rifà il programma con impatto temporaneo a legge di potenza h(v)=ηvαh(v) = \eta v^\alpha. Per l'esponente empiricamente favorito α1/2\alpha \approx 1/2 — la legge della radice quadrata — le traiettorie ottimali cambiano carattere: l'impatto concavo punisce le raffiche meno di quanto faccia l'impatto lineare, quindi gli schedule ottimali diventano più front-loaded a parità di λ\lambda. La struttura qualitativa (parametro di urgenza, frontiera efficiente) sopravvive; la formula sinh no.

Resilienza e il LOB — Obizhaeva e Wang (2013). "Optimal trading strategy and supply/demand dynamics" (Journal of Financial Markets 16(1), 1–32; il working paper circolava dal 2005) sostituisce la dicotomia temporaneo/permanente con un limit order book a profondità finita e impatto a decadimento esponenziale: il vostro trade consuma il book, e il book si ricostituisce al tasso di resilienza ρ\rho. L'assunzione di Almgren-Chriss "l'impatto temporaneo svanisce istantaneamente" è il limite ρ\rho \to \infty. La strategia ottimale cambia forma in modo drastico: un blocco di trade all'inizio, un blocco alla fine, e un tasso di negoziazione costante nel mezzo — i blocchi sfruttano il recupero del book. Se il vostro intervallo tra child order è paragonabile al tempo di ricostituzione della venue (nel crypto, da secondi a un minuto — spesso è così), siete in territorio Obizhaeva-Wang, non Almgren-Chriss, e l'artificio Δtr\Delta t_r nella calibrazione sopra è il vostro segnale d'allarme.

No-dynamic-arbitrage — Gatheral (2010). "No-dynamic-arbitrage and market impact" (Quantitative Finance 10(7), 749–759) chiede quali combinazioni di funzione di impatto istantaneo f(v)f(v) e kernel di decadimento G(t)G(t) sono internamente coerenti, ossia non ammettono strategie di round-trip con costo atteso negativo. I risultati sono netti: il decadimento esponenziale è compatibile solo con impatto lineare — combinare decadimento esponenziale con impatto a radice quadrata rende il modello sfruttabile per profitto tramite una sequenza di trade oscillante; l'impatto non lineare richiede decadimento a legge di potenza, con una disuguaglianza che lega i due esponenti (per impatto vδ\sim v^\delta e decadimento tγd\sim t^{-\gamma_d}, all'incirca γd+δ1\gamma_d + \delta \geq 1). Questo è l'articolo da leggere prima di innestare un fantasioso kernel di decadimento sul vostro modello di impatto: la maggior parte delle combinazioni ad hoc sono segretamente arbitraggiabili, il che in pratica significa che il vostro ottimizzatore scoprirà l'arbitraggio e produrrà schedule oscillanti assurdi. Se la vostra traiettoria "ottimale" alterna acquisti e vendite durante una pura liquidazione, avete violato Gatheral, non scoperto alpha.

I seguiti basati su ML. Due filoni di questa serie si costruiscono direttamente su questa impalcatura. Primo, l'esecuzione via reinforcement learning: una volta ammesso che l'impatto è non lineare, dipendente dallo stato e parzialmente osservabile, la forma chiusa scompare, e l'RL (dal paper di Q-learning del 2006 di Nevmyvaka, Feng e Kearns in poi) è un modo naturale per esplorare lo spazio delle traiettorie — ma ogni agente RL di esecuzione serio viene benchmarkato contro, e spesso inizializzato dalla, soluzione AC. Secondo, i modelli neurali di price impact: sostituire h(v)=ηvh(v) = \eta v con un funzionale appreso dello stato dell'order book, mantenendo sopra la logica di scheduling media-varianza. Nessuno dei due seguiti ha senso senza sapere esattamente cos'è il baseline lineare-gaussiano e perché ha quella forma.

Cosa portare a casa

Il modello è tre assunzioni, un'equazione alle differenze e un numero. Impatto permanente lineare (imposto dall'assenza di manipolazione), impatto temporaneo lineare (un'approssimazione attorno alla quale si calibra), rumore browniano aritmetico. L'ottimo bilancia la varianza di inventario contro il costo di impatto, l'intera strategia collassa nell'urgenza κ=λσ2/η\kappa = \sqrt{\lambda\sigma^2/\eta}, e il TWAP emerge come il caso degenere λ=0\lambda = 0 — che è il fatto singolarmente più utile del modello, perché trasforma "dovremmo fare TWAP su questo?" da questione di abitudine in un'affermazione verificabile sull'avversione al rischio. La calibrazione è il vero lavoro: σ\sigma è facile, η\eta è un gioco a fattore 2, γ\gamma è un progetto di ricerca, e la traiettoria perdona tutti e tre. Implementatelo in un pomeriggio; spendete il resto del mese sulla diagnostica della regressione.

Riferimenti bibliografici

  • 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.
Disclaimer: le informazioni fornite in questo articolo hanno solo scopo didattico e informativo e non costituiscono consulenza finanziaria, di investimento o di trading. Il trading di criptovalute comporta un rischio significativo di perdita.

Autori

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Resta un Passo Avanti al Mercato

Iscriviti alla nostra newsletter per approfondimenti esclusivi sul trading con IA, analisi di mercato e aggiornamenti sulla piattaforma.

Rispettiamo la tua privacy. Annulla l'iscrizione in qualsiasi momento.