diff --git a/app/services/Bybit/functions/Futures.py b/app/services/Bybit/functions/Futures.py index 7a314ac..d82e6e6 100644 --- a/app/services/Bybit/functions/Futures.py +++ b/app/services/Bybit/functions/Futures.py @@ -1,6 +1,7 @@ import asyncio import logging.config import time +import math import app.services.Bybit.functions.balance as balance_g import app.services.Bybit.functions.price_symbol as price_symbol import app.telegram.database.requests as rq @@ -41,7 +42,7 @@ def safe_float(val) -> float: return 0.0 -def format_trade_details_position(data, commission_fee): +def format_trade_details_position(data): """ Форматирует информацию о сделке в виде строки. """ @@ -55,9 +56,6 @@ def format_trade_details_position(data, commission_fee): commission = safe_float(msg.get("execFee", 0)) pnl = safe_float(msg.get("execPnl", 0)) - if commission_fee == "Да": - pnl -= commission - movement = "" if side.lower() == "buy": movement = "Покупка" @@ -223,8 +221,6 @@ async def handle_execution_message(message, msg): """ tg_id = message.from_user.id data = msg.get("data", [{}])[0] - data_main_risk_stgs = await rq.get_user_risk_management_settings(tg_id) - commission_fee = data_main_risk_stgs.get("commission_fee", "ДА") pnl = parse_pnl_from_msg(msg) data_main_stgs = await rq.get_user_main_settings(tg_id) symbol = data.get("symbol") @@ -234,15 +230,8 @@ async def handle_execution_message(message, msg): starting_quantity = safe_float(data_main_stgs.get("starting_quantity")) martingale_factor = safe_float(data_main_stgs.get("martingale_factor")) closed_size = safe_float(data.get("closedSize", 0)) - commission = safe_float(data.get("execFee", 0)) - if commission_fee == "Да": - pnl -= commission - - trade_info = format_trade_details_position( - data=msg, - commission_fee=commission_fee - ) + trade_info = format_trade_details_position(data=msg) if trade_info: await message.answer(f"{trade_info}", reply_markup=inline_markup.back_to_main) @@ -351,6 +340,11 @@ async def open_position( bybit_margin_mode = ( "ISOLATED_MARGIN" if margin_mode == "Isolated" else "REGULAR_MARGIN" ) + + positions_get = client.get_positions(category="linear", symbol=symbol) + positions = positions_get.get("result", {}).get("list", []) + logger.info(f"Позиции: {positions}") + trigger_price = await rq.get_trigger_price(tg_id) limit_price = None if order_type == "Limit": @@ -400,7 +394,6 @@ async def open_position( await error_max_step(message) return - client.set_margin_mode(setMarginMode=bybit_margin_mode) max_leverage = safe_float(instrument[0].get("leverageFilter", {}).get("maxLeverage", 0)) if safe_float(leverage) > max_leverage: @@ -438,17 +431,21 @@ async def open_position( else: min_order_value = 5.0 - order_value = float(quantity) * price_for_calc - if order_value < min_order_value: + qty_step = float(instrument[0].get("lotSizeFilter", {}).get("qtyStep","1")) + quantity_in_usdt = float(quantity) + min_qty_lots = min_order_value / price_for_calc + adjusted_min_lots = math.ceil(min_qty_lots / qty_step) * qty_step + lots = quantity_in_usdt / price_for_calc + requested_lots = int(lots) + + if requested_lots < adjusted_min_lots: logger.error( - f"Сумма ордера слишком мала: {order_value:.2f} USDT. " - f"Минимум для торговли — {min_order_value} USDT. " - f"Пожалуйста, увеличьте количество позиций." + f"Сумма ордера слишком мала. " + f"Пожалуйста, увеличьте сумму позиций." ) await message.answer( - f"Сумма ордера слишком мала: {order_value:.2f} USDT. " - f"Минимум для торговли — {min_order_value} USDT. " - f"Пожалуйста, увеличьте количество позиций.", + f"Сумма ордера слишком мала. " + f"Пожалуйста, увеличьте сумму позиций.", reply_markup=inline_markup.back_to_main, ) return False @@ -461,7 +458,7 @@ async def open_position( symbol=symbol, side=side, orderType="Stop" if order_type == "Conditional" else order_type, - qty=str(quantity), + qty=str(requested_lots), price=(str(limit_price) if order_type == "Limit" and limit_price else None), triggerPrice=str(trigger_price), triggerBy="LastPrice", @@ -476,7 +473,7 @@ async def open_position( symbol=symbol, side=side, orderType=order_type, - qty=str(quantity), + qty=str(requested_lots), price=(str(limit_price) if order_type == "Limit" and limit_price else None), timeInForce="GTC", orderLinkId=f"deal_{symbol}_{int(time.time())}", @@ -555,7 +552,7 @@ async def open_position( take_profit_price = base_price * tp_multiplier stop_loss_price = base_price * (1 - loss_profit / 100) else: - take_profit_price = base_price * (1 - (loss_profit / 100) - (commission_fee_percent)) + take_profit_price = base_price * (1 - (loss_profit / 100) - (tp_multiplier - 1)) stop_loss_price = base_price * (1 + loss_profit / 100) take_profit_price = max(take_profit_price, 0) @@ -577,7 +574,7 @@ async def open_position( symbol=symbol, side=side, orderType=order_type, - qty=str(quantity), + qty=str(requested_lots), price=( str(limit_price) if order_type == "Limit" and limit_price else None ),