Om 10:07 op een dinsdag signaleerde onze onderzoeksagent een kortetermijnkans met een bullish vooruitzicht in een index-ETF. Het onderliggende signaal was alledaags: de koers was weer boven het gemiddelde over 20 bars gekomen, de gerealiseerde volatiliteit nam af en voor de volgende sessie stond een macro-economische publicatie gepland. De voorgestelde transactie was een callspread met ongeveer twee weken tot afloop.
De backtest was er enthousiast over. De papieren strategie plaatste de order niet. Toen we de orders vergeleken, kwamen de signaaltijdstempels overeen en weken de koersen van de onderliggende waarde maar een paar cent af. De contracten verschilden: de backtest had de vrijdagexpiratie gekocht die er in de historische keten het best uitzag; het papieren proces selecteerde de eerstvolgende genoteerde expiratie, een week later.
Die afwijking kwam door een kalenderkoppeling. We behandelden ‘dagen tot afloop’ als een eigenschap van een datum en selecteerden vervolgens het contract waarvan de afloopdatum het dichtst bij het doel lag. In de historische gegevens stond een wekelijkse expiratie die pas na de datum waarop we testten was toegevoegd. De backtest had dus een toekomstig contract gebruikt, op een manier die op een onschuldige handigheid leek.
Eerst vermoedden we een tijdzonefout. Optie-expiraties zijn daar bijzonder gevoelig voor: de handelssessie eindigt in New York, tijdstempels van de beurs kunnen in UTC zijn opgeslagen en een datum op middernacht kan verschuiven als een pipeline die onzorgvuldig omzet. We controleerden het. De tijdstempels klopten. Het contract bestond die dinsdag simpelweg nog niet in het historische universum.
Dat was de eerste les: een historische optieketen heeft een point-in-time-noteringsuniversum nodig. De afloopdatum van een contract vertelt je wanneer het afloopt. Niet wanneer het werd genoteerd, wanneer het verhandelbaar werd of of je systeem het op dat moment had kunnen selecteren.
We bouwden de selectiestap opnieuw op rond de informatie die op het beslismoment beschikbaar was. Voor elk kandidaatcontract eisten we een noteringstijdstempel die niet later was dan het beslismoment, een geldige koers die niet ouder was dan onze versheidsdrempel en een handelssessie waarin de strategie een order kon indienen. We legden ook de volledige verzameling kandidaten vast voordat we die rangschikten. Dat laatste was belangrijk, want de oude backtest bewaarde alleen de winnaar; we konden niet zien of die vijf geschikte contracten had vergeleken of stilletjes uit een kalender had gekozen die toen nog niet bestond.
Vervolgens bekeken we de koers die was gebruikt om de spread te prijzen. De backtest had voor elk been afzonderlijk de meest recente koers genomen. De ask van de call was van 10:06:58; de bid van de short call was van 10:04:11. Volgens het ruime gegevensbeleid waren beide technisch gezien recent, maar de markt was ertussenin bewogen. Een spreadmidprijs op basis van niet-gelijktijdige benen kan een markt beschrijven die nooit heeft bestaan.
We pasten de koersregel aan: de tijdstempels van beide benen moeten hooguit twee seconden uiteenliggen en gekruiste markten of markten zonder omvang moeten worden afgewezen. Daardoor nam het aantal bruikbare historische waarnemingen af. De overgebleven waarderingen werden wel geloofwaardiger. Als er geen gesynchroniseerde koers was, markeerden we de kandidaat als niet beschikbaar in plaats van het gat met een verouderde prijs op te vullen.
Daarna volgde de rangschikkingsregel. De agent had de expiratie met de laagste genoteerde spreadkosten gekozen. Dat klinkt verstandig, totdat de spread maar één contract breed is en de koers verouderd. We maakten het doel expliciet: maximaliseer de verwachte opbrengst per eenheid afgebakend risico voor contracten die voldoen aan de minimumeisen voor koersomvang, versheid en notering. In dit voorbeeld had de dichtstbijzijnde geschikte expiratie een genoteerde breedte van $0.42 over beide benen, terwijl de latere expiratie een breedte van $0.31 had. Bij de keuze die goedkoper leek, stond er op het short-been ook maar één contract in het orderboek.
| Kandidaat | Toen al beschikbare expiratie? | Leeftijd koers | Weergegeven omvang short-been | Beslissing |
|---|---|---|---|---|
| Wekelijkse vrijdagexpiratie | Nee | Niet van toepassing | Niet van toepassing | Uitsluiten |
| Volgende vrijdag | Ja | 1.4 seconden | 18 contracten | Geschikt |
| Derde vrijdag | Ja | 9.8 seconden | 1 contract | Uitsluiten als verouderd en dun verhandeld |
We speelden het incident opnieuw af met deze regels. De backtest koos nu dezelfde expiratie als de papieren strategie en legde vast waarom de andere contracten werden afgewezen. De resulterende instap in de spread was $0.11 slechter dan de oorspronkelijke historische uitvoering. Dat betekende niet dat de strategie geen waarde had; het betekende dat het oude prestat cijfer een transactieselectie bevatte die het liveproces niet kon reproduceren.
Een kleine ergernis: beursnotaties van symbolen laten fouten met afloopdatums op problemen met gegevenskwaliteit lijken. We vonden een wekelijkse code van een dataleverancier die één teken verschilde van de maandelijkse code. In auditlogs bewaar ik nog steeds het ruwe symbool naast de genormaliseerde contractsleutel. Niet elegant, maar het heeft ons behoed voor overhaast vertrouwen in een nette koppeling.
Als je een optietest bouwt, bewaar dan bij elk beslismoment de volledige verzameling kandidaten, samen met de noteringsstatus, tijdstempels van koersen, omvang en afwijsreden van elk contract. Maak contractselectie daarna een deterministische functie van die momentopname. De keuze van een expiratie is onderdeel van de strategie. Als de backtest een contract kan zien dat het papieren proces niet kon zien, begint de vergelijking van signalen pas nadat het antwoord al is veranderd.
← Alle artikelen


