105 lines
5.1 KiB
Markdown
105 lines
5.1 KiB
Markdown
---
|
||
type: Note
|
||
_organized: true
|
||
---
|
||
|
||
# Phase 10c — Deterministische Slippage (DETERMINISTIC_FIXED)
|
||
|
||
**Geändert von:** Rain Ocampo (Hermes)
|
||
**Datum:** 23.08.2026
|
||
**Grund:** Deterministische Slippage-Komponente `DETERMINISTIC_FIXED` als zusätzliche, eigenständige Ausführungskomponente auf Basis von `LEGACY_SINGLE_PRICE` / `REFERENCE_BID_ASK` — formal/verifikativ abgeschlossen nach Deploy.
|
||
|
||
## Zusammenfassung
|
||
|
||
Phase 10c führt ein **deterministisches Slippage-Modell** (`slippage_model = DETERMINISTIC_FIXED`, Version `slippage_model_v1`) ein. Slippage ist eine **zusätzliche, eigenständige Komponente** auf dem Fill-Preis — **getrennt vom Spread**. Der Spread bleibt beim Ausführungspfad `REFERENCE_BID_ASK` intrinsisch (`BID_ASK_INTRINSIC`); Slippage wird **erst danach** auf den Fill-Preis aufgeschlagen. Legacy (`LEGACY_SINGLE_PRICE`) bleibt byte-identisch unverändert.
|
||
|
||
## Modell & Einheit
|
||
|
||
- **`DETERMINISTIC_FIXED`** + `slippage_model_version = slippage_model_v1`
|
||
- `slippage_unit = PRICE` → absolute Preisdistanz (keine implizite Umrechnung; Audit zeigt Einheit)
|
||
- **Kein** Random/Seed/Volatilität/Liquidität — reproduzierbar
|
||
- `NONE` (Default) vs `FIXED(0)`: **gleiche Fillpreise/PnL**, aber **unterschiedlicher ExecutionContext/run_hash** — gewollt
|
||
|
||
## Adverse Slippage-Semantik
|
||
|
||
- **LONG ENTRY** = ASK + slip, **LONG EXIT** = BID − slip
|
||
- **SHORT ENTRY** = BID − slip, **SHORT EXIT** = ASK + slip
|
||
- Basis: LONG Entry=ASK / Exit=BID, SHORT Entry=BID / Exit=ASK (unverändert)
|
||
- BUY → höher, SELL → tiefer (adversarial)
|
||
|
||
## Trigger ≠ Fill
|
||
|
||
- Stop/Target-Trigger laufen gegen **Basis-Preise** (ohne Slippage)
|
||
- Slippage erst auf den **Fill-Preis** — kein Doppel-Aufschlag
|
||
|
||
## Fail-Closed (15)
|
||
|
||
- `DETERMINISTIC_FIXED` ohne gültigen Wert → blockiert
|
||
- negativ/NaN/Inf/nichtnumerisch → ungültig
|
||
- unbekannte Einheit → ungültig
|
||
- `NONE`/Default → 0.0, V2-Pfad unverändert
|
||
|
||
## ExecutionContext / run_hash / Audit
|
||
|
||
- ExecutionContext Default: `NONE`/0.0; V2-Pfad unverändert, wenn nicht gesetzt
|
||
- `run_hash` inkl. `slippage_value` + `slippage_unit` (18)
|
||
- Audit: `entry/exit_market_price`/`fill_price`/`slippage` (19)
|
||
- gleiche Slippage-Konfig 2× → **identischer** run_hash; 0.10 vs 0.20 → anderer; NONE vs FIXED(0) → anderer
|
||
- Audit exakt = ExecutionContext
|
||
|
||
## Legacy byte-identisch (21)
|
||
|
||
- `params["slippage"]` unverändert (Legacy-Slippage-Feld)
|
||
- **kein** V2-Slippage-Audit im Legacy-Pfad
|
||
- **kein** DatasetGate-Block im Legacy-Pfad
|
||
|
||
## Beweis (Tests)
|
||
|
||
| Suite | Ergebnis |
|
||
|---|---|
|
||
| Phase10cSlippage | **30/30** grün (inkl. symmetrischer PnL-Beweis: LONG +2.80 / SHORT +2.80, slip 0.10) |
|
||
| Phase10bFixtureE2E | **8/8** grün |
|
||
| Phase10bEngine | **7/7** grün |
|
||
| Phase10a (execution_context) | **15/15** grün |
|
||
| Phase8 | **14/14** grün |
|
||
| Phase6/5 | 14/14 / 20/20 grün |
|
||
| M13Shared A–J + M13Compat | grün |
|
||
| **Gesamtsuite (Runner, nach Deploy)** | **2× alle 12 Suiten grün** |
|
||
|
||
## Deployment (kontrollierter Minimal-Deploy, Backup + Rollback)
|
||
|
||
- **Backup:** `/opt/data/m12m13_work/backup_phase10c_deploy_20260823_095549/` (m12 5 Dateien, sha256-verifiziert)
|
||
- **M12** (`Modul-12-Backtesting`): `core/pricing.py`, `core/engine.py`, `core/service.py`, `api/schemas.py`, `shared/historical/execution_context.py`
|
||
- **Verifikation:** Backup+sha256 VORHER, `docker cp`, `chown 1001:1001`, py_compile OK, Import-Smoke OK, Restart; `/health`=200, `/health/ready`=`{"status":"ready","db":"ok"}` (10.0.13.16:55012, intern)
|
||
- **M13**: `shared/execution_context.py` vorhanden, /health+ready grün (10.0.13.9:55013)
|
||
- **KEINE Phase 10d, keine IG-Calls/Orders, keine V2-Produktivaktivierung**
|
||
|
||
## V2-Runtime-Smoke (nach Deploy)
|
||
|
||
- `DETERMINISTIC_FIXED` importierbar
|
||
- `SlippageUnit.PRICE` importierbar
|
||
- `BID_ASK_INTRINSIC` weiterhin korrekt
|
||
- `slippage_amount(exec)` liefert erwarteten Wert (0.0001 für FIXED 0.0001)
|
||
- LONG entry +slip / SHORT entry −slip (adversarial)
|
||
- Audit/ExecutionContext serialisierbar, keine Importfehler
|
||
|
||
## Legacy-Produktions-Smoke (nach Deploy, 2 Runs A/B)
|
||
|
||
- **run_hash: `bc6e25533d22ee102b6921eeeccd8f7b7dff4ec74a3316e381007ec56b0e1b37`** (A=B, deterministisch)
|
||
- **data_hash: `d76a75496453d9c05d5690237f4621534f954f9f3e87b67eee4ae9327c5c6bb9`** (A=B, identisch Phase 8)
|
||
- **net_pnl: 196.586062** (A=B), total_trades 1, LONG 1/SHORT 0
|
||
- Trades/Fills/PnL identisch; **Legacy-Slippage unverändert**; kein V2-Audit; kein Gate-Block
|
||
|
||
## Produktions-Gate (Final Check)
|
||
|
||
- M12: `/health`=200, `/health/ready`=200, `HISTORICAL_DATA_SOURCE=UNSET` (legacy), `ALLOW_FIXTURE_DATA=UNSET` (false)
|
||
- M13: `/health`=200, `/health/ready`=200, Gates UNSET
|
||
- Keine V2-Produktivläufe, keine Fixture-Aktivierung, keine verwaisten Testprozesse
|
||
- M13-Optimizer-Parameterraum enthält **kein** `slippage_model/value/unit`; keine Execution-/Cost-Parameter optimierbar
|
||
|
||
## Bekannte Grenzen
|
||
|
||
- NONE vs FIXED(0) → unterschiedlicher run_hash (gewollt, kein Fehler)
|
||
- Fixture-E2E nur mit `ALLOW_FIXTURE_DATA=true` (test-only); danach garantiert false/unset
|
||
- M13-Optimizer nutzt das neue Slippage-Modell **nicht** im Parameterraum (Legacy-`slippage`-Feld bleibt)
|
||
- Kein Random-/Volatilitäts-Slippage implementiert (bewusst, Scope-10c)
|