Fixed
This commit is contained in:
@@ -5,6 +5,8 @@ from aiogram import F, Router
|
||||
from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import CallbackQuery
|
||||
|
||||
from app.telegram.tasks.tasks import add_start_task_merged, cancel_start_task_merged, add_start_task_switch, \
|
||||
cancel_start_task_switch
|
||||
import app.telegram.keyboards.inline as kbi
|
||||
import database.request as rq
|
||||
from app.bybit.get_functions.get_positions import get_active_positions_by_symbol
|
||||
@@ -17,8 +19,6 @@ logger = logging.getLogger("start_trading")
|
||||
|
||||
router_start_trading = Router(name="start_trading")
|
||||
|
||||
user_trade_tasks = {}
|
||||
|
||||
|
||||
@router_start_trading.callback_query(F.data == "start_trading")
|
||||
async def start_trading(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||
@@ -39,36 +39,41 @@ async def start_trading(callback_query: CallbackQuery, state: FSMContext) -> Non
|
||||
deals = await get_active_positions_by_symbol(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol
|
||||
)
|
||||
size = deals.get("size") or 0
|
||||
position_idx = deals.get("positionIdx")
|
||||
position = next((d for d in deals if d.get("symbol") == symbol), None)
|
||||
if position:
|
||||
size = position.get("size", 0)
|
||||
position_idx = position.get("positionIdx")
|
||||
else:
|
||||
size = 0
|
||||
position_idx = None
|
||||
|
||||
if position_idx != 0 and safe_float(size) > 0 and trade_mode == "Merged_Single":
|
||||
await callback_query.answer(
|
||||
text="У вас есть активная позиция в режиме хеджирования. "
|
||||
"Открытие сделки в одностороннем режиме невозможно.",
|
||||
"Открытие сделки в одностороннем режиме невозможно.",
|
||||
)
|
||||
return
|
||||
|
||||
if position_idx == 0 and safe_float(size) > 0 and trade_mode == "Both_Sides":
|
||||
await callback_query.answer(
|
||||
text="У вас есть активная позиция в одностороннем режиме. "
|
||||
"Открытие сделки в режиме хеджирования невозможно.",
|
||||
"Открытие сделки в режиме хеджирования невозможно.",
|
||||
)
|
||||
return
|
||||
|
||||
if trade_mode == "Merged_Single":
|
||||
await callback_query.message.edit_text(
|
||||
text="Выберите режим торговли:\n\n"
|
||||
"Лонг - все сделки серии открываются на покупку.\n"
|
||||
"Шорт - все сделки серии открываются на продажу.\n"
|
||||
"Свитч - направление каждой сделки серии меняется по переменно.\n",
|
||||
"Лонг - все сделки серии открываются на покупку.\n"
|
||||
"Шорт - все сделки серии открываются на продажу.\n"
|
||||
"Свитч - направление каждой сделки серии меняется по переменно.\n",
|
||||
reply_markup=kbi.merged_start_trading,
|
||||
)
|
||||
else: # trade_mode == "Both_Sides":
|
||||
await callback_query.message.edit_text(
|
||||
text="Выберите режим торговли:\n\n"
|
||||
"Лонг - все сделки открываются на покупку.\n"
|
||||
"Шорт - все сделки открываются на продажу.\n",
|
||||
"Лонг - все сделки открываются на покупку.\n"
|
||||
"Шорт - все сделки открываются на продажу.\n",
|
||||
reply_markup=kbi.both_start_trading,
|
||||
)
|
||||
logger.debug(
|
||||
@@ -106,8 +111,13 @@ async def start_trading_long(callback_query: CallbackQuery, state: FSMContext) -
|
||||
deals = await get_active_positions_by_symbol(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol
|
||||
)
|
||||
size = deals.get("size") or 0
|
||||
position_idx = deals.get("positionIdx")
|
||||
position = next((d for d in deals if d.get("symbol") == symbol), None)
|
||||
if position:
|
||||
size = position.get("size", 0)
|
||||
position_idx = position.get("positionIdx")
|
||||
else:
|
||||
size = 0
|
||||
position_idx = None
|
||||
|
||||
if position_idx == 0 and safe_float(size) > 0:
|
||||
await callback_query.answer(
|
||||
@@ -120,19 +130,22 @@ async def start_trading_long(callback_query: CallbackQuery, state: FSMContext) -
|
||||
)
|
||||
timer_start = conditional_data.timer_start
|
||||
|
||||
if callback_query.from_user.id in user_trade_tasks:
|
||||
task = user_trade_tasks[callback_query.from_user.id]
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
del user_trade_tasks[callback_query.from_user.id]
|
||||
cancel_start_task_merged(user_id=callback_query.from_user.id)
|
||||
|
||||
async def delay_start():
|
||||
if timer_start > 0:
|
||||
await callback_query.message.edit_text(
|
||||
text=f"Торговля будет запущена с задержкой {timer_start} мин.",
|
||||
reply_markup=kbi.cancel_timer,
|
||||
reply_markup=kbi.cancel_timer_merged,
|
||||
)
|
||||
await rq.set_start_timer(
|
||||
tg_id=callback_query.from_user.id, timer_start=0
|
||||
)
|
||||
await asyncio.sleep(timer_start * 60)
|
||||
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True, side=side
|
||||
)
|
||||
res = await start_trading_cycle(
|
||||
tg_id=callback_query.from_user.id,
|
||||
side=side,
|
||||
@@ -146,27 +159,24 @@ async def start_trading_long(callback_query: CallbackQuery, state: FSMContext) -
|
||||
"estimated will trigger liq": "Лимитный ордер может вызвать мгновенную ликвидацию. Проверьте параметры ордера.",
|
||||
"ab not enough for new order": "Недостаточно средств для создания нового ордера",
|
||||
"InvalidRequestError": "Произошла ошибка при запуске торговли.",
|
||||
"Order does not meet minimum order value": "Сумма ордера не sufficientдля запуска торговли",
|
||||
"Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли",
|
||||
"position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента",
|
||||
"Qty invalid": "Некорректное значение ордера для данного инструмента",
|
||||
}
|
||||
|
||||
if res == "OK":
|
||||
await rq.set_start_timer(
|
||||
tg_id=callback_query.from_user.id, timer_start=0
|
||||
)
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True
|
||||
)
|
||||
await callback_query.answer(text="Торговля запущена")
|
||||
await state.clear()
|
||||
else:
|
||||
# Получаем сообщение из таблицы, или дефолтный текст
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side
|
||||
)
|
||||
text = error_messages.get(res, "Произошла ошибка при запуске торговли")
|
||||
await callback_query.answer(text=text)
|
||||
|
||||
await callback_query.message.edit_text("Запуск торговли...")
|
||||
task = asyncio.create_task(delay_start())
|
||||
user_trade_tasks[callback_query.from_user.id] = task
|
||||
await add_start_task_merged(user_id=callback_query.from_user.id, task=task)
|
||||
|
||||
except Exception as e:
|
||||
await callback_query.answer(text="Произошла ошибка при запуске торговли")
|
||||
@@ -181,7 +191,7 @@ async def start_trading_long(callback_query: CallbackQuery, state: FSMContext) -
|
||||
|
||||
@router_start_trading.callback_query(lambda c: c.data == "switch")
|
||||
async def start_trading_switch(
|
||||
callback_query: CallbackQuery, state: FSMContext
|
||||
callback_query: CallbackQuery, state: FSMContext
|
||||
) -> None:
|
||||
"""
|
||||
Handles the "switch" callback query.
|
||||
@@ -194,10 +204,10 @@ async def start_trading_switch(
|
||||
await state.clear()
|
||||
await callback_query.message.edit_text(
|
||||
text="Выберите направление первой сделки серии:\n\n"
|
||||
"Лонг - открывается первая сделка на покупку.\n"
|
||||
"Шорт - открывается первая сделка на продажу.\n"
|
||||
"По направлению - сделка открывается в направлении последней сделки предыдущей серии.\n"
|
||||
"Противоположно - сделка открывается в противоположном направлении последней сделки предыдущей серии.\n",
|
||||
"Лонг - открывается первая сделка на покупку.\n"
|
||||
"Шорт - открывается первая сделка на продажу.\n"
|
||||
"По направлению - сделка открывается в направлении последней сделки предыдущей серии.\n"
|
||||
"Противоположно - сделка открывается в противоположном направлении последней сделки предыдущей серии.\n",
|
||||
reply_markup=kbi.switch_side,
|
||||
)
|
||||
except Exception as e:
|
||||
@@ -211,7 +221,7 @@ async def start_trading_switch(
|
||||
|
||||
@router_start_trading.callback_query(
|
||||
lambda c: c.data
|
||||
in {"switch_long", "switch_short", "switch_direction", "switch_opposite"}
|
||||
in {"switch_long", "switch_short", "switch_direction", "switch_opposite"}
|
||||
)
|
||||
async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
@@ -249,8 +259,13 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
|
||||
deals = await get_active_positions_by_symbol(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol
|
||||
)
|
||||
size = deals.get("size") or 0
|
||||
position_idx = deals.get("positionIdx")
|
||||
position = next((d for d in deals if d.get("symbol") == symbol), None)
|
||||
if position:
|
||||
size = position.get("size", 0)
|
||||
position_idx = position.get("positionIdx")
|
||||
else:
|
||||
size = 0
|
||||
position_idx = None
|
||||
|
||||
if position_idx == 1 and safe_float(size) > 0 and side == "Buy":
|
||||
await callback_query.answer(
|
||||
@@ -269,19 +284,21 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
|
||||
)
|
||||
timer_start = conditional_data.timer_start
|
||||
|
||||
if callback_query.from_user.id in user_trade_tasks:
|
||||
task = user_trade_tasks[callback_query.from_user.id]
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
del user_trade_tasks[callback_query.from_user.id]
|
||||
cancel_start_task_switch(user_id=callback_query.from_user.id)
|
||||
|
||||
async def delay_start():
|
||||
if timer_start > 0:
|
||||
await callback_query.message.edit_text(
|
||||
text=f"Торговля будет запущена с задержкой {timer_start} мин.",
|
||||
reply_markup=kbi.cancel_timer,
|
||||
reply_markup=kbi.cancel_timer_switch,
|
||||
)
|
||||
await rq.set_start_timer(
|
||||
tg_id=callback_query.from_user.id, timer_start=0
|
||||
)
|
||||
await asyncio.sleep(timer_start * 60)
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True, side=side
|
||||
)
|
||||
res = await start_trading_cycle(
|
||||
tg_id=callback_query.from_user.id,
|
||||
side=side,
|
||||
@@ -295,26 +312,24 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
|
||||
"estimated will trigger liq": "Лимитный ордер может вызвать мгновенную ликвидацию. Проверьте параметры ордера.",
|
||||
"ab not enough for new order": "Недостаточно средств для создания нового ордера",
|
||||
"InvalidRequestError": "Произошла ошибка при запуске торговли.",
|
||||
"Order does not meet minimum order value": "Сумма ордера не sufficientдля запуска торговли",
|
||||
"Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли",
|
||||
"position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента",
|
||||
"Qty invalid": "Некорректное значение ордера для данного инструмента",
|
||||
}
|
||||
|
||||
if res == "OK":
|
||||
await rq.set_start_timer(
|
||||
tg_id=callback_query.from_user.id, timer_start=0
|
||||
)
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True
|
||||
)
|
||||
await callback_query.answer(text="Торговля запущена")
|
||||
await state.clear()
|
||||
else:
|
||||
await rq.set_auto_trading(
|
||||
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side
|
||||
)
|
||||
text = error_messages.get(res, "Произошла ошибка при запуске торговли")
|
||||
await callback_query.answer(text=text)
|
||||
|
||||
await callback_query.message.edit_text("Запуск торговли...")
|
||||
task = asyncio.create_task(delay_start())
|
||||
user_trade_tasks[callback_query.from_user.id] = task
|
||||
await add_start_task_switch(user_id=callback_query.from_user.id, task=task)
|
||||
except asyncio.CancelledError:
|
||||
logger.error("Cancelled timer for user %s", callback_query.from_user.id)
|
||||
except Exception as e:
|
||||
@@ -326,9 +341,9 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
|
||||
)
|
||||
|
||||
|
||||
@router_start_trading.callback_query(F.data == "cancel_timer")
|
||||
@router_start_trading.callback_query(lambda c: c.data == "cancel_timer_merged" or c.data == "cancel_timer_switch")
|
||||
async def cancel_start_trading(
|
||||
callback_query: CallbackQuery, state: FSMContext
|
||||
callback_query: CallbackQuery, state: FSMContext
|
||||
) -> None:
|
||||
"""
|
||||
Handles the "cancel_timer" callback query.
|
||||
@@ -338,21 +353,12 @@ async def cancel_start_trading(
|
||||
:return: None
|
||||
"""
|
||||
try:
|
||||
task = user_trade_tasks.get(callback_query.from_user.id)
|
||||
if task and not task.done():
|
||||
task.cancel()
|
||||
try:
|
||||
await task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
user_trade_tasks.pop(callback_query.from_user.id, None)
|
||||
await callback_query.message.edit_text(
|
||||
"Таймер отменён.", reply_markup=kbi.profile_bybit
|
||||
)
|
||||
else:
|
||||
await callback_query.message.edit_text(
|
||||
"Таймер не запущен.", reply_markup=kbi.profile_bybit
|
||||
)
|
||||
await state.clear()
|
||||
if callback_query.data == "cancel_timer_merged":
|
||||
cancel_start_task_merged(user_id=callback_query.from_user.id)
|
||||
elif callback_query.data == "cancel_timer_switch":
|
||||
cancel_start_task_switch(user_id=callback_query.from_user.id)
|
||||
await callback_query.message.edit_text(text="Запуск торговли отменен", reply_markup=kbi.profile_bybit)
|
||||
except Exception as e:
|
||||
await callback_query.answer("Произошла ошибка при отмене запуска торговли")
|
||||
logger.error(
|
||||
@@ -360,5 +366,3 @@ async def cancel_start_trading(
|
||||
callback_query.from_user.id,
|
||||
e,
|
||||
)
|
||||
finally:
|
||||
await state.clear()
|
||||
|
Reference in New Issue
Block a user