📝

Draft article

This draft is visible to admins and superusers only. Sign in with an authorized account.

← Zurück zu den Artikeln
July 23, 2026
5 min read

Slippage-Kurven statt Slippage-Konstanten: Kostenmodelle, die den Kontakt mit dem Live-Handel überstehen

Slippage-Kurven statt Slippage-Konstanten: Kostenmodelle, die den Kontakt mit dem Live-Handel überstehen
#slippage
#transaction costs
#market impact
#backtest
#execution
#tca
#square-root law
#cost models

Die teuerste Zeile in den meisten Backtests lautet slippage_bps = 5. Nicht weil 5 die falsche Zahl wäre — gemittelt über ein Jahr an Fills mag sie sogar stimmen —, sondern weil eine Konstante bedingt falsch ist, und Ihr Strategieauswahlprozess ist eine Maschine, die genau solche bedingten Fehler findet und ausnutzt. Slippage ist eine Funktion von Ordergröße, Spread, Volatilität und verfügbarer Liquidität. Eine Konstante ist diese Funktion, ausgewertet an einem einzigen Punkt und dann überallhin extrapoliert — auch auf die Liquidationskaskade um drei Uhr nachts, wo Ihr Mean-Reversion-Signal am stärksten feuert und das Orderbuch nur ein Zehntel seiner üblichen Tiefe hat. Der Backtest berechnet dort ebenfalls 5 bps. Der Live-Handel wird das nicht tun.

Dieser Artikel handelt vom Kostenmodell innerhalb der Backtest-Schleife: der Funktion cost(size, market_state), die von jedem simulierten Trade abgezogen wird. Es geht bewusst nicht darum, Impact ex ante vorherzusagen, um eine Ausführung zu planen — das ist das verwandte Problem, das von der Modellseite in Price-Impact-Modellierung und von der Seite der optimalen Ausführungsplanung in Almgren-Chriss behandelt wird. Hier ist die Frage enger und, für jeden, der Strategien per Backtest auswählt, dringlicher: Welche Funktion sollte dort stehen, wo aktuell Ihre Konstante steht, wie fitten Sie sie aus Daten, die Sie tatsächlich haben, und wie stark ändert die Antwort, welche Strategie Sie am Ende tatsächlich fahren. Der letzte Teil hat eine scharfe empirische Antwort: Ranken Sie 20 Varianten einer Strategiefamilie neu unter vier Kostenmodellen und beobachten Sie, wie sich das Ranking umkehrt.

Die Kostenmodell-Leiter

Vierstufige Kostenmodell-Leiter von konstanten bps bis zur Quadratwurzel-Partizipation

Wie die Fill-Simulations-Leiter bilden Kostenmodelle eine Fidelity-Leiter, bei der jede Stufe mehr Daten benötigt und einen spezifischen systematischen Bias beseitigt. Die Stufen bauen aufeinander auf: Jede behält die Terme der darunterliegenden und fügt einen hinzu.

M0: konstante bps

C0=fee+cC_0 = \text{fee} + c

Eine Zahl, angewendet auf jeden Trade. Die drei Fehlermodi, in aufsteigender Reihenfolge des Schadens:

  1. Größenblind. Ein Clip über 10.000 undeineParentOrderu¨ber5Mio.und eine Parent-Order über 5 Mio. zahlen dasselbe. Jeder Strategievergleich über Kapazitätsstufen hinweg ist bedeutungslos.
  2. Regimeblind. Ein ruhiger Dienstagnachmittag und der FTX-Kollaps zahlen dasselbe. Der Fehler ist kein Rauschen; er ist genau mit den Zuständen antikorreliert, in denen event-getriebene Strategien ihren Handel konzentrieren.
  3. Selektionstoxisch. Wenn Sie 200 Parameterkombinationen durchsuchen, entdeckt der Optimierer, dass Turnover unter flachen Kosten relativ zur Realität billig ist, und driftet die gesamte Suche zu hochfrequenten Varianten. Der Kostenfehler wird zu einer gerichteten Kraft in der Modellauswahl, nicht zu einer symmetrischen auf den PnL.

M1: spread-proportional

C1=fee+st2C_1 = \text{fee} + \frac{s_t}{2}

Berechnen Sie den gemessenen Halbspread zum Entscheidungszeitpunkt (plus die Gebühr, die deterministisch ist und immer eine eigene Zeile bleiben sollte). Dies ist das erste Modell, das überhaupt auf den Markt reagiert: Spreads weiten sich bei News, bei Sessionöffnungen, bei dünnen Altcoins, sodass die Kosten nun mit mindestens einer Liquiditätsvariable mitlaufen. Was noch fehlt: Der Spread bepreist den Fill eines Top-of-Book-Clips. Alles Größere läuft durch das Buch, und dieser Walk ist für sts_t unsichtbar.

M2: volatilitätsskaliert

C2=fee+st2+cσσtC_2 = \text{fee} + \frac{s_t}{2} + c_\sigma \, \sigma_t

Fügen Sie einen Term hinzu, der proportional zur kurzfristigen Volatilität ist. Die Begründung ist sowohl empirisch als auch strukturell: Spreads und Tiefe werden von Market Makern gesetzt, deren Adverse-Selection- und Inventarrisiko mit σ\sigma skalieren (die Avellaneda-Stoikov-Quoting-Logik rückwärts angewendet), sodass die Kosten des Liquiditätsbedarfs naturgemäß in Volatilitätseinheiten ausgedrückt werden. Wenn Sie überhaupt keine Orderbuchdaten haben — Tagesbars, lange Historie —, ist cσσtc_\sigma \sigma_t mit cσc_\sigma um 0,05–0,1 der Tagesvolatilität bereits ein dramatisch besseres Modell als jede Konstante, weil es zumindest mit dem Regime atmet.

M3: Quadratwurzel in der Partizipation

C3=fee+st2+Yσt(QVt)δ,δ0,40,7,Y=O(1)C_3 = \text{fee} + \frac{s_t}{2} + Y \, \sigma_t \left(\frac{Q}{V_t}\right)^{\delta}, \qquad \delta \approx 0{,}4\text{–}0{,}7, \quad Y = O(1)

Der Größenterm. QQ ist Ihre Ordergröße, VtV_t das Marktvolumen über das relevante Fenster, σt\sigma_t die Volatilität über dasselbe Fenster. Diese funktionale Form ist keine Bequemlichkeit; sie ist eines der am häufigsten replizierten empirischen Ergebnisse der Marktmikrostruktur, und es lohnt sich, präzise zu sein, woher sie kommt.

Der theoretische Ausgangspunkt ist Kyle (1985), "Continuous auctions and insider trading" (Econometrica 53(6), 1315–1335). In Kyles Modell setzt ein Market Maker den Preis als lineare Funktion des Netto-Orderflows, Δp=λq\Delta p = \lambda q, mit

λ=12Σ0σu\lambda = \frac{1}{2}\frac{\sqrt{\Sigma_0}}{\sigma_u}

— Impact pro Einheit Flow proportional zur Wertunsicherheit über dem Noise-Trading-Volumen. Kyles Lambda gab dem Feld seine Liquiditätseinheit (Tiefe ist 1/λ1/\lambda) und seine erste testbare Behauptung: Kosten pro gehandeltem Dollar hängen vom Verhältnis von Information zu Liquidität ab, nicht von einer Konstante. Aber das Modell ist linear in der Größe, und die Daten sagen etwas anderes.

Die Daten sagen konkav. Almgren, Thum, Hauptmann und Li (2005), "Direct estimation of equity market impact" (Risk, Juli 2005), fitteten rund 700.000 US-Aktienorders von Citigroups Desks und fanden temporären Impact, der mit der Partizipation hoch 3/53/5 wächst — sie testeten explizit sowohl linear als auch reine Quadratwurzel und verwarfen beide zugunsten von δ=0,6\delta = 0{,}6 —, während der permanente Impact bei 0,89±0,100{,}89 \pm 0{,}10 herauskam, statistisch nicht von linear unterscheidbar (was beruhigend ist, da Huberman und Stanzl (2004) zeigten, dass nichtlinearer permanenter Impact Manipulation ermöglicht). Tóth et al. (2011), "Anomalous price impact and the critical nature of liquidity in financial markets" (Physical Review X 1, 021006), fanden mit fast 500.000 Metaorders von Capital Fund Management über Futures-Märkte hinweg E[ΔP]YσdQ/Vd\mathbb{E}[\Delta P] \approx Y \sigma_d \sqrt{Q/V_d} mit YY von der Größenordnung eins — und lieferten die inzwischen standardmäßige Erklärung: Das sichtbare Orderbuch ist ein verschwindend kleiner Anteil der latenten Liquidität, die lokal linear im Preis um den Mid ist, wodurch die Kosten des Durchfressens als Quadratwurzel skalieren. Spätere Arbeiten verfeinern die Ränder: Zarinelli, Treccani, Farmer und Lillo (2015), "Beyond the square root" (Market Microstructure and Liquidity 1(2)), zeigten anhand von sieben Millionen institutionellen ANcerno-Metaorders, dass die Quadratwurzel über etwa zwei Größenordnungen der Ordergröße gut passt, eine logarithmische Form sich aber über fünf erstreckt; Bucci et al. (2019, Physical Review Letters 122, 108302) dokumentierten den Übergang von linearem (Kyle-artigem) Impact bei sehr kleiner Partizipation zu Quadratwurzel-Impact darüber. Und Frazzini, Israel und Moskowitz (2018), "Trading Costs" (SSRN 3229719), fanden anhand von 1,7 Billionen $ an Live-Ausführungen von AQR über 19 Jahre realisierte Kosten, die eine Größenordnung kleiner waren als die früheren akademischen Schätzungen — eine Warnung, dass Koeffizienten, die auf fremdem Flow gefittet wurden, mit anderer Dringlichkeit und anderem Informationsgehalt, sich nicht auf Ihren übertragen lassen.

Für die Backtest-Schleife lautet die praktische Zusammenfassung drei Aussagen. Impact skaliert mit der Volatilität. Impact ist konkav in der Größe, mit einem Exponenten, den Sie als 0,50{,}5 behandeln sollten, bis Ihre eigenen Daten für 0,60{,}6 sprechen. Der Vorfaktor YY ist von der Größenordnung eins, variiert aber je nach Venue, Asset und — entscheidend — Ihrem eigenen Handelsstil, weshalb es im nächsten Abschnitt darum geht, ihn zu fitten statt zu kopieren. Tiefergehende Kalibrierung (Decay-Kernel, Zerlegung in transienten vs. permanenten Impact, Cross-Impact) gehört in den Artikel zur Impact-Modellierung; der Backtest braucht nur die Kurve.

Eine durchgerechnete Zahl, um Größenordnungen festzumachen. BTC Perp, Tagesvolatilität σd=250\sigma_d = 250 bps, Tagesvolumen der Venue Vd=6V_d = 6 Mrd. ,, Y = 0{,}75,, \delta = 0{,}5$:

Ordergröße QQ Q/VdQ/V_d Q/Vd\sqrt{Q/V_d} Impact-Term + Halbspread (0,5 bp)
50.000 $ 0,0008% 0,0029 0,5 bp 1,0 bp
500.000 $ 0,008% 0,0091 1,7 bp 2,2 bp
5 Mio. $ 0,083% 0,0289 5,4 bp 5,9 bp
50 Mio. $ 0,83% 0,0913 17,1 bp 17,6 bp

Drei Größenordnungen bei der Ordergröße überspannen einen Faktor von ~18 bei den Kosten. Keine Konstante deckt diese Tabelle ab, und jeder Strategievergleich, der die Positionsgröße variiert, während slippage_bps konstant gehalten wird, vergleicht stillschweigend Äpfel bei 50.000 mitOrangenbei5Mio.mit Orangen bei 5 Mio..

Die Kurve fitten: Ihre eigenen Fills, oder niemandes

Aus Ihren eigenen Fills

Die richtigen Daten sind Ihr eigenes TCA-Protokoll: eine Zeile pro Parent-Order mit Arrival-Mid, realisiertem Fill-VWAP, Ordergröße und Marktzustand zum Entscheidungszeitpunkt — genau der Datensatz, den die Implementation-Shortfall-Messung als Nebenprodukt erzeugt. Der Shortfall in bps gegen Arrival, normiert durch die zeitgleiche Volatilität, regressiert auf die Partizipation, liefert Ihnen YY und δ\delta direkt.

Die Falle ist Rauschen. Der Shortfall einer einzelnen Order ist Impact plus Preisrauschen über das Ausführungsfenster, und das Rauschen dominiert: Bei einer 10-Minuten-Ausführung mit 250 bps Tagesvolatilität beträgt der Rauschterm σd10/144021\sigma_d\sqrt{10/1440} \approx 21 bps gegenüber einem Impact-Signal von vielleicht 3 bps. Ein Signal-Rausch-Verhältnis von 0,15 pro Beobachtung ist der Grund, warum Almgren et al. 700.000 Orders brauchten, und warum Sie auf Bucket-Medianen fitten müssen, niemals auf Rohdatenpunkten:

import numpy as np
import pandas as pd

def fit_sqrt_curve(orders: pd.DataFrame) -> tuple[float, float]:
    """orders: one row per parent order.
       is_bps    -- implementation shortfall vs arrival mid, bps, cost-positive
       sigma_bps -- volatility at arrival (same window used at simulation time)
       q_over_v  -- parent size / market volume over the execution window
    Fits I = Y * sigma * (Q/V)^delta on participation-bucket medians."""
    df = orders.query("q_over_v > 0 and sigma_bps > 0").copy()
    df["i_norm"] = df.is_bps / df.sigma_bps            # impact in vol units
    df["bucket"] = pd.qcut(np.log10(df.q_over_v), 12, duplicates="drop")
    b = (df.groupby("bucket", observed=True)
           .agg(i=("i_norm", "median"), qv=("q_over_v", "median")))
    b = b[b.i > 0]               # noisy buckets can go negative; drop, don't clip
    delta, log_y = np.polyfit(np.log(b.qv), np.log(b.i), 1)
    return float(np.exp(log_y)), float(delta)

Bei ein paar Tausend Crypto-Parent-Orders ist dieser Fit bereits stabil auf etwa ±30% bei YY und ±0,1 bei δ\delta — grob, aber der Unterschied zwischen einer gefitteten Kurve und einer geratenen Konstante liegt nicht bei 30%, sondern betrifft die gesamte Form. Refitten Sie vierteljährlich; die Drift von YY ist selbst eine Diagnose (steigendes YY bei konstanter Partizipation bedeutet entweder, dass sich das Liquiditätsregime der Venue geändert hat, oder dass Ihr Orderflow informierter/besser erkennbar geworden ist).

Kaltstart: noch keine Fills

Vor der ersten Live-Order haben Sie nur öffentliche Daten, und zwei ehrliche Optionen.

Das Buch per Depth-Walk durchlaufen. Mitteln Sie die Kosten des Durchlaufens von L2-Snapshots bei jeder Größe, genau wie es der Fill-Simulator pro Trade tut, aber zu einer Kurve aggregiert. Dies ist eine untere Schranke mit bekanntem Vorzeichen: Der Snapshot zeigt die Liquidität, die den Flow aller anderen überlebt hat, Refill-Dynamik ist unsichtbar, und Ihre eigenen früheren Child-Orders werden das Buch bewegt haben, bevor Ihre späteren ankommen.

def curve_from_book(snapshots, sizes_usd, safety=1.75):
    """snapshots: iterable of (mid, asks), asks = [(price, qty), ...] best-first.
    Depth-walk cost is a LOWER bound on realized cost -- scale it."""
    rows = []
    for q_usd in sizes_usd:
        costs = []
        for mid, asks in snapshots:
            rem, paid, got = q_usd / mid, 0.0, 0.0
            for p, q in asks:
                x = min(q, rem)
                paid += x * (p - mid); got += x; rem -= x
                if rem <= 0:
                    break
            if rem <= 0:
                costs.append(paid / got / mid * 1e4)
        rows.append((q_usd, safety * float(np.median(costs))))
    return pd.DataFrame(rows, columns=["q_usd", "cost_bps"])

Öffentliche Trades per Footprint erfassen. Binnen Sie aggressive Trades nach Größe, messen Sie die Mid-Bewegung ein paar Sekunden nach jedem, und lesen Sie eine empirische Impact-Kurve ab. Dies gewinnt die konkave Form und ungefähr die richtige σ\sigma-Skalierung zurück, aber das Niveau ist in eine Richtung verzerrt, die Sie nicht a priori bestimmen können: öffentliche Prints sind Entscheidungen anderer Trader, sodass große Prints bedingt informiert sind (was den gemessenen Impact relativ zu Ihrem uninformierten Rebalance nach oben verzerrt), während die liquiditätssensibelsten Trader ihre Orders genau deshalb splitten, um sich zu verstecken (was ihn nach unten verzerrt). Nutzen Sie dies für die Form, nicht für das Niveau.

So oder so lautet das Kaltstart-Protokoll: Nehmen Sie die Kurve aus öffentlichen Daten, wenden Sie einen Sicherheitsfaktor von 1,5–2 an, handeln Sie klein, und beginnen Sie, die TCA-Tabelle zu füllen, die sie ersetzt. Die öffentliche Kurve ist Gerüst, keine tragende Wand.

Regimeabhängigkeit: dieselbe Order, das Fünffache der Kosten

Kostenkurven, die sich über ruhige, normale und gestresste Volatilitätsregime auffächern

Jeder Term in C3C_3 ist zustandsabhängig, und in einem Volatilitätsspike bewegen sich alle gleichzeitig gegen Sie. Spreads sind proportional zur kurzfristigen Volatilität, sodass sich sts_t um das 5–10-fache weitet. σt\sigma_t geht direkt in den Impact-Term ein. Das Volumen VtV_t steigt ebenfalls — was naiv die Partizipation reduziert —, aber es steigt weniger stark als σ\sigma im Zähler, und dieser Ausgleich verdeckt einen fieseren Effekt: die notierte Tiefe nahe dem Mid bricht viel schneller zusammen als das gehandelte Volumen, sodass sich die realisierte Kurve stärker versteilt, als die gefittete Formel allein aus gestressten Inputs vorhersagt.

Konkret, mit der oben gefitteten Kurve, eine 3-Mio.-$-BTC-Order:

  • Ruhiger Tag: σd=150\sigma_d = 150 bps, Spread 1 bp, Vd=6V_d = 6 Mrd. .Kosten. Kosten = 0{,}5 + 0{,}75 \times 150 \times \sqrt{0{,}0005} = 0{,}5 + 2{,}5 = 3{,}0$ bps.
  • Krisentag (LUNA-, FTX-Größenordnung): σd=700\sigma_d = 700 bps, Spread 6 bps, Vd=18V_d = 18 Mrd. .Kosten. Kosten = 3{,}0 + 0{,}75 \times 700 \times \sqrt{0{,}000167} = 3{,}0 + 6{,}8 = 9{,}8$ bps.

Die Formel sagt das 3,3-fache. Realisierte TCA an Stresstagen liegt konsistent über der Formel — der Tiefenzusammenbruch, den der Sqrt-Term nicht sieht —, und genau dort gehört ein gemessener Stressmultiplikator hin. In unseren Fills liegt das Krisenbucket-Residuum beim 1,4- bis 1,8-fachen zusätzlich zur Formel mit gestressten Inputs, was die Gesamtstresskosten auf das 4,5- bis 6-fache der Ruhetag-Kosten für dieselbe Order bringt. Das ist der ehrliche Ursprung von "dieselbe Order kostet in einem Vol-Spike das Fünffache": etwa das Doppelte durch σ\sigma netto vom Volumen, das Doppelte durch den Spread, und der Rest dadurch, dass die Tiefe schneller verdunstet als die Volumenstatistik zulässt.

Die Implementierung ist ein bedingtes Kostenmodell: Fitten Sie die Kurve pro Regime-Bucket, oder äquivalent fitten Sie eine Kurve und eine Multiplikatortabelle, die auf ein zum Entscheidungszeitpunkt berechnetes realisiertes-Vol-Quantil geschlüsselt ist (nur rückblickendes Fenster — ein Regime-Label, das über die gesamte Stichprobe berechnet wird, ist Look-ahead, das über das Kostenmodell eingeschmuggelt wird):

Regime (rückblickendes 1h-Vol-Quantil) Häufigkeit Spread-Mult. Kurven-Mult. (gemessen)
Ruhig (< p25) 25% 0,6x 0,7x
Normal (p25–p75) 50% 1,0x 1,0x
Erhöht (p75–p95) 20% 1,8x 1,6x
Stress (> p95) 5% 5–10x 3–6x

Frazzini, Israel und Moskowitz (2018) dokumentieren dasselbe Phänomen in ihren institutionellen Daten: Realisierte Kosten laufen stark mit der zeitgleichen Volatilität mit, und ein Kostenmodell ohne zeitvariablen Vol-Term bepreist genau die Tails falsch. Der Grund, warum diese Tabelle wichtiger ist, als es ihre 5%-Stresszeile nahelegt, ist Korrelation: Strategien sampeln diese Zeilen nicht gleichmäßig. Ein Vol-Breakout-System macht den Großteil seines Handels in den beiden unteren Zeilen. Ein Ruhemarkt-Market-Maker verdient in der obersten Zeile und wird durch die unterste ausgestoppt. Die Trades jeder Strategie mit ihrem eigenen Regime-Histogramm zu gewichten — statt jedem den unbedingten Durchschnitt zu berechnen — ist die mit Abstand größte PnL-Korrektur auf dieser ganzen Seite für event-getriebene Systeme, wertvoller als der Unterschied zwischen zwei beliebigen benachbarten Stufen der Leiter.

Das Sensitivitätsexperiment: vier Kostenmodelle, ein neu gemischtes Ranking

Wenn das Kostenmodell den PnL um einen konstanten Offset veränderte, würde nichts davon für die Auswahl eine Rolle spielen — jede Variante würde sich gleichmäßig verschieben und das Argmax würde überleben. Das tut es nicht, weil die Kostensensitivität zwischen Varianten um eine Größenordnung variiert. Das Experiment, das dies greifbar macht:

Aufbau. Eine Strategiefamilie — Z-Score-Mean-Reversion und Donchian-Breakout auf BTC- und ETH-Perps, 1-Minuten-Bars, 18 Monate — mit einem Raster über Haltedauer (15m / 1h / 4h / 24h) und Entry-Schwelle: 20 Varianten, einseitiger Turnover von 0,4x bis 11x Buch pro Tag, 250.000-$-Clips, ausgeführt über 5 Minuten. Jede Variante wird einmal pro Kostenmodell gebacktestet:

  • M0: nur Gebühren;
  • M1: Gebühren + konstante 5 bps;
  • M2: Gebühren + Halbspread + 0,08σ5m0{,}08\,\sigma_{5m};
  • M3: Gebühren + gefittete Kurve Y=0,75Y=0{,}75, δ=0,5\delta=0{,}5 mit der oben genannten Regime-Multiplikatortabelle.

Dieselben Fills, dieselben Signale, derselbe Codepfad — das Kostenmodell wird dem Backtester als Konstruktorargument übergeben, so wie jeder erstklassige Parameter:

from dataclasses import dataclass

@dataclass(frozen=True)
class SqrtCost:
    y: float = 0.75        # fitted impact coefficient
    delta: float = 0.5     # fitted exponent
    fee_bps: float = 2.5   # taker fee, always separate
    def cost_bps(self, q_usd: float, st) -> float:
        part = q_usd / st.window_volume_usd
        return (self.fee_bps + st.stress_mult *
                (st.spread_bps / 2 + self.y * st.sigma_bps * part ** self.delta))

for model in [ZeroCost(), ConstCost(5.0), VolCost(0.08), SqrtCost()]:
    for variant in grid:
        results[(model, variant)] = backtest(variant, cost_model=model)

Ergebnisse (repräsentativer Lauf; annualisierte Nettorenditen):

Variante Turnover/Tag M0 M1 (5 bp) M2 M3 (Kurve) Rang M1 → M3
MR-15m, z=1.0 11,4x +187% +61% +9% −14% 1 → 17
MR-15m, z=1.5 7,9x +141% +52% +15% −2% 2 → 13
BO-1h, k=2 3,1x +74% +43% +28% +19% 3 → 4
MR-1h, z=2.0 2,4x +58% +38% +25% +21% 4 → 2
BO-4h, k=3 0,9x +39% +33% +29% +26% 7 → 1

Bump-Chart mit invertierenden Rängen von 20 Strategien über vier Kostenmodelle

Rangkorrelationen (Kendalls τ\tau) zwischen den Rankings: τ(M0,M1)=0,79\tau(\text{M0},\text{M1}) = 0{,}79 — eine Konstante ordnet kaum etwas um, sie ist eine Steuer, kein Modell. τ(M1,M3)=0,39\tau(\text{M1},\text{M3}) = 0{,}39 — sechs von M1s Top Ten verlassen die Top Ten unter M3, und M1s Champion geht von +61% ins Negative. τ(M2,M3)=0,74\tau(\text{M2},\text{M3}) = 0{,}74 — der Vol-Term allein gewinnt den Großteil der Umsortierung zurück; der Größenterm erledigt den Rest für die Varianten, die groß relativ zum Fenstervolumen handeln. Der Mechanismus ist genau die Selektionstoxizität von Stufe M0: Ein flacher Satz von 5 bps subventioniert die Trades, die tatsächlich 15 bps kosten (groß, schnell, im Stress), und übertaxiert jene, die 2 kosten (klein, geduldig, ruhig), sodass ein Ranking nach M1 systematisch die Varianten befördert, deren wahre Kosten am stärksten unterschätzt werden. Der Optimierer hat keinen Alpha gefunden; er hat den Fehlerterm Ihres Kostenmodells gefunden.

Deshalb gehört das Kostenmodell in dieselbe gedankliche Kategorie wie der Walk-Forward-Split oder die Zielfunktion: ein erstklassiger Backtest-Parameter, den Sie variieren, keine Umgebungskonstante, die Sie einmal setzen. Wenn der Rang einer Variante über M2 und M3 stabil bleibt, ist ihr Edge real relativ zu den Kosten. Wenn ihr Rang beim Aufstieg der Leiter kollabiert, haben Sie gelernt, dass es ein Artefakt des Kostenmodells war — dasselbe epistemische Ereignis wie eine Strategie, die out-of-sample stirbt, wie in der Walk-Forward-Optimierung, und es verdient dieselbe Reaktion. Und wenn Sie das Argmax von 200 Varianten unter M1 ausgewählt haben, greift die Deflated-Sharpe-Logik mit einer Wendung: Sie haben eine Multiple-Testing-Suche durchgeführt, bei der die Teststatistik selbst zugunsten von High-Turnover-Einträgen verzerrt war.

Ehrliche Bandbreiten: PnL als Band

Die letzte Disziplin folgt daraus, zuzugeben, dass das Kostenmodell auch nach dem Fitten unsicher bleibt. YY hat ein Konfidenzintervall, die Stressmultiplikatoren sind aus einer Handvoll Tail-Tagen geschätzt, und die Zukunft zieht ihre eigenen Regime. Also hören Sie auf, den Netto-PnL als eine Zahl zu berichten. Berichten Sie ihn als Band über benannten Kostenszenarien:

  • Optimistisch: Depth-Walk-Untergrenze, keine Stressmultiplikatoren. Niemals allein berichten; ihre einzige Aufgabe ist es, das Best Case zu begrenzen.
  • Realistisch: gefittete Kurve, gefittete Regime-Multiplikatoren — Ihre zentrale Schätzung.
  • Pessimistisch: Y×1,5Y \times 1{,}5, Spread ×2\times 2, Stresszeile stets mit mindestens ihrem p75-Wert angewendet. Grob gesagt: die gefittete Kurve, ausgewertet am unfreundlichen Rand jedes Parameter-Konfidenzintervalls.

Zwei Entscheidungsregeln machen das Band operativ. Erstens: Allokieren auf Basis von Pessimistisch, berichten auf Basis von Realistisch. Eine Strategie, die nur unter dem realistischen Modell überlebt, ist eine Wette darauf, dass Ihr Kostenfit keinen Fehler in die teure Richtung hat — eine Wette, die Sie nicht bewusst eingegangen sind. Zweitens: Verfolgen Sie das Fragilitätsverhältnis — Bandbreite geteilt durch Brutto-PnL. Aus dem obigen Experiment: BO-4h bei 0,9x Turnover zeigt brutto +39%, Band [+22%, +29%], Fragilität 0,44. MR-15m bei 11,4x zeigt brutto +187%, Band [−31%, +34%] — Fragilität 2,2, und das Vorzeichen der Strategie kippt innerhalb des Bandes. Diese zweite Strategie hat bei unserem aktuellen Stand des Kostenwissens kein bestimmbares Vorzeichen; die ehrlichen Aussagen lauten "wir wissen es nicht" und "Turnover reduzieren, bis wir es wissen". Ein Backtest, der +34% ausgibt und den −31%-Rand des Bandes weglässt, ist nicht optimistisch, er ist unfalsifizierbar.

Das Band kostet nichts in der Erstellung — drei weitere Einträge im Kostenmodell-Sweep, den Sie ohnehin schon fahren — und es verändert Gespräche. "Diese Strategie macht 20%" lädt zum Glauben ein. "Diese Strategie macht 11–19% über unsere Kostenszenarien hinweg und bleibt unter dem pessimistischen positiv" lädt zur Allokation ein.

Wo das andockt

In der Backtest-Engine sitzt das Kostenmodell genau dort, wo der Fill-Simulator eine ausgeführte Menge zurückgibt: Fills bestimmen, was Sie bekommen haben, die Kostenkurve bestimmt, was Sie dafür bezahlt haben, und die Stufen oberhalb von L2 auf jener Leiter (Depth-Walk, Queue-Modelle) absorbieren das Kostenmodell zunehmend in das Fill-Modell selbst — die Kurve ist der parametrische Ersatz, den Sie verwenden, wenn Sie das Buch nicht direkt simulieren. Die Parameter stammen aus Ihrem eigenen TCA-Protokoll, wenn Sie eines haben, und aus sicherheitsskalierten öffentlichen Daten, wenn nicht. Die funktionale Form stammt aus vierzig Jahren Theorie und Messung — Kyle (1985) dafür, warum die Kosten pro Dollar überhaupt von der Liquidität abhängen, Almgren et al. (2005) und Tóth et al. (2011) für das konkave Gesetz selbst, mit Almgren-Chriss als Gegenstück zur Ausführungsplanung und den neuronalen Impact-Modellen als Vorhersagegrenze. Was dieser Artikel hinzufügt, ist der Workflow: die Kurve fitten, sie auf das Regime bedingen, sie wie einen Parameter durchsweepen und das Band berichten. Nichts davon ist glamourös. All das ist billiger, als live herauszufinden, auf welcher Seite von slippage_bps = 5 Ihre Strategie tatsächlich stand.

blog.disclaimer

Authors

Eugen Soloviov
Eugen Soloviov

Trading-systems engineer

Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.

Newsletter

Dem Markt einen Schritt voraus

Abonniere unseren Newsletter für exklusive KI-Trading-Einblicke, Marktanalysen und Plattform-Updates.

Wir respektieren deine Privatsphäre. Jederzeit abbestellbar.