Drücken Sie ESC, um zu schließen

Order Book vs AMM: Marktmikrostruktur & HFT-Arbitrage

Falls du immer noch glaubst, dass ein Trade an der Börse einfach nur ein Klick auf den „Buy“-Button ist, nach dem irgendwelche Magie passiert – ich habe News für dich. Auf Mikrosekunden- und Millisekunden-Ebene ist der Markt ein gnadenloses Schlachtfeld: Liquidität shiftet permanent zwischen verschiedenen Zuständen, während Ausführungsgeschwindigkeit und die Anatomie des Liquidity Pools darüber entscheiden, wer den Profit einfährt und кто für Slippage sowie toxic Flow blechen muss.

Im zentralisierten Trading (TradFi und CEX) regiert das Orderbuch. Im DeFi-Space hat sich der AMM als Standard etabliert. Schaut man jedoch auf das High-Frequency-Trading-Level (HFT), ist der Unterschied nicht bloß technischer Natur – er verändert die Mechanik von Preisbildung, Arbitrage und Orderausführung fundamental.

Werfen wir einen Blick unter die Haube beider Systeme: Wie funktioniert die Liquiditätsmechanik wirklich, wo verstecken sich implizite Kosten und wie lässt sich dieses Wissen in der Praxis nutzen?

1. Anatomie des L2/L3-Orderbuchs: Wie Liquidität wirklich aussieht

Die meisten Retail-Trader sehen nur das L2-Orderbuch: aggregierte Volumina auf den jeweiligen Preis-Leveln. HFT-Algorithmen und Institutionelle arbeiten hingegen mit L3 (Order-by-Order) – einem reinen Rohdatenstream, in dem jedes Event eine eindeutige ID (order_id), einen exakten Zeitstempel und eine feste Position in der Queue besitzt.

Market Data
 

Das Price-Time-Priority-Prinzip (FIFO)

In einer klassischen Matching Engine werden Orders strikt nach Priorität gematcht:

  • Preis (der beste Preis gewinnt).
  • Zeit (bei gleichem Preis wird die ältere Order zuerst ausgeführt).

Durch diese zeitliche Warteschlange entstehen zwei zentrale Effekte in der Marktmikrostruktur:

Adverse Selection (Adverse Selektion): Wenn deine Buy-Limit-Order sofort gefillt wird, ist die Wahrscheinlichkeit hoch, dass ein großer Seller mit aggressivem Flow (Toxic Flow) in den Markt gedrückt hat – der Preis wird extrem wahrscheinlich weiter fallen.

Queue Position Value: Der Platz ganz vorne in der Queue eines Preis-Levels besitzt einen eigenen Wert. HFT-Bots stornieren und platzieren permanent Orders neu (Spoofing/Layering-Mechaniken oder adaptives Liquiditätsmanagement), um die Priorität zu halten, ohne unkalkulierbares Invenatarrisiko einzugehen.

2. AMM: Vom klassischen Constant Product zu Concentrated Liquidity

Ein AMM unterscheidet sich grundlegend vom Orderbuch: Es gibt keine Order-Queue. Der Preis ergibt sich direkt aus einer mathematischen Invarianten-Funktion.

Constant Product (v2): x · y = k

Im klassischen Uniswap v2 ist die Liquidität über die gesamte Spanne von Null bis Unendlich verteilt.

Führt man einen Trade mit dem Volumen Δx aus, zieht man Δy aus dem Pool, berechnet unter Berücksichtigung der Fee γ = (1 - fee):

Δy = (y · Δx · γ) / (x + Δx · γ)

Der Ausführungspreis ist nicht fix, sondern „slidet“ im Moment der Execution entlang der Kurve.

Concentrated Liquidity (v3 / Tick-basiert)

Uniswap v3 hat den AMM quasimäßig in ein Orderbuch verwandelt, indem Liquidity Provider (LPs) eigene Preisspannen [Pa, Pb] definieren können.

Der Preis ist in Ticks unterteilt, wobei jeder Tick einer Preisänderung von 0,01% (1 bps) entspricht:

P(i) = 1.0001i

Die Liquidität L innerhalb einer Range agiert wie eine „virtuelle“ Invariante. Sobald jedoch die Grenze eines Ticks überschritten wird, ändert sich die aktive Liquidität schlagartig. Für HFT-Arbitrageure bedeutet das: Die Tiefe eines AMM v3 ist diskret und verändert sich beim Durchbrechen von Ticks stufenweise.

3. Vergleichsmatrix: Mikrostruktur

ParameterOrder Book (CEX/TradFi)AMM (Uniswap v2)Concentrated AMM (v3)
AusführungsprioritätPrice-Time (FIFO) / Pro-RataGas Price / MEV (Priority Fee)Gas Price / MEV (Priority Fee)
Latenz (Latency)Mikrosekunden / NanosekundenBlockzeit (oder Slotted Latency)Blockzeit / P2P-Mempool
PreisbildungFortlaufende Auktion (Continuous Double Auction)Dynamisch basierend aufs Volumen (x · y = k)Dynamisch innerhalb des aktiven Ticks
LiquiditätskostenKein Impermanent Loss (dafuer Inventory Risk)Impermanent Loss (IL)Loss-Versus-Rebalancing (LVR)
Flow-TransparenzL3 Data Feeds (Pitch, ITCH, FIX)Mempool (vor dem Block) / On-Chain (danach)Mempool (vor dem Block) / On-Chain (danach)

4. Versteckte Mechaniken: MEV, LVR und Toxic Flow

Im CEX-Orderbuch kämpfen HFT-Trading-Desks um Nanosekunden physikalischer Netzwerklatenz (Colocation im RZ der Börse, Glasfaser, FPGA-Karten).

Im DeFi-Bereich verschiebt sich das Konzept von Zeit: Hier dreht sich alles um die Strukturierung des Blocks.

MEV (Maximal Extractable Value)

In einem AMM wird die Reihenfolge der Transaktionen innerhalb eines Blocks von Searchern und Block-Buildern zusammengestellt. Das führt zu ganz spezifischen HFT-Dynamiken:

  • Frontrunning / Backrunning: Abfangen von Trades im Mempool durch Bieten einer höheren Gebühr (Priority Fee).
  • Sandwich Attacks: Ein Kaufen direkt vor einer großen User-Order, um den Preis hochzutreiben, gefolgt von einem sofortigen Verkauf direkt danach.

LVR (Loss-Versus-Rebalancing)

Normalerweise berechnen LPs ihr Risiko über den Impermanent Loss (IL). Auf HFT-Ebene greift jedoch eine präzisere Metrik: LVR, entwickelt von Forschern der Columbia University und Paradigm.

LVR (Loss-Versus-Rebalancing) beschreibt den systematischen Verlust eines Liquidity Providers im AMM im Vergleich zu einem identischen Portfolio, das auf einer CEX unter Nutzung externer Marktpreise kontinuierlich rebalanciert wird.

Die Ursache für LVR ist Volatilitätsarbitrage. Rennt der Preis auf der CEX davon, hinkt der AMM-Pool mit einem veralteten Preis hinterher (Stale Price). Ein HFT-Arbitrageur erkennt diesen Spread, schöpft die günstige Liquidität aus dem AMM ab und sichert sich zeitgleich auf der CEX ab. Der AMM-LP wird somit systematisch zum schlechteren Preis gegen informierten Flow (Toxic Flow) ausgeführt.

LVR ≈ (σ² / 8) · ∫0T St · Lt dt

Wobei σ für die Volatilität des Assets steht, St für den Preis und Lt für die aktive Liquidität. Takeaway: Je höher die Marktvolatilität, desto mehr Yield drücken LPs an HFT-Arbitrageure ab.

5. Praxis: Python-Skript zur Quote-Berechnung (AMM v3 vs. L2-Tiefe)

Ein bisschen Code gefällig? Wir bauen ein Tool zur Berechnung des effektiven Ausführungspreises (inklusive Slippage) für eine Beispiel-Order. Dabei vergleichen wir die Tiefe eines L2-Orderbuchs mit einem Constant Product AMM Pool.

Das Skript ist in Pure Python gehalten – ganz ohne schwere Third-Party-Frameworks.

from __future__ import annotations
from dataclasses import dataclass
from enum import Enum
from typing import List
class FeeMode(Enum):
    QUOTE = "quote"  # Gebühr wird vom eingehenden USDT-Betrag abgezogen
    BASE = "base"    # Gebühr wird vom erhaltenen ETH-Betrag abgezogen
@dataclass
class AskLevel:
    price: float
    volume: float
class OrderBookL2:
    """
    L2-Orderbuch (Ask-Seite).
    Beispiel für das Paar ETH/USDT:
        price  = USDT pro 1 ETH
        volume = ETH
    """
    def __init__(
        self,
        asks: List[tuple[float, float]],
        taker_fee: float = 0.001,
    ) -> None:
        if not (0 <= taker_fee < 1):
            raise ValueError("taker_fee muss im Bereich [0, 1) liegen")
        self.taker_fee = float(taker_fee)
        self.asks: List[AskLevel] = []
        for price, volume in asks:
            if price <= 0:
                raise ValueError("Preis muss > 0 sein")
            if volume <= 0:
                raise ValueError("Volumen muss > 0 sein")
            self.asks.append(
                AskLevel(
                    price=float(price),
                    volume=float(volume),
                )
            )
        self.asks.sort(key=lambda x: x.price)
    def best_ask(self) -> float:
        if not self.asks:
            raise ValueError("Orderbuch ist leer")
        return self.asks[0].price
    def spot_price(self) -> float:
        return self.best_ask()
    def total_liquidity_quote(self) -> float:
        return sum(
            level.price * level.volume
            for level in self.asks
        )
    def total_liquidity_base(self) -> float:
        return sum(
            level.volume
            for level in self.asks
        )
    def simulate_buy(
        self,
        amount_in_quote: float,
        mutate: bool = True,
        fee_mode: FeeMode = FeeMode.QUOTE,
    ) -> tuple[float, float]:
        """
        Kauf des Basis-Assets für amount_in_quote.
        Rückgabe:
            (
                erhaltenes_basis_asset,
                durchschnittlicher_effektiver_preis
            )
        """
        if amount_in_quote <= 0:
            raise ValueError(
                "amount_in_quote muss > 0 sein"
            )
        if fee_mode == FeeMode.QUOTE:
            quote_for_trade = (
                amount_in_quote *
                (1.0 - self.taker_fee)
            )
        else:
            quote_for_trade = amount_in_quote
        remaining_quote = quote_for_trade
        total_base_bought = 0.0
        new_levels: List[AskLevel] = []
        for level in self.asks:
            if remaining_quote <= 0:
                new_levels.append(level)
                continue
            level_cost = (
                level.price *
                level.volume
            )
            if remaining_quote >= level_cost:
                total_base_bought += level.volume
                remaining_quote -= level_cost
            else:
                base_from_level = (
                    remaining_quote /
                    level.price
                )
                total_base_bought += base_from_level
                remaining_volume = (
                    level.volume -
                    base_from_level
                )
                if remaining_volume > 1e-12:
                    new_levels.append(
                        AskLevel(
                            level.price,
                            remaining_volume,
                        )
                    )
                remaining_quote = 0.0
        if remaining_quote > 1e-9:
            raise ValueError(
                "Nicht genügend Liquidität im Orderbuch"
            )
        if fee_mode == FeeMode.BASE:
            total_base_bought *= (
                1.0 - self.taker_fee
            )
        if total_base_bought <= 0:
            raise ValueError(
                "Erhaltenes Volumen ist Null"
            )
        avg_price = (
            amount_in_quote /
            total_base_bought
        )
        if mutate:
            self.asks = new_levels
        return total_base_bought, avg_price
class ConstantProductAMM:
    """
    AMM im Stile von Uniswap v2
    x = ETH
    y = USDT
    spot = y / x
    """
    def __init__(
        self,
        reserve_x: float,
        reserve_y: float,
        fee: float = 0.003,
    ) -> None:
        if reserve_x <= 0:
            raise ValueError(
                "reserve_x muss > 0 sein"
            )
        if reserve_y <= 0:
            raise ValueError(
                "reserve_y muss > 0 sein"
            )
        if not (0 <= fee < 1):
            raise ValueError(
                "fee muss im Bereich [0, 1) liegen"
            )
        self.x = float(reserve_x)
        self.y = float(reserve_y)
        self.fee = float(fee)
    def spot_price(self) -> float:
        return self.y / self.x
    def invariant(self) -> float:
        return self.x * self.y
    def simulate_buy(
        self,
        amount_y_in: float,
        mutate: bool = True,
    ) -> tuple[float, float]:
        """
        Kauf von ETH gegen USDT.
        Rückgabe:
            (
                erhaltenes_ETH,
                durchschnittlicher_preis
            )
        """
        if amount_y_in <= 0:
            raise ValueError(
                "amount_y_in muss > 0 sein"
            )
        y_effective = (
            amount_y_in *
            (1.0 - self.fee)
        )
        x_out = (
            self.x *
            y_effective
        ) / (
            self.y +
            y_effective
        )
        if x_out <= 0:
            raise ValueError(
                "Erhaltenes Volumen ist Null"
            )
        if x_out >= self.x:
            raise ValueError(
                "Nicht genügend Liquidität im Pool"
            )
        avg_price = (
            amount_y_in /
            x_out
        )
        if mutate:
            self.x -= x_out
            self.y += amount_y_in
        return x_out, avg_price
def print_trade_result(
    title: str,
    received: float,
    avg_price: float,
    spot_price: float,
) -> None:
    slippage = (
        (avg_price - spot_price)
        / spot_price
    ) * 100
    print(
        f"{title:<12}"
        f" Erhalten: {received:.6f}"
        f" | Durchschn. Preis: {avg_price:,.4f}"
        f" | Slippage: {slippage:.4f}%"
    )
def main() -> None:
    asks = [
        (3000.0, 1.5),
        (3001.0, 2.0),
        (3002.5, 5.0),
        (3005.0, 10.0),
        (3010.0, 25.0),
    ]
    orderbook = OrderBookL2(
        asks=asks,
        taker_fee=0.001,
    )
    amm = ConstantProductAMM(
        reserve_x=1000.0,
        reserve_y=3_000_000.0,
        fee=0.003,
    )
    trade_size = 15_000.0
    ob_spot = orderbook.spot_price()
    amm_spot = amm.spot_price()
    ob_received, ob_avg = orderbook.simulate_buy(
        amount_in_quote=trade_size,
        mutate=True,
        fee_mode=FeeMode.QUOTE,
    )
    amm_received, amm_avg = amm.simulate_buy(
        amount_y_in=trade_size,
        mutate=True,
    )
    print(
        f"\n=== Vergleich der Ausführung für "
        f"{trade_size:,.2f} USDT ===\n"
    )
    print_trade_result(
        "ORDERBOOK",
        ob_received,
        ob_avg,
        ob_spot,
    )
    print_trade_result(
        "AMM V2",
        amm_received,
        amm_avg,
        amm_spot,
    )
    print("\n=== Zustand nach dem Trade ===\n")
    if orderbook.asks:
        print(
            f"Bester Ask: "
            f"{orderbook.best_ask():,.4f}"
        )
    else:
        print("Orderbuch vollständig ausgeräumt")
    print(
        f"AMM Spot: "
        f"{amm.spot_price():,.4f}"
    )
    print(
        f"AMM Reserven: "
        f"{amm.x:.6f} ETH | "
        f"{amm.y:.2f} USDT"
    )
if __name__ == "__main__":
    main()

Interpretation der Ergebnisse

In tiefen AMM-Pools werden kleine Orders mit minimaler Slippage ausgeführt. Nimmt das Volumen jedoch zu, steigt der Preis im AMM entlang einer konvexen Kurve extrem an. Im Orderbuch hingegen hängt alles an den „Liquiditätswänden“ (Liquidity Walls). Ist das Orderbuch dünn, rasierst du direkt mehrere Levels ab und fängst dir eine Slippage ein, die um ein Vielfaches schlechter ist als im AMM.

6. Hybride Modelle: Wie DEXes Orderbücher einführen und warum CEXes auf AMMs schielen

Die Grenze zwischen Orderbüchern und AMMs verschwimmt zusehends. Hochfrequenzhändler und Institutionelle sind schnell an die Grenzen des klassischen Uniswap v2 gestoßen: Die geringe Kapitaleffizienz und das Fehlen komplexer Limit-Orders (Stop-Loss, Take-Profit, Iceberg) machten DEXes für aktives Market Making schlichtweg unattraktiv.

Das hat zu einem evolutionären Wandel und zur Entstehung hybrider Architekturen geführt.

1. On-Chain- und L2-Orderbücher (dYdX, Hyperliquid, Vertex)

Mit dem Aufkommen hochperformanter L1/L2-Netzwerke (Aptos, Sui, Arbitrum) und spezialisierter AppChains wurde es möglich, vollständige Orderbücher direkt auf der Blockchain zu betreiben.

Off-Chain Matching + On-Chain Settlement: Die Order-Matching-Engines laufen auf extrem schnellen Off-Chain-Engines (um Latenzen von < 10 ms zu erreichen), während die Ausführungsergebnisse und Margin-Anforderungen in Smart Contracts verankert werden.

Fully On-Chain (Hyperliquid, Serum/Ellipsis): Das Orderbuch lebt komplett im Konsens der Blockchain. Die größte Herausforderung hierbei ist das massive Transaktionsvolumen: Das Ersetzen und Stornieren von Orders (Cancel/Replace) macht im HFT-Bereich bis zu 95–98 % aller eingehenden Transaktionen aus.

2. Intent-Based-Architektur und RFQ (Request for Quote)

Das "Intent"-Modell (Uniswap X, 1inch Fusion, CoW Protocol) bringt im Grunde den institutionellen Ausführungsansatz zurück in die DeFi-Welt.

Der Trader signiert keine Transaktion zur Interaktion mit einem bestimmten Pool, sondern eine Absicht (z. B.: „Ich möchte 100 ETH gegen mindestens 300.000 USDC tauschen“). Ein Netzwerk externer Ausführer (Fillers / Solvers) konkurriert dann darum, diese Order zu erfüllen – und kann dafür beliebige Liquiditätsquellen nutzen: CEXes, das Inventar privater Market Maker oder DEXes.

Architecture
 

Für den aktiven Trader bedeutet das: null Slippage und Schutz vor MEV-Sandwich-Attacken. Das gesamte Ausführungs- und Slippage-Risiko übernimmt der Solver, der seinen Gewinn aus der Arbitrage zwischen verschiedenen Assets zieht.

7. Praxis: Fortgeschrittenes Arbitrage-Skript zwischen CEX L2 Orderbook und AMM v2

In der Praxis suchen HFT-Bots ununterbrochen nach Preisungleichgewichten zwischen CEXes und AMMs. Schießt der Preis eines Assets auf einer CEX durch einen Marktkauf nach oben, bleibt der AMM-Pool für einen kurzen Moment „veraltet“ (stale). Der Arbitrageur zieht den Preis im AMM durch einen Kauf auf das CEX-Niveau und verkauft das gekaufte Volumen direkt wieder auf der CEX.

Unten findest du ein funktionsfähiges Python-Skript, das unter Berücksichtigung der AMM-Gebühr, der CEX-Orderbuchtiefe und der Maker/Taker-Gebühren die optimale Arbitrage-Treffergröße (dx) in Echtzeit berechnet.

from __future__ import annotations
from dataclasses import dataclass
from typing import List, Dict, Any
@dataclass
class BidLevel:
    price: float
    volume: float
class OrderBookSide:
    """
    Bid-Seite des Orderbuchs.
    price  = Kaufpreis
    volume = Volumen des Basis-Assets
    """
    def __init__(self, bids: List[tuple[float, float]]):
        self.bids: List[BidLevel] = []
        for price, volume in bids:
            if price <= 0:
                raise ValueError("Preis muss > 0 sein")
            if volume <= 0:
                raise ValueError("Volumen muss > 0 sein")
            self.bids.append(
                BidLevel(
                    float(price),
                    float(volume)
                )
            )
        self.bids.sort(
            key=lambda x: x.price,
            reverse=True
        )
    def is_empty(self) -> bool:
        return len(self.bids) == 0
    def best_bid(self) -> float:
        if self.is_empty():
            raise ValueError("Orderbuch ist leer")
        return self.bids[0].price
    def cumulative_levels(self) -> List[tuple[float, float]]:
        """
        Gibt die Liquiditätsänderungspunkte zurück.
        [
            (2 ETH, VWAP bis 2 ETH),
            (7 ETH, VWAP bis 7 ETH),
            ...
        ]
        """
        result = []
        cumulative_x = 0.0
        cumulative_y = 0.0
        for level in self.bids:
            cumulative_x += level.volume
            cumulative_y += level.volume * level.price
            result.append(
                (
                    cumulative_x,
                    cumulative_y
                )
            )
        return result
    def execute_sell(
        self,
        amount_x: float
    ) -> tuple[float, float]:
        """
        Verkauf von amount_x in das Orderbuch.
        Gibt zurück:
        (
            erhaltene_USDT,
            VWAP
        )
        """
        if amount_x <= 0:
            raise ValueError(
                "amount_x muss > 0 sein"
            )
        remaining_x = amount_x
        received_y = 0.0
        for level in self.bids:
            if remaining_x <= 0:
                break
            executed = min(
                remaining_x,
                level.volume
            )
            received_y += (
                executed *
                level.price
            )
            remaining_x -= executed
        if remaining_x > 1e-9:
            raise ValueError(
                "Nicht genügend Liquidität im Orderbuch"
            )
        vwap = received_y / amount_x
        return received_y, vwap
class AMMPool:
    """
    Constant Product AMM
    x = ETH
    y = USDT
    """
    def __init__(
        self,
        reserve_x: float,
        reserve_y: float,
        fee: float = 0.003
    ):
        if reserve_x <= 0:
            raise ValueError(
                "reserve_x muss > 0 sein"
            )
        if reserve_y <= 0:
            raise ValueError(
                "reserve_y muss > 0 sein"
            )
        if not (0 <= fee < 1):
            raise ValueError(
                "fee muss im Bereich [0,1) liegen"
            )
        self.x = float(reserve_x)
        self.y = float(reserve_y)
        self.fee = float(fee)
    def spot_price(self) -> float:
        return self.y / self.x
    def calculate_out_x(
        self,
        amount_y_in: float
    ) -> float:
        if amount_y_in <= 0:
            raise ValueError(
                "amount_y_in muss > 0 sein"
            )
        y_effective = (
            amount_y_in *
            (1.0 - self.fee)
        )
        x_out = (
            self.x *
            y_effective
        ) / (
            self.y +
            y_effective
        )
        return x_out
    def calculate_required_y_for_x(
        self,
        target_x_out: float
    ) -> float:
        """
        Inversion der AMM-Formel.
        Wie viel USDT eingezahlt werden muss,
        um target_x_out zu erhalten.
        """
        if target_x_out <= 0:
            raise ValueError(
                "target_x_out muss > 0 sein"
            )
        if target_x_out >= self.x:
            raise ValueError(
                "Die gesamte Reserve kann nicht abgehoben werden"
            )
        y_effective = (
            target_x_out *
            self.y
        ) / (
            self.x -
            target_x_out
        )
        amount_y_in = (
            y_effective /
            (1.0 - self.fee)
        )
        return amount_y_in
def find_optimal_arbitrage(
    amm: AMMPool,
    cex_bids: OrderBookSide,
    cex_fee: float = 0.001
) -> Dict[str, Any]:
    if not (0 <= cex_fee < 1):
        raise ValueError(
            "cex_fee muss im Bereich [0,1) liegen"
        )
    if cex_bids.is_empty():
        return {
            "opportunity": False,
            "reason": "CEX-Orderbuch ist leer"
        }
    best_bid = cex_bids.best_bid()
    if (
        best_bid *
        (1.0 - cex_fee)
        <=
        amm.spot_price()
    ):
        return {
            "opportunity": False,
            "reason": "Kein Spread vorhanden"
        }
    best_result = None
    best_profit = float("-inf")
    cumulative = cex_bids.cumulative_levels()
    for cumulative_x, cumulative_y in cumulative:
        try:
            required_usdt = (
                amm.calculate_required_y_for_x(
                    cumulative_x
                )
            )
            gross_usdt = cumulative_y
            net_usdt = (
                gross_usdt *
                (1.0 - cex_fee)
            )
            profit = (
                net_usdt -
                required_usdt
            )
            if profit > best_profit:
                avg_buy_price = (
                    required_usdt /
                    cumulative_x
                )
                avg_sell_price = (
                    gross_usdt /
                    cumulative_x
                )
                amm_spot = (
                    amm.spot_price()
                )
                impact_pct = (
                    (
                        avg_buy_price -
                        amm_spot
                    )
                    /
                    amm_spot
                ) * 100
                roi_pct = (
                    profit /
                    required_usdt
                ) * 100
                best_profit = profit
                best_result = {
                    "opportunity": True,
                    "input_usdt_amm": required_usdt,
                    "bought_x": cumulative_x,
                    "gross_usdt_cex": gross_usdt,
                    "net_usdt_cex": net_usdt,
                    "net_profit_usdt": profit,
                    "roi_pct": roi_pct,
                    "amm_spot_price": amm_spot,
                    "amm_avg_buy_price": avg_buy_price,
                    "amm_price_impact_pct": impact_pct,
                    "cex_vwap": avg_sell_price,
                }
        except ValueError:
            continue
    if best_result is None:
        return {
            "opportunity": False,
            "reason": "Unzureichende Liquidität"
        }
    if best_result["net_profit_usdt"] <= 0:
        return {
            "opportunity": False,
            "reason": "Slippage frisst den gesamten Gewinn auf"
        }
    return best_result
def main():
    amm = AMMPool(
        reserve_x=1000.0,
        reserve_y=3_000_000.0,
        fee=0.003
    )
    cex = OrderBookSide([
        (3050.0, 2.0),
        (3048.0, 5.0),
        (3045.0, 10.0),
        (3040.0, 20.0),
        (3030.0, 50.0),
    ])
    result = find_optimal_arbitrage(
        amm,
        cex,
        cex_fee=0.0005
    )
    print(
        "\n=== Arbitrage-Suchergebnis ===\n"
    )
    if not result["opportunity"]:
        print(
            f"Status: ABGEBROCHEN\n"
            f"Grund: {result['reason']}"
        )
        return
    print("Status: ARBITRAGE-CHANCE GEFUNDEN")
    print()
    print(
        f"AMM-Einsatz: "
        f"${result['input_usdt_amm']:,.2f}"
    )
    print(
        f"Gekaufte ETH: "
        f"{result['bought_x']:.6f}"
    )
    print(
        f"CEX Bruttoerlös: "
        f"${result['gross_usdt_cex']:,.2f}"
    )
    print(
        f"CEX Nettoerlös: "
        f"${result['net_usdt_cex']:,.2f}"
    )
    print(
        f"Nettogewinn: "
        f"${result['net_profit_usdt']:,.2f}"
    )
    print(
        f"ROI: "
        f"{result['roi_pct']:.4f}%"
    )
    print(
        f"AMM Spot-Preis: "
        f"{result['amm_spot_price']:.4f}"
    )
    print(
        f"AMM Durschn. Kaufpreis: "
        f"{result['amm_avg_buy_price']:.4f}"
    )
    print(
        f"AMM Price Impact: "
        f"{result['amm_price_impact_pct']:.4f}%"
    )
    print(
        f"CEX VWAP: "
        f"{result['cex_vwap']:.4f}"
    )
if __name__ == "__main__":
    main()

8. Key Takeaways für Trader: Wie man die «Unwissenheits-Steuer» vermeidet

Die Marktmikrostruktur zu verstehen ist keine graue Theorie, sondern dein wichtigstes Werkzeug, um dein Depot vor schleichendem Kapitalfraß zu schützen.

  • Wähle den Order-Typ passend zur Marktlage: Wer auf einer CEX große Volumina per Market Order kauft, frisst sich garantiert durch mehrere Orderbuch-Ebenen und kassiert bösen negativen Slippage. Wenn es schnell gehen muss, nutze IOC- (Immediate-or-Cancel) oder FOK-Orders (Fill-or-Kill) mit einem fest definierten, schlechtestmöglichen Ausführungspreis.
  • Achte auf die effektive Tiefe, nicht nur auf den Spread: Enge Spreads auf L2s (z. B. $0.01) sind oft eine Illusion. Wenn auf dem besten Bid/Ask-Level nur 100 $ Liquidität liegen, ballert deine 50.000-$-Order eiskalt durchs Orderbuch und wird zu einem katastrophalen Durchschnittspreis ausgeführt.
  • Kalkuliere den Toxic Flow bei AMMs ein: Wenn du bei Uniswap v3 in einer engen Range Liquidität bereitstellst, während wichtige News reinkommen oder die Volatilität hochschießt, wirst du zum leichten Ziel für HFT-Arbitrageure. Die Metrik LVR (Loss-Versus-Rebalancing) frisst deine Gebühreneinnahmen in wenigen Minuten komplett auf.
  • Schütze dich auf DEXes vor MEV: Schränke bei AMM-Trades deine Slippage Tolerance immer stark ein (am besten auf 0.1–0.3 %) oder nutze private RPC-Nodes (wie Flashbots Protect oder MEV-Blocker), damit deine Transaktionen gar nicht erst im öffentlichen Mempool landen und ge-sandwicht werden.

Schreib mal in die Kommentare, wie viel Slippage dich große Orders bisher gekostet haben und welches Modell (CEX Orderbook oder DEX AMM) du im Trading-Alltag bevorzugst!


FAQ

Order Books führen Limit- und Market-Orders über ein kontinuierliches Auktionsverfahren basierend auf der Preis-Zeit-Priorität (FIFO) aus, während Automated Market Makers (AMMs) Trades programmatisch gegen Liquiditätspools über mathematische Invarianten wie X x Y = k abwickeln.

Impermanent Loss misst den relativen Portfoliowertverlust rein als Funktion preisunabhängiger Wertänderungen gegenüber HODL, während Loss-Versus-Rebalancing (LVR) die unhedgbaren Kosten der negativen Selektion quantifiziert, die an HFT-Arbitrageure gezahlt werden, welche veraltete AMM-Preise bei externen CEX-Kursabweichungen ausnutzen.

MEV-Bots überwachen unbestätigte Transaktionen im öffentlichen Mempool, drängen sich mit einer höheren Prioritätsgebühr vor eine Ziel-Buy-Order, um den Token-Preis künstlich bis zur maximalen Slippage-Grenze des Nutzers zu treiben, und verkaufen sofort im selben Block, um risikofreien Gewinn abzuschöpfen.
Martyn Borkowski

I am a crypto trader specializing in digital assets and blockchain markets.

My focus is on identifying opportunities, managing risk, and optimizing strategies to achieve consistent growth in the fast-evolving world of cryptocurrency.

Verification & Professional Profiles: X Profile

...

Diskussion beitreten

Ihre E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind markiert *