From b1513a28ef081187e76cc38def5cae3e71a2f9ef Mon Sep 17 00:00:00 2001 From: Sergey Date: Tue, 5 May 2026 20:28:43 +0300 Subject: [PATCH] =?UTF-8?q?07.4.3.12=20=E2=80=94=20Real=20Risk=20Engine=20?= =?UTF-8?q?(execution-level)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app/src/telegram/handlers/auto/risk.py | 2 +- app/src/trading/auto/runner.py | 2 + app/src/trading/execution/engine.py | 16 +-- docs/roadmap/master-roadmap.md | 7 + docs/roadmap/stage-07-auto-trading-roadmap.md | 9 ++ ...4_3_12-real_risk_engine-execution_level.md | 130 ++++++++++++++++++ 6 files changed, 157 insertions(+), 9 deletions(-) create mode 100644 docs/stages/stage-07_4_3_12-real_risk_engine-execution_level.md diff --git a/app/src/telegram/handlers/auto/risk.py b/app/src/telegram/handlers/auto/risk.py index 0b7a853..b9aad36 100644 --- a/app/src/telegram/handlers/auto/risk.py +++ b/app/src/telegram/handlers/auto/risk.py @@ -287,7 +287,7 @@ async def reset_risk(callback: CallbackQuery, state: FSMContext) -> None: ) await callback.answer() - await asyncio.sleep(5.5) + await asyncio.sleep(2.5) if getattr(AutoTradeRunner, "_current_screen", None) != "auto_risk": return diff --git a/app/src/trading/auto/runner.py b/app/src/trading/auto/runner.py index 2671c33..31684ce 100644 --- a/app/src/trading/auto/runner.py +++ b/app/src/trading/auto/runner.py @@ -343,6 +343,8 @@ class AutoTradeRunner: f"{payload.get('old_size')}:" f"{payload.get('new_size')}:" f"{payload.get('pnl')}" + f"{payload.get('risk_reason')}:" + f"{payload.get('is_forced')}:" ) @classmethod def _build_execution_alert_text( diff --git a/app/src/trading/execution/engine.py b/app/src/trading/execution/engine.py index 1759eb9..c4a5ebf 100644 --- a/app/src/trading/execution/engine.py +++ b/app/src/trading/execution/engine.py @@ -275,6 +275,14 @@ class ExecutionEngine: price_move_percent = self._calculate_price_move_percent(current_price) unrealized_pnl = self._calculate_pnl(current_price) + if self._is_max_loss_hit(state, unrealized_pnl): + return self._close_position( + state, + forced_reason="MAX_LOSS", + forced_exit_price=current_price, + forced_pnl=unrealized_pnl, + ) + if self._is_stop_loss_hit(state, price_move_percent): return self._close_position( state, @@ -291,14 +299,6 @@ class ExecutionEngine: forced_pnl=unrealized_pnl, ) - if self._is_max_loss_hit(state, unrealized_pnl): - return self._close_position( - state, - forced_reason="MAX_LOSS", - forced_exit_price=current_price, - forced_pnl=unrealized_pnl, - ) - return None def _is_stop_loss_hit( diff --git a/docs/roadmap/master-roadmap.md b/docs/roadmap/master-roadmap.md index 7e3d204..63ed22d 100644 --- a/docs/roadmap/master-roadmap.md +++ b/docs/roadmap/master-roadmap.md @@ -215,6 +215,13 @@ - единая навигация: Auto ↔ Settings ↔ Risk - UX-подсказки и валидация ввода +#### 07.4.3.12 — Real Risk Engine (execution-level) ✅ +- risk checks внутри ExecutionEngine +- SL / TP / ML закрывают позицию +- forced close с risk_reason +- интеграция в основной цикл автоторговли +- Telegram execution alerts с причиной риска +- единая точка принятия решений (execution layer) ### 07.4.4 ⏳ Grid Strategy diff --git a/docs/roadmap/stage-07-auto-trading-roadmap.md b/docs/roadmap/stage-07-auto-trading-roadmap.md index f8f4c70..d18cac8 100644 --- a/docs/roadmap/stage-07-auto-trading-roadmap.md +++ b/docs/roadmap/stage-07-auto-trading-roadmap.md @@ -199,6 +199,15 @@ - единая навигация: Auto ↔ Settings ↔ Risk - UX-подсказки и валидация ввода +#### 07.4.3.12 — Real Risk Engine (execution-level) ✅ + +- risk checks внутри ExecutionEngine +- SL / TP / ML закрывают позицию +- forced close с risk_reason +- интеграция в основной цикл автоторговли +- Telegram execution alerts с причиной риска +- единая точка принятия решений (execution layer) + --- ### 07.4.4 diff --git a/docs/stages/stage-07_4_3_12-real_risk_engine-execution_level.md b/docs/stages/stage-07_4_3_12-real_risk_engine-execution_level.md new file mode 100644 index 0000000..34795a2 --- /dev/null +++ b/docs/stages/stage-07_4_3_12-real_risk_engine-execution_level.md @@ -0,0 +1,130 @@ +# 07.4.3.12 — Real Risk Engine (execution-level) + +## 📌 Цель +Перенести risk-логику (Stop Loss, Take Profit, Max Loss) +с уровня UI/настроек на уровень execution engine. + +Теперь риск не просто отображается, а **влияет на реальные торговые действия**. + +--- + +## ⚙️ Что реализовано + +### 1. Risk checks внутри ExecutionEngine + +Добавлен блок: + +- `_risk_close_decision()` +- вызывается **до execution логики (open / flip)** + +Порядок проверок: +1. MAX_LOSS (USD) +2. STOP_LOSS (%) +3. TAKE_PROFIT (%) + +--- + +### 2. Принудительное закрытие позиции (forced close) + +При срабатывании риска: + +``` +_close_position( + forced_reason="STOP_LOSS" | "TAKE_PROFIT" | "MAX_LOSS" +) +``` + +Добавлено: + +- risk_reason +- is_forced=True + +--- + +### 3. Telegram execution alerts + +Добавлено в alert: + +``` +Risk: STOP_LOSS +Risk: TAKE_PROFIT +Risk: MAX_LOSS +``` + +Работает для: + +- paper_position_closed +- forced close событий + +--- + +### 4. Интеграция в цикл автоторговли + +Risk engine: + +- встроен в ExecutionEngine.process() +- вызывается на каждом цикле +- не требует отдельного триггера + +--- + +### 5. Поддерживаемые типы риска + +- STOP_LOSS: % движения цены +- TAKE_PROFIT: % движения цены +- MAX_LOSS: P&L в USD + +--- + +### 🧠 Архитектурные принципы + +* Risk проверяется до входа в позицию +* Risk не дублируется в UI +* Все решения централизованы в ExecutionEngine +* UI только отображает состояние + +--- + +### ⚠️ Ограничения текущей версии + +1. Position size пока не связан с риском +2. MAX_LOSS — paper-based (USD), не account-based +3. Нет связи с балансом аккаунта +4. Нет partial close / trailing logic + +--- + +### ✅ Тест-кейсы (пройдены) + +TAKE_PROFIT + +- LONG → TP → позиция закрывается +- Telegram: Risk: TAKE_PROFIT + +STOP_LOSS + +- LONG → SL → позиция закрывается +- Telegram: Risk: STOP_LOSS + +MAX_LOSS + +- позиция → убыток → закрытие +- Telegram: Risk: MAX_LOSS + +--- + +### 📊 Итог + +Risk engine теперь: + +* работает на уровне execution +* влияет на реальные торговые решения +* синхронизирован с Telegram alerts + +--- + +## Это первый шаг к production-grade risk management. + +--- + +## Следующий шаг — 07.4.3.13 Position sizing (realistic) \ No newline at end of file