PINK Phase 0: FET -$5,990 fix batch — leverage-free PnL, true fill prices, reconcile baseline anchors

Defects fix (FET -$5,990 replay, 2026-06-11):
- realized_pnl() and mark_price(): PnL = qty × Δprice, side-signed; no ×leverage inflation (was 3× every leg).
- BingX MARKET fill events carry true fill price (avgPrice/lastFillPrice), never the order's nominal price (protective bound ±20-25% from mark, poisoned PnL to -$5,990 on a +$164 round-trip).
- Fill routing by ORDER IDENTITY first, FSM state second — late entry-remainder fills during EXIT_WORKING no longer misclassify as exits.
- Entry basis = VWAP across entry fills, not last fill price.
- reconcile_from_slots / restore_state: re-anchor _last_settled_pnl / _slot_was_closed to adopted slot state (cross-restart double-book of carried PnL).
- ACCOUNT_UPDATE with wallet_balance=0 dropped (margin-only frames no longer zero e_available_margin).
- Foreign-fill skip on shared VST account (PRODGREEN collision filter).
- exec_router TTL: entry-requote venue-truth gate (recent own fill + live exchange position probes prevent double-entry).
- bingx_direct: openOrders fetched BEFORE positions (sequential ordering prevents dangerous tear → double-entries).
- Dual-leverage translation via map_internal_conviction_to_exchange_leverage() (strategy conviction → integer at-exchange leverage, bankers rounding).
- BLUE-parity alpha components wired: asset picker (IRP universe ranking) + alpha sizer (cubic-convex dynamic leverage, 0.5-8.0 range).
- ch_writer: date_time_input_format=best_effort on insert URLs; flush error logging at WARNING with counter.
- blue_parity.price_of(): hyphen-tolerant fallback (FET-USDT → FETUSDT).
- Fill test updated to incremental filled_size semantics (BingX WS lastFilledQty).
- Env-override base URLs, supervisord autorestart, per-asset DC histories, single-slot invariant, fill-attribution filter.

Co-authored-by: CommandCodeBot <noreply@commandcode.ai>
This commit is contained in:
Codex
2026-06-11 20:53:49 +02:00
parent 9e210b5a02
commit 2c9da8f592
10 changed files with 929 additions and 50 deletions

View File

@@ -288,19 +288,51 @@ def _build_runtime(*, phase: PinkPhase) -> PinkDirectRuntime:
# DOLPHIN_PINK_VEL_DIV_THRESHOLD: relax for on-exchange debugging (e.g. -0.005).
# Default -0.02 matches BLUE production. BLUE is unaffected.
_vel_div_threshold = float(os.environ.get("DOLPHIN_PINK_VEL_DIV_THRESHOLD", "-0.02"))
# BLUE-parity sizing (SYSTEM BIBLE §6, restored 2026-06-10): cubic-convex
# dynamic leverage over [min, max] strategy conviction. BLUE production
# runs 0.58.0 convexity 3. The integer at-exchange leverage is derived
# separately at the venue boundary (prod/bingx/leverage.py conviction map,
# security-capped). Previously PINK pinned every entry at 3.0x flat.
_min_leverage = float(os.environ.get("DOLPHIN_PINK_MIN_LEVERAGE", "0.5"))
_max_leverage = float(os.environ.get("DOLPHIN_PINK_MAX_LEVERAGE", "8.0"))
_convexity = float(os.environ.get("DOLPHIN_PINK_LEVERAGE_CONVEXITY", "3.0"))
_vel_div_extreme = min(_vel_div_threshold * 2.5, -0.001)
cfg = DecisionConfig(
vel_div_threshold=_vel_div_threshold,
vel_div_extreme=min(_vel_div_threshold * 2.5, -0.001),
vel_div_extreme=_vel_div_extreme,
fixed_tp_pct=float(os.environ.get("DOLPHIN_FIXED_TP_PCT", "0.0020")),
max_hold_bars=int(os.environ.get("DOLPHIN_MAX_HOLD_BARS", "250")),
capital_fraction=0.20,
max_leverage=3.0,
max_leverage=_max_leverage,
allow_short=True,
allow_long=False,
policy_version="pink_ditav2_v1",
exit_leg_ratios=_resolve_pink_exit_leg_ratios(phase),
)
decision = DecisionEngine(cfg)
# BLUE-parity alpha components. Kill switches: DOLPHIN_PINK_ALPHA_SIZER=0
# restores the legacy flat-leverage formula; DOLPHIN_PINK_ASSET_SELECTION=0
# restores single-symbol (snapshot anchor) trading.
alpha_sizer = None
asset_picker = None
if _env_bool("DOLPHIN_PINK_ALPHA_SIZER", True):
from prod.clean_arch.dita_v2.blue_parity import PinkAlphaSizer
alpha_sizer = PinkAlphaSizer(
base_fraction=0.20,
min_leverage=_min_leverage,
max_leverage=_max_leverage,
leverage_convexity=_convexity,
vel_div_threshold=_vel_div_threshold,
vel_div_extreme=_vel_div_extreme,
use_dynamic_leverage=_env_bool("DOLPHIN_PINK_DYNAMIC_LEVERAGE", True),
use_alpha_layers=_env_bool("DOLPHIN_PINK_ALPHA_LAYERS", True),
)
if _env_bool("DOLPHIN_PINK_ASSET_SELECTION", True):
from prod.clean_arch.dita_v2.blue_parity import PinkAssetPicker
asset_picker = PinkAssetPicker(
lookback=int(os.environ.get("DOLPHIN_PINK_IRP_LOOKBACK", "0") or 0),
min_irp_alignment=float(os.environ.get("DOLPHIN_PINK_MIN_IRP_ALIGNMENT", "0.0")),
)
decision = DecisionEngine(cfg, sizer=alpha_sizer)
intent = IntentEngine(cfg)
# DITAv2 execution bundle: kernel + venue + control + Zinc + projection.
@@ -337,6 +369,8 @@ def _build_runtime(*, phase: PinkPhase) -> PinkDirectRuntime:
persistence=persistence,
market_state_runtime=market_state_runtime,
hz_state_writer=hz_state_writer,
asset_picker=asset_picker,
alpha_sizer=alpha_sizer,
)