266 lines
12 KiB
Python
266 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)
|
||
|
||
|
||
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"
|
||
|
||
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
|
||
)
|
||
if user_deals_data is not None and auto_trading:
|
||
await rq.set_total_fee_user_auto_trading(
|
||
tg_id=tg_id, symbol=symbol, total_fee=total_fee
|
||
)
|
||
text += f"Текущая ставка: {user_deals_data.order_quantity} USDT\n"
|
||
else:
|
||
text += f"Количество: {exec_qty}\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Реализованная прибыль: {total_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(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_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)
|