Du skickade anteckningsboken till mig sent på söndagskvällen, och den har varit öppen på min andra skärm sedan dess. Tvärsnittsmomentum, de 150 Binance USDⓈ-M-perpetualerna med högst dollarvolym under 30 dagar, ombalansering varje vecka, lång de översta 10 procenten och kort de nedersta, 2021-01 till 2026-06. Sharpe 2.31, maximal nedgång 14.2 % och en kostnadsmodell som verkade ärlig: taker in, taker ut, finansiering periodiserad per intervall, en slippage-term som skalar med din storlek i förhållande till orderboken. Du gjorde de svåra delarna rätt. Sedan frågade du varför sex veckors papperstest har gått sidledes och om edge försvagats.
Den försvagades inte. Den fanns aldrig med i backtestet. Titta på cell 4:
info = requests.get(BASE + "/fapi/v1/exchangeInfo").json()
symbols = [s["symbol"] for s in info["symbols"]
if s["status"] == "TRADING" and s["quoteAsset"] == "USDT"]
Du anropade den endpointen i juni 2026 och använde svaret för att avgöra vad som gick att handla i mars 2021. Varje symbol på den listan hade överlevt till juni 2026, per konstruktion. Det är hela felet, och det är mer värt att rätta till än resten av kostnadsmodellen tillsammans.
Vad endpointen inte berättar
exchangeInfo har ingen historik. Ingen asOf-parameter, inget arkiv, ingen ändringslogg. Det är en ögonblicksbild av läget just nu, och Binance har aldrig lovat något annat. När ett kontrakt avnoteras tas dess post bort från svaret och tickern upphör att existera ur API:ets perspektiv. Binance har listat över 600 USDⓈ-M-perpetualer sedan 2019 och pensionerat långt fler än hundra av dem. BTS, COCOS, TOMO, RAY, FTT, SC – en lång svans av kontrakt från altcoinsäsongen 2021 som hade ett strålande kvartal och sedan tynade bort tills handelsplatsen drog in dem.
Fråga dig vilka namn en 30-dagars momentumskärm gillar. Inte BTC. Den gillar det som just tredubblats i en noteringsrusning och en Twitter-cykel. De här populationerna överlappar kraftigt med de kontrakt som senare avnoteras, och ditt universumfilter tog bort överlappningen.
Jag körde om din strategi mot vårt snapshotarkiv med ett punkt-i-tid-universum, samma signal och samma kostnader. Sharpe blev 0.74 och nedgången 31 %. Ungefär två femtedelar av gapet beror på avnoterade namn som du aldrig fick hålla. Ytterligare en fjärdedel beror på det omvända problemet, som är mer subtilt och som jag misstänker att du gillar ännu mindre.
Den andra änden av tidsmaskinen: symboler som ännu inte fanns
Din feature är avkastningen över 90 dagar. Ditt rullande fönster har min_periods=20, eftersom du ställde in det en gång för att slippa att uppvärmningsperioden slog ut urvalets första kvartal och sedan aldrig såg över det. Därför får ett kontrakt som noterades för 21 dagar sedan ett momentumvärde beräknat på tre veckors prisrörelser efter noteringen. Det hamnar i den översta decilen ungefär när noteringen gått bra och tas in i portföljen.
Den delen är kanske försvarbar. Här är det som inte är det: din dataleverantör fyllde i historiken för vissa av de här symbolerna med spot- eller indexdata från tiden innan perpetualen fanns, så några kontrakt har kline-historik som går längre tillbaka än deras egen onboardDate. Det kan du kontrollera på ungefär en minut. Koppla din pristabell till noteringsdatumen och räkna raderna före noteringen. I dina data finns det 41 symboler med staplar före noteringen, och en av dem bidrar sommaren 2023 med en uppgång på 6 % under en enda vecka i aktiekurvan, från en position i ett kontrakt som inte skulle finnas förrän nio dagar senare.
En tickers namn är ingen identifierare. Det är en etikett som handelsplatsen hyr ut, ibland två gånger.
Det för oss till namnbyten. MATICUSDT blev POLUSDT. FTMUSDT blev SUSDT vid en konvertering på 1:1. LUNA-situationen i maj 2022 lämnade efter sig en LUNCUSDT och senare en helt ny LUNAUSDT, vars tickerstam delas med något som förlorade mer eller mindre allt. Om din inläsare använder symbolsträngen som nyckel och sammanfogar de filer den hittar har du minst en tidsserie med ett avbrott som inte beror på en prisrörelse. Din momentum-feature kommer att läsa avbrottet som den starkaste signalen i tvärsnittet.
Allt annat som förändras under tiden
När du väl accepterar att symbolistan varierar över tid gäller samma resonemang för alla andra fält i svaret. Du använder dagens värden för allihop.
| Fält | Så förändras det | Vad som går sönder |
|---|---|---|
| status | TRADING → SETTLING → borta | Överlevnadsbias; påhittade exits till ett stängningspris som aldrig handlades |
| onboardDate | Nya noteringar varje vecka; saknas för döda symboler | Kontrakt handlas innan de existerar |
| tickSize / stepSize | Justeras när prisnivåerna förändras | Orderavrundning och limitpriser som skulle ha avvisats |
| minNotional | Höjs över tid på illikvida orderböcker | Små positioner som din live-router skulle neka |
| fundingIntervalHours | 8h i flera år, sedan 4h eller 1h för många symboler | Finansieringskostnaden blir fel med en faktor på 2–3× för precis de altcoins som din skärm håller |
| leverage brackets | Nivåer och underhållsmarginal har reviderats | Likvideringsmodellering och marginalkapacitet |
Finansieringsdelen slår hårdast i ditt fall. Din periodiseringsloop antar tre betalningar om dagen under hela historiken. En betydande del av altcoinportföljen gick över till finansiering var fjärde timme, och det är korta positioner i namn med hög finansiering som står för mycket av din simulerade PnL. Där har du inte bara ett avrundningsfel. Felet är en faktor.
Avnoteringen är en händelse, och du modellerar den inte
I din omkörning med punkt-i-tid-data gav jag strategin en generös exit. Verkliga avnoteringar följer ett schema: ett tillkännagivande, vanligtvis sju till fjorton dagar i förväg, sedan ett fönster där man bara får minska positioner och därefter tvångsavveckling till ett markpris. Tillkännagivandet är offentlig information som du kan agera på, så en hederlig simulering lämnar positionen vid stängning på tillkännagivandedagen. Men en typisk avnotering av en altcoin sker efter att priset redan fallit 10-20 % jämfört med föregående vecka. Orderboken är tunn, och slippage-termen måste ta hänsyn till att marknaden befinner sig i ett annat läge. Om din fyllningsmotor ger dig avvecklingspriset utan någon påverkan har du i tysthet gjort döende tillgångar möjliga att handla till verkligt värde.
Om du aldrig arkiverade exchangeInfo är du inte körd. Den offentliga dumpen på data.binance.vision/data/futures/um/monthly/klines/ har fortfarande kataloger för avnoterade symboler långt efter att API:et glömt dem. Lista katalogerna, så ger den första och sista månadsfilen per symbol ett användbart intervall för notering och avnotering utan någon dataleverantör. Det är en rekonstruktion, inte ett register, och den återskapar inte tick sizes eller finansieringsintervall. Men den talar om vilka symboler som fanns när, vilket täcker 80 % av det du behöver på måndag.
Det här vill jag att du bygger innan du rör signalen igen
- Ett cron-jobb som hämtar exchangeInfo från varje handelsplats du undersöker, varje dag, och skriver resultatet till objektlagring med datum som nyckel. Gzip-komprimerat tar det mindre än en halv megabyte. Tio år kostar dig knappt något i S3 och ger dig en forskningsmöjlighet som du inte kan köpa i efterhand.
- En tillgångsdatabas byggd från dessa snapshots: en rad per (venue, symbol, valid_from, valid_to) med hela fältuppsättningen. Jämför på varandra följande snapshots för att skapa den och behandla varje fältändring som en ny rad.
- En universumfunktion med en obligatorisk tidsstämpel som argument.
universe(ts), aldriguniverse(). Gör det omöjligt att välja något annat som standard, så att ingen, inte ens du själv i framtiden klockan 1 på natten, råkar använda överlevnadslistan. - En kontroll av data före noteringen i datainläsaren: ingen stapel får finnas före
onboard_tsminus en dag. Avbryt körningen, skicka ingen varning. - Ett stabilt internt instrument-ID som överlever namnbyten, med tickern som attribut i stället. Koppla POL och MATIC till samma ID och flagga redenomineringar så att kontinuitetslogiken kan vägra att sammanfoga serierna.
Gör det där och kör om. Min gissning är att du hamnar nära 0.74, som jag fick, och då blir den intressanta frågan om en Sharpe på 0.74 som inkluderar de döda namnen innehåller något som är värt att papperstesta. Kanske. Tvärsnittsmomentum i perpetualer är inte betydelselöst, och en del av det som återstår när du rättat universumet är äkta carry från kortsidan. Du kommer också att se att dina papperstester och ditt backtest börjar stämma överens, eftersom papperstestet alltid har körts med ett punkt-i-tid-universum. Det hade inget val.
P.S. Det här är ingen kryptosärprägel, bara mer påtagligt här. Aktieanalytiker har brottats med avnoteringsavkastning och återanvända tickers sedan CRSP började distribuera sådana data, och prediktionsmarknader drar det till sin spets: varje kontrakt löper ut av konstruktion, så universumet består bara av noteringar och avnoteringar. Om du någon gång flyttar den här skärmen till Kalshi, bygg tillgångsdatabasen först. Där finns ingen annan sorts historik.
← Alla inlägg


