07.4.4.1.9.4 Execution Semantic Layer
This commit is contained in:
@@ -139,6 +139,15 @@ def _build_stopped_without_position_text(state) -> str:
|
||||
return "\n".join(parts)
|
||||
|
||||
|
||||
def _execution_semantic_line(state) -> str:
|
||||
message = getattr(state, "execution_semantic_message", None)
|
||||
|
||||
if not message:
|
||||
return ""
|
||||
|
||||
return str(message)
|
||||
|
||||
|
||||
def _build_waiting_text(state) -> str:
|
||||
price = _signal_entry_price(state)
|
||||
|
||||
@@ -157,9 +166,8 @@ def _build_waiting_text(state) -> str:
|
||||
_signal_confirmation_line(state),
|
||||
_market_semantic_line(state),
|
||||
_entry_block_line(state),
|
||||
_execution_quality_line(state),
|
||||
_execution_semantic_line(state),
|
||||
*_signal_confidence_lines(state),
|
||||
*_execution_block_lines(state),
|
||||
]
|
||||
|
||||
signal_lines = [line for line in signal_lines if line]
|
||||
@@ -213,8 +221,7 @@ def _build_active_position_text(state) -> str:
|
||||
|
||||
market_lines = [
|
||||
_market_semantic_line(state),
|
||||
_execution_quality_line(state),
|
||||
*_execution_block_lines(state),
|
||||
_execution_semantic_line(state),
|
||||
]
|
||||
market_lines = [line for line in market_lines if line]
|
||||
|
||||
@@ -360,64 +367,6 @@ def _entry_block_line(state) -> str:
|
||||
return f"🧩 Фильтр · {compact_message}"
|
||||
|
||||
|
||||
def _execution_quality_line(state) -> str:
|
||||
quality = getattr(state, "execution_quality", None)
|
||||
reason = getattr(state, "execution_quality_reason", None)
|
||||
spread_percent = getattr(state, "spread_percent", None)
|
||||
age_seconds = getattr(state, "snapshot_age_seconds", None)
|
||||
|
||||
if not quality:
|
||||
return ""
|
||||
|
||||
if quality == "GOOD":
|
||||
return ""
|
||||
|
||||
if reason == "WIDE_SPREAD" and spread_percent is not None:
|
||||
return f"⚠️ Вход · spread {_format_percent(spread_percent)}"
|
||||
|
||||
if reason == "AGING_SNAPSHOT" and age_seconds is not None:
|
||||
return f"⚠️ Вход · данные стареют {age_seconds:.1f}с"
|
||||
|
||||
if reason == "STALE_SNAPSHOT":
|
||||
return "⛔ Вход · рынок неактуален"
|
||||
|
||||
if reason == "HIGH_SPREAD" and spread_percent is not None:
|
||||
return f"⛔ Вход · высокий spread {_format_percent(spread_percent)}"
|
||||
|
||||
if reason == "SNAPSHOT_UNAVAILABLE":
|
||||
return "⚠️ Вход · нет стакана"
|
||||
|
||||
if reason == "SNAPSHOT_ERROR":
|
||||
return "⛔ Вход · нет данных рынка"
|
||||
|
||||
message = getattr(state, "execution_quality_message", None)
|
||||
|
||||
if not message:
|
||||
return ""
|
||||
|
||||
return f"⚠️ Вход · {message}"
|
||||
|
||||
|
||||
def _execution_block_lines(state) -> list[str]:
|
||||
lines: list[str] = []
|
||||
|
||||
reason = getattr(state, "execution_block_reason", None)
|
||||
if reason and reason not in {
|
||||
"высокий spread",
|
||||
"spread повышен",
|
||||
"snapshot устарел",
|
||||
"рынок неактуален",
|
||||
}:
|
||||
lines.append(f"Вход · {reason}")
|
||||
|
||||
adjustment = getattr(state, "execution_size_adjustment_reason", None)
|
||||
|
||||
if adjustment == "MARGIN_LIMIT":
|
||||
lines.append("Позиция ограничена настройкой Max Reserved.")
|
||||
|
||||
return lines
|
||||
|
||||
|
||||
def _allocated_balance(state) -> float:
|
||||
return float(getattr(state, "allocated_balance_usd", 1000.0) or 1000.0)
|
||||
|
||||
@@ -608,8 +557,7 @@ def _risk_loss_text(
|
||||
return ""
|
||||
|
||||
if size is None or size <= 0 or entry_price is None or entry_price <= 0:
|
||||
loss = _target_loss_by_percent_stub(percent)
|
||||
return f"-{_format_money_compact(loss)}" if loss is not None else ""
|
||||
return ""
|
||||
|
||||
move = entry_price * (percent / 100)
|
||||
loss = move * size
|
||||
@@ -635,13 +583,6 @@ def _risk_profit_text(
|
||||
return f"+{_format_money_compact(profit)}"
|
||||
|
||||
|
||||
def _target_loss_by_percent_stub(percent: float | None) -> float | None:
|
||||
if percent is None:
|
||||
return None
|
||||
|
||||
return None
|
||||
|
||||
|
||||
def _risk_reward_line(state) -> str:
|
||||
if (
|
||||
state.stop_loss_percent is None
|
||||
@@ -777,16 +718,6 @@ def _status_text(status: str) -> str:
|
||||
return mapping.get(status, status)
|
||||
|
||||
|
||||
def _decision_human_text(status: str) -> str:
|
||||
mapping = {
|
||||
"WAITING": "Ожидание сигнала",
|
||||
"CONFIRMING": "Подтверждение сигнала",
|
||||
"READY": "Сигнал готов",
|
||||
"BLOCKED": "Сигнал заблокирован",
|
||||
}
|
||||
return mapping.get(status, status)
|
||||
|
||||
|
||||
def _account_mode_line() -> str:
|
||||
return "DEMO аккаунт" if "DEMO" in mode_line().upper() else "LIVE аккаунт"
|
||||
|
||||
@@ -911,29 +842,6 @@ def _format_plain_or_dash(value: float | int | None) -> str:
|
||||
return _format_money_compact(value)
|
||||
|
||||
|
||||
def _format_usd_or_dash(value: float | None) -> str:
|
||||
return _format_plain_or_dash(value)
|
||||
|
||||
|
||||
def _format_signed_usd(value: float | int | None) -> str:
|
||||
if value is None:
|
||||
return "—"
|
||||
|
||||
amount = float(value)
|
||||
|
||||
if amount > 0:
|
||||
return f"+{_format_money_compact(amount)}"
|
||||
|
||||
if amount < 0:
|
||||
return f"−{_format_money_compact(abs(amount))}"
|
||||
|
||||
return "0"
|
||||
|
||||
|
||||
def _format_signed_usd_with_direction(value: float | int | None) -> str:
|
||||
return _format_signed_plain_with_direction(value)
|
||||
|
||||
|
||||
def _format_signed_plain_with_direction(value: float | int | None) -> str:
|
||||
if value is None:
|
||||
return "—"
|
||||
|
||||
Reference in New Issue
Block a user