Files
dzentra_bot/app/src/telegram/handlers/market.py

160 lines
4.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# app/src/telegram/handlers/market.py
from __future__ import annotations
from aiogram import F, Router
from aiogram.fsm.context import FSMContext
from aiogram.types import Message
from src.integrations.exchange.exceptions import ExchangeError
from src.integrations.exchange.service import ExchangeService
from src.trading.journal.service import JournalService
router = Router(name="market")
def _safe_log_info(
journal: JournalService,
event_type: str,
message: str,
payload: dict | None = None,
) -> None:
try:
journal.log_info(event_type, message, payload)
except Exception:
pass
def _safe_log_warning(
journal: JournalService,
event_type: str,
message: str,
payload: dict | None = None,
) -> None:
try:
journal.log_warning(event_type, message, payload)
except Exception:
pass
def _safe_log_error(
journal: JournalService,
event_type: str,
message: str,
payload: dict | None = None,
) -> None:
try:
journal.log_error(event_type, message, payload)
except Exception:
pass
@router.message(F.text == "📈 Рынок")
async def open_market(message: Message, state: FSMContext) -> None:
# Глобальный экран: всегда выходим из текущего FSM-сценария.
await state.clear()
service = ExchangeService()
journal = JournalService()
user_id = message.from_user.id if message.from_user else None
chat_id = message.chat.id if message.chat else None
requested_symbol = service.settings.default_symbol
_safe_log_info(
journal,
"user_open_market",
"Пользователь открыл экран рынка.",
{
"user_id": user_id,
"chat_id": chat_id,
"symbol": requested_symbol,
},
)
try:
validation = service.validate_symbol(requested_symbol)
if not validation.is_valid:
_safe_log_warning(
journal,
"market_symbol_invalid",
f"Символ не прошел проверку: {validation.message}",
{
"user_id": user_id,
"chat_id": chat_id,
"symbol": requested_symbol,
},
)
await message.answer(
"<b>📈 Рынок</b>\n\n"
f"Ошибка инструмента: {validation.message}"
)
return
ticker = service.get_price(validation.normalized_symbol)
except ExchangeError as exc:
_safe_log_error(
journal,
"market_open_error",
f"Не удалось открыть экран рынка: {exc}",
{
"user_id": user_id,
"chat_id": chat_id,
"symbol": requested_symbol,
},
)
await message.answer(
"<b>📈 Рынок</b>\n\n"
"Не удалось получить цену с биржи.\n"
f"Ошибка: {exc}"
)
return
symbol_info = validation.symbol_info
symbol_status = symbol_info.status if symbol_info else "n/a"
market_type = symbol_info.market_type if symbol_info else "n/a"
market_modes = (
", ".join(symbol_info.market_modes)
if symbol_info and symbol_info.market_modes
else "n/a"
)
tick_size = (
f"{symbol_info.tick_size}"
if symbol_info and symbol_info.tick_size is not None
else "n/a"
)
base_asset = symbol_info.base_asset if symbol_info and symbol_info.base_asset else "n/a"
quote_asset = symbol_info.quote_asset if symbol_info and symbol_info.quote_asset else "n/a"
name = symbol_info.name if symbol_info and symbol_info.name else ticker.symbol
text = (
"<b>📈 Рынок</b>\n\n"
f"Символ: <b>{ticker.symbol}</b>\n"
f"Название: {name}\n"
f"Цена: <b>{ticker.price:.2f}</b>\n"
f"Статус: {symbol_status}\n"
f"Тип рынка: {market_type}\n"
f"Режимы: {market_modes}\n"
f"Base asset: {base_asset}\n"
f"Quote asset: {quote_asset}\n"
f"Tick size: {tick_size}\n"
f"Источник: {ticker.source}\n"
f"Обновлено: {ticker.updated_at}"
)
_safe_log_info(
journal,
"market_open_success",
"Экран рынка успешно показан пользователю.",
{
"user_id": user_id,
"chat_id": chat_id,
"symbol": ticker.symbol,
"price": ticker.price,
"base_asset": base_asset,
"quote_asset": quote_asset,
},
)
await message.answer(text)