267 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			267 lines
		
	
	
		
			12 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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, trading_cycle_profit
 | 
						||
from app.helper_functions import format_value, safe_float
 | 
						||
 | 
						||
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"))
 | 
						||
            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"))
 | 
						||
 | 
						||
            status_map = {
 | 
						||
                "Untriggered": "Условный ордер выставлен",
 | 
						||
            }
 | 
						||
 | 
						||
            if order_status == "Filled" or order_status not in status_map:
 | 
						||
                return None
 | 
						||
 | 
						||
            user_auto_trading = await rq.get_user_auto_trading(
 | 
						||
                tg_id=tg_id, symbol=symbol
 | 
						||
            )
 | 
						||
            auto_trading = (
 | 
						||
                user_auto_trading.auto_trading if user_auto_trading else False
 | 
						||
            )
 | 
						||
            user_deals_data = await rq.get_user_deal_by_symbol(
 | 
						||
                tg_id=tg_id, symbol=symbol
 | 
						||
            )
 | 
						||
 | 
						||
            text = (
 | 
						||
                f"Торговая пара: {symbol}\n"
 | 
						||
                f"Движение: {side_rus}\n"
 | 
						||
            )
 | 
						||
 | 
						||
            if user_deals_data is not None and auto_trading:
 | 
						||
                text += f"Текущая ставка: {user_deals_data.order_quantity} USDT\n"
 | 
						||
            else:
 | 
						||
                text += f"Количество: {qty}\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_qty = format_value(execution.get("execQty"))
 | 
						||
            exec_fees = format_value(execution.get("execFee"))
 | 
						||
            fee_rate = format_value(execution.get("feeRate"))
 | 
						||
            side = format_value(execution.get("side"))
 | 
						||
            side_rus = (
 | 
						||
                "Покупка"
 | 
						||
                if side == "Buy"
 | 
						||
                else "Продажа" if side == "Sell" else "Нет данных"
 | 
						||
            )
 | 
						||
            if safe_float(exec_fees) == 0:
 | 
						||
                exec_fee = safe_float(exec_price) * safe_float(exec_qty) * safe_float(
 | 
						||
                    fee_rate
 | 
						||
                )
 | 
						||
            else:
 | 
						||
                exec_fee = safe_float(exec_fees)
 | 
						||
 | 
						||
            if safe_float(closed_size) == 0:
 | 
						||
                await rq.set_fee_user_auto_trading(
 | 
						||
                    tg_id=tg_id, symbol=symbol, fee=safe_float(exec_fee)
 | 
						||
                )
 | 
						||
 | 
						||
            user_auto_trading = await rq.get_user_auto_trading(
 | 
						||
                tg_id=tg_id, symbol=symbol
 | 
						||
            )
 | 
						||
 | 
						||
            get_total_fee = user_auto_trading.total_fee
 | 
						||
            total_fee = safe_float(exec_fee) + safe_float(get_total_fee)
 | 
						||
 | 
						||
            exec_pnl = format_value(execution.get("execPnl"))
 | 
						||
            pnl = safe_float(exec_pnl)
 | 
						||
 | 
						||
            header = (
 | 
						||
                "Сделка закрыта:" if safe_float(closed_size) > 0 else "Сделка открыта:"
 | 
						||
            )
 | 
						||
            text = f"{header}\n" f"Торговая пара: {symbol}\n"
 | 
						||
 | 
						||
            auto_trading = (
 | 
						||
                user_auto_trading.auto_trading if user_auto_trading else False
 | 
						||
            )
 | 
						||
            user_deals_data = await rq.get_user_deal_by_symbol(
 | 
						||
                tg_id=tg_id, symbol=symbol
 | 
						||
            )
 | 
						||
            commission_fee = user_deals_data.commission_fee
 | 
						||
            commission_place = user_deals_data.commission_place
 | 
						||
            current_series = user_deals_data.current_series
 | 
						||
 | 
						||
            if commission_fee == "Yes_commission_fee":
 | 
						||
                if commission_place == "Commission_for_qty":
 | 
						||
                    total_quantity = safe_float(user_deals_data.order_quantity) + safe_float(
 | 
						||
                        total_fee
 | 
						||
                    )
 | 
						||
                else:
 | 
						||
                    total_quantity = safe_float(user_deals_data.order_quantity)
 | 
						||
            else:
 | 
						||
                total_quantity = safe_float(user_deals_data.order_quantity)
 | 
						||
 | 
						||
            if user_deals_data is not None and auto_trading and safe_float(closed_size) == 0:
 | 
						||
                await rq.set_total_fee_user_auto_trading(
 | 
						||
                    tg_id=tg_id, symbol=symbol, total_fee=total_fee
 | 
						||
                )
 | 
						||
                text += f"Текущая ставка: {total_quantity:.2f} USDT\n"
 | 
						||
                text += f"Серия №: {user_deals_data.current_series}\n"
 | 
						||
                text += f"Сделка №: {user_deals_data.current_step}\n"
 | 
						||
 | 
						||
            text += (
 | 
						||
                f"Цена исполнения: {exec_price}\n"
 | 
						||
                f"Комиссия: {exec_fee:.8f}\n"
 | 
						||
            )
 | 
						||
 | 
						||
            if safe_float(closed_size) == 0:
 | 
						||
                text += f"Движение: {side_rus}\n"
 | 
						||
            else:
 | 
						||
                text += f"\nПрибыль: {pnl:.7f}\n"
 | 
						||
 | 
						||
            await self.telegram_bot.send_message(
 | 
						||
                chat_id=tg_id, text=text, reply_markup=kbi.profile_bybit
 | 
						||
            )
 | 
						||
 | 
						||
            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(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_last_side_by_symbol(
 | 
						||
                        tg_id=tg_id, symbol=symbol, last_side=r_side)
 | 
						||
                    await rq.set_total_fee_user_auto_trading(
 | 
						||
                        tg_id=tg_id, symbol=symbol, total_fee=0
 | 
						||
                    )
 | 
						||
                    await rq.set_fee_user_auto_trading(
 | 
						||
                        tg_id=tg_id, symbol=symbol, fee=0
 | 
						||
                    )
 | 
						||
 | 
						||
                    res = await trading_cycle_profit(
 | 
						||
                        tg_id=tg_id, symbol=symbol, side=r_side
 | 
						||
                    )
 | 
						||
                    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, "❗️ Не удалось открыть новую сделку"
 | 
						||
                        )
 | 
						||
                        await rq.set_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, auto_trading=False
 | 
						||
                        )
 | 
						||
 | 
						||
                        await rq.set_total_fee_user_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, total_fee=0
 | 
						||
                        )
 | 
						||
                        await rq.set_fee_user_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, fee=0
 | 
						||
                        )
 | 
						||
                        await self.telegram_bot.send_message(
 | 
						||
                            chat_id=tg_id,
 | 
						||
                            text=error_text,
 | 
						||
                            reply_markup=kbi.profile_bybit,
 | 
						||
                        )
 | 
						||
                else:
 | 
						||
                    open_order_text = "\n❗️ Открываю новую сделку с увеличенной ставкой.\n"
 | 
						||
                    await self.telegram_bot.send_message(
 | 
						||
                        chat_id=tg_id, text=open_order_text
 | 
						||
                    )
 | 
						||
 | 
						||
                    if side == "Buy":
 | 
						||
                        r_side = "Sell"
 | 
						||
                    else:
 | 
						||
                        r_side = "Buy"
 | 
						||
 | 
						||
                    res = await trading_cycle(
 | 
						||
                        tg_id=tg_id, symbol=symbol, side=r_side
 | 
						||
                    )
 | 
						||
 | 
						||
                    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, "❗️ Не удалось открыть новую сделку"
 | 
						||
                        )
 | 
						||
                        await rq.set_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, auto_trading=False
 | 
						||
                        )
 | 
						||
 | 
						||
                        await rq.set_total_fee_user_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, total_fee=0
 | 
						||
                        )
 | 
						||
                        await rq.set_fee_user_auto_trading(
 | 
						||
                            tg_id=tg_id, symbol=symbol, fee=0
 | 
						||
                        )
 | 
						||
                        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)
 |