Der Status des Projekts stand verstreut in elf Umsetzungsplaenen, drei Konzepten, der Linux-Analyse und dem Projektstand - teils widersprechend, teils wochenlang veraltet. Ab jetzt gibt es genau eine Statusquelle. docs/ROADMAP.md (neu): - Alle Vorhaben in vier Stufen A bis D, plus technische Schuld und Verlauf. Die Stufen sind eine Reihenfolge, keine Termine: jede schafft die Voraussetzung fuer die naechste. - Statuszeichen: erledigt / offen / blockiert (mit Ursache) / bewusst zurueckgestellt / Idee, nicht beschlossen. Damit ist das, was wir NICHT bauen wollen, sichtbar vorgehalten statt unauffindbar in einem Plan zu schlummern. - Inhaltlich getragen, nicht nur verlinkt: je Vorhaben Ziel, Phasen, Akzeptanzkriterien, offene Entscheidungen und Leitplanken aus den Quelldokumenten. - Sichtbar gemacht, was vorher zwischen den Dokumenten verborgen lag: CopyTrading Phase 1 ist der Engpass der gesamten Roadmap (MarketMaking und BundleArbitrage haben harte Voraussetzungen darauf), und die Sniper-Metriken aus Phase 3.2 sind ein Spezialfall des StrategieDrift-Fingerprints - zusammen bauen statt doppelt. Archiv (docs/archiv/): - 15 Dokumente verschoben (11 Umsetzungsplaene, 3 Konzepte, ANALYSE-Linux-Portierung). Sie bleiben die Bauanleitungen mit Code-Bezuegen, Risikotabellen und Begruendungen - eingefroren ist nur ihr Status. - archiv/README.md ordnet jedes Dokument seinem Roadmap-Punkt zu. Verweise nachgezogen - der eigentliche Aufwand: - 25 Markdown-Links repariert. 15 davon verschiebungsbedingt (eine Ebene tiefer), der Rest war schon vorher falsch: die Ideensammlung verlinkte Quellcode relativ zum Repo-Wurzelverzeichnis statt zu docs/. - 12 Dateien ausserhalb von docs/ verwiesen in Kommentaren auf die Plaene (csproj, props, setup.json, sechs Quelldateien) - alle auf archiv/ umgebogen. - Verweise auf Dateien, die der Fruehjahrsputz geloescht hat (Ui/, Program.cs, WindowMenuBar), zu Klartext entschaerft statt tote Links zu lassen. - Gegenprobe: 85 Links geprueft, 0 kaputt. Build gruen, 476 Tests gruen. PROJEKTSTAND.md entdoppelt: Abschnitt "Offen" verweist jetzt auf die Roadmap. Arbeitsteilung ist damit klar - Projektstand sagt was IST, Roadmap was KOMMT. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
315 lines
15 KiB
Markdown
315 lines
15 KiB
Markdown
# Umsetzungsplan: Copytrading-Modul — Rentabilitäts-Verbesserungen
|
||
|
||
> Stand: 2026-07-06
|
||
> Ziel: Bekannte Verlustquellen im Copytrading-Modul beseitigen und die
|
||
> Rentabilität durch datengetriebene Trader-Auswahl, echte Fill-Daten und
|
||
> besseres SELL-Handling steigern.
|
||
> Reihenfolge: **Dieser Plan zuerst.** Phase 1 (Marktdaten-Fundament) ist
|
||
> Voraussetzung für die Strategiemodule MarketMaking und BundleArbitrage.
|
||
|
||
---
|
||
|
||
## 0. Kontext & Hintergrund (für die Umsetzung ohne Vorwissen)
|
||
|
||
Das Copytrading-Modul (`src/PolyTrader.Modules.CopyTrading/`) kopiert Trades von
|
||
Master-Tradern auf Polymarket. Signalkette:
|
||
|
||
1. `AlchemyWebsocketService` erkennt On-Chain-Events der Master-Wallets (WSS).
|
||
2. `TraderMonitorService.TriggerFastBlockchainPoll()` parst die Transaktion direkt
|
||
(Fast Track, ~3–4 s hinter dem Master) oder fällt auf Data-API-Polling zurück.
|
||
3. Signale (`CopySignal`) laufen über einen Channel in die `CopyTradingEngine`.
|
||
4. Die Engine prüft Risiko-Limits (`CopyTradingAccountSettings`: PerMarketLimit,
|
||
PerMasterLimit, Zeitfenster-Limits, MaxBuyPrice) und platziert CLOB-Orders
|
||
über `PolymarketClobClient` (Core).
|
||
|
||
**Historischer Kontext (wichtig!):** Eine Verlustanalyse im April 2026
|
||
(`agentspace/prompts/AnalyzingOvernightTradingLosses.md`) hat als Hauptursache
|
||
für Overnight-Verluste identifiziert, dass der Bot SELLs der Master mit
|
||
Market-Orders ins leergeräumte Orderbuch kopiert und so zur „Exit-Liquidity"
|
||
wird (Beispiel: Entry 0.51, Master-Exit 0.99, unser Exit 0.49). Der damalige
|
||
Fix (GTD-Limit-Sells) ist **im aktuellen Modul-Code nicht mehr vorhanden** —
|
||
vermutlich bei der Modularisierung verloren gegangen.
|
||
|
||
**Seit März 2026 erhebt Polymarket Taker-Fees** (Sports ~0,75 %, Politik/Finanzen
|
||
~1,0 %, Krypto ~1,8 %, am 50-¢-Preis am höchsten, Richtung 1 ¢/99 ¢ abnehmend;
|
||
Maker zahlen nichts und erhalten Rebates). Der Bot ist heute fast immer Taker.
|
||
Quelle: https://docs.polymarket.com/trading/fees — **bei Umsetzung aktuellen
|
||
Stand verifizieren.**
|
||
|
||
### Leitplanken (gelten für alle Phasen)
|
||
|
||
1. `.agents/rules/clob.md` beachten: Änderungen an der CLOB-Integration sind
|
||
hochkritisch. Vor jeder Änderung Backup/Commit der alten Version, jede
|
||
Änderung mehrfach prüfen.
|
||
2. Jede Phase lässt die App baubar und lauffähig zurück (Debug-Build grün).
|
||
3. Entscheidungslogik als testbare, pure Funktionen extrahieren und in
|
||
`PolyTrader.Tests` (xUnit, existiert bereits) abdecken.
|
||
4. Kein Livegang einer Phase ohne mehrtägige Beobachtung auf dem Server.
|
||
|
||
---
|
||
|
||
## Phase 0 — Sofortmaßnahmen: Blutung stoppen
|
||
|
||
### 0.1 🔴 SELL-Exit-Liquidity-Regression beheben (höchste Priorität)
|
||
|
||
**Befund:** In `CopyTradingEngine.cs` (Live-SELL-Pfad, aktuell ~Zeile 694–735)
|
||
werden SELLs als `"MARKET"` mit Fallback-Limit `0.01m` gesendet:
|
||
|
||
```csharp
|
||
decimal sellLimit = 0.01m; // Market Order Fallback Limit
|
||
...
|
||
var result = await _clob.PlaceOrderAsync(account, signal.TokenId, signal.Side,
|
||
expectedUsdc, sellLimit, "MARKET", _state.DebugOrderPayloadLog, isNegRisk);
|
||
```
|
||
|
||
Das ist exakt das Verhalten, das die April-Verluste verursacht hat.
|
||
|
||
**Ziel-Design: Eskalationsleiter statt Market-Order**
|
||
|
||
1. Referenzpreis = `signal.Price` (Exit-Preis des Masters).
|
||
2. Erste Order: GTD-Limit.
|
||
- HF-Trader (`trader.Category == "HF"`): `signal.Price - 0.005m`.
|
||
- Sonst: `signal.Price * (1 - settings.MaxPriceDifference / 100m)`.
|
||
3. Neuer Setting-Wert `SellFloorPct` in `CopyTradingAccountSettings`
|
||
(Default z. B. 15 %): absolute Untergrenze = `signal.Price * (1 - SellFloorPct/100)`.
|
||
4. Hintergrund-Loop (Erweiterung von `CleanupStaleOpenOrdersAsync` in
|
||
`TraderMonitorService` oder eigener Loop): Order nach T Sekunden ohne Fill
|
||
(HF: ~20 s, sonst: ~120 s) canceln und eine Stufe tiefer neu platzieren
|
||
(Schrittweite z. B. 2 ¢ oder 3 % relativ), bis zum Floor.
|
||
5. Floor erreicht und kein Fill → Position halten, **Threema-Benachrichtigung**
|
||
senden (`ThreemaService` im Core existiert) und Position als „ExitPending"
|
||
markieren.
|
||
6. Position darf **nicht mehr optimistisch** aus `account.OpenPositions`
|
||
entfernt werden. Stattdessen Flag `ExitPending` (neues Property auf
|
||
`Position` oder Tracking-Dictionary im `CopyTradingState`), damit Limits
|
||
weiterhin korrekt rechnen und kein Doppel-SELL entsteht. Entfernen erst,
|
||
wenn der Fill über Sync/User-Channel (Phase 1) bestätigt ist.
|
||
|
||
**Preis-/Stufenlogik als pure statische Funktion** implementieren (z. B.
|
||
`SellLadder.NextPrice(referencePrice, step, floor, attempt)`) und mit
|
||
Unit-Tests abdecken.
|
||
|
||
**Akzeptanzkriterien:**
|
||
- Kein Code-Pfad sendet mehr `"MARKET"`-SELLs mit 0.01-Limit.
|
||
- Unit-Tests für Ladder-Preise (HF/normal, Floor-Clamping, 0.01/0.99-Grenzen).
|
||
- Log zeigt pro SELL: Referenzpreis, gewähltes Limit, Stufe.
|
||
|
||
### 0.2 Fee-Modell einführen
|
||
|
||
1. Fee-Rate je Markt beschaffen: Die CLOB-/Gamma-API liefert Fee-Informationen
|
||
am Markt-Objekt (Feldname bei Umsetzung anhand
|
||
https://docs.polymarket.com/trading/fees verifizieren, z. B. `fee_rate_bps`).
|
||
Fallback: statische Kategorie-Tabelle (Sports 0.75 %, Politics/Finance 1.0 %,
|
||
Crypto 1.8 %, Geopolitics 0 %).
|
||
2. `MarketData` (Core) um `TakerFeeBps` erweitern (EF-Migration Core),
|
||
Befüllung über `MarketSyncService` bzw. beim Markt-Fetch.
|
||
3. Risk-Check in `CopyTradingEngine`: erwartete Fee vom verfügbaren Edge
|
||
abziehen; Mikro-Trades, deren Fee den erwartbaren Gewinn frisst, verwerfen
|
||
(Logging mit Begründung wie bei den bestehenden Checks).
|
||
4. PnL-Berechnung (Demo **und** Live-Anzeige) um Fees korrigieren.
|
||
|
||
**Akzeptanz:** Fee erscheint im TradeReasoning-Log jedes BUY; Demo-PnL weist
|
||
Fees aus.
|
||
|
||
### 0.3 `ProfitTarget` implementieren oder entfernen
|
||
|
||
`CopyTradingAccountSettings.ProfitTarget` (Default 50.0) existiert in Settings,
|
||
DB und UI, wird aber **nirgends ausgewertet** (toter Knopf).
|
||
|
||
**Empfehlung: implementieren** als optionaler Take-Profit:
|
||
- Semantik: `0` = deaktiviert; sonst Prozent-Gewinnschwelle.
|
||
- Prüfung im 30-s-Live-Sync (`PollLiveAccountsAsync`): wenn
|
||
`CurrentPrice >= EntryPrice * (1 + ProfitTarget/100)` → Verkauf über die
|
||
Eskalationsleiter aus 0.1 (Startlimit = CurrentPrice), ExitReason
|
||
`"Profit Target"`.
|
||
- Zusammenspiel mit `PreRedeemLimit` beachten (beide können feuern —
|
||
PreRedeem hat Vorrang, da näher an 1.00).
|
||
|
||
### 0.4 Kleinere Konsistenz-Fixes
|
||
|
||
1. **20-Sekunden-Spam-Blockade** (`PendingOrderTimestamps`-Check am Anfang des
|
||
SELL-Pfads): blockiert aktuell auch legitime SELLs, wenn der Master < 20 s
|
||
nach dem Kauf aussteigt. Fix: Blockade nur für gleichgerichtete Orders
|
||
(BUY nach BUY), SELL nach BUY zulassen.
|
||
2. **`_state.GlobalPnl`**: wird in `PollLiveAccountsAsync`-Close-Pfaden addiert,
|
||
in `PollClosedAccountsAsync` nicht → Anzeige driftet. Vereinheitlichen.
|
||
3. **Demo-`ClosedTrade` ohne `TokenId`**: Im Demo-SELL-Pfad wird `TokenId` nicht
|
||
gesetzt (Preload von `_processedClosures` filtert auf `TokenId`). Setzen.
|
||
|
||
---
|
||
|
||
## Phase 1 — Marktdaten-Fundament (Core-Infrastruktur)
|
||
|
||
> Diese Phase gehört in **PolyTrader.Core** (`src/PolyTrader.Core/Streaming/`),
|
||
> nicht ins Modul — MarketMaking- und BundleArbitrage-Modul (separate Pläne)
|
||
> setzen sie voraus.
|
||
|
||
### 1.1 CLOB User-Channel (echte Fills in Echtzeit)
|
||
|
||
Polymarket bietet einen authentifizierten WSS-User-Channel, der Order-Events
|
||
(Platzierung, Teil-/Voll-Fill, Cancel) der eigenen Accounts pusht.
|
||
Endpoint/Protokoll bei Umsetzung verifizieren:
|
||
https://docs.polymarket.com (CLOB WSS, `user` channel; Auth via API-Key/
|
||
Secret/Passphrase — liegen je Account in `AccountState`).
|
||
|
||
Neuer Core-Service `ClobUserChannelService : BackgroundService`:
|
||
- Verbindet pro Live-Account, Auto-Reconnect mit Backoff (Muster von
|
||
`AlchemyWssClient` übernehmen).
|
||
- Publiziert Fill-Events intern (Event oder Channel), z. B.
|
||
`record OrderFillEvent(int AccountId, string TokenId, string OrderId, string Side, decimal Price, decimal Size, DateTime Ts)`.
|
||
|
||
Konsumenten im Copytrading-Modul:
|
||
- `Position.EntryPrice`/`Size` mit **echten Fill-Daten** aktualisieren
|
||
(heute: Limit-Preis als EntryPrice, Korrektur erst im 30-s-REST-Sync).
|
||
- SELL-Eskalationsleiter (Phase 0.1): Fill-Bestätigung beendet die Leiter.
|
||
- Neue Tabelle `ct_fill_log` (EF-Migration im Modul): SignalPrice, OrderPrice,
|
||
FillPrice, Latenz (Signal→Fill in ms), TraderId, AccountId, TokenId, Side.
|
||
→ Grundlage für Slippage-Statistik in Phase 3.
|
||
|
||
### 1.2 CLOB Market-Channel (Orderbücher live)
|
||
|
||
Neuer Core-Service `ClobMarketDataService`:
|
||
- Abonniert den öffentlichen `market`-Channel für eine dynamische Token-Liste
|
||
(Subscribe/Unsubscribe zur Laufzeit).
|
||
- Hält `OrderBookCache` (Best-Bid/Ask, Tiefe der obersten N Level, Timestamp).
|
||
- Interface für Konsumenten: `IOrderBookProvider.TryGetBook(tokenId, maxAgeMs)`.
|
||
- REST-Fallback `GET /book` über `PolymarketClobClient`, wenn kein Stream aktiv.
|
||
|
||
**Hinweis:** Im Modul existiert bereits ein `PolymarketWssClient` (Auto-Redeem).
|
||
Nicht verschieben/umbauen (Regression-Risiko), sondern den neuen Core-Service
|
||
parallel aufbauen; spätere Konsolidierung als separater Schritt.
|
||
|
||
### 1.3 Pre-Trade-Orderbuch-Check in der Engine
|
||
|
||
Vor jedem Live-BUY in `CopyTradingEngine.ProcessAccountOrderAsync`:
|
||
1. Buch holen (`IOrderBookProvider`, Fallback REST, Timeout ~150 ms —
|
||
bei Timeout Verhalten wie heute, nicht blockieren).
|
||
2. Checks (neue Settings in `CopyTradingAccountSettings`):
|
||
- `MaxSpreadPct` (Default z. B. 5 %): Spread größer → Skip mit Log.
|
||
- Tiefen-Check: liegt an unserem Limit-Preis genug Ask-Size für
|
||
`exactShares`? Wenn nein → Skip („Sniping-Verdacht: Liquidität bereits
|
||
konsumiert") statt teuer ins dünne Buch zu laufen.
|
||
|
||
**Akzeptanz Phase 1:** Fill-Log füllt sich mit echten Fills; TradeReasoning
|
||
zeigt Spread/Tiefe-Entscheidungen; kein messbarer Latenz-Nachteil im Hot-Path
|
||
(> 200 ms Zusatz wäre Regression).
|
||
|
||
---
|
||
|
||
## Phase 2 — SELL-Verfeinerung: Proportionalität
|
||
|
||
Heute (Proportionalitätsfilter in `CopyTradingEngine`, SELL-Pre-Flight):
|
||
verkauft der Master < 30 % seines Bestands → ignorieren; ≥ 30 % → **wir
|
||
verkaufen alles**. Information über gestaffelte Exits geht verloren.
|
||
|
||
**Ziel:** Verkaufsquote spiegeln.
|
||
1. Beim Öffnen einer Position den Master-Bestand zum Einstiegszeitpunkt
|
||
festhalten (`MasterSharesAtEntry`, im `CopyTradingState.MasterTraderPositions`
|
||
bzw. auf der Position persistieren).
|
||
2. Bei SELL-Signal: `sellRatio = signal.Size / masterSharesVorVerkauf` (wie
|
||
heute berechnet). Statt Voll-Exit: `sharesToSell = ourShares * sellRatio`.
|
||
3. Untergrenzen beachten: bleibt danach < Polymarket-Minimum (5–6 Shares) übrig
|
||
→ Voll-Exit statt Rest-Dust.
|
||
4. Kleiner Teilverkauf (< 10 %) weiterhin ignorieren (Rauschen von Day-Tradern),
|
||
Schwelle konfigurierbar (`MinSellRatioPct`).
|
||
5. Verkauf läuft immer über die Eskalationsleiter aus Phase 0.1.
|
||
|
||
Akzeptanz: Unit-Tests für die Ratio-Logik inkl. Dust-Grenzen; Logs zeigen
|
||
„Teilverkauf x % gespiegelt".
|
||
|
||
---
|
||
|
||
## Phase 3 — Trader-Intelligence (Auswahl automatisieren)
|
||
|
||
> Beim Copytrading entscheidet die Master-Auswahl über den Großteil des
|
||
> Ergebnisses. Diese Phase macht sie messbar und selbstkorrigierend.
|
||
|
||
### 3.1 Copy-PnL-Score („Kopierbarkeit")
|
||
|
||
Der `MasterTraderAnalyticsJob` misst heute den PnL des **Masters**. Relevanter
|
||
ist, was **wir** mit ihm verdient haben — inkl. unserer Slippage und Fees.
|
||
|
||
1. Neue Kennzahlen je Master aus `ct_`-Closed-Trades (`ICopyTradeLogRepository`,
|
||
Filter `SourceTraderId`, letzte 30 Tage):
|
||
- `CopyPnl30d`, `CopyProfitFactor` (Bruttogewinn/Bruttoverlust),
|
||
`CopyAvgPnlPerTrade`, `CopyTradeCount30d`.
|
||
- `AvgSlippagePct` aus `ct_fill_log` (Phase 1.1): Ø(FillPrice−SignalPrice)/SignalPrice.
|
||
2. Felder auf `TrackedTrader` ergänzen (+ EF-Migration `mod_copytrading_trackers`),
|
||
Berechnung im `MasterTraderAnalyticsJob`, Anzeige in `MastersTradersView`.
|
||
3. **Achtung Metrik-Falle:** Winrate allein ist irreführend (Favoriten-Käufer
|
||
haben 95 % Winrate und können trotzdem negativ sein). Profit-Faktor und
|
||
Ø-PnL/Trade als primäre Sortierung in der UI.
|
||
|
||
### 3.2 Sniper-/Verhaltens-Metriken in den Analytics-Job
|
||
|
||
Portierung der Logik aus `analyze_snipers.py` (liegt im Projektroot) nach C#
|
||
in den `MasterTraderAnalyticsJob`:
|
||
1. Data-API-Activity je Master über volle 3 Tage paginieren (das Skript zeigt
|
||
das Pagination-Muster; API-Limit je Request beachten).
|
||
2. Kennzahlen: `MedianHoldMinutes`, `SellWithin5MinPct` (Anteil SELLs < 5 min
|
||
nach zugehörigem BUY), `SellCount3d`.
|
||
3. Schwellen (konfigurierbar): `SellWithin5MinPct > 50 %` → Master als Sniper
|
||
flaggen: Warn-Status in UI + Threema-Hinweis. Optional Auto-Pause (siehe 3.3).
|
||
|
||
### 3.3 Automatischer Kill-Switch je Master
|
||
|
||
Neue Modul-Settings (global, z. B. in `CopyTradingState` + Persistenz):
|
||
`AutoPauseEnabled`, `AutoPauseMinTrades` (z. B. 10), `AutoPauseDrawdownUsd`
|
||
oder `-Pct`.
|
||
|
||
Regel im Analytics-Job (läuft 2×/Tag — zusätzlich stündlicher Light-Check
|
||
sinnvoll): Copy-PnL der letzten N Trades unter Schwelle → `IsActive = false`,
|
||
`Reasoning` mit Begründung + Zeitstempel befüllen, Threema-Notification.
|
||
Reaktivierung bewusst nur manuell.
|
||
|
||
**Akzeptanz Phase 3:** UI zeigt Copy-Score-Spalten; ein simulierter
|
||
Verlust-Master wird automatisch pausiert (Test mit Demo-Daten).
|
||
|
||
---
|
||
|
||
## Phase 4 — Maker-Mode & Demo-Realismus
|
||
|
||
### 4.1 Maker-Einstieg für langsame Master
|
||
|
||
Für Master mit Haltedauern von Stunden/Tagen (SwissTony/RN1-Typ) ist der
|
||
3-Sekunden-Taker-Fill unnötig teuer (Fees + Spread). Neues Verhalten
|
||
(Flag je Trader, z. B. `Category == "HOLDER"` oder eigenes Bool `MakerEntry`):
|
||
1. BUY als GTC-Limit **auf** Best-Bid (oder Mid − 1 Tick) statt über dem Ask.
|
||
2. Kein Fill nach T Minuten (konfigurierbar, z. B. 10) und Signal-Markt noch
|
||
im Preisband → auf Taker-Verhalten eskalieren oder verwerfen (Setting).
|
||
3. Fees: Maker zahlt 0 und sammelt ggf. Rebates — im Fee-Modell (0.2) abbilden.
|
||
|
||
### 4.2 Demo-Modus realistisch machen
|
||
|
||
Demo füllt heute zum Signalpreis ohne Slippage/Fees → Demo-Ergebnisse sind
|
||
systematisch geschönt und als Validierung neuer Master unbrauchbar.
|
||
|
||
Fill-Modell im Demo-Pfad der Engine:
|
||
`FillPreis = Signalpreis + halber Spread (aus IOrderBookProvider, Fallback
|
||
+1 ¢) `, Fee der Marktkategorie abziehen, beides im `ClosedTrade` ausweisen.
|
||
|
||
**Akzeptanz:** Demo- und Live-PnL desselben Masters weichen über 2 Wochen um
|
||
< 20 % relativ ab (grobe Plausibilität statt heutiger Systematik-Lücke).
|
||
|
||
---
|
||
|
||
## Offene Entscheidungen (vor Umsetzung mit Richard klären)
|
||
|
||
1. `SellFloorPct`-Default und Stufen-Timing der Eskalationsleiter (0.1).
|
||
2. `ProfitTarget`: implementieren (Empfehlung) oder Feld entfernen?
|
||
3. Auto-Pause: nur benachrichtigen oder hart deaktivieren? (Empfehlung: hart,
|
||
nachts passiert sonst genau das Falsche.)
|
||
4. Maker-Mode: als Trader-Flag oder automatisch aus `MedianHoldMinutes`
|
||
ableiten? (Empfehlung: automatisch ab z. B. Median > 60 min, manuell
|
||
überschreibbar.)
|
||
|
||
## Reihenfolge & Abhängigkeiten
|
||
|
||
```
|
||
Phase 0 (sofort, unabhängig)
|
||
└── Phase 1 (Core-Infra; parallel zu 0 möglich, Livegang nach 0)
|
||
├── Phase 2 (braucht 0.1-Leiter)
|
||
├── Phase 3 (braucht 1.1-Fill-Log für Slippage; Rest unabhängig)
|
||
└── Phase 4 (braucht 1.2-Orderbuch)
|
||
```
|