diff --git a/app/src/telegram/handlers/trade/__init__.py b/app/src/telegram/handlers/trade/__init__.py
new file mode 100644
index 0000000..d8df7b8
--- /dev/null
+++ b/app/src/telegram/handlers/trade/__init__.py
@@ -0,0 +1 @@
+"""Package marker."""
diff --git a/app/src/telegram/handlers/trade/main.py b/app/src/telegram/handlers/trade/main.py
new file mode 100644
index 0000000..3841738
--- /dev/null
+++ b/app/src/telegram/handlers/trade/main.py
@@ -0,0 +1,18 @@
+from __future__ import annotations
+
+from aiogram import F, Router
+from aiogram.types import Message
+
+router = Router(name="trade_main")
+
+
+@router.message(F.text == "⚡ Торговля")
+async def open_trade(message: Message) -> None:
+ text = (
+ "⚡ Торговля\n\n"
+ "Доступные действия:\n"
+ "• /new_order — создать черновик ордера\n"
+ "• /drafts — показать последние черновики\n\n"
+ "На этом этапе реальные ордера ещё не отправляются."
+ )
+ await message.answer(text)
diff --git a/app/src/telegram/handlers/trade/new_order.py b/app/src/telegram/handlers/trade/new_order.py
new file mode 100644
index 0000000..741c3e2
--- /dev/null
+++ b/app/src/telegram/handlers/trade/new_order.py
@@ -0,0 +1,53 @@
+from __future__ import annotations
+
+from aiogram import Router
+from aiogram.filters import Command
+from aiogram.types import Message
+
+from src.trading.orders.service import OrderDraftsService
+
+router = Router(name="trade_new_order")
+
+
+@router.message(Command("new_order"))
+async def create_new_order_draft(message: Message) -> None:
+ service = OrderDraftsService()
+ draft = service.create_default_draft()
+
+ text = (
+ "📝 Черновик ордера создан\n\n"
+ f"• инструмент: {draft.symbol}\n"
+ f"• сторона: {draft.side}\n"
+ f"• тип: {draft.order_type}\n"
+ f"• количество: {draft.quantity}\n"
+ f"• статус: {draft.status}\n\n"
+ "Это тестовый draft flow. Реальный ордер не отправлялся."
+ )
+ await message.answer(text)
+
+
+@router.message(Command("drafts"))
+async def show_recent_drafts(message: Message) -> None:
+ service = OrderDraftsService()
+ drafts = service.list_recent_drafts(limit=5)
+
+ if not drafts:
+ await message.answer(
+ "📝 Черновики ордеров\n\n"
+ "Черновиков пока нет."
+ )
+ return
+
+ lines = ["📝 Черновики ордеров", "", "Последние записи", ""]
+
+ for item in drafts:
+ lines.extend(
+ [
+ f"• {item['symbol']} | {item['side']} | {item['order_type']}",
+ f" qty: {item['quantity']} | status: {item['status']}",
+ f" time: {item['created_at']}",
+ "",
+ ]
+ )
+
+ await message.answer("\n".join(lines).rstrip())
diff --git a/app/src/telegram/routers.py b/app/src/telegram/routers.py
index 5e08e44..9425b98 100644
--- a/app/src/telegram/routers.py
+++ b/app/src/telegram/routers.py
@@ -7,7 +7,8 @@ from src.telegram.handlers.market import router as market_router
from src.telegram.handlers.portfolio import router as portfolio_router
from src.telegram.handlers.start import router as start_router
from src.telegram.handlers.system import router as system_router
-from src.telegram.handlers.trade import router as trade_router
+from src.telegram.handlers.trade.main import router as trade_main_router
+from src.telegram.handlers.trade.new_order import router as trade_new_order_router
def setup_routers(dispatcher: Dispatcher) -> None:
@@ -15,7 +16,8 @@ def setup_routers(dispatcher: Dispatcher) -> None:
dispatcher.include_router(home_router)
dispatcher.include_router(market_router)
dispatcher.include_router(portfolio_router)
- dispatcher.include_router(trade_router)
+ dispatcher.include_router(trade_main_router)
+ dispatcher.include_router(trade_new_order_router)
dispatcher.include_router(auto_router)
dispatcher.include_router(journal_router)
dispatcher.include_router(system_router)
diff --git a/app/src/trading/orders/__init__.py b/app/src/trading/orders/__init__.py
new file mode 100644
index 0000000..d8df7b8
--- /dev/null
+++ b/app/src/trading/orders/__init__.py
@@ -0,0 +1 @@
+"""Package marker."""
diff --git a/app/src/trading/orders/models.py b/app/src/trading/orders/models.py
new file mode 100644
index 0000000..b46b622
--- /dev/null
+++ b/app/src/trading/orders/models.py
@@ -0,0 +1,12 @@
+from __future__ import annotations
+
+from dataclasses import dataclass
+
+
+@dataclass(slots=True)
+class OrderDraft:
+ symbol: str
+ side: str
+ order_type: str
+ quantity: str
+ status: str = "draft"
diff --git a/app/src/trading/orders/service.py b/app/src/trading/orders/service.py
new file mode 100644
index 0000000..5e7611a
--- /dev/null
+++ b/app/src/trading/orders/service.py
@@ -0,0 +1,55 @@
+from __future__ import annotations
+
+from src.core.config import load_settings
+from src.storage.repositories.order_drafts import OrderDraftRepository
+from src.trading.journal.service import JournalService
+from src.trading.orders.models import OrderDraft
+
+
+class OrderDraftsService:
+ def __init__(self) -> None:
+ self.settings = load_settings()
+ self.repository = OrderDraftRepository()
+ self.journal = JournalService()
+
+ def create_default_draft(self) -> OrderDraft:
+ draft = OrderDraft(
+ symbol=self.settings.default_symbol,
+ side="BUY",
+ order_type="MARKET",
+ quantity="0.001",
+ status="draft",
+ )
+ self._save_draft(draft)
+ return draft
+
+ def _save_draft(self, draft: OrderDraft) -> None:
+ self.repository.add_draft(
+ symbol=draft.symbol,
+ side=draft.side,
+ order_type=draft.order_type,
+ quantity=draft.quantity,
+ status=draft.status,
+ payload={
+ "source": "trade_screen",
+ "mode": "draft_only",
+ },
+ )
+
+ try:
+ self.journal.log_info(
+ "order_draft_saved",
+ "Черновик ордера сохранён.",
+ {
+ "symbol": draft.symbol,
+ "side": draft.side,
+ "order_type": draft.order_type,
+ "quantity": draft.quantity,
+ "status": draft.status,
+ },
+ )
+ except Exception:
+ pass
+
+ def list_recent_drafts(self, limit: int = 5) -> list[dict[str, str]]:
+ return self.repository.list_recent_drafts(limit=limit)
diff --git a/docs/decisions/0012-order-drafts-before-live-orders.md b/docs/decisions/0012-order-drafts-before-live-orders.md
new file mode 100644
index 0000000..fb671d6
--- /dev/null
+++ b/docs/decisions/0012-order-drafts-before-live-orders.md
@@ -0,0 +1,14 @@
+# 0012 — Order Drafts before Live Orders
+
+## Решение
+Сначала внедрить безопасный draft flow, а уже потом реальные live orders.
+
+## Причины
+- это снижает торговый риск
+- позволяет проверить архитектуру order flow
+- даёт возможность тестировать UI и storage без отправки ордеров
+
+## Последствия
+- появляется первый безопасный трейдинговый сценарий
+- order_drafts начинают реально использоваться
+- live order execution откладывается на следующий этап
diff --git a/docs/stages/stage-05-1-order-draft-flow.md b/docs/stages/stage-05-1-order-draft-flow.md
new file mode 100644
index 0000000..82a43d3
--- /dev/null
+++ b/docs/stages/stage-05-1-order-draft-flow.md
@@ -0,0 +1,27 @@
+# Stage 05.1 — Order Draft Flow
+
+## Цель
+Сделать первый безопасный trading flow без отправки реальных ордеров.
+
+## Что реализовано
+- `OrderDraftsService`
+- `OrderDraft` model
+- сохранение draft в `order_drafts`
+- команды:
+ - `/new_order`
+ - `/drafts`
+- экран `⚡ Торговля` как входная точка
+
+## Что это даёт
+- появляется первый order flow
+- storage начинает использоваться не только для snapshots
+- можно безопасно тестировать торговый сценарий без риска отправки ордера
+
+## Ограничения
+- параметры draft пока фиксированные
+- нет диалога ввода стороны / количества
+- нет отправки live order
+
+## Следующий шаг
+- Stage 05.2 — interactive draft builder
+- Stage 05.3 — order validation