Snapshot PINK DITAv2 system + Sprint 0 flaw-fix verification
First commit of the previously-untracked PINK-on-DITAv2 migration system (execution moves to the Rust kernel; policy stays on legacy DITA, so Alpha Engine algorithmic integrity is preserved). BLUE is untouched. Sprint 0 (safety snapshot + flaw-fix verification, MARKET single-leg scope): - Verified Rust FSM fixes (flaws 2,4,10,11,13) by source read of lib.rs. - Hardened 5 vacuous/guarded assertions in test_flaws.py so each flaw test genuinely exercises its fix. Most important: Flaw 5 now asserts capital moves by EXACTLY realized PnL (was entering/exiting at the same price). - Offline suites: 533 passed, 0 failed (35 flaws + 402 kernel/accounting/ bridge + 96 runtime/persistence/multi-exit/restart/seams). - GATE PASS: MARKET-path-critical flaws 1,2,5 confirmed fixed + green. - Added SPRINT0_FLAW_VERIFICATION.md report and _rust_kernel/.gitignore (excludes Rust target/ build artifacts). LIMIT/partial-fill remain explicitly out of scope (MARKET-only bring-up). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
97
prod/clean_arch/dita_v2/projection.py
Normal file
97
prod/clean_arch/dita_v2/projection.py
Normal file
@@ -0,0 +1,97 @@
|
||||
"""Hazelcast-compatible projection helpers for DITAv2."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from dataclasses import dataclass
|
||||
from datetime import datetime
|
||||
import os
|
||||
from typing import Any, Callable, Dict, Iterable, List, Optional
|
||||
|
||||
from .account import AccountProjection
|
||||
from .contracts import KernelTransition, TradeSlot, TradeStage, VenueEvent
|
||||
from .control import KernelControlSnapshot
|
||||
from .journal import _transition_row
|
||||
from .utils import json_safe
|
||||
|
||||
Writer = Callable[[str, Dict[str, Any]], None]
|
||||
|
||||
|
||||
@dataclass
|
||||
class HazelcastProjection:
|
||||
"""Projection helper for BLUE/PINK-compatible durable writes."""
|
||||
|
||||
active_slots_map: str = "hz:dita_active_slots"
|
||||
trade_events_topic: str = "hz:dita_trade_events"
|
||||
control_map: str = "hz:dita_control"
|
||||
writer: Optional[Writer] = None
|
||||
control_snapshot: Optional[KernelControlSnapshot] = None
|
||||
|
||||
def write_slot(self, slot: TradeSlot) -> Dict[str, Any]:
|
||||
row = build_position_state_row(slot, self.control_snapshot)
|
||||
if self.writer is not None:
|
||||
self.writer(self.active_slots_map, row)
|
||||
return row
|
||||
|
||||
def write_transition(
|
||||
self,
|
||||
*,
|
||||
transition: KernelTransition,
|
||||
slot: TradeSlot,
|
||||
event: Optional[VenueEvent] = None,
|
||||
control: Optional[KernelControlSnapshot] = None,
|
||||
) -> Dict[str, Any]:
|
||||
row = _transition_row(transition=transition, slot=slot, event=event, control=control)
|
||||
if self.writer is not None:
|
||||
self.writer(self.trade_events_topic, row)
|
||||
return row
|
||||
|
||||
def write_control(self, control: KernelControlSnapshot) -> Dict[str, Any]:
|
||||
self.control_snapshot = control
|
||||
row = control.as_dict()
|
||||
if self.writer is not None:
|
||||
self.writer(self.control_map, row)
|
||||
return row
|
||||
|
||||
|
||||
def build_projection(
|
||||
*,
|
||||
writer: Optional[Writer] = None,
|
||||
client: Optional[Any] = None,
|
||||
prefer_real_hazelcast: Optional[bool] = None,
|
||||
control_snapshot: Optional[KernelControlSnapshot] = None,
|
||||
) -> HazelcastProjection:
|
||||
"""Build the active projection helper with an operator-visible switch.
|
||||
|
||||
The default remains the callback-based projection helper. If a Hazelcast
|
||||
client is supplied and the caller opts in via ``prefer_real_hazelcast`` or
|
||||
``DITA_V2_HAZELCAST=REAL``, the helper routes directly through the
|
||||
client-backed map/topic writer path.
|
||||
"""
|
||||
|
||||
env_choice = os.environ.get("DITA_V2_HAZELCAST", "").strip().upper()
|
||||
real_requested = prefer_real_hazelcast if prefer_real_hazelcast is not None else env_choice in {"REAL", "REAL_HZ", "HAZELCAST"}
|
||||
if real_requested and client is not None:
|
||||
try:
|
||||
from .hazelcast_projection import HazelcastRowWriter
|
||||
|
||||
writer = HazelcastRowWriter(client)
|
||||
except Exception:
|
||||
pass
|
||||
return HazelcastProjection(writer=writer, control_snapshot=control_snapshot)
|
||||
|
||||
|
||||
def build_position_state_row(slot: TradeSlot, control: Optional[KernelControlSnapshot] = None) -> Dict[str, Any]:
|
||||
"""Build a state row shaped for durable compatibility."""
|
||||
row = slot.to_dict()
|
||||
row.update(
|
||||
{
|
||||
"runtime_namespace": control.runtime_namespace if control else "dita_v2",
|
||||
"strategy_namespace": control.strategy_namespace if control else "dita_v2",
|
||||
"event_namespace": control.event_namespace if control else "dita_v2",
|
||||
"actor_name": control.actor_name if control else "ExecutionKernel",
|
||||
"exec_venue": control.exec_venue if control else "bingx",
|
||||
"data_venue": control.data_venue if control else "binance",
|
||||
"ledger_authority": control.ledger_authority if control else "exchange",
|
||||
}
|
||||
)
|
||||
return row
|
||||
Reference in New Issue
Block a user