5. september 2026 · risiko

Din backtest blev aldrig likvideret: margin, mark price og gearingsgrænsen, du overså

Din backtest blev aldrig likvideret: margin, mark price og gearingsgrænsen, du overså

Sidste måned kom der en aktiekurve ud af en genereret strategi med et drawdown på 63%. Dybt, grimt og derefter en pæn genopretning i løbet af de næste 6 uger — den slags forløb, en analytiker studerer lidt og beslutter sig for kan overleves, hvis man skruer ned for positionsstørrelsen. Jeg kørte den igen gennem en margingmotor, der kender til vedligeholdelsesmargintrin. Kontoen blev likvideret på dag 41 midt i drawdownet, og alt efter dag 41 var fiktion.

Det her er den dyreste type backtestfejl, jeg kender, fordi den ikke forvrænger afkastet med nogle få basispoint. Den fjerner en absorberende tilstand fra simuleringen. En strategi, der kan gå i nul, og en strategi, der ikke kan, er to forskellige strategier, og en backtest, der aldrig kontrollerer marginen, kan ikke fortælle dig, hvilken af dem du har.

Her er 3 måder, jeg stadig ser det blive gjort forkert på.

Forkert måde 1: gearing som et tal, du ganger afkastet med

Den mest almindelige model. Du beregner en afkastserie ud fra dine signaler, beslutter dig for at handle med 10x gearing og ganger med 10. Nogle gange er modellen lidt mere avanceret — positionsstørrelsen er equity * leverage / price — men kontotilstanden er stadig bare en skalar, der går op og ned. Ingen marginkonto, intet loft over den nominelle værdi, ingen betingelse for, hvornår kontoen går ned.

Skaderne er subtile, og derfor slipper fejlen gennem review. Sharpe er skala-invariant, så dit nøgletal ændrer sig ikke, når du går fra 3x til 30x gearing, og analytikeren konkluderer, at gearing er et gratis håndtag, der bytter volatilitet for afkast. Maksimalt drawdown skalerer lineært og holder sig under 100% ved et aritmetisk tilfælde, fordi en serie af gangede afkast nærmer sig nul asymptotisk uden at krydse det. Gang en dag med -9% med 12, og du får -108% i den ærlige version og "-108%, men aktiekurven er stadig positiv" i den naive version, alt efter om du renters rente-beregner eller summerer. Jeg har set begge dele.

Det, der mangler, er, at gearing ikke anvendes på dit afkast. Den anvendes på din sikkerhedsstillelse, og sikkerhedsstillelsen er et begrænset beløb, som handelsplatformen overvåger hvert sekund. Når den falder under vedligeholdelseskravet, er positionen ikke længere din.

Tegn på fejlen: Hvis din simulering ikke kan ende med et totalt tab uanset gearing, modellerer den ikke gearing.

Forkert måde 2: en likvidationspris, der kun beregnes ud fra gearingen

Det næste niveau af sofistikering tilføjer et likvidationstjek, som regel sådan her: ved 20x udsletter en ugunstig bevægelse på 5% marginen, så likvidér ved indgangspris × 0.95 for en long-position. Enkelt, intuitivt og forkert på 4 forskellige måder på én gang.

Handelsplatforme for perpetual futures bruger ikke din gearingsindstilling til at afgøre, hvornår det er slut. De bruger en vedligeholdelsesmargin, der stiger trinvist med positionens nominelle værdi, baseret på en trintabel. Omtrent sådan ser BTCUSDT USDⓈ-M ud; niveauerne ændres, når platformene reviderer dem:

Positionens nominelle værdi (USDT)VedligeholdelsesmarginMaks. gearing
0 – 50,0000.40%125x
50,000 – 600,0000.50%100x
600,000 – 3,000,0001.00%50x
3,000,000 – 12,000,0002.50%20x
12,000,000 – 70,000,0005.00%10x

Den ugunstige bevægelse, du kan tåle på en isoleret long-position, er altså omtrent 1/L − MMR, ikke 1/L. Ved 20x i det andet trin er den 5% − 0.5% = 4.5%. En halv procent lyder som afrunding. På BTC til 84,000 er det 420 dollars i pris, og i en voldsom time er 420 dollars forskellen på en wick, der rammer din position, og en, der ikke gør. Hver wick er et møntkast, og du har givet dig selv en fordel på dem alle.

Så er der gebyrerne. Taker-gebyret ved indgang trækkes fra din margin, så snart du får fyld: 0.045% af en nominel værdi på 500,000 er 225 USDT mod en margin på 25,000, hvilket flytter likvidationsprisen, før positionen overhovedet har gjort noget. Funding gør det samme løbende, og på gearet nominel værdi er effekten meget større, end analytikere forventer:

4.55%faktisk ugunstig bevægelse før likvidation ved 20x, inkl. indgangsgebyr
0.60%dagligt fundingtab på margin ved 20x, 0.01%/8h
18%af marginen tabt i en stille måned

En position, der ikke gør noget i 30 dage — ingen ugunstig bevægelse, ingen handler — har brugt næsten en femtedel af sin sikkerhedsstillelse og rykket likvidationsprisen mærkbart tættere på. Den tredje og fjerde fejlretning: trinnet ændrer sig, når du skalerer ind, så en position, der starter i trinnet på 0.5% og bliver øget til trinnet på 1.0%, får en dårligere likvidationspris end den, du beregnede ved indgangen; og cross margin samler sikkerhedsstillelsen på tværs af positioner, så din BTC-longpositions overlevelse afhænger af, hvad din ETH-shortposition gør. Hvis du simulerer cross margin som et sæt uafhængige, isolerede positioner, har du vendt korrelationsstrukturen på din egen konto på hovedet.

Forkert måde 3: at afvikle likvidationen til den forkerte pris, på det forkerte tidspunkt og med det forkerte fill

Lad os sige, at du fandt det rigtige udløsningsniveau. Så melder spørgsmålene sig: Hvilken pris krydser det, hvornår kontrollerer du det, og hvilken pris får du fyldt til?

Likvidation udløses af mark price, som er et indeks over flere spotplatforme med et udglattet basisled, bevidst konstrueret til at modstå en wick på én enkelt platform. Dit stop-loss udløses sandsynligvis af den senest handlede pris, alt efter hvordan du har konfigureret det. De to tal er uenige præcis, når det betyder mest. Under en kaskade kan perpetual-futures-kontraktens seneste pris ligge 1–2% under mark price i adskillige ti sekunder. En backtest, der bruger samme OHLCV-lavpunkt til både stop og likvidation, modellerer en handelsplatform, der ikke findes.

Begge fejl er til stede her, og de udligner ikke hinanden. Bruger du den seneste pris, likviderer du på wicks, som platformen ignorerede. Bruger du mark price, overser du tilfælde, hvor selve mark price har flyttet sig — en afvigelse i indekset på en spotplatform er en reel måde at blive likvideret på til en pris, der aldrig blev handlet på den perpetual futures-kontrakt, du handlede.

Så er der fyldet. Naive motorer lukker positionen til likvidationsprisen og bogfører tabet, som om det var et stop. Det, der faktisk sker, er, at likvidationsmotoren overtager positionen til konkursprisen — niveauet, hvor din margin er præcis nul, og som er dårligere end udløsningsprisen — og derudover opkræves et likvidationsgebyr, som afhænger af trinnet og ligger omkring 1% af den nominelle værdi i de lavere trin. Ved 20x svarer 1% af den nominelle værdi til 20% af din resterende margin. Hvis motoren får fyld under konkursprisen, dækker forsikringsfonden forskellen; på nogle platforme rammer et socialiseret tab den profitable side af ordrebogen, hvis fonden er tømt. Dit realiserede tab er ikke drawdownet frem til likvidationsprisen. Det er større, og tillægstabet er størst netop på de dage, hvor ordrebogen var tynd nok til at gøre det værst.

Og spørgsmålet om timing fra intrabar-mekanikken gør sig gældende her med større konsekvenser end normalt. Hvis en 1-minute-bar indeholder både dit take-profit-niveau og dit likvidationsniveau, bogfører en backtest, der tjekker exits før margin, gladeligt gevinsten. Handelsplatformen kontrollerer marginen ved hver opdatering af mark price, omtrent én gang i sekundet, før alt andet, du måtte ønske skulle ske.

Hvad motoren skal holde styr på i stedet

Intet af det her behøver være avanceret. Det skal have tilstand. Kontoen er et objekt med en saldo, ikke en afkastserie, og hver bar opdateres den i den rækkefølge, handelsplatformen ville bruge:

  1. Wallet-saldo og urealiseret PnL hver for sig. Marginforholdet er vedligeholdelsesmargin divideret med marginsaldoen, og marginsaldoen inkluderer urealiseret PnL. Hvis man slår dem sammen, ser en tabsgivende position ud til at have bedre sikkerhedsstillelse, end den faktisk har.
  2. Trintabellen for hvert symbol, versionsstyret efter dato. Trin bliver revideret. En backtest fra 2023, der køres med 2026-trin, indebærer subtil look-ahead-bias — som regel en fordel, fordi platformene generelt har lempet kravene til de største aktiver over tid.
  3. En serie af mark price, ikke kun kline-data. Hvis du ikke kan skaffe historik for mark price, så skriv det i resultaterne, og brug en konservativ proxy. Erstat aldrig stiltiende med den seneste pris.
  4. Marginen kontrolleres først i barens hændelsesrækkefølge, før stops, mål, signaler eller rebalancering.
  5. Fyld til konkursprisen plus likvidationsgebyret, hvor gebyrsatsen hentes fra samme trinrække som MMR.
  6. En absorberende sluttilstand. Når egenkapitalen når nul, slutter kørslen. Ingen nulstilling af beregningsgrundlaget, ingen "antag, at traderen indskyder flere penge", ingen fortsættelse af serien med en ny nominel værdi.

Det sidste punkt giver anledning til flest diskussioner. Nogen påpeger altid, at et rigtigt desk ville indskyde mere sikkerhedsstillelse, så det er urealistisk strengt at afslutte simuleringen. Måske. Men "den her strategi virker, hvis du bliver ved med at skyde penge ind, efter den er brudt sammen" er en påstand, der bør formuleres præcis sådan og testes bevidst med indskuddene som en eksplicit inputværdi, i stedet for at blive smuglet ind som standard. Når man skriver det ærligt ned, opdager de fleste, at det ikke var det, de mente.

Den praktiske gevinst ved det hele: Når du kører den samme strategi på papir mod den live handelsplatform, bør marginforholdet, som platformen rapporterer, og det, din simulator beregner, følge hinanden inden for 1 eller 2 basispoint hele dagen. Den overensstemmelse kan kontrolleres hvert minut på hver åben position, helt gratis. Det er den billigste paritetstest i hele systemet, og næsten ingen kører den — og når de to tal afviger, har handelsplatformen ret, og du har en fejl, som er værd at finde, før drawdownet finder den for dig.

perpetual futuresgearinglikvidationmargingmotorbacktesting
← Alle indlæg