Om 10:14 UTC kocht een eenvoudige breakoutstrategie een crypto-perpetual nadat de prijs boven het hoogste punt van de afgelopen 20 minuten uitkwam. De backtest liet een uitvoering zien op $64,210. Dat getal stond in de data, het signaal had de juiste tijdstempel en de gesimuleerde order kwam op de volgende bar binnen. We stonden op het punt het een zuiver resultaat te noemen.
Toen legden we de instrument-ID’s naast elkaar. Het signaal kwam van de BTCUSDT-perpetual. De uitvoering kwam van een BTCUSD-inversecontract. Beide werden verhandeld rond $64,210 en beide waren liquide markten. Toch ging het om verschillende orderboeken, met verschillende prijzen, tickgroottes, diepte en kostenstructuren. De backtest had een markt in elkaar gezet waartoe geen enkele trader toegang had.
De strategie zelf was weinig bijzonder: instappen bij een slot boven het voortschrijdende hoogtepunt, uitstappen bij een slot onder het voortschrijdende dieptepunt, en elke positie afmeten op een vast bedrag aan risico in dollars. Het probleem kwam pas aan het licht toen we een preciezere vraag stelden dan “wat was BTC waard?” We vroegen: “wat had deze order op dat moment in dit specifieke contract kunnen kopen?”
De grafiek was al samengesteld voordat de strategie draaide
Met onze onderzoeksfeed konden we venues gemakkelijk vergelijken. De feed normaliseerde symbolen en toonde een geconsolideerde prijsreeks. Handig om de markt te bekijken, maar een slechte referentie voor de uitvoering. Een samengestelde reeks kan de beste prijs op verschillende beurzen tonen, terwijl de strategie maar naar één venue een order kan sturen.
Bij de uitbraak stond de hoogste koers van de geconsolideerde bar op $64,205. De laatste transactie van het geselecteerde contract was ondertussen al opgelopen tot $64,218. Tegelijkertijd toonde een gecachte quote voor het inversecontract nog een ask van $64,210. De simulator gebruikte de uitbraak uit de ene reeks en de aantrekkelijke ask uit de andere. Beide waarden waren echt. De combinatie ervan was fictief.
| Invoer | Wat de backtest gebruikte | Wat de order nodig had |
|---|---|---|
| Hoogste koers bij uitbraak | Geconsolideerde BTC-prijs | Prijsgeschiedenis van het geselecteerde contract |
| Referentie voor instap | Gecachte ask van inversecontract | Verse ask voor het verhandelde instrument |
| Uitvoeringshoeveelheid | Gevraagde positiegrootte | Hoeveelheid beschikbaar op elk prijsniveau |
Een rij in een marktdata-tabel kan compleet lijken terwijl de velden verschillende markten beschrijven. Een symboolalias bewijst niet dat twee instrumenten hetzelfde orderboek delen. De contract-ID, venue, noteringsvaluta en tijdstempel moeten samen worden doorgegeven tijdens het genereren van signalen en het uitvoeren van orders.
We speelden de order opnieuw af tegen het orderboek
We draaiden de instap opnieuw met de eigen beste ask van de geselecteerde perpetual en de orderboekupdates die op het beslismoment beschikbaar waren. De quote was vers, maar op het beste prijsniveau lag slechts 0.18 BTC. Onze gesimuleerde order was 0.50 BTC. De resterende 0.32 BTC zou tegen hogere asks zijn uitgevoerd.
De aangepaste instap was $21 per BTC slechter dan de getoonde uitvoeringsprijs, vóór kosten. Dat is een klein verschil voor één transactie. Over de hele test haalde de strategie echter het grootste deel van haar brutowinst uit een handvol snelle uitbraken. Toen we die instappen opnieuw afspeelden tegen de juiste orderboeken, daalde het brutoresultaat met 31%; taker-kosten en marktimpact drukten het resultaat nog verder.
We vonden ook twee gevallen waarin de quote van het beste prijsniveau pas na het beslismoment van het signaal binnenkwam. Een backtest die op de dichtstbijzijnde tijdstempel koppelt, kan ongemerkt een latere update kiezen. We koppelen nu terug in de tijd: de quote moet zijn waargenomen vóór de order werd verstuurd, en we leggen de ouderdom ervan vast. Is de meest recente bruikbare quote te oud, dan markeert de simulator de order als niet uitvoerbaar of past hij een expliciete regel voor verouderde data toe.
Wat een verhandelbare prijs vereist
Een slotkoers is nuttig om een signaal te berekenen. Daarmee staat nog niet vast dat een specifieke order tegen die prijs uitgevoerd had kunnen worden. Daarvoor moet de prijs bij het exacte instrument en de exacte venue horen, beschikbaar zijn op het aankomstmoment van de order en moet er voldoende volume aan de andere kant staan voor de gevraagde omvang. Als de data die vragen niet kan beantwoorden, is een bandbreedte of een ontbrekende uitvoering de eerlijke uitkomst, geen verzonnen exacte prijs.
We behielden de geconsolideerde reeks voor marktcontext en haalden die uit het uitvoeringstraject. Signalen verwijzen nu naar de eigen geschiedenis van het gekozen contract; orders worden opnieuw afgespeeld tegen het orderboek van dat contract, waarbij kosten en omvang worden toegepast nadat de uitvoering is berekend. Iets meer technisch werk, en een veel minder flatterende vermogenscurve.
Die uitbraak heeft echt plaatsgevonden. De backtest gaf haar simpelweg een betere markt dan de markt die de strategie had geselecteerd.
← Alle artikelen


