feat(live): alert Telegram esecuzione reale + doc shadow-execution in CLAUDE.md

- telegram_notifier: eventi REAL_EXEC_LIVE (primo ordine reale verificato per worker)
  e REAL_OPEN_FAIL (apertura reale non verificata)
- StrategyWorker: notifica una-tantum al primo REAL_OPEN verificato + ogni FAIL;
  flag real_first_notified persistito
- CLAUDE.md: documentato lo shadow-execution (ExecutionClient, lineari USDC,
  verifica sul trade, fee reali, config, alert, smoke)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
Adriano Dal Pastro
2026-06-03 10:20:08 +00:00
parent fec15c07bb
commit 719509fb2f
3 changed files with 18 additions and 1 deletions
+7
View File
@@ -55,6 +55,7 @@ class StrategyWorker:
self.real_entry_notional = 0.0 # USD effettivi esposti all'entrata
self.real_order_id = ""
self.real_trades = 0
self.real_first_notified = False # alert Telegram "esecuzione viva" una tantum
self.worker_id = f"{strategy.name}__{asset}__{tf}"
self.work_dir = data_dir / self.worker_id
@@ -116,6 +117,7 @@ class StrategyWorker:
self.real_entry_notional = state.get("real_entry_notional", 0.0)
self.real_order_id = state.get("real_order_id", "")
self.real_trades = state.get("real_trades", 0)
self.real_first_notified = state.get("real_first_notified", False)
self._log("RESUME", {"capital": round(self.capital, 2),
"total_trades": self.total_trades,
@@ -147,6 +149,7 @@ class StrategyWorker:
"real_entry_notional": self.real_entry_notional,
"real_order_id": self.real_order_id,
"real_trades": self.real_trades,
"real_first_notified": self.real_first_notified,
"last_update": datetime.now(timezone.utc).isoformat(),
}
with open(self.status_path, "w") as f:
@@ -228,8 +231,12 @@ class StrategyWorker:
if linear else fill.amount)
self.real_order_id = fill.order_id or ""
self._log("REAL_OPEN", data)
if not self.real_first_notified: # conferma una-tantum: l'esecuzione reale e' viva
self._notify("REAL_EXEC_LIVE", data)
self.real_first_notified = True
else:
self._log("REAL_OPEN_FAIL", {**data, "note": fill.notes})
self._notify("REAL_OPEN_FAIL", {**data, "note": fill.notes})
def _real_close(self, sim_exit: float, reason: str, sim_pnl: float):
"""Chiusura REALE (reduce-only della quota worker) + confronto col sim."""
+3
View File
@@ -14,6 +14,9 @@ CHAT_ID = os.environ.get("TELEGRAM_CHAT_ID", "")
NOTIFY_EVENTS = {
"SIGNAL", "OPENED", "CLOSED", "OPEN_FAILED", "CLOSE_FAILED",
"ERROR", "STARTUP", "SHUTDOWN", "TRAINING_FAILED",
# esecuzione REALE (shadow su Deribit testnet)
"REAL_EXEC_LIVE", # primo ordine reale verificato di un worker (conferma "e' vivo")
"REAL_OPEN_FAIL", # un'apertura reale NON si e' verificata (problema da guardare)
}