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:
@@ -3,6 +3,7 @@ from __future__ import annotations
|
||||
import asyncio
|
||||
import json
|
||||
import logging
|
||||
import os
|
||||
import socket
|
||||
import subprocess
|
||||
from contextlib import asynccontextmanager
|
||||
@@ -58,9 +59,16 @@ class BingxHttpClient:
|
||||
self._logger = logging.getLogger(__name__)
|
||||
self._config = config
|
||||
require_mainnet_opt_in(config.environment, getattr(config, "allow_mainnet", False), context="BingX HTTP client")
|
||||
# Env overrides (2026-06-10): the *.bingx.pro backup mirrors serve an
|
||||
# incomplete TLS chain (missing Cloudflare intermediate) and can never
|
||||
# verify on this host, so every failover retry was burning time on a
|
||||
# dead endpoint. Operators can point the backup at a reachable host
|
||||
# (e.g. the primary itself) without touching code.
|
||||
_env_primary = os.environ.get("DOLPHIN_BINGX_BASE_URL", "").strip()
|
||||
_env_backup = os.environ.get("DOLPHIN_BINGX_BASE_URL_BACKUP", "").strip()
|
||||
self._base_urls = (
|
||||
config.base_url_http or get_rest_base_urls(config.environment)[0],
|
||||
config.base_url_http_backup or get_rest_base_urls(config.environment)[1],
|
||||
_env_primary or config.base_url_http or get_rest_base_urls(config.environment)[0],
|
||||
_env_backup or config.base_url_http_backup or get_rest_base_urls(config.environment)[1],
|
||||
)
|
||||
self._base_hosts = tuple(urlsplit(url).hostname for url in self._base_urls)
|
||||
self._api_key = config.api_key
|
||||
|
||||
Reference in New Issue
Block a user