07.4.4.1.9.4 Execution Semantic Layer

This commit is contained in:
2026-05-12 13:41:42 +03:00
parent 0dbb609b5a
commit 2be7d92660
7 changed files with 355 additions and 109 deletions

View File

@@ -373,6 +373,9 @@ class AutoTradeService:
state.signal_confirmation_progress = 0.0
state.signal_confirmation_reason = None
state.execution_block_reason = None
state.execution_semantic_status = None
state.execution_semantic_message = None
state.execution_semantic_reason = None
state.signal_started_at = None
state.signal_updated_at = None
state.market_state = None
@@ -381,6 +384,11 @@ class AutoTradeService:
state.market_analysis_interval = None
state.market_analysis_reason = None
state.market_analysis_updated_at = None
state.market_runtime_degraded = False
state.market_trend_strength = None
state.market_trend_quality = None
state.market_phase = None
state.market_phase_direction = None
state.entry_block_reason = None
state.entry_block_message = None
state.runtime_expired_reason = None
@@ -390,10 +398,6 @@ class AutoTradeService:
state.execution_quality = None
state.execution_quality_reason = None
state.execution_quality_message = None
state.market_runtime_degraded = False
state.market_trend_strength = None
state.market_trend_quality = None
state.market_phase = None
# собрать контекст для стратегии
def _build_strategy_context(self) -> StrategyContext:
@@ -809,6 +813,7 @@ class AutoTradeService:
state.market_trend_strength = payload.get("market_trend_strength")
state.market_trend_quality = payload.get("market_trend_quality")
state.market_phase = payload.get("market_phase")
state.market_phase_direction = payload.get("market_phase_direction")
state.market_analysis_interval = payload.get("market_analysis_interval")
state.market_analysis_reason = payload.get("market_analysis_reason")
state.market_analysis_updated_at = time.monotonic()
@@ -1266,6 +1271,58 @@ class AutoTradeService:
except Exception:
pass
def _sync_execution_semantic_state(self, state: AutoTradeState) -> None:
if state.execution_quality == "BLOCKED":
state.execution_semantic_status = "BLOCKED"
state.execution_semantic_message = self._execution_block_semantic_message(state)
state.execution_semantic_reason = state.execution_quality_reason
return
if state.position_side != "NONE":
state.execution_semantic_status = "POSITION_OPEN"
state.execution_semantic_message = "📌 Исполнение · позиция открыта"
state.execution_semantic_reason = state.last_execution_reason
return
if state.decision_status == "READY" and state.is_signal_ready:
state.execution_semantic_status = "READY"
state.execution_semantic_message = "✅ Исполнение · готово"
state.execution_semantic_reason = state.decision_reason
return
if state.decision_status == "CONFIRMING":
state.execution_semantic_status = "WAITING_SIGNAL"
state.execution_semantic_message = "⏳ Исполнение · ждёт подтверждения"
state.execution_semantic_reason = state.decision_reason
return
if state.last_signal in {"BUY", "SELL"}:
state.execution_semantic_status = "WAITING_SIGNAL"
state.execution_semantic_message = "⏳ Исполнение · сигнал проверяется"
state.execution_semantic_reason = state.decision_reason
return
state.execution_semantic_status = "IDLE"
state.execution_semantic_message = ""
state.execution_semantic_reason = state.decision_reason
def _execution_block_semantic_message(self, state: AutoTradeState) -> str:
reason = state.execution_quality_reason
if reason == "STALE_SNAPSHOT":
return "⛔ Исполнение · рынок неактуален"
if reason == "HIGH_SPREAD":
return "⛔ Исполнение · высокий spread"
if reason == "SNAPSHOT_ERROR":
return "⛔ Исполнение · нет данных рынка"
if reason == "SNAPSHOT_UNAVAILABLE":
return "⚠️ Исполнение · нет стакана"
return "⛔ Исполнение · заблокировано"
def run_cycle(self) -> AutoTradeState:
state = self.get_state()
@@ -1299,4 +1356,6 @@ class AutoTradeService:
if state.execution_quality != "BLOCKED":
ExecutionEngine().process(state)
self._sync_execution_semantic_state(state)
return state

View File

@@ -124,6 +124,9 @@ class AutoTradeState:
# фаза рынка: IMPULSE / PULLBACK / RANGE / SQUEEZE / UNKNOWN
market_phase: str | None = None
# направление короткой фазы рынка: UP / DOWN / FLAT / UNKNOWN
market_phase_direction: str | None = None
# таймфрейм анализа рынка
market_analysis_interval: str | None = None
@@ -179,4 +182,14 @@ class AutoTradeState:
signal_confirmation_progress: float = 0.0
# человекочитаемая причина текущего confirmation status
signal_confirmation_reason: str | None = None
signal_confirmation_reason: str | None = None
# semantic-статус execution слоя:
# IDLE / WAITING_SIGNAL / READY / BLOCKED / EXECUTED / POSITION_OPEN / PROTECTED
execution_semantic_status: str | None = None
# короткая строка для UI
execution_semantic_message: str | None = None
# техническая детализация для логов / отладки
execution_semantic_reason: str | None = None

View File

@@ -0,0 +1,2 @@
# app/src/trading/execution/quality.py