import logging.config import app.telegram.keyboards.inline as kbi import database.request as rq from app.bybit.logger_bybit.logger_bybit import LOGGING_CONFIG from app.bybit.open_positions import trading_cycle from app.helper_functions import format_value, safe_float, safe_int logging.config.dictConfig(LOGGING_CONFIG) logger = logging.getLogger("telegram_message_handler") class TelegramMessageHandler: def __init__(self, telegram_bot): self.telegram_bot = telegram_bot async def format_position_update(self, message): pass async def format_order_update(self, message, tg_id): try: order_data = message.get("data", [{}])[0] symbol = format_value(order_data.get("symbol")) qty = format_value(order_data.get("qty")) order_type = format_value(order_data.get("orderType")) order_type_rus = ( "Рыночный" if order_type == "Market" else "Лимитный" if order_type == "Limit" else "Нет данных" ) side = format_value(order_data.get("side")) side_rus = ( "Покупка" if side == "Buy" else "Продажа" if side == "Sell" else "Нет данных" ) order_status = format_value(order_data.get("orderStatus")) price = format_value(order_data.get("price")) trigger_price = format_value(order_data.get("triggerPrice")) take_profit = format_value(order_data.get("takeProfit")) stop_loss = format_value(order_data.get("stopLoss")) position_idx = safe_int(order_data.get("positionIdx")) position_idx_rus = ( "Односторонний" if position_idx == 0 else ( "Покупка в режиме хеджирования" if position_idx == 1 else ( "Продажа в режиме хеджирования" if position_idx == 2 else "Нет данных" ) ) ) status_map = { "New": "Ордер создан", "Cancelled": "Ордер отменен", "Deactivated": "Ордер деактивирован", "Untriggered": "Условный ордер выставлен", } if order_status == "Filled" or order_status not in status_map: return None status_text = status_map[order_status] text = ( f"{status_text}:\n" f"Торговая пара: {symbol}\n" f"Режим позиции: {position_idx_rus}\n" f"Количество: {qty}\n" f"Тип ордера: {order_type_rus}\n" f"Движение: {side_rus}\n" ) if price and price != "0": text += f"Цена: {price}\n" if take_profit and take_profit != "Нет данных": text += f"Тейк-профит: {take_profit}\n" if stop_loss and stop_loss != "Нет данных": text += f"Стоп-лосс: {stop_loss}\n" if trigger_price and trigger_price != "Нет данных": text += f"Триггер цена: {trigger_price}\n" await self.telegram_bot.send_message( chat_id=tg_id, text=text, reply_markup=kbi.profile_bybit ) except Exception as e: logger.error("Error in format_order_update: %s", e) async def format_execution_update(self, message, tg_id): try: execution = message.get("data", [{}])[0] closed_size = format_value(execution.get("closedSize")) symbol = format_value(execution.get("symbol")) exec_price = format_value(execution.get("execPrice")) exec_fee = format_value(execution.get("execFee")) exec_qty = format_value(execution.get("execQty")) order_type = format_value(execution.get("orderType")) order_type_rus = ( "Рыночный" if order_type == "Market" else "Лимитный" if order_type == "Limit" else "Нет данных" ) side = format_value(execution.get("side")) side_rus = ( "Покупка" if side == "Buy" else "Продажа" if side == "Sell" else "Нет данных" ) if safe_float(closed_size) == 0: await rq.set_fee_user_auto_trading( tg_id=tg_id, symbol=symbol, side=side, fee=safe_float(exec_fee) ) if side == "Buy": res_side = "Sell" else: res_side = "Buy" user_auto_trading = await rq.get_user_auto_trading( tg_id=tg_id, symbol=symbol, side=res_side ) if user_auto_trading is not None and user_auto_trading.fee is not None: fee = user_auto_trading.fee else: fee = 0 exec_pnl = format_value(execution.get("execPnl")) risk_management_data = await rq.get_user_risk_management(tg_id=tg_id) commission_fee = risk_management_data.commission_fee if commission_fee == "Yes_commission_fee": total_pnl = safe_float(exec_pnl) - safe_float(exec_fee) - fee else: total_pnl = safe_float(exec_pnl) header = ( "Сделка закрыта:" if safe_float(closed_size) > 0 else "Сделка открыта:" ) text = f"{header}\n" f"Торговая пара: {symbol}\n" if safe_float(closed_size) > 0: text += f"Количество закрытых сделок: {closed_size}\n" text += ( f"Цена исполнения: {exec_price}\n" f"Количество исполненных сделок: {exec_qty}\n" f"Тип ордера: {order_type_rus}\n" f"Движение: {side_rus}\n" f"Комиссия за сделку: {exec_fee}\n" ) if safe_float(closed_size) > 0: text += f"\nРеализованная прибыль: {total_pnl:.7f}\n" await self.telegram_bot.send_message( chat_id=tg_id, text=text, reply_markup=kbi.profile_bybit ) auto_trading = ( user_auto_trading.auto_trading if user_auto_trading else False ) user_symbols = user_auto_trading.symbol if user_auto_trading else None if ( auto_trading and safe_float(closed_size) > 0 and user_symbols is not None ): if safe_float(total_pnl) > 0: profit_text = "📈 Прибыль достигнута\n" await self.telegram_bot.send_message( chat_id=tg_id, text=profit_text, reply_markup=kbi.profile_bybit ) if side == "Buy": r_side = "Sell" else: r_side = "Buy" await rq.set_auto_trading( tg_id=tg_id, symbol=symbol, auto_trading=False, side=r_side ) user_deals_data = await rq.get_user_deal_by_symbol( tg_id=tg_id, symbol=symbol ) if user_deals_data and user_deals_data.switch_side_mode: await rq.set_auto_trading( tg_id=tg_id, symbol=symbol, auto_trading=False, side=side ) else: open_order_text = "\n❗️ Сделка закрылась в минус, открываю новую сделку с увеличенной ставкой.\n" await self.telegram_bot.send_message( chat_id=tg_id, text=open_order_text ) res = await trading_cycle( tg_id=tg_id, symbol=symbol, reverse_side=side, size=closed_size ) if res == "OK": pass else: errors = { "Max bets in series": "❗️ Максимальное количество сделок в серии достигнуто", "Risk is too high for this trade": "❗️ Риск сделки слишком высок для продолжения", "ab not enough for new order": "❗️ Недостаточно средств для продолжения торговли", "InvalidRequestError": "❗️ Недостаточно средств для размещения нового ордера с заданным количеством и плечом.", "The number of contracts exceeds maximum limit allowed": "❗️ Количество контрактов превышает допустимое максимальное количество контрактов", } error_text = errors.get( res, "❗️ Не удалось открыть новую сделку" ) if side == "Buy": r_side = "Sell" else: r_side = "Buy" await rq.set_auto_trading( tg_id=tg_id, symbol=symbol, auto_trading=False, side=r_side ) user_deals_data = await rq.get_user_deal_by_symbol( tg_id=tg_id, symbol=symbol ) if user_deals_data and user_deals_data.switch_side_mode: await rq.set_auto_trading( tg_id=tg_id, symbol=symbol, auto_trading=False, side=side, ) await self.telegram_bot.send_message( chat_id=tg_id, text=error_text, reply_markup=kbi.profile_bybit, ) except Exception as e: logger.error("Error in telegram_message_handler: %s", e)