From 2a9e95540e7f211472c3ef31e6a3b3b21491668c Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 13 May 2026 10:12:05 +0300 Subject: [PATCH] 07.4.4.1.10.1 Semantic Diagnostic Snapshot Builder --- app/src/trading/diagnostics/__init__.py | 1 + .../trading/diagnostics/semantic_runtime.py | 238 ++++++++++++ docs/roadmap/master-roadmap.md | 28 ++ ..._1-semantic_diagnostic_snapshot_builder.md | 359 ++++++++++++++++++ 4 files changed, 626 insertions(+) create mode 100644 app/src/trading/diagnostics/__init__.py create mode 100644 app/src/trading/diagnostics/semantic_runtime.py create mode 100644 docs/stages/stage-07_4_4_1_10_1-semantic_diagnostic_snapshot_builder.md diff --git a/app/src/trading/diagnostics/__init__.py b/app/src/trading/diagnostics/__init__.py new file mode 100644 index 0000000..6c43ea2 --- /dev/null +++ b/app/src/trading/diagnostics/__init__.py @@ -0,0 +1 @@ +from __future__ import annotations \ No newline at end of file diff --git a/app/src/trading/diagnostics/semantic_runtime.py b/app/src/trading/diagnostics/semantic_runtime.py new file mode 100644 index 0000000..e0d5c95 --- /dev/null +++ b/app/src/trading/diagnostics/semantic_runtime.py @@ -0,0 +1,238 @@ +# app/src/trading/diagnostics/semantic_runtime.py + +from __future__ import annotations + +import time +from typing import Any + +from src.trading.auto.state import AutoTradeState + + +class SemanticRuntimeDiagnostics: + def build(self, state: AutoTradeState) -> dict[str, Any]: + now = time.monotonic() + + return { + "snapshot_type": "SEMANTIC_RUNTIME_DIAGNOSTIC", + "snapshot_version": "07.4.4.1.10.1", + "built_at_monotonic": now, + "status": self._status_section(state), + "signal": self._signal_section(state, now), + "market": self._market_section(state, now), + "momentum": self._momentum_section(state), + "execution": self._execution_section(state), + "adaptive_size": self._adaptive_size_section(state), + "position": self._position_section(state), + "runtime_health": self._runtime_health_section(state, now), + "summary": self._summary_section(state), + } + + def _status_section(self, state: AutoTradeState) -> dict[str, Any]: + return { + "status": state.status, + "symbol": state.symbol, + "strategy": state.strategy, + "last_check_at": state.last_check_at, + "is_configured": self._is_configured(state), + } + + def _signal_section( + self, + state: AutoTradeState, + now: float, + ) -> dict[str, Any]: + signal_age_seconds = self._age_seconds( + started_at=state.signal_started_at, + now=now, + ) + + return { + "signal": state.last_signal, + "confidence": state.last_signal_confidence, + "reason": state.last_signal_reason, + "repeat_count": state.last_signal_repeat_count, + "started_at": state.signal_started_at, + "updated_at": state.signal_updated_at, + "age_seconds": signal_age_seconds, + "decision_status": state.decision_status, + "decision_reason": state.decision_reason, + "is_confirmed": state.is_signal_confirmed, + "is_ready": state.is_signal_ready, + "confirmation_seconds": state.signal_confirmation_seconds, + "confirmation_required_seconds": state.signal_confirmation_required_seconds, + "confirmation_missing_repeats": state.signal_confirmation_missing_repeats, + "confirmation_progress": state.signal_confirmation_progress, + "confirmation_reason": state.signal_confirmation_reason, + } + + def _market_section( + self, + state: AutoTradeState, + now: float, + ) -> dict[str, Any]: + market_age_seconds = self._age_seconds( + started_at=state.market_analysis_updated_at, + now=now, + ) + + return { + "state": state.market_state, + "trend": state.market_trend, + "volatility": state.market_volatility, + "trend_strength": state.market_trend_strength, + "trend_quality": state.market_trend_quality, + "phase": state.market_phase, + "phase_direction": state.market_phase_direction, + "interval": state.market_analysis_interval, + "reason": state.market_analysis_reason, + "updated_at": state.market_analysis_updated_at, + "age_seconds": market_age_seconds, + "entry_block_reason": state.entry_block_reason, + "entry_block_message": state.entry_block_message, + } + + def _momentum_section(self, state: AutoTradeState) -> dict[str, Any]: + return { + "state": state.momentum_state, + "direction": state.momentum_direction, + "change_percent": state.momentum_change_percent, + "strength": state.momentum_strength, + "breakout_level": state.breakout_level, + "breakout_distance_percent": state.breakout_distance_percent, + "breakout_reason": state.breakout_reason, + "is_breakout": state.momentum_state in { + "BREAKOUT_UP", + "BREAKOUT_DOWN", + }, + "is_momentum": state.momentum_state in { + "MOMENTUM_UP", + "MOMENTUM_DOWN", + "BREAKOUT_UP", + "BREAKOUT_DOWN", + }, + } + + def _execution_section(self, state: AutoTradeState) -> dict[str, Any]: + return { + "quality": state.execution_quality, + "quality_reason": state.execution_quality_reason, + "quality_message": state.execution_quality_message, + "semantic_status": state.execution_semantic_status, + "semantic_message": state.execution_semantic_message, + "semantic_reason": state.execution_semantic_reason, + "confidence_score": state.execution_confidence_score, + "confidence_level": state.execution_confidence_level, + "confidence_required_score": state.execution_confidence_required_score, + "confidence_reason": state.execution_confidence_reason, + "confidence_factors": state.execution_confidence_factors, + "block_reason": state.execution_block_reason, + "snapshot_age_seconds": state.snapshot_age_seconds, + "spread_percent": state.spread_percent, + "market_runtime_degraded": state.market_runtime_degraded, + } + + def _adaptive_size_section(self, state: AutoTradeState) -> dict[str, Any]: + return { + "base_size": state.adaptive_size_base, + "final_size": state.adaptive_size_final, + "multiplier": state.adaptive_size_multiplier, + "reason": state.adaptive_size_reason, + "factors": state.adaptive_size_factors, + "effective_risk_percent": state.effective_risk_percent, + "effective_target_risk_usd": state.effective_target_risk_usd, + "size_adjustment_reason": state.execution_size_adjustment_reason, + } + + def _position_section(self, state: AutoTradeState) -> dict[str, Any]: + return { + "side": state.position_side, + "entry_price": state.entry_price, + "size": state.position_size, + "unrealized_pnl_usd": state.unrealized_pnl_usd, + "realized_pnl_usd": state.realized_pnl_usd, + "last_execution_action": state.last_execution_action, + "last_execution_reason": state.last_execution_reason, + "last_flip_block_reason": state.last_flip_block_reason, + "last_flip_at": state.last_flip_at, + } + + def _runtime_health_section( + self, + state: AutoTradeState, + now: float, + ) -> dict[str, Any]: + signal_age_seconds = self._age_seconds( + started_at=state.signal_updated_at, + now=now, + ) + market_age_seconds = self._age_seconds( + started_at=state.market_analysis_updated_at, + now=now, + ) + + return { + "runtime_expired_reason": state.runtime_expired_reason, + "runtime_expired_message": state.runtime_expired_message, + "signal_age_seconds": signal_age_seconds, + "market_age_seconds": market_age_seconds, + "has_market_data": state.market_state is not None, + "has_execution_quality": state.execution_quality is not None, + "has_signal": state.last_signal is not None, + "has_momentum_data": state.momentum_state is not None, + "is_runtime_degraded": bool(state.market_runtime_degraded), + } + + def _summary_section(self, state: AutoTradeState) -> dict[str, Any]: + blockers = [] + + if state.entry_block_message: + blockers.append(state.entry_block_message) + + if state.execution_quality == "BLOCKED": + blockers.append(state.execution_quality_message or "execution blocked") + + if state.decision_status == "BLOCKED": + blockers.append(state.decision_reason or "decision blocked") + + return { + "mode": state.status, + "signal": state.last_signal, + "market": state.market_state, + "phase": state.market_phase, + "momentum": state.momentum_state, + "execution": state.execution_semantic_status, + "position": state.position_side, + "is_trade_candidate": state.last_signal in {"BUY", "SELL"}, + "is_ready": bool(state.is_signal_ready), + "is_blocked": bool(blockers), + "blockers": blockers, + } + + def _is_configured(self, state: AutoTradeState) -> bool: + if not state.symbol: + return False + + if not state.strategy: + return False + + if state.risk_percent is None: + return False + + if state.strategy.upper() == "TREND": + return ( + state.stop_loss_percent is not None + and state.stop_loss_percent > 0 + ) + + return True + + def _age_seconds( + self, + *, + started_at: float | None, + now: float, + ) -> int | None: + if started_at is None: + return None + + return max(0, int(now - float(started_at))) \ No newline at end of file diff --git a/docs/roadmap/master-roadmap.md b/docs/roadmap/master-roadmap.md index 6f439e3..a1a92c9 100644 --- a/docs/roadmap/master-roadmap.md +++ b/docs/roadmap/master-roadmap.md @@ -1157,6 +1157,34 @@ --- +### 07.4.4.1.10 Semantic Runtime Diagnostics & Observability + +#### 07.4.4.1.10.1 ✅ Semantic Diagnostic Snapshot Builder +- реализован semantic diagnostic snapshot builder +- реализован diagnostic runtime aggregation layer +- реализован единый semantic diagnostic snapshot +- реализована агрегация signal diagnostics +- реализована агрегация decision diagnostics +- реализована агрегация market semantic diagnostics +- реализована агрегация momentum / breakout diagnostics +- реализована агрегация execution quality diagnostics +- реализована агрегация execution confidence diagnostics +- реализована агрегация adaptive sizing diagnostics +- реализована агрегация runtime expiration diagnostics +- runtime diagnostics вынесены в отдельный read-only слой +- diagnostic layer не меняет торговую логику +- diagnostic layer подготовлен к Telegram Diagnostic Screen +- diagnostic layer подготовлен к Human-readable formatter +- diagnostic layer подготовлен к Diagnostic Journal Layer +- diagnostic layer подготовлен к Auto-refresh Diagnostic UI +- execution runtime стал explainability-ready +- execution runtime стал diagnostic-aware +- execution runtime стал semantic-state-aware +- execution runtime подготовлен к professional observability layer +- execution runtime подготовлен к institutional execution diagnostics + +--- + ### 07.4.5 ⏳ Scalping Strategy diff --git a/docs/stages/stage-07_4_4_1_10_1-semantic_diagnostic_snapshot_builder.md b/docs/stages/stage-07_4_4_1_10_1-semantic_diagnostic_snapshot_builder.md new file mode 100644 index 0000000..5d542c6 --- /dev/null +++ b/docs/stages/stage-07_4_4_1_10_1-semantic_diagnostic_snapshot_builder.md @@ -0,0 +1,359 @@ +# 07.4.4.1.10.1 Semantic Diagnostic Snapshot Builder + +## Цель этапа + +Этап **07.4.4.1.10.1 Semantic Diagnostic Snapshot Builder** направлен на создание отдельного диагностического слоя, который собирает текущее состояние автоторговли в единый semantic snapshot. + +После внедрения предыдущих semantic-слоёв runtime начал анализировать не только торговый сигнал, но и качество рынка, тренда, фазы, momentum, breakout, execution confidence, execution quality и adaptive sizing. Однако эти данные были распределены по разным полям `AutoTradeState`, payload стратегии, execution runtime и UI. + +Цель этапа — собрать все ключевые runtime-факторы в одну структурированную диагностическую модель, чтобы дальше на её основе построить: +- human-readable diagnostic formatter +- отдельный Telegram diagnostic screen +- diagnostic journal layer +- auto-refresh diagnostic UI +- расширенную проверку причин HOLD / BLOCKED / READY +- прозрачную диагностику market / signal / execution / sizing context + +--- + +# Что реализовано + +## Реализован Semantic Diagnostic Snapshot Builder + +Добавлен отдельный слой диагностики, который формирует единый snapshot текущего состояния автоторговли. + +Snapshot Builder агрегирует данные из: +- AutoTrade runtime state +- signal runtime +- decision runtime +- market semantic layer +- momentum / breakout semantic layer +- execution quality layer +- execution confidence layer +- adaptive sizing layer +- runtime expiration layer +- position / PnL context + +Вместо ручного просмотра отдельных полей теперь появляется единая точка сборки диагностики. + +--- + +## Реализована диагностическая модель runtime-состояния + +Diagnostic Snapshot Builder структурирует данные по смысловым блокам: + +- **status block** — режим автоторговли и базовый runtime context +- **signal block** — текущий сигнал, уверенность, повторы, длительность и причина +- **decision block** — статус решения, готовность сигнала и причина блокировки / ожидания +- **market block** — состояние рынка, тренд, волатильность, сила и качество тренда +- **market phase block** — фаза рынка, направление фазы и причина классификации +- **momentum block** — momentum state, direction, strength, breakout level и breakout distance +- **execution block** — execution quality, semantic status, confidence score и confidence level +- **sizing block** — adaptive size multiplier, effective risk и причина изменения размера +- **position block** — текущая позиция, entry price, position size и unrealized PnL +- **runtime block** — snapshot age, spread, stale/runtime expiration diagnostics + +--- + +## Реализована подготовка к отдельному диагностическому экрану + +Этап создаёт foundation для будущего Telegram Diagnostic Screen. + +Диагностический экран сможет показывать не только короткие строки вида: +- `📉 Рынок · снижение` +- `🧩 Фильтр · слабый импульс` +- `⚡️ Импульс · вниз` + +но и полную расшифровку: +- почему рынок классифицирован именно так +- почему вход заблокирован +- почему сигнал не READY +- какой фактор снижает confidence +- какой слой ограничивает adaptive sizing +- есть ли momentum / breakout +- является ли движение продолжением, откатом или слабым импульсом +- насколько свежий snapshot +- есть ли spread / execution degradation + +--- + +# Что изменилось в аналитике + +## Аналитика стала собираться в единый semantic snapshot + +До этапа 07.4.4.1.10.1 аналитические данные существовали в runtime, но были распределены по нескольким слоям: + +- market analysis payload +- strategy payload +- AutoTradeState fields +- execution confidence factors +- adaptive sizing factors +- execution quality fields +- Telegram UI semantic lines + +Теперь появляется единая структура, которая объединяет эти данные в один диагностический объект. + +Это важно, потому что последующие этапы диагностики смогут работать не с разрозненными runtime-полями, а с одним snapshot, который уже содержит полную картину торгового контекста. + +--- + +## Реализована explainable diagnostic aggregation + +Snapshot Builder не принимает торговые решения сам. Его задача — объяснить уже существующее состояние runtime. + +Он собирает: +- что сейчас видит стратегия +- какой сигнал сформирован +- почему сигнал удерживается или блокируется +- что говорит market semantic layer +- что говорит momentum / breakout layer +- что говорит execution quality layer +- что говорит execution confidence layer +- что говорит adaptive sizing layer +- какой итоговый runtime context сложился + +Таким образом, runtime становится не только исполняющим, но и объяснимым. + +--- + +## Диагностика стала пригодной для UI и журнала + +Данные snapshot builder подготовлены так, чтобы их можно было использовать сразу в нескольких слоях: + +- Telegram diagnostic screen +- compact human-readable formatter +- expanded diagnostic formatter +- journal payload +- debug output +- future AI interpretation layer + +Это отделяет диагностическую модель от конкретного способа отображения. + +--- + +## Подготовлена аналитика причин HOLD + +Одна из главных задач этапа — подготовить основу для объяснения, почему бот не входит в сделку. + +Snapshot Builder собирает факторы, которые могут удерживать систему в HOLD: +- market filter blocked +- weak market trend +- noisy market trend +- pullback phase +- weak live impulse +- not enough live data +- low execution confidence +- stale snapshot +- high spread +- adaptive size zero +- signal confirmation pending + +В дальнейшем formatter сможет превращать эти данные в понятное объяснение для пользователя. + +--- + +## Подготовлена аналитика причин READY / BLOCKED + +Диагностический snapshot также фиксирует, почему сигнал стал READY или почему был заблокирован. + +В snapshot попадают: +- decision status +- decision reason +- signal confirmation progress +- repeat count +- confirmation seconds +- execution confidence score +- execution confidence level +- execution confidence reason +- execution semantic status +- execution semantic message + +Это позволит на следующих этапах сделать отдельный экран, где будет видно не только итоговое состояние, но и путь к нему. + +--- + +## Подготовлена аналитика market semantics + +Snapshot Builder собирает все данные, появившиеся в semantic market layer: + +- market state +- market trend +- market volatility +- market trend strength +- market trend quality +- market phase +- market phase direction +- market analysis reason + +Это позволит диагностическому экрану объяснять, почему рынок считается: +- трендовым +- слабым +- шумным +- импульсным +- откатным +- флетовым +- сжатым +- слишком волатильным + +--- + +## Подготовлена аналитика momentum / breakout semantics + +Snapshot Builder также собирает данные из momentum / breakout layer: + +- momentum state +- momentum direction +- momentum change percent +- momentum strength +- breakout level +- breakout distance percent +- breakout reason + +Это особенно важно для ситуаций, когда основной market state ещё выглядит слабым или неподходящим, но рынок уже показывает быстрый directional acceleration или breakout. + +Диагностика сможет показать, является ли движение: +- обычным шумом +- краткосрочным momentum +- подтверждённым breakout +- быстрым продолжением +- потенциальным ложным пробоем + +--- + +## Подготовлена аналитика execution confidence + +Snapshot Builder собирает execution confidence diagnostics: + +- execution confidence score +- execution confidence level +- execution confidence required score +- execution confidence reason +- execution confidence factors + +Это даёт возможность объяснять, почему вход разрешён или заблокирован не только через сигнал стратегии, но и через совокупную оценку качества execution context. + +--- + +## Подготовлена аналитика adaptive sizing + +В snapshot попадают данные adaptive sizing: + +- adaptive size base +- adaptive size final +- adaptive size multiplier +- adaptive size reason +- adaptive size factors +- effective risk percent +- effective target risk USD + +Это позволит видеть, почему размер позиции: +- не изменён +- уменьшен +- сильно уменьшен +- увеличен +- заблокирован + +--- + +## Подготовлена аналитика execution quality + +Snapshot Builder собирает execution quality diagnostics: + +- execution quality +- execution quality reason +- execution quality message +- snapshot age seconds +- spread percent +- market runtime degraded + +Это позволит диагностировать проблемы с исполнением: +- stale snapshot +- aging snapshot +- high spread +- unavailable depth snapshot +- snapshot error +- degraded market runtime + +--- + +# Интеграция с текущей архитектурой + +Этап 07.4.4.1.10.1 не меняет торговую логику входа напрямую. + +Он добавляет аналитический диагностический слой поверх текущей runtime architecture. + +Интеграция выполнена так, чтобы не ломать: +- AutoTradeService +- TrendStrategy +- ExecutionEngine +- текущий Telegram UI +- adaptive sizing +- execution confidence +- market semantic layer +- momentum / breakout semantic layer + +Diagnostic Snapshot Builder является read-only слоем: он читает текущее состояние и формирует структурированную диагностическую картину. + +--- + +# Результат этапа + +После этапа 07.4.4.1.10.1 система получила foundation для полноценной semantic diagnostics architecture. + +Runtime теперь подготовлен к тому, чтобы объяснять: +- что сейчас происходит на рынке +- почему бот держит HOLD +- почему вход заблокирован +- почему сигнал подтверждается +- почему сигнал READY +- какой слой ограничивает execution +- какой слой уменьшает размер позиции +- есть ли momentum или breakout +- является ли рынок пригодным для входа +- является ли execution context качественным + +--- + +# Что подготовлено для следующих этапов + +Этап 07.4.4.1.10.1 подготовил основу для: + +## 07.4.4.1.10.2 Human-readable formatter +- преобразование diagnostic snapshot в понятный текст +- короткий и расширенный формат диагностики +- объяснение причин HOLD / BLOCKED / READY +- человекочитаемые market / signal / execution / sizing diagnostics + +## 07.4.4.1.10.3 Telegram Diagnostic Screen +- отдельный экран диагностики в Telegram +- кнопка перехода из AutoTrade UI +- отображение полного semantic snapshot +- разделение краткого UI и расширенной диагностики + +## 07.4.4.1.10.4 Diagnostic Journal Layer +- запись диагностических событий в журнал +- explainable diagnostic payload +- история изменений market / signal / execution context +- анализ причин блокировок и слабых входов + +## 07.4.4.1.10.5 Auto-refresh Diagnostic UI +- автообновление диагностического экрана +- semantic refresh filtering +- обновление при изменении diagnostic snapshot +- защита от volatile timer refresh spam + +--- + +# Итог + +Этап 07.4.4.1.10.1 сделал runtime более explainable и подготовил систему к полноценной диагностике. + +Система стала: +- diagnostic-aware +- semantic-state-aware +- explainability-ready +- UI-diagnostics-ready +- journal-diagnostics-ready +- лучше подготовленной к анализу причин HOLD / BLOCKED / READY +- ближе к professional runtime observability layer +- ближе к institutional execution diagnostics architecture