315 lines
11 KiB
Python
315 lines
11 KiB
Python
import logging.config
|
|
|
|
from aiogram import F, Router
|
|
from aiogram.fsm.context import FSMContext
|
|
from aiogram.types import CallbackQuery
|
|
|
|
import app.telegram.keyboards.inline as kbi
|
|
from app.bybit.get_functions.get_positions import (
|
|
get_active_orders,
|
|
get_active_orders_by_symbol,
|
|
get_active_positions,
|
|
get_active_positions_by_symbol,
|
|
)
|
|
from logger_helper.logger_helper import LOGGING_CONFIG
|
|
|
|
logging.config.dictConfig(LOGGING_CONFIG)
|
|
logger = logging.getLogger("get_positions_handlers")
|
|
|
|
router_get_positions_handlers = Router(name="get_positions_handlers")
|
|
|
|
|
|
@router_get_positions_handlers.callback_query(F.data == "my_deals")
|
|
async def get_positions_handlers(
|
|
callback_query: CallbackQuery, state: FSMContext
|
|
) -> None:
|
|
"""
|
|
Gets the user's active positions.
|
|
:param callback_query: CallbackQuery object.
|
|
:param state: FSMContext
|
|
:return: None
|
|
"""
|
|
try:
|
|
await state.clear()
|
|
await callback_query.message.edit_text(
|
|
text="Выберите какие сделки вы хотите посмотреть:",
|
|
reply_markup=kbi.change_position,
|
|
)
|
|
except Exception as e:
|
|
logger.error("Error in get_positions_handler: %s", e)
|
|
await callback_query.answer(text="Произошла ошибка при получении сделок.")
|
|
|
|
|
|
@router_get_positions_handlers.callback_query(F.data == "change_position")
|
|
async def get_positions_handler(
|
|
callback_query: CallbackQuery, state: FSMContext
|
|
) -> None:
|
|
"""
|
|
Gets the user's active positions.
|
|
:param callback_query: CallbackQuery object.
|
|
:param state: FSMContext
|
|
:return: None
|
|
"""
|
|
try:
|
|
res = await get_active_positions(tg_id=callback_query.from_user.id)
|
|
|
|
if res is None:
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных позиций."
|
|
)
|
|
return
|
|
|
|
if res == ["No active positions found"]:
|
|
await callback_query.answer(text="Нет активных позиций.")
|
|
return
|
|
|
|
active_positions = [pos for pos in res if float(pos.get("size", 0)) > 0]
|
|
|
|
if not active_positions:
|
|
await callback_query.answer(text="Нет активных позиций.")
|
|
return
|
|
|
|
active_symbols_sides = [
|
|
(pos.get("symbol"), pos.get("side")) for pos in active_positions
|
|
]
|
|
|
|
await callback_query.message.edit_text(
|
|
text="Ваши активные позиции:",
|
|
reply_markup=kbi.create_active_positions_keyboard(
|
|
symbols=active_symbols_sides
|
|
),
|
|
)
|
|
except Exception as e:
|
|
logger.error("Error in get_positions_handler: %s", e)
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных позиций."
|
|
)
|
|
finally:
|
|
await state.clear()
|
|
|
|
|
|
@router_get_positions_handlers.callback_query(
|
|
lambda c: c.data.startswith("get_position_")
|
|
)
|
|
async def get_position_handler(callback_query: CallbackQuery, state: FSMContext):
|
|
try:
|
|
data = callback_query.data
|
|
parts = data.split("_")
|
|
symbol = parts[2]
|
|
get_side = parts[3]
|
|
res = await get_active_positions_by_symbol(
|
|
tg_id=callback_query.from_user.id, symbol=symbol
|
|
)
|
|
|
|
if res is None:
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных позиций."
|
|
)
|
|
return
|
|
|
|
position = next((pos for pos in res if pos.get("side") == get_side), None)
|
|
|
|
if position:
|
|
side = position.get("side")
|
|
symbol = position.get("symbol") or "Нет данных"
|
|
avg_price = position.get("avgPrice") or "Нет данных"
|
|
size = position.get("size") or "Нет данных"
|
|
take_profit = position.get("takeProfit") or "Нет данных"
|
|
stop_loss = position.get("stopLoss") or "Нет данных"
|
|
position_idx = position.get("positionIdx") or "Нет данных"
|
|
liq_price = position.get("liqPrice") or "Нет данных"
|
|
else:
|
|
side = "Нет данных"
|
|
symbol = "Нет данных"
|
|
avg_price = "Нет данных"
|
|
size = "Нет данных"
|
|
take_profit = "Нет данных"
|
|
stop_loss = "Нет данных"
|
|
position_idx = "Нет данных"
|
|
liq_price = "Нет данных"
|
|
|
|
side_rus = (
|
|
"Покупка"
|
|
if side == "Buy"
|
|
else "Продажа" if side == "Sell" else "Нет данных"
|
|
)
|
|
|
|
position_idx_rus = (
|
|
"Односторонний"
|
|
if position_idx == 0
|
|
else (
|
|
"Покупка в режиме хеджирования"
|
|
if position_idx == 1
|
|
else (
|
|
"Продажа в режиме хеджирования"
|
|
if position_idx == 2
|
|
else "Нет данных"
|
|
)
|
|
)
|
|
)
|
|
|
|
text_lines = [
|
|
f"Торговая пара: {symbol}",
|
|
f"Режим позиции: {position_idx_rus}",
|
|
f"Цена входа: {avg_price}",
|
|
f"Количество: {size}",
|
|
f"Движение: {side_rus}",
|
|
]
|
|
|
|
if take_profit and take_profit != "Нет данных":
|
|
text_lines.append(f"Тейк-профит: {take_profit}")
|
|
if stop_loss and stop_loss != "Нет данных":
|
|
text_lines.append(f"Стоп-лосс: {stop_loss}")
|
|
if liq_price and liq_price != "Нет данных":
|
|
text_lines.append(f"Цена ликвидации: {liq_price}")
|
|
|
|
text = "\n".join(text_lines)
|
|
|
|
await callback_query.message.edit_text(
|
|
text=text,
|
|
reply_markup=kbi.make_close_position_keyboard(
|
|
symbol_pos=symbol, side=side, position_idx=position_idx, qty=size
|
|
),
|
|
)
|
|
|
|
except Exception as e:
|
|
logger.error("Error in get_position_handler: %s", e)
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных позиций."
|
|
)
|
|
finally:
|
|
await state.clear()
|
|
|
|
|
|
@router_get_positions_handlers.callback_query(F.data == "open_orders")
|
|
async def get_open_orders_handler(
|
|
callback_query: CallbackQuery, state: FSMContext
|
|
) -> None:
|
|
"""
|
|
Gets the user's open orders.
|
|
:param callback_query: CallbackQuery object.
|
|
:param state: FSMContext
|
|
:return: None
|
|
"""
|
|
try:
|
|
res = await get_active_orders(tg_id=callback_query.from_user.id)
|
|
|
|
if res is None:
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных ордеров."
|
|
)
|
|
return
|
|
|
|
if res == ["No active orders found"]:
|
|
await callback_query.answer(text="Нет активных ордеров.")
|
|
return
|
|
|
|
active_positions = [pos for pos in res if pos.get("orderStatus", 0) == "New"]
|
|
|
|
if not active_positions:
|
|
await callback_query.answer(text="Нет активных ордеров.")
|
|
return
|
|
|
|
active_orders_sides = [
|
|
(pos.get("symbol"), pos.get("side")) for pos in active_positions
|
|
]
|
|
|
|
await callback_query.message.edit_text(
|
|
text="Ваши активные ордера:",
|
|
reply_markup=kbi.create_active_orders_keyboard(orders=active_orders_sides),
|
|
)
|
|
except Exception as e:
|
|
logger.error("Error in get_open_orders_handler: %s", e)
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных ордеров."
|
|
)
|
|
finally:
|
|
await state.clear()
|
|
|
|
|
|
@router_get_positions_handlers.callback_query(lambda c: c.data.startswith("get_order_"))
|
|
async def get_order_handler(callback_query: CallbackQuery, state: FSMContext):
|
|
try:
|
|
data = callback_query.data
|
|
parts = data.split("_")
|
|
symbol = parts[2]
|
|
get_side = parts[3]
|
|
res = await get_active_orders_by_symbol(
|
|
tg_id=callback_query.from_user.id, symbol=symbol
|
|
)
|
|
|
|
if res is None:
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных ордеров."
|
|
)
|
|
return
|
|
|
|
orders = next((pos for pos in res if pos.get("side") == get_side), None)
|
|
|
|
if orders:
|
|
side = orders.get("side")
|
|
symbol = orders.get("symbol")
|
|
price = orders.get("price")
|
|
qty = orders.get("qty")
|
|
order_type = orders.get("orderType")
|
|
trigger_price = orders.get("triggerPrice")
|
|
take_profit = orders.get("takeProfit")
|
|
stop_loss = orders.get("stopLoss")
|
|
order_id = orders.get("orderId")
|
|
else:
|
|
side = "Нет данных"
|
|
symbol = "Нет данных"
|
|
price = "Нет данных"
|
|
qty = "Нет данных"
|
|
order_type = "Нет данных"
|
|
trigger_price = "Нет данных"
|
|
take_profit = "Нет данных"
|
|
stop_loss = "Нет данных"
|
|
order_id = "Нет данных"
|
|
|
|
side_rus = (
|
|
"Покупка"
|
|
if side == "Buy"
|
|
else "Продажа" if side == "Sell" else "Нет данных"
|
|
)
|
|
|
|
order_type_rus = (
|
|
"Рыночный"
|
|
if order_type == "Market"
|
|
else "Лимитный" if order_type == "Limit" else "Нет данных"
|
|
)
|
|
|
|
text_lines = [
|
|
f"Торговая пара: {symbol}",
|
|
f"Количество: {qty}",
|
|
f"Движение: {side_rus}",
|
|
f"Тип ордера: {order_type_rus}",
|
|
]
|
|
if price:
|
|
text_lines.append(f"Цена: {price}")
|
|
|
|
if trigger_price and trigger_price != "Нет данных":
|
|
text_lines.append(f"Триггер цена: {trigger_price}")
|
|
|
|
if take_profit and take_profit != "Нет данных":
|
|
text_lines.append(f"Тейк-профит: {take_profit}")
|
|
|
|
if stop_loss and stop_loss != "Нет данных":
|
|
text_lines.append(f"Стоп-лосс: {stop_loss}")
|
|
|
|
text = "\n".join(text_lines)
|
|
|
|
await callback_query.message.edit_text(
|
|
text=text,
|
|
reply_markup=kbi.make_close_orders_keyboard(
|
|
symbol_order=symbol, order_id=order_id
|
|
),
|
|
)
|
|
except Exception as e:
|
|
logger.error("Error in get_order_handler: %s", e)
|
|
await callback_query.answer(
|
|
text="Произошла ошибка при получении активных ордеров."
|
|
)
|
|
finally:
|
|
await state.clear()
|