Fyra tal, alla uppmätta från vår egen paper-trading-stack, en strategi, 1-minuts BTCUSDT perpetual-signaler, 31 dagar och 1,418 ordrar. Median från bar-stängning till order bekräftad av börsen: 195 ms. 99:e percentilen: 2,970 ms. Median på de 1 % av minuterna med högst realiserad volatilitet: 840 ms. Och latenskonstanten som satt i backtest-konfigurationen under större delen av det föregående året: 0.
Tre av dessa tal är tråkiga. Alla vet att nollan är fel, alla ersätter den så småningom med något, och det där något är nästan alltid en konstant som någon har valt på känsla. 100 ms, 250 ms, "låt oss vara konservativa, 500." Det tal som faktiskt spelar roll är 840, eftersom det visar att din latens är en funktion av marknadsläget, och de marknadslägen där den skjuter i höjden är samma marknadslägen där din signal tror att den har hittat något.
Vart de 195 millisekunderna tar vägen
Här är hela budgeten, uppmätt steg för steg med monotona klocktidsstämplar vid varje hopp. Boxen är en AWS-instans i ap-northeast-1, samma region som handelsplatsens slutpunkter, vilket är ungefär så bra som en icke-colokaliserad retail-formad uppsättning blir.
| Steg | p50 | p95 | p99 |
|---|---|---|---|
| Bar-stängning → WS kline-stängd-händelse mottagen | 128 ms | 402 ms | 1,940 ms |
| Parsning + uppdatering av feature-tillstånd | 3 ms | 9 ms | 28 ms |
| Beslut: modellutvärdering + riskkontroller | 11 ms | 22 ms | 60 ms |
| Orderskick → börs-bekräftelse | 47 ms | 180 ms | 1,100 ms |
| End-to-end (uppmätt, inte summerad) | 195 ms | 690 ms | 2,970 ms |
Två saker att notera innan den intressanta delen. För det första adderas inte medianerna: 128 + 3 + 11 + 47 = 189, och den uppmätta totalmedianen är 195. Percentiler är inte additiva, och om du bygger din latensuppskattning genom att summera per-steg-p99:or får du 3,128 ms när det riktiga p99 är 2,970. Tillräckligt nära här, fullständigt fel när stegen är korrelerade åt andra hållet. Mät hela kedjan.
För det andra, titta på översta raden. Två tredjedelar av medianbudgeten går åt till att vänta på att börsen ska tala om att baren har stängts. Inte nätverk, inte din kod, inte orderdirigering. Handelsplatsen aggregerar trades till en kline, beslutar att minuten är över och skickar. Den pushen har en kö framför sig, och kön delas med alla andra prenumeranter på den strömmen.
De 840
Dela in var och en av dessa 1,418 ordrar efter realiserad volatilitet för minuten som producerade signalen, och fördelningen faller isär.
| Signalbar-volatilitetsfack | Ordrar | p50 total | p99 total |
|---|---|---|---|
| Bottenkvartil | 201 | 141 ms | 488 ms |
| Mellersta två kvartilerna | 796 | 183 ms | 1,210 ms |
| Topp-kvartil | 407 | 312 ms | 2,880 ms |
| Topp 1 % av alla minuter | 14 | 840 ms | 4,100 ms |
Varje steg försämras tillsammans, och det är därför det ackumuleras. Handelsplatsens aggregerings- och sändningskö matas av matching engine-belastning, så en minut med 11,000 trades i sig skickas senare än en minut med 600. Din egen process hanterar fler djupuppdateringar och fler trade-prints i samma fönster, så feature-uppdateringen som normalt tar 3 ms tar 28. REST-ordervägen konkurrerar med allas annans panik, och du börjar se enstaka 503-och-försök-igen som kostar dig en hel sekund på egen hand. Korrelationskoefficienten mellan signalbar-tradeantal och total latens i vårt urval var 0.41. Inte enorm. Tillräckligt för att förstöra en konstant.
Och strategierna som överlever en första gallring är, till övervägande del, de som handlar utbrott, vändningar, dislokationer, likvidationskaskader. De utlöses exakt i det fack där latensen är sämst. En momentumsignal som bara löser ut när minuten rörde sig 40 bps är en signal som har strukturellt arrangerat sig för att alltid serveras av den långsammaste versionen av din stack.
Vi lade en gång en dag på att jaga en 3.6-sekunders outlier som dök upp vid ungefär samma tid varje natt. Det var logrotate, copy-truncate på en 2 GB-fil på samma EBS-volym som processen skrev till, vilket blockerade event-loopen. Marknaden var oskyldig. Mät först, skyll sedan på mikrostruktur.
Vad det gör med en fyllning
Priset driver medan du väntar. På en slumpmässig minut var den genomsnittliga negativa rörelsen över vår median på 195 ms ungefär 1.1 bps mot signalens riktning. På topp-kvartil-minuterna vid 312 ms, 5.8 bps. På topp-1 %-minuterna vid 840 ms, ungefär 14 bps negativ drift innan ordern ens når boken.
På BTC-perps deltar spreaden knappt i detta: ett tick på en 84,000-kurs är 0.012 bps, så skadan är negativ drift snarare än korsningskostnad. Flytta samma strategi till en mid-cap-perp och vaknar den andra termen — top-of-book-spreaden i vårt urval gick från 1.4 bps i lugna minuter till 6.2 bps i topp-kvartilen, och djupet vid den nivån blev tunnare med mer än hälften. Du betalar driften och den bredare spreaden och det sämre djupet, allt på en gång, allt eftersom de delar orsak.
När vi spelade upp samma 31 dagar med per-bar villkorlig latens istället för en platt 200 ms försämrades backtestens genomsnittliga inträdespris med 3.1 bps, nästan helt koncentrerat till 9 % av traden. Backtest-mot-paper-inträdesprisavvikelsen föll från 4.2 bps till 0.9 bps. In-sample Sharpe för den strategin gick från 1.7 till 1.1, vilket är det ärliga talet och alltid har varit.
Vad ska du då faktiskt lägga in i konfigurationen
Inte en skalär. Vad vi kör nu:
- Sampla, sätt inte. Dra latensen för varje simulerad order från en empirisk fördelning villkorad på den barens egen aktivitet — tradeantal och absolut avkastning räcker, och båda finns redan i en standard-kline. Fitta den en gång per handelsplats per ordertyp, fitta om varje månad.
- Behåll svansen. Fitta inte en lognormal och anse det klart; p99 lever i återförsöksstormar och GC-pauser som ingen jämn fördelning återger. Vi använder de empiriska kvantilerna med en omsamplad svans över p95.
- Latens gäller även annulleringar. En stop-ersättning eller en hedge-annullering omfattas av samma fördröjning, och i snabba marknader tävlar din annullering med en fyllning. Om din simulator annullerar direkt är din riskmodell fiktion.
- Lägg till en färskhetsvakt och simulera den. Vår släpper varje signal vars bar är mer än 1.5 sekunder gammal vid ankomst. Det är ett verkligt beteende med verklig kostnad — det tar tyst bort trades, och det måste ta bort samma i backtesten.
- Kalibrera om mot paper. Paper-trading är där du får sanningen. Logga de fyra hopp-tidsstämplarna på varje order och jämför fördelningarna mot vad simulatorn antog, varje vecka.
Andra tillgångsklasser, samma sjuka. US-aktier: den konsoliderade tapen lägger till sin egen aggregeringsfördröjning ovanpå din mäklares, och den vidgas under meddelandetryck av samma strukturella skäl. Prediktionsmarknader: enbart REST-orderinmatning på de flesta handelsplatser, och vi har mätt sub-100 ms-medianer som går till flera sekunder när en resolutionshändelse inträffar och alla anländer samtidigt. Kryptooptioner: kursen du prisar från kan vara två sekunder gammal i exakt den minut den underliggande rörde sig.
Det allmänna felet är att behandla en executionsparameter som en oberoende konstant när den är en funktion av samma tillståndsvariabel som driver din signal. Avgifter beter sig; funding beter sig; latens gör det inte. Om du ska bära ett enda tal med dig från allt detta, bär kvoten: vårt p99 är femton gånger vår median, och vår signal anländer oproportionerligt nära p99-änden.
Ge dig ut och instrumentera de fyra hoppen. Det är ett eftermiddagsjobb och det kommer att berätta mer om din strategi än ytterligare en veckas parametersökning.
← Alla inlägg

