Stage 07.4.4.1.14 — Execution refactoring and runtime semantics

This commit is contained in:
2026-07-02 16:25:18 +03:00
parent d9e6392e28
commit e08c604ff5
72 changed files with 13626 additions and 4233 deletions

View File

@@ -48,8 +48,9 @@ class Settings:
db_user: str
db_password: str
# Debag helper
# Debug helpers
debug_enabled: bool
journal_debug_enabled: bool
# helper: demo/live mode
def is_demo_mode(self) -> bool:
@@ -91,6 +92,9 @@ def load_settings() -> Settings:
log_level=os.getenv("LOG_LEVEL", "INFO").strip().upper() or "INFO",
tz=os.getenv("TZ", "Europe/Minsk").strip() or "Europe/Minsk",
debug_enabled=_parse_bool(os.getenv("DEBUG_ENABLED", "false")),
journal_debug_enabled=_parse_bool(
os.getenv("JOURNAL_DEBUG_ENABLED", "false")
),
# Exchange
exchange_enabled=_parse_bool(os.getenv("EXCHANGE_ENABLED", "false")),
@@ -101,8 +105,8 @@ def load_settings() -> Settings:
exchange_api_secret=os.getenv("EXCHANGE_API_SECRET", "").strip(),
exchange_timeout_sec=_parse_int(os.getenv("EXCHANGE_TIMEOUT_SEC", "10"), 10),
exchange_testnet=_parse_bool(os.getenv("EXCHANGE_TESTNET", "false")),
default_symbol=os.getenv("DEFAULT_SYMBOL", "BTC/USD_LEVERAGE").strip()
or "BTC/USD_LEVERAGE",
default_symbol=os.getenv("DEFAULT_SYMBOL", "ETH/USD_LEVERAGE").strip()
or "ETH/USD_LEVERAGE",
# Database
db_host=os.getenv("DB_HOST", "localhost").strip() or "localhost",

View File

@@ -9,6 +9,8 @@ class EventBus:
_version: int = 0
_last_event_type: str | None = None
_last_payload: dict[str, Any] = {}
_events: list[tuple[int, str, dict[str, Any]]] = []
_max_events: int = 100
# зафиксировать важное событие системы
@classmethod
@@ -17,6 +19,17 @@ class EventBus:
cls._last_event_type = event_type
cls._last_payload = payload or {}
cls._events.append(
(
cls._version,
event_type,
dict(cls._last_payload),
)
)
if len(cls._events) > cls._max_events:
cls._events = cls._events[-cls._max_events:]
# текущая версия событий
@classmethod
def version(cls) -> int:
@@ -25,4 +38,13 @@ class EventBus:
# последнее событие
@classmethod
def last_event(cls) -> tuple[str | None, dict[str, Any]]:
return cls._last_event_type, dict(cls._last_payload)
return cls._last_event_type, dict(cls._last_payload)
# события после указанной версии
@classmethod
def events_after(cls, version: int) -> list[tuple[int, str, dict[str, Any]]]:
return [
(event_version, event_type, dict(payload))
for event_version, event_type, payload in cls._events
if event_version > version
]

View File

@@ -55,6 +55,7 @@ EVENT_TITLES = {
"journal_export_xlsx_success": "Журнал",
"journal_export_xlsx_error": "Журнал",
"journal_cleared_old": "Журнал",
"journal_debug_changed": "Журнал",
"system_open_requested": "Система",
"system_open_alert": "Система",
@@ -84,6 +85,8 @@ EVENT_TITLES = {
"market_closed": "Автоторговля",
"market_rest_fallback_available": "Автоторговля",
"market_rest_fallback_unavailable": "Автоторговля",
"ws_depth_alive": "WebSocket debug",
}

View File

@@ -1,11 +1,7 @@
# app/src/core/numbers.py
# src/core/numbers.py
from __future__ import annotations
from src.core.types import NumericLike
def safe_float(
value: object,
@@ -20,4 +16,36 @@ def safe_float(
try:
return float(str(value).strip())
except (TypeError, ValueError):
return default
return default
def safe_round(
value: object,
digits: int,
) -> float | None:
"""
Безопасное округление.
None -> None
любое число -> round(...)
"""
number = safe_float(value)
if number is None:
return None
return round(number, digits)
def get_value(value: object) -> object | None:
"""
Возвращает значение Enum или сам объект.
Enum -> .value
None -> None
Остальные типы -> без изменений.
"""
if value is None:
return None
return getattr(value, "value", value)