5 september 2026 · risk

Din backtest blev aldrig likviderad: marginal, marknadspris och hävstångsgränsen du missade

Din backtest blev aldrig likviderad: marginal, marknadspris och hävstångsgränsen du missade

Förra månaden kom en aktiekurva från en genererad strategi med en nedgång på 63%. Djup, ful och sedan en stadig återhämtning under de följande 6 veckorna — den sortens kurva som får en forskare att kisa och tänka att den går att överleva om man minskar positionsstorleken. Jag körde den igen genom en marginalmotor som känner till underhållsmarginalnivåer. Kontot likviderades dag 41, mitt i nedgången, och allt efter dag 41 var fiktion.

Det här är den dyraste typen av backtestbugg jag känner till, eftersom den inte förvränger avkastningen med några baspunkter. Den raderar ett absorberande tillstånd ur simuleringen. En strategi som kan gå till noll och en strategi som inte kan det är olika strategier, och ett backtest som aldrig kontrollerar marginalen kan inte säga vilken av dem du har.

Här är 3 sätt jag gång på gång ser det göras fel.

Fel sätt 1: hävstång som ett tal du multiplicerar avkastningen med

Den vanligaste varianten. Du beräknar en avkastningsserie från dina signaler, bestämmer dig för att köra den med 10x hävstång och multiplicerar. Ibland är det lite mer sofistikerat — positionsstorleken är equity * leverage / price — men kontotillståndet är fortfarande bara en skalär som går upp och ner. Ingen marginalbalans, ingen gräns för nominellt värde, inget villkor för när det tar slut.

Skadan är subtil, vilket är anledningen till att den passerar granskning. Sharpe är skaleringsinvariant, så huvudtalet ändras inte när du går från 3x till 30x hävstång, och forskaren drar slutsatsen att hävstång är ett gratis reglage som byter volatilitet mot avkastning. Maximal nedgång skalar linjärt och stannar under 100% av en aritmetisk tillfällighet, eftersom en serie multiplicerade avkastningar närmar sig noll asymptotiskt utan att någonsin passera den. Multiplicera en dag med -9% med 12 så får du -108% i den rättvisande versionen och ”-108%, men aktiekurvan är fortfarande positiv” i den naiva, beroende på om du räknade med ränta på ränta eller summerade. Jag har sett båda.

Det som saknas är att hävstång inte tillämpas på avkastningen. Den tillämpas på ditt säkerhetskapital, och säkerhetskapitalet är en ändlig mängd som handelsplatsen bevakar varje sekund. När det sjunker under underhållskravet är positionen inte längre din.

Varningssignalen: om din simulering inte kan ge en total förlust vid någon hävstångsnivå, modellerar den inte hävstång.

Fel sätt 2: ett likvideringspris som enbart beräknas utifrån hävstången

Nästa nivå av sofistikering lägger till en likvideringskontroll, vanligtvis ungefär så här: vid 20x utplånar en ogynnsam rörelse på 5% marginalen, så likvidera vid ingångspriset × 0.95 för en lång position. Enkelt, intuitivt och fel på 4 olika sätt samtidigt.

Handelsplatser för eviga terminer använder inte din hävstångsinställning för att avgöra när det är slut. De använder en underhållsmarginalsats som ökar stegvis med positionens nominella värde, enligt en nivåtabell. Ungefärlig struktur för BTCUSDT USDⓈ-M, som ändras när handelsplatserna uppdaterar den:

Positionens nominella värde (USDT)UnderhållsmarginalsatsMaximal hävstång
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 ogynnsamma rörelse du kan tåla med en isolerad lång position är alltså ungefär 1/L − MMR, inte 1/L. Vid 20x i den andra nivån är den 5% − 0.5% = 4.5%. En halv procent låter som avrundning. På BTC vid 84,000 är det 420 dollar i pris, och under en våldsam timme är 420 dollar skillnaden mellan en svans som tog ut dig och en som inte gjorde det. Varje svans blir ett myntkast, och du har viktat dem alla till din fördel.

Sedan har vi avgifterna. Taker-avgiften vid inträde dras från marginalen så fort din order fylls: 0.045% på ett nominellt värde på 500,000 är 225 USDT från en marginalbalans på 25,000, vilket flyttar likvideringspriset innan positionen ens hunnit göra något. Finansieringen gör samma sak kontinuerligt, och på ett nominellt värde med hävstång är effekten mycket större än forskare brukar vänta sig:

4.55%faktisk ogynnsam rörelse som krävs för likvidering vid 20x, inkl. inträdesavgift
0.60%daglig finansieringskostnad på marginalen vid 20x, 0.01%/8h
18%av den marginalen försvunnen under en stillastående månad

En position som inte gör något på 30 dagar — ingen ogynnsam rörelse, inga affärer — har förbrukat nästan en femtedel av sitt säkerhetskapital och flyttat likvideringspriset märkbart närmare. De 2 återstående felen är att nivåerna ändras när du ökar positionen, så en position som börjar i nivån 0.5% och snittas upp till nivån 1.0% får ett sämre likvideringspris än det du räknade fram vid inträdet, och att cross margin samlar säkerhetskapitalet från flera positioner, så din BTC-långpositions överlevnad beror på vad din ETH-kortposition gör. Om du simulerar cross margin som en uppsättning oberoende isolerade positioner har du vänt upp och ner på korrelationsstrukturen i ditt eget konto.

Fel sätt 3: att fastställa likvideringen utifrån fel pris, vid fel tidpunkt och med fel fyllnadspris

Säg att du fick utlösningsnivån rätt. Då återstår frågorna: vilket pris passerar den, när kontrollerar du och vilket pris får du ordern fylld till?

Likvidering utlöses av marknadspriset, ett index från flera spotmarknader med en utjämnad basiskomponent, utformat för att stå emot en svans på en enskild handelsplats. Din stop-loss utlöses förmodligen av senast betalt pris, beroende på hur du har ställt in den. De här 2 priserna skiljer sig åt precis när det betyder mest. Under en likvideringskaskad kan det senast betalda priset för den eviga terminen avvika 1–2% nedåt från marknadspriset i tiotals sekunder. Ett backtest som använder samma OHLCV-lägsta för både stop-loss och likvidering modellerar en handelsplats som inte finns.

Båda felen förekommer här och de tar inte ut varandra. Använder du senast betalt pris likvideras du på svansar som handelsplatsen ignorerade. Använder du marknadspriset missar du fallet där själva marknadspriset rörde sig — en indexavvikelse på en spotmarknad är ett verkligt sätt att bli likviderad till ett pris som aldrig noterades på den eviga termin du handlade.

Sedan har vi fyllnadspriset. Naiva motorer stänger positionen till likvideringspriset och bokför förlusten som om den vore en stop-loss. I verkligheten tar likvideringsmotorn över positionen vid konkurspriset — nivån där marginalen är exakt noll, sämre än utlösningsnivån — och tar dessutom ut en likvideringsavgift som beror på nivån och ligger runt 1% av det nominella värdet på de lägre nivåerna. Vid 20x är 1% av det nominella värdet 20% av den återstående marginalen. Om motorn fyller under konkurspriset täcker försäkringsfonden mellanskillnaden. På vissa handelsplatser når en socialiserad förlust in på den lönsamma sidan av orderboken om fonden är tömd. Din realiserade förlust är större än nedgången fram till likvideringspriset, och överskottet är som störst just de dagar då orderboken var tunn nog att göra utfallet som värst.

Frågan om tidpunkt i baren, från mekaniken för intrabar-händelser, får här ännu större konsekvenser än vanligt. Om en 1-minutsbar innehåller både din take-profit och din likvideringsnivå kommer ett backtest som kontrollerar utträden före marginalen glatt att bokföra vinsten. Handelsplatsen kontrollerar marginalen vid varje uppdatering av marknadspriset, ungefär en gång i sekunden, före allt annat du hade tänkt skulle hända.

Vad motorn måste hålla reda på i stället

Inget av det här behöver vara komplicerat. Det behöver vara tillståndsbaserat. Kontot är ett objekt med ett saldo, inte en avkastningsserie, och varje bar uppdateras det i den ordning handelsplatsen skulle använda:

  1. Plånbokssaldo och orealiserad PnL, separat. Marginalkvoten är underhållsmarginalen delad med marginalbalansen, och marginalbalansen inkluderar orealiserad PnL. Om du blandar ihop dem ser en position med förlust ut att ha bättre täckning än den faktiskt har.
  2. Nivåtabellen för varje symbol, versionshanterad per datum. Nivåerna uppdateras. Ett backtest från 2023 som körs mot nivåer från 2026 innebär en subtil framåtblickningsbias — oftast till din fördel, eftersom handelsplatser i allmänhet har lättat på kraven för större tillgångar med tiden.
  3. En serie för marknadspriset, inte bara kursstaplar. Om du inte kan få fram historik för marknadspriset ska du säga det i resultaten och använda en försiktig proxy. Ersätt aldrig i tysthet med senast betalt pris.
  4. Marginalkontrollen först i barens händelseordning, före stop-loss, målpriser, signaler och ombalansering.
  5. Fyllningar till konkurspris plus likvideringsavgiften, med avgiftssatsen hämtad från samma nivåpost som MMR.
  6. Ett absorberande sluttillstånd. När eget kapital når noll avslutas körningen. Ingen ny bas, inget ”anta att handlaren skjuter till pengar”, ingen fortsättning av serien från ett nytt nominellt värde.

Det är den sista punkten som brukar leda till flest diskussioner. Någon påpekar alltid att en verklig handelsdisk skulle sätta in mer säkerhetskapital, så att avsluta simuleringen är orealistiskt hårt. Kanske. Men ”den här strategin fungerar om du fortsätter att mata in pengar efter att den har sprängt kontot” är ett påstående som bör uttryckas just så och testas med avsikt, med insättningarna som en uttrycklig indata, i stället för att smygas in som standard. När man skriver det så ärligt upptäcker de flesta att det inte var vad de menade.

Den praktiska vinsten med allt det här: när du kör samma strategi på papper mot handelsplatsen i realtid ska marginalkvoten som börsen rapporterar och den din simulator beräknar följa varandra med högst 1 eller 2 baspunkters skillnad, hela dagen. Den överensstämmelsen går att kontrollera varje minut för varje öppen position, helt gratis. Det är det billigaste paritetstestet i hela stacken, och nästan ingen kör det — och när de 2 talen glider isär har börsen rätt, och du har en bugg värd att hitta innan nedgången hittar den åt dig.

eviga terminerhävstånglikvideringmarginalmotorbacktestning
← Alla inlägg