15 knowledge objects (log, note, index, module, history) migrated to C3 knowledge schema v1. Bodies unchanged, metadata preserved.
6.2 KiB
| id | type | role | representation | state | knowledge_schema |
|---|---|---|---|---|---|
| object/086b7673-c183-6ca2-52fc-6f394107c9cf | arch | history | canonical | historical | 1 |
Phase 10a — ExecutionContext-Dataclass + Versionierung + Tests (M12/M13)
Autoren: Rain Ocampo (Hermes) | Datum: 2026-08-23 Status: ABGESCHLOSSEN + DEPLOYT (Analyse/Design/Verifikation + Datenmodell/Audit/Run-Hash-Integration, OHNE Fill-Änderungen) Tags: trading, mt5, architecture, historical-v2, m12, m13, phase10a, execution-context
1. Ziel (aus Phase-9-Freigabe)
Phase 10a = ExecutionContext-Dataclass + Versionierung + Tests.
WICHTIG — NUR Datenmodell/Context/Audit/Run-Hash-Integration vorbereiten. Noch KEINE Bid/Ask-Ausführung, KEINE Spread-/Slippage-/Kostenberechnung. Danach STOPP und Bericht.
Die 7 festgelegten Entscheidungen (Christian, 22.08.2026) sind als Modellversionen und Defaults in diesem Modul kodiert — aber es wird NOCH NICHTS berechnet.
2. Modul: shared/historical/execution_context.py (NEU)
Gemeinsame Quelle für M12 UND M13 (konsistent mit DatasetContext, R1-Prinzip).
Enums (festgelegte Bezeichnungen, Entscheidung 7)
ExecutionModel:LEGACY_SINGLE_PRICE,REFERENCE_BID_ASK,BROKER_APPROXIMATION,BROKER_REPLAY,TICK_REPLAYSpreadModel:NONE,BID_ASK_INTRINSIC,SYNTHETIC_FIXED(Entscheidung 1)SlippageModel:NONE,DETERMINISTIC_FIXED(Entscheidung 3: deterministisch V1)CostModel:NONE,cost_model_v1_simple(Entscheidung 4)IntrabarPolicy:PESSIMISTIC(Default),OPTIMISTIC,STOP_FIRST,TARGET_FIRST,TICK_RESOLUTION,UNKNOWN(Entscheidung 2)
Modellversionen (pro Modell unabhängig, künftig bumpbar)
execution_context_v1, execution_model_v1, spread_model_v1, slippage_model_v1, cost_model_v1, intrabar_policy_v1.
Dataclass ExecutionContext
Felder: execution_context_version, execution_model+_version, price_basis, spread_model+_version+spread_points, slippage_model+_version+slippage_points, cost_model+_version, intrabar_policy+_version, feed_type, validation_errors.
Methoden: to_dict(), is_valid(), validate() (fail-closed bei unbekanntem Modell), Build-Helper build_execution_context().
Keine Berechnung — nur Konfiguration + Modellversionen für Hash/Audit.
3. service.py-Integration (M12 Run-Hash + Audit)
_compute_run_hash — erweitert um execution-Parameter
- Legacy (
execution=None): exakt alter Hash, unverändert (diff-verifiziert). - V2 (
executiongesetzt): fließen zusätzlich ein (Entscheidung J — Modellwerte + Versionen):execution_model,execution_model_versionprice_basisspread_model,spread_model_versionslippage_model,slippage_model_versioncost_model,cost_model_versionintrabar_policy,intrabar_policy_version
Wichtiger Befund (Reproducibility): Anfangs wurden nur die Modell-Versionen in den Hash genommen. Das war fehlerhaft: ein Wechsel
bid_ask→singleändert das Ausführungsmodell (REFERENCE_BID_ASK vs LEGACY_SINGLE_PRICE), aber die Version bliebexecution_model_v1→ identischer Hash. Korrigiert: Modellwerte UND Versionen fließen in den Hash. Testtest_andere_execution_andere_hash+test_andere_execution_version_andere_hashdecken beides ab.
Gate/Audit — ExecutionContext im V2-Pfad
- Im Gate (
ctx is not None) wird ein ExecutionContext gebaut (ausprice_basis+feed_typedes DatasetContext):price_basis=="bid_ask"→execution_model=REFERENCE_BID_ASK- sonst →
LEGACY_SINGLE_PRICE
- Das Execution-Audit (
exec_ctx.to_dict()) wird sowohl für allowed als auch blocked Runs anaudit["execution"]angehängt (auditierbar). - Der V2-run_hash nutzt dieses Execution-Audit.
4. Tests: m12_app/tests/test_phase10a_execution_context.py (11/11)
| # | Test | Zweck |
|---|---|---|
| 1 | test_default_legacy_single_price |
Defaults: LEGACY_SINGLE_PRICE, NONE-Modelle, PESSIMISTIC, keine Doppelzählung |
| 2 | test_build_reference_bid_ask |
REFERENCE_BID_ASK-Ableitung; kein künstlicher Spread |
| 3 | test_validate_fail_closed_unknown_model |
unbekanntes Modell → invalid |
| 4 | test_validate_unknown_intrabar |
unbekannte Intrabar-Policy → invalid |
| 5 | test_to_dict_roundtrip |
to_dict serialisierbar |
| 6 | test_gleiche_execution_gleicher_hash |
gleiche Execution → gleicher Hash |
| 7 | test_andere_execution_andere_hash |
bid_ask vs single → anderer Hash + Audit-Model |
| 8 | test_andere_execution_version_andere_hash |
Versions-Bump → andere Identität |
| 9 | test_legacy_kein_execution_audit |
Legacy: kein Audit, kein Execution-Dict, Hash unverändert |
| 10 | test_v2_execution_audit_present |
V2: Audit.execution vorhanden mit Modellversionen |
| 11 | test_blocked_execution_audit_present |
Blocked-Run trägt Execution-Audit |
Regression (alle grün):
- Phase 8 Gate: 13/13
- M12 Backtest: 12/12
- Phase 5: 20/20, Phase 6: 14/14, Phase 7: A–J (Legacy-Hash
8a5760…unverändert) - M13 shared A–J
5. Deploy & Verifikation (Produktion)
- Deploy:
execution_context.py+__init__.py+service.pyperdocker cpin Modul-12-Backtesting;execution_context.py+__init__.pyauch in Modul-13-Optimization (geteiltes shared/historical — sonst ImportError beiimport shared.historical). - chown auf appuser 1001 (Deploy-Pitfall, bekannt aus Phase 8).
- Restart M12 (uvicorn ohne
--reload). - Health:
/health200,/health/ready200 (via Python urllib im Container). - Legacy-Smoke PASS: beide Runs COMPLETED, run_hash
bc6e2553…+ data_hashd76a7549…identisch wie Phase 8 → Legacy unverändert. - Rollback-Backup:
/opt/trading-modules/backup_phase10a_<TS>/(service.py, shared_init.py, execution_context.py).
6. Nächster Schritt (Phase 10b, nach Freigabe)
Bid/Ask-Datenmodell + Fill — vollständige Propagation der bid/ask-OHLC durch den M12-Engine-/Execution-Pfad (Entscheidung 5), erste echte Bid/Ask-Fills (Long Entry=Ask, Exit=Bid; Short umgekehrt, Entscheidung 1). NOCH NICHT jetzt — STOPP nach dieser Phase.
7. STOPP
Phase 10a abgeschlossen. Keine Implementierung von Phase 10b. Auf Freigabe warten.