2
0
forked from kodorvan/stcs

Fixed check auto trading

This commit is contained in:
algizn97
2025-10-04 09:33:44 +05:00
parent 086c7c8170
commit ce5d0605de
4 changed files with 136 additions and 66 deletions

View File

@@ -123,6 +123,7 @@ async def start_trading_cycle(
"Order does not meet minimum order value", "Order does not meet minimum order value",
"position idx not match position mode", "position idx not match position mode",
"Qty invalid", "Qty invalid",
"The number of contracts exceeds maximum limit allowed"
} }
else None else None
) )
@@ -132,7 +133,9 @@ async def start_trading_cycle(
return None return None
async def trading_cycle(tg_id: int, symbol: str, reverse_side: str, size: str) -> str | None: async def trading_cycle(
tg_id: int, symbol: str, reverse_side: str, size: str
) -> str | None:
try: try:
user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol) user_deals_data = await rq.get_user_deal_by_symbol(tg_id=tg_id, symbol=symbol)
trade_mode = user_deals_data.trade_mode trade_mode = user_deals_data.trade_mode
@@ -169,7 +172,6 @@ async def trading_cycle(tg_id: int, symbol: str, reverse_side: str, size: str) -
leverage=leverage, leverage=leverage,
) )
if reverse_side == "Buy": if reverse_side == "Buy":
real_side = "Sell" real_side = "Sell"
else: else:
@@ -239,6 +241,7 @@ async def trading_cycle(tg_id: int, symbol: str, reverse_side: str, size: str) -
"Risk is too high for this trade", "Risk is too high for this trade",
"ab not enough for new order", "ab not enough for new order",
"InvalidRequestError", "InvalidRequestError",
"The number of contracts exceeds maximum limit allowed"
} }
else None else None
) )
@@ -359,7 +362,6 @@ async def open_positions(
tg_id=tg_id, tg_id=tg_id,
entry_price=price_for_calc, entry_price=price_for_calc,
symbol=symbol, symbol=symbol,
order_quantity=order_quantity,
leverage=get_leverage, leverage=get_leverage,
) )
@@ -388,7 +390,6 @@ async def open_positions(
take_profit_price = max(take_profit_price, 0) take_profit_price = max(take_profit_price, 0)
stop_loss_price = max(stop_loss_price, 0) stop_loss_price = max(stop_loss_price, 0)
# Place order # Place order
order_params = { order_params = {
"category": "linear", "category": "linear",

View File

@@ -5,7 +5,6 @@ from aiogram.fsm.context import FSMContext
from aiogram.types import CallbackQuery from aiogram.types import CallbackQuery
import app.telegram.keyboards.inline as kbi import app.telegram.keyboards.inline as kbi
from app.bybit.get_functions.get_positions import ( from app.bybit.get_functions.get_positions import (
get_active_orders, get_active_orders,
get_active_orders_by_symbol, get_active_orders_by_symbol,
@@ -70,11 +69,15 @@ async def get_positions_handler(
await callback_query.answer(text="Нет активных позиций.") await callback_query.answer(text="Нет активных позиций.")
return return
active_symbols_sides = [(pos.get("symbol"), pos.get("side")) for pos in active_positions] active_symbols_sides = [
(pos.get("symbol"), pos.get("side")) for pos in active_positions
]
await callback_query.message.edit_text( await callback_query.message.edit_text(
text="Ваши активные позиции:", text="Ваши активные позиции:",
reply_markup=kbi.create_active_positions_keyboard(symbols=active_symbols_sides), reply_markup=kbi.create_active_positions_keyboard(
symbols=active_symbols_sides
),
) )
except Exception as e: except Exception as e:
logger.error("Error in get_positions_handler: %s", e) logger.error("Error in get_positions_handler: %s", e)
@@ -113,7 +116,8 @@ async def get_position_handler(callback_query: CallbackQuery, state: FSMContext)
size = position.get("size") or "Нет данных" size = position.get("size") or "Нет данных"
take_profit = position.get("takeProfit") or "Нет данных" take_profit = position.get("takeProfit") or "Нет данных"
stop_loss = position.get("stopLoss") or "Нет данных" stop_loss = position.get("stopLoss") or "Нет данных"
position_idx = position.get("positionIdx") position_idx = position.get("positionIdx") or "Нет данных"
liq_price = position.get("liqPrice") or "Нет данных"
else: else:
side = "Нет данных" side = "Нет данных"
symbol = "Нет данных" symbol = "Нет данных"
@@ -122,6 +126,7 @@ async def get_position_handler(callback_query: CallbackQuery, state: FSMContext)
take_profit = "Нет данных" take_profit = "Нет данных"
stop_loss = "Нет данных" stop_loss = "Нет данных"
position_idx = "Нет данных" position_idx = "Нет данных"
liq_price = "Нет данных"
side_rus = ( side_rus = (
"Покупка" "Покупка"
@@ -129,23 +134,42 @@ async def get_position_handler(callback_query: CallbackQuery, state: FSMContext)
else "Продажа" if side == "Sell" else "Нет данных" else "Продажа" if side == "Sell" else "Нет данных"
) )
position_idx_rus = ("Односторонний" if position_idx == 0 position_idx_rus = (
else "Покупка в режиме хеджирования" if position_idx == 1 "Односторонний"
else "Продажа в режиме хеджирования" if position_idx == 2 if position_idx == 0
else "Нет данных") 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( await callback_query.message.edit_text(
text=f"Торговая пара: {symbol}\n" text=text,
f"Режим позиции: {position_idx_rus}\n" reply_markup=kbi.make_close_position_keyboard(
f"Цена входа: {avg_price}\n" symbol_pos=symbol, side=side, position_idx=position_idx, qty=size
f"Количество: {size}\n" ),
f"Движение: {side_rus}\n"
f"Тейк-профит: {take_profit}\n"
f"Стоп-лосс: {stop_loss}\n",
reply_markup=kbi.make_close_position_keyboard(symbol_pos=symbol,
side=side,
position_idx=position_idx,
qty=size),
) )
except Exception as e: except Exception as e:
@@ -186,7 +210,9 @@ async def get_open_orders_handler(
await callback_query.answer(text="Нет активных ордеров.") await callback_query.answer(text="Нет активных ордеров.")
return return
active_orders_sides = [(pos.get("symbol"), pos.get("side")) for pos in active_positions] active_orders_sides = [
(pos.get("symbol"), pos.get("side")) for pos in active_positions
]
await callback_query.message.edit_text( await callback_query.message.edit_text(
text="Ваши активные ордера:", text="Ваши активные ордера:",
@@ -222,13 +248,13 @@ async def get_order_handler(callback_query: CallbackQuery, state: FSMContext):
if orders: if orders:
side = orders.get("side") side = orders.get("side")
symbol = orders.get("symbol") or "Нет данных" symbol = orders.get("symbol")
price = orders.get("price") or "Нет данных" price = orders.get("price")
qty = orders.get("qty") or "Нет данных" qty = orders.get("qty")
order_type = orders.get("orderType") or "" order_type = orders.get("orderType")
trigger_price = orders.get("triggerPrice") or "Нет данных" trigger_price = orders.get("triggerPrice")
take_profit = orders.get("takeProfit") or "Нет данных" take_profit = orders.get("takeProfit")
stop_loss = orders.get("stopLoss") or "Нет данных" stop_loss = orders.get("stopLoss")
order_id = orders.get("orderId") order_id = orders.get("orderId")
else: else:
side = "Нет данных" side = "Нет данных"
@@ -253,16 +279,31 @@ async def get_order_handler(callback_query: CallbackQuery, state: FSMContext):
else "Лимитный" if order_type == "Limit" else "Нет данных" 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( await callback_query.message.edit_text(
text=f"Торговая пара: {symbol}\n" text=text,
f"Цена: {price}\n" reply_markup=kbi.make_close_orders_keyboard(
f"Количество: {qty}\n" symbol_order=symbol, order_id=order_id
f"Движение: {side_rus}\n" ),
f"Тип ордера: {order_type_rus}\n"
f"Триггер цена: {trigger_price}\n"
f"Тейк-профит: {take_profit}\n"
f"Стоп-лосс: {stop_loss}\n",
reply_markup=kbi.make_close_orders_keyboard(symbol_order=symbol, order_id=order_id),
) )
except Exception as e: except Exception as e:
logger.error("Error in get_order_handler: %s", e) logger.error("Error in get_order_handler: %s", e)

View File

@@ -162,17 +162,18 @@ async def start_trading_long(callback_query: CallbackQuery, state: FSMContext) -
"Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли", "Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли",
"position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента", "position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента",
"Qty invalid": "Некорректное значение ордера для данного инструмента", "Qty invalid": "Некорректное значение ордера для данного инструмента",
"The number of contracts exceeds maximum limit allowed": "️️Количество контрактов превышает допустимое максимальное количество контрактов",
} }
if res == "OK": if res == "OK":
await callback_query.answer(text="Торговля запущена") await callback_query.message.edit_text(text="Торговля запущена")
await state.clear() await state.clear()
else: else:
await rq.set_auto_trading( await rq.set_auto_trading(
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side
) )
text = error_messages.get(res, "Произошла ошибка при запуске торговли") text = error_messages.get(res, "Произошла ошибка при запуске торговли")
await callback_query.answer(text=text) await callback_query.message.edit_text(text=text, reply_markup=kbi.profile_bybit)
await callback_query.message.edit_text("Запуск торговли...") await callback_query.message.edit_text("Запуск торговли...")
task = asyncio.create_task(delay_start()) task = asyncio.create_task(delay_start())
@@ -299,6 +300,11 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
await rq.set_auto_trading( await rq.set_auto_trading(
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True, side=side tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True, side=side
) )
if side == "Buy":
r_side = "Sell"
else:
r_side = "Buy"
await rq.set_auto_trading(tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=True, side=r_side)
res = await start_trading_cycle( res = await start_trading_cycle(
tg_id=callback_query.from_user.id, tg_id=callback_query.from_user.id,
side=side, side=side,
@@ -315,17 +321,24 @@ async def start_switch(callback_query: CallbackQuery, state: FSMContext) -> None
"Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли", "Order does not meet minimum order value": "Сумма ордера не достаточна для запуска торговли",
"position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента", "position idx not match position mode": "Торговля уже запущена в режиме хеджирования на продажу для данного инструмента",
"Qty invalid": "Некорректное значение ордера для данного инструмента", "Qty invalid": "Некорректное значение ордера для данного инструмента",
"The number of contracts exceeds maximum limit allowed": " ️️Количество контрактов превышает допустимое максимальное количество контрактов",
} }
if res == "OK": if res == "OK":
await callback_query.answer(text="Торговля запущена") await callback_query.message.edit_text(text="Торговля запущена")
await state.clear() await state.clear()
else: else:
await rq.set_auto_trading( await rq.set_auto_trading(
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=side
) )
if side == "Buy":
r_side = "Sell"
else:
r_side = "Buy"
await rq.set_auto_trading(tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False,
side=r_side)
text = error_messages.get(res, "Произошла ошибка при запуске торговли") text = error_messages.get(res, "Произошла ошибка при запуске торговли")
await callback_query.answer(text=text) await callback_query.message.edit_text(text=text, reply_markup=kbi.profile_bybit)
await callback_query.message.edit_text("Запуск торговли...") await callback_query.message.edit_text("Запуск торговли...")
task = asyncio.create_task(delay_start()) task = asyncio.create_task(delay_start())

View File

@@ -37,21 +37,32 @@ async def stop_all_trading(callback_query: CallbackQuery, state: FSMContext):
await rq.set_stop_timer(tg_id=callback_query.from_user.id, timer_end=0) await rq.set_stop_timer(tg_id=callback_query.from_user.id, timer_end=0)
await asyncio.sleep(timer_end * 60) await asyncio.sleep(timer_end * 60)
user_auto_trading_list = await rq.get_all_user_auto_trading(tg_id=callback_query.from_user.id) user_auto_trading_list = await rq.get_all_user_auto_trading(
tg_id=callback_query.from_user.id
)
if any(item.auto_trading for item in user_auto_trading_list):
for active_auto_trading in user_auto_trading_list: for active_auto_trading in user_auto_trading_list:
if active_auto_trading.auto_trading: if active_auto_trading.auto_trading:
symbol = active_auto_trading.symbol symbol = active_auto_trading.symbol
get_side = active_auto_trading.side get_side = active_auto_trading.side
req = await rq.set_auto_trading( req = await rq.set_auto_trading(
tg_id=callback_query.from_user.id, symbol=symbol, auto_trading=False, side=get_side tg_id=callback_query.from_user.id,
symbol=symbol,
auto_trading=False,
side=get_side,
) )
if not req: if not req:
await callback_query.edit_text(text="Произошла ошибка при остановке торговли", await callback_query.message.edit_text(
reply_markup=kbi.profile_bybit) text="Произошла ошибка при остановке торговли",
reply_markup=kbi.profile_bybit,
)
return return
await callback_query.message.edit_text(
await callback_query.message.edit_text(text="Торговля остановлена", reply_markup=kbi.profile_bybit) text="Торговля остановлена", reply_markup=kbi.profile_bybit
)
else:
await callback_query.message.edit_text(text="Нет активной торговли")
task = asyncio.create_task(delay_start()) task = asyncio.create_task(delay_start())
await add_stop_task(user_id=callback_query.from_user.id, task=task) await add_stop_task(user_id=callback_query.from_user.id, task=task)
@@ -74,9 +85,13 @@ async def cancel_stop_trading(callback_query: CallbackQuery, state: FSMContext):
try: try:
await state.clear() await state.clear()
cancel_stop_task(callback_query.from_user.id) cancel_stop_task(callback_query.from_user.id)
await callback_query.message.edit_text(text="Таймер отменён.", reply_markup=kbi.profile_bybit) await callback_query.message.edit_text(
text="Таймер отменён.", reply_markup=kbi.profile_bybit
)
except Exception as e: except Exception as e:
await callback_query.answer(text="Произошла ошибка при отмене остановки торговли") await callback_query.answer(
text="Произошла ошибка при отмене остановки торговли"
)
logger.error( logger.error(
"Error processing command cancel_timer_stop for user %s: %s", "Error processing command cancel_timer_stop for user %s: %s",
callback_query.from_user.id, callback_query.from_user.id,