07.4.4.1.10.2 Human-readable formatter

This commit is contained in:
2026-05-13 10:18:43 +03:00
parent 2a9e95540e
commit 8e1c09ad66
4 changed files with 587 additions and 0 deletions

View File

@@ -0,0 +1,200 @@
# app/src/trading/diagnostics/formatter.py
from __future__ import annotations
from typing import Any
class SemanticDiagnosticFormatter:
def format(self, snapshot: dict[str, Any]) -> str:
sections: list[str] = []
status = snapshot.get("status", {})
signal = snapshot.get("signal", {})
market = snapshot.get("market", {})
momentum = snapshot.get("momentum", {})
execution = snapshot.get("execution", {})
adaptive = snapshot.get("adaptive_size", {})
runtime = snapshot.get("runtime_health", {})
summary = snapshot.get("summary", {})
position = snapshot.get("position", {})
sections.extend(
[
"🧠 Semantic Runtime Diagnostics",
"",
self._status_block(status),
self._signal_block(signal),
self._market_block(market),
self._momentum_block(momentum),
self._execution_block(execution),
self._adaptive_block(adaptive),
self._position_block(position),
self._runtime_block(runtime),
self._summary_block(summary),
]
)
return "\n".join(
line
for line in sections
if line is not None
).strip()
def _status_block(self, data: dict[str, Any]) -> str:
return (
"📦 Runtime\n"
f"• Status: {data.get('status')}\n"
f"• Symbol: {data.get('symbol')}\n"
f"• Strategy: {data.get('strategy')}\n"
f"• Configured: {self._bool(data.get('is_configured'))}\n"
)
def _signal_block(self, data: dict[str, Any]) -> str:
return (
"📡 Signal\n"
f"• Signal: {data.get('signal')}\n"
f"• Confidence: {self._float(data.get('confidence'))}\n"
f"• Decision: {data.get('decision_status')}\n"
f"• Confirmed: {self._bool(data.get('is_confirmed'))}\n"
f"• Ready: {self._bool(data.get('is_ready'))}\n"
f"• Repeats: {data.get('repeat_count')}\n"
f"• Progress: {self._percent(data.get('confirmation_progress'))}\n"
f"• Age: {self._seconds(data.get('age_seconds'))}\n"
f"• Reason: {data.get('reason')}\n"
)
def _market_block(self, data: dict[str, Any]) -> str:
return (
"📈 Market\n"
f"• State: {data.get('state')}\n"
f"• Trend: {data.get('trend')}\n"
f"• Volatility: {data.get('volatility')}\n"
f"• Strength: {data.get('trend_strength')}\n"
f"• Quality: {data.get('trend_quality')}\n"
f"• Phase: {data.get('phase')}\n"
f"• Phase Direction: {data.get('phase_direction')}\n"
f"• Entry Block: {data.get('entry_block_message')}\n"
f"• Analysis Age: {self._seconds(data.get('age_seconds'))}\n"
)
def _momentum_block(self, data: dict[str, Any]) -> str:
return (
"⚡ Momentum / Breakout\n"
f"• State: {data.get('state')}\n"
f"• Direction: {data.get('direction')}\n"
f"• Strength: {self._float(data.get('strength'))}\n"
f"• Change %: {self._float(data.get('change_percent'))}\n"
f"• Breakout Level: {self._float(data.get('breakout_level'))}\n"
f"• Breakout Distance %: "
f"{self._float(data.get('breakout_distance_percent'))}\n"
f"• Is Breakout: {self._bool(data.get('is_breakout'))}\n"
f"• Reason: {data.get('breakout_reason')}\n"
)
def _execution_block(self, data: dict[str, Any]) -> str:
return (
"🛡 Execution\n"
f"• Quality: {data.get('quality')}\n"
f"• Semantic Status: {data.get('semantic_status')}\n"
f"• Confidence Score: "
f"{self._float(data.get('confidence_score'))}\n"
f"• Confidence Level: {data.get('confidence_level')}\n"
f"• Spread %: {self._float(data.get('spread_percent'))}\n"
f"• Snapshot Age: "
f"{self._seconds(data.get('snapshot_age_seconds'))}\n"
f"• Runtime Degraded: "
f"{self._bool(data.get('market_runtime_degraded'))}\n"
f"• Reason: {data.get('semantic_reason')}\n"
)
def _adaptive_block(self, data: dict[str, Any]) -> str:
return (
"🧮 Adaptive Sizing\n"
f"• Multiplier: {self._float(data.get('multiplier'))}\n"
f"• Effective Risk %: "
f"{self._float(data.get('effective_risk_percent'))}\n"
f"• Effective Risk USD: "
f"{self._float(data.get('effective_target_risk_usd'))}\n"
f"• Reason: {data.get('reason')}\n"
)
def _position_block(self, data: dict[str, Any]) -> str:
return (
"📌 Position\n"
f"• Side: {data.get('side')}\n"
f"• Entry: {self._float(data.get('entry_price'))}\n"
f"• Size: {self._float(data.get('size'))}\n"
f"• Unrealized PnL: "
f"{self._float(data.get('unrealized_pnl_usd'))}\n"
f"• Realized PnL: "
f"{self._float(data.get('realized_pnl_usd'))}\n"
f"• Last Action: {data.get('last_execution_action')}\n"
)
def _runtime_block(self, data: dict[str, Any]) -> str:
return (
"🧬 Runtime Health\n"
f"• Runtime Degraded: "
f"{self._bool(data.get('is_runtime_degraded'))}\n"
f"• Signal Age: "
f"{self._seconds(data.get('signal_age_seconds'))}\n"
f"• Market Age: "
f"{self._seconds(data.get('market_age_seconds'))}\n"
f"• Expired Reason: "
f"{data.get('runtime_expired_reason')}\n"
f"• Has Market Data: "
f"{self._bool(data.get('has_market_data'))}\n"
f"• Has Momentum Data: "
f"{self._bool(data.get('has_momentum_data'))}\n"
)
def _summary_block(self, data: dict[str, Any]) -> str:
blockers = data.get("blockers") or []
if blockers:
blockers_text = ", ".join(str(item) for item in blockers)
else:
blockers_text = "none"
return (
"🧾 Summary\n"
f"• Market: {data.get('market')}\n"
f"• Phase: {data.get('phase')}\n"
f"• Momentum: {data.get('momentum')}\n"
f"• Execution: {data.get('execution')}\n"
f"• Position: {data.get('position')}\n"
f"• Ready: {self._bool(data.get('is_ready'))}\n"
f"• Blocked: {self._bool(data.get('is_blocked'))}\n"
f"• Blockers: {blockers_text}\n"
)
def _bool(self, value: object) -> str:
return "YES" if bool(value) else "NO"
def _float(self, value: object) -> str:
if value is None:
return ""
try:
return f"{float(value):.4f}"
except Exception:
return str(value)
def _percent(self, value: object) -> str:
if value is None:
return ""
try:
return f"{float(value) * 100:.1f}%"
except Exception:
return str(value)
def _seconds(self, value: object) -> str:
if value is None:
return ""
try:
return f"{int(float(value))}s"
except Exception:
return str(value)

View File

@@ -1183,6 +1183,28 @@
- execution runtime подготовлен к professional observability layer - execution runtime подготовлен к professional observability layer
- execution runtime подготовлен к institutional execution diagnostics - execution runtime подготовлен к institutional execution diagnostics
#### 07.4.4.1.10.2 ✅ Human-readable formatter
- реализован human-readable diagnostic formatter
- реализован presentation layer для semantic diagnostics
- реализован человекочитаемый runtime diagnostic report
- реализовано форматирование signal diagnostics
- реализовано форматирование decision diagnostics
- реализовано форматирование market semantic diagnostics
- реализовано форматирование momentum / breakout diagnostics
- реализовано форматирование execution quality diagnostics
- реализовано форматирование execution confidence diagnostics
- реализовано форматирование adaptive sizing diagnostics
- реализовано форматирование runtime health diagnostics
- реализовано форматирование position diagnostics
- diagnostic snapshot теперь можно выводить в Telegram
- diagnostic snapshot теперь можно использовать для journal diagnostics
- diagnostic snapshot теперь можно использовать для debug output
- diagnostic layer стал explainable
- diagnostic layer стал user-readable
- diagnostic layer подготовлен к Telegram Diagnostic Screen
- diagnostic layer подготовлен к Diagnostic Journal Layer
- diagnostic layer подготовлен к Auto-refresh Diagnostic UI
--- ---
### 07.4.5 ### 07.4.5

View File

@@ -1133,6 +1133,56 @@
--- ---
### 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.4.1.10.2 ✅ Human-readable formatter
- реализован human-readable diagnostic formatter
- реализован presentation layer для semantic diagnostics
- реализован человекочитаемый runtime diagnostic report
- реализовано форматирование signal diagnostics
- реализовано форматирование decision diagnostics
- реализовано форматирование market semantic diagnostics
- реализовано форматирование momentum / breakout diagnostics
- реализовано форматирование execution quality diagnostics
- реализовано форматирование execution confidence diagnostics
- реализовано форматирование adaptive sizing diagnostics
- реализовано форматирование runtime health diagnostics
- реализовано форматирование position diagnostics
- diagnostic snapshot теперь можно выводить в Telegram
- diagnostic snapshot теперь можно использовать для journal diagnostics
- diagnostic snapshot теперь можно использовать для debug output
- diagnostic layer стал explainable
- diagnostic layer стал user-readable
- diagnostic layer подготовлен к Telegram Diagnostic Screen
- diagnostic layer подготовлен к Diagnostic Journal Layer
- diagnostic layer подготовлен к Auto-refresh Diagnostic UI
---
### 07.4.5 ### 07.4.5
⏳ Scalping strategy ⏳ Scalping strategy

View File

@@ -0,0 +1,315 @@
# 07.4.4.1.10.2 — Human-readable formatter
## Статус
✅ Этап реализован.
## Назначение этапа
Этап **07.4.4.1.10.2 Human-readable formatter** добавляет человекочитаемый слой поверх диагностического snapshot builder из этапа **07.4.4.1.10.1**.
Если предыдущий этап собирал структурированный diagnostic snapshot в виде технического словаря, то текущий этап превращает этот snapshot в понятный текстовый отчёт, который можно напрямую показывать пользователю в Telegram, писать в журнал или использовать как основу для отдельного diagnostic screen.
Главная цель этапа — сделать runtime-состояние автоторговли объяснимым: не только хранить значения `market_state`, `momentum_state`, `execution_quality`, `execution_confidence_score`, `adaptive_size_multiplier`, но и отображать их в единой логичной структуре.
## Что было реализовано
Создан отдельный formatter-слой:
```text
app/src/trading/diagnostics/formatter.py
```
В файл добавлен класс:
```python
SemanticDiagnosticFormatter
```
Класс получает на вход диагностический snapshot и формирует человекочитаемый отчёт по ключевым runtime-блокам автоторговли.
Formatter не меняет торговую логику, не влияет на сигналы, не открывает и не закрывает позиции, не пересчитывает market analysis и не изменяет состояние `AutoTradeState`. Это read-only presentation layer.
## Архитектурная роль
До этого этапа диагностическая информация существовала в виде набора технических полей:
- `last_signal`
- `decision_status`
- `market_state`
- `market_trend`
- `market_phase`
- `momentum_state`
- `breakout_reason`
- `execution_quality`
- `execution_confidence_score`
- `adaptive_size_multiplier`
- `runtime_expired_reason`
- `position_side`
Такая структура удобна для кода, но неудобна для ручной проверки в Telegram.
Этап **07.4.4.1.10.2** добавил промежуточный уровень:
```text
AutoTradeState
SemanticDiagnosticSnapshotBuilder
SemanticDiagnosticFormatter
Telegram screen / journal / debug output
```
Теперь диагностический snapshot можно не только собрать, но и вывести в читаемом виде.
## Реализованные диагностические блоки
Formatter формирует отчёт из отдельных смысловых секций.
### 1. Runtime
Блок показывает базовый runtime-контекст автоторговли:
- статус автоторговли
- торговый инструмент
- стратегия
- признак корректной настройки
Этот блок нужен, чтобы сразу видеть, в каком режиме находится система: `OFF`, `OBSERVING` или `RUNNING`.
### 2. Signal
Блок отображает состояние сигнального слоя:
- текущий сигнал
- confidence стратегии
- decision status
- подтверждён ли сигнал
- готов ли сигнал к execution
- количество повторов
- прогресс подтверждения
- возраст сигнала
- причина сигнала
Этот блок помогает понять, почему бот держит `HOLD`, почему BUY / SELL ещё подтверждается, или почему сигнал уже готов к исполнению.
### 3. Market
Блок отображает semantic market diagnostics:
- состояние рынка
- направление тренда
- волатильность
- силу тренда
- качество тренда
- фазу рынка
- направление фазы
- причину блокировки входа
- возраст market analysis
Именно этот блок делает видимой работу market semantic layer, добавленного на предыдущих этапах.
Теперь можно увидеть не только короткую UI-строку вроде `📉 Рынок · снижение`, но и полный набор факторов, из которых это состояние собрано.
### 4. Momentum / Breakout
Блок отображает momentum и breakout diagnostics:
- momentum state
- momentum direction
- momentum strength
- процент изменения цены в momentum window
- breakout level
- breakout distance percent
- является ли состояние breakout
- причина классификации
Этот блок особенно важен после этапа **07.4.4.1.9.6.2 Momentum & Breakout Semantic Engine**, потому что позволяет проверить, видит ли бот импульс, пробой, направление ускорения и силу движения.
### 5. Execution
Блок отображает execution diagnostics:
- execution quality
- semantic execution status
- execution confidence score
- execution confidence level
- spread percent
- snapshot age
- признак runtime degradation
- semantic reason
Этот блок объясняет, почему execution разрешён, ограничен или заблокирован.
Он объединяет данные execution quality layer, execution confidence engine и semantic execution state.
### 6. Adaptive Sizing
Блок отображает adaptive sizing diagnostics:
- итоговый multiplier
- effective risk percent
- effective target risk USD
- причина изменения размера
Этот блок показывает, как execution context влияет на размер будущей позиции.
Если размер уменьшен, увеличен или заблокирован, formatter делает это видимым.
### 7. Position
Блок отображает состояние позиции:
- сторона позиции
- цена входа
- размер
- unrealized PnL
- realized PnL
- последнее execution-действие
Этот блок нужен для связи диагностики сигнала с фактической позицией.
### 8. Runtime Health
Блок отображает техническое здоровье runtime:
- есть ли degraded state
- возраст сигнала
- возраст market analysis
- причина runtime expiration
- наличие market data
- наличие momentum data
Этот блок помогает понять, устарели ли данные, сброшен ли сигнал, доступна ли рыночная аналитика и не работает ли бот на деградированном контексте.
### 9. Summary
Финальный блок собирает короткое резюме:
- market summary
- phase summary
- momentum summary
- execution summary
- position summary
- готовность к execution
- блокировка
- список blockers
Это верхнеуровневое объяснение текущего состояния автоторговли.
## Что сделано в части аналитики
На этом этапе аналитика была не пересчитана, а структурирована для человека.
Это важное отличие: formatter не добавляет новые торговые правила, но делает уже существующую аналитику наблюдаемой.
В человекочитаемый отчёт теперь выводятся ключевые аналитические слои:
- signal layer
- decision layer
- market semantic layer
- market phase layer
- trend strength layer
- trend quality layer
- momentum semantic layer
- breakout semantic layer
- execution quality layer
- execution confidence layer
- adaptive sizing layer
- runtime health layer
- position state layer
Таким образом, аналитика перестала быть скрытой внутри payload и runtime state.
Теперь можно вручную проверить:
- почему бот видит рынок как trend / range / squeeze / high volatility
- почему фаза определена как impulse / pullback / range / squeeze
- есть ли momentum или breakout
- насколько сильный импульс
- где находится breakout level
- почему вход заблокирован
- почему execution confidence низкий или нормальный
- почему adaptive sizing уменьшил или увеличил размер
- есть ли stale snapshot или широкий spread
- почему позиция открыта, не открыта или не переворачивается
## Почему это важно
До появления formatter диагностика была доступна только через внутренние поля и payload.
Это создавало несколько проблем:
1. В UI Telegram отображалось только несколько коротких строк.
2. Нельзя было быстро понять, какой именно слой заблокировал вход.
3. Momentum и breakout были рассчитаны, но не имели полноценного human-readable вывода.
4. Execution confidence был числом, но без нормальной расшифровки в общем контексте.
5. Adaptive sizing работал, но его причина не была частью единого diagnostic report.
6. Для проверки приходилось смотреть код, payload или журнал.
Новый formatter решает эти проблемы и готовит систему к отдельному diagnostic screen.
## Пример будущего использования
Formatter рассчитан на дальнейшее использование в Telegram Diagnostic Screen:
```python
snapshot = SemanticDiagnosticSnapshotBuilder().build()
text = SemanticDiagnosticFormatter().format(snapshot)
```
После этого `text` можно отправить в Telegram как отдельный экран диагностики.
## Что этап НЕ делает
Этап не добавляет новую торговую стратегию.
Этап не меняет расчёт сигналов.
Этап не меняет thresholds.
Этап не меняет execution engine.
Этап не меняет adaptive sizing.
Этап не пишет автоматически диагностику в журнал.
Этап не добавляет Telegram handler.
Этап только создаёт human-readable presentation layer для уже существующего diagnostic snapshot.
## Подготовка к следующим этапам
Этап подготавливает базу для:
- **07.4.4.1.10.3 Telegram Diagnostic Screen**
- **07.4.4.1.10.4 Diagnostic Journal Layer**
- **07.4.4.1.10.5 Auto-refresh Diagnostic UI**
После этого этапа можно безопасно строить отдельный экран диагностики, потому что форматтер уже умеет превращать технический snapshot в готовый текст для пользователя.
## Проверка
Минимальная проверка:
```bash
python3 -m compileall app/src/trading/diagnostics
```
Ожидаемый результат:
```text
Listing 'app/src/trading/diagnostics'...
Compiling 'app/src/trading/diagnostics/formatter.py'...
```
Если ошибок нет, formatter синтаксически корректен.
## Итог
Этап **07.4.4.1.10.2 Human-readable formatter** завершает второй слой диагностической инфраструктуры.
Теперь система умеет не только собирать semantic diagnostic snapshot, но и превращать его в понятный отчёт.
Это переводит диагностику автоторговли из raw technical state в explainable runtime representation и подготавливает основу для полноценного Telegram diagnostic screen.