Fixed close position

This commit is contained in:
algizn97
2025-10-03 14:18:53 +05:00
parent 6705bf4492
commit 4adbd70948
2 changed files with 51 additions and 78 deletions

View File

@@ -1,63 +1,56 @@
import logging.config import logging.config
from app.bybit import get_bybit_client from app.bybit import get_bybit_client
from app.bybit.get_functions.get_positions import get_active_positions_by_symbol
from app.bybit.logger_bybit.logger_bybit import LOGGING_CONFIG from app.bybit.logger_bybit.logger_bybit import LOGGING_CONFIG
logging.config.dictConfig(LOGGING_CONFIG) logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("close_positions") logger = logging.getLogger("close_positions")
async def close_position(tg_id: int, symbol: str) -> bool: async def close_position(tg_id: int, symbol: str, side: str, position_idx: int, qty: float) -> bool:
""" """
Closes position Closes all positions
:param tg_id: Telegram user ID :param tg_id: Telegram user ID
:param symbol: symbol :param symbol: symbol
:param side: side
:param position_idx: position index
:param qty: quantity
:return: bool :return: bool
""" """
try: try:
client = await get_bybit_client(tg_id) client = await get_bybit_client(tg_id)
active_positions = await get_active_positions_by_symbol(tg_id, symbol)
side = active_positions.get("side")
size = active_positions.get("size")
position_idx = active_positions.get("positionIdx")
if side == "Buy": if side == "Buy":
side = "Sell" r_side = "Sell"
elif side == "Sell": else:
side = "Buy" r_side = "Buy"
response = client.place_order( response = client.place_order(
category="linear", category="linear",
symbol=symbol, symbol=symbol,
side=side, side=r_side,
orderType="Market", orderType="Market",
qty=size, qty=qty,
timeInForce="GTC", timeInForce="GTC",
positionIdx=position_idx, positionIdx=position_idx,
) )
if response["retCode"] == 0: if response["retCode"] == 0:
logger.info("Position closed for %s for user %s", symbol, tg_id) logger.info("All positions closed for %s for user %s", symbol, tg_id)
return True return True
else: else:
logger.error("Error closing position for %s for user %s", symbol, tg_id) logger.error("Error closing all positions for %s for user %s", symbol, tg_id)
return False return False
except Exception as e: except Exception as e:
logger.error("Error closing position for %s for user %s: %s", symbol, tg_id, e) logger.error("Error closing all positions for %s for user %s: %s", symbol, tg_id, e)
return False return False
async def cancel_order(tg_id: int, symbol: str, order_id: str) -> bool:
async def cancel_order(tg_id, symbol) -> bool:
""" """
Cancel order by order id Cancel order by order id
""" """
try: try:
client = await get_bybit_client(tg_id) client = await get_bybit_client(tg_id)
orders_resp = client.get_open_orders(category="linear", symbol=symbol)
orders = orders_resp.get("result", {}).get("list", [])
for order in orders:
order_id = order.get("orderId")
cancel_resp = client.cancel_order( cancel_resp = client.cancel_order(
category="linear", symbol=symbol, orderId=order_id category="linear", symbol=symbol, orderId=order_id
) )
@@ -71,7 +64,6 @@ async def cancel_order(tg_id, symbol) -> bool:
cancel_resp.get("retMsg"), cancel_resp.get("retMsg"),
) )
return False return False
return False
except Exception as e: except Exception as e:
logger.error("Error canceling order for user %s: %s", tg_id, e) logger.error("Error canceling order for user %s: %s", tg_id, e)
return False return False

View File

@@ -1,12 +1,15 @@
import logging.config import logging.config
from aiogram import F, Router from aiogram import Router
from aiogram.fsm.context import FSMContext from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery from aiogram.types import CallbackQuery
from app.bybit.close_positions import cancel_all_orders, cancel_order, close_position from app.bybit.close_positions import cancel_order, close_position
from app.helper_functions import safe_float
from logger_helper.logger_helper import LOGGING_CONFIG from logger_helper.logger_helper import LOGGING_CONFIG
import database.request as rq
logging.config.dictConfig(LOGGING_CONFIG) logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("close_orders") logger = logging.getLogger("close_orders")
@@ -26,13 +29,23 @@ async def close_position_handler(
:return: None :return: None
""" """
try: try:
symbol = callback_query.data.split("_", 2)[2] data = callback_query.data
res = await close_position(tg_id=callback_query.from_user.id, symbol=symbol) parts = data.split("_")
symbol = parts[2]
side = parts[3]
position_idx = int(parts[4])
qty = safe_float(parts[5])
res = await close_position(tg_id=callback_query.from_user.id,
symbol=symbol,
side=side,
position_idx=position_idx,
qty=qty)
if not res: if not res:
await callback_query.answer(text="Произошла ошибка при закрытии позиции.") await callback_query.answer(text="Произошла ошибка при закрытии позиции.")
return return
await rq.set_auto_trading(tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side)
await callback_query.answer(text="Позиция успешно закрыта.") await callback_query.answer(text="Позиция успешно закрыта.")
logger.debug( logger.debug(
"Command close_position processed successfully for user: %s", "Command close_position processed successfully for user: %s",
@@ -62,8 +75,11 @@ async def cancel_order_handler(
:return: None :return: None
""" """
try: try:
symbol = callback_query.data.split("_", 2)[2] data = callback_query.data
res = await cancel_order(tg_id=callback_query.from_user.id, symbol=symbol) parts = data.split("_")
symbol = parts[2]
order_id = parts[3]
res = await cancel_order(tg_id=callback_query.from_user.id, symbol=symbol, order_id=order_id)
if not res: if not res:
await callback_query.answer(text="Произошла ошибка при закрытии ордера.") await callback_query.answer(text="Произошла ошибка при закрытии ордера.")
@@ -83,38 +99,3 @@ async def cancel_order_handler(
) )
finally: finally:
await state.clear() await state.clear()
@router_close_orders.callback_query(F.data == "cancel_all_orders")
async def cancel_all_orders_handler(
callback_query: CallbackQuery, state: FSMContext
) -> None:
"""
Close all open positions and orders.
:param callback_query: Incoming callback query from Telegram inline keyboard.
:param state: Finite State Machine context for the current user session.
:return: None
"""
try:
res = await cancel_all_orders(tg_id=callback_query.from_user.id)
if not res:
await callback_query.answer(
text="Произошла ошибка при закрытии всех ордеров."
)
return
await callback_query.answer(text="Все ордера успешно закрыты.")
logger.debug(
"Command close_all_orders processed successfully for user: %s",
callback_query.from_user.id,
)
except Exception as e:
await callback_query.answer(text="Произошла ошибка при закрытии всех ордеров.")
logger.error(
"Error processing command close_all_orders for user %s: %s",
callback_query.from_user.id,
e,
)
finally:
await state.clear()