import logging.config from aiogram import Router from aiogram.fsm.context import FSMContext from aiogram.types import CallbackQuery, Message import app.telegram.keyboards.inline as kbi from app.bybit.set_functions.set_tp_sl import set_tp_sl_for_position from app.helper_functions import is_number from app.telegram.states.states import SetTradingStopState from logger_helper.logger_helper import LOGGING_CONFIG logging.config.dictConfig(LOGGING_CONFIG) logger = logging.getLogger("tp_sl_handlers") router_tp_sl_handlers = Router(name="tp_sl_handlers") @router_tp_sl_handlers.callback_query(lambda c: c.data.startswith("pos_tp_sl_")) async def set_tp_sl_handler(callback_query: CallbackQuery, state: FSMContext) -> None: """ Handles the 'pos_tp_sl' callback query. Clears the current FSM state, sets the state to 'take_profit', and prompts the user to enter the take-profit. Args: callback_query (CallbackQuery): Incoming callback query from Telegram inline keyboard. state (FSMContext): Finite State Machine context for the current user session. """ try: await state.clear() data = callback_query.data parts = data.split("_") symbol = parts[3] position_idx = int(parts[4]) await state.set_state(SetTradingStopState.take_profit_state) await state.update_data(symbol=symbol) await state.update_data(position_idx=position_idx) msg = await callback_query.message.answer( text="Введите тейк-профит:", reply_markup=kbi.cancel ) await state.update_data(prompt_message_id=msg.message_id) except Exception as e: logger.error("Error in set_tp_sl_handler: %s", e) await callback_query.answer(text="Произошла ошибка, попробуйте позже") @router_tp_sl_handlers.message(SetTradingStopState.take_profit_state) async def set_take_profit_handler(message: Message, state: FSMContext) -> None: """ Handles the 'take_profit' state. Clears the current FSM state, sets the state to 'stop_loss', and prompts the user to enter the stop-loss. Args: message (Message): Incoming message from Telegram. state (FSMContext): Finite State Machine context for the current user session. Returns: None """ try: try: data = await state.get_data() if "prompt_message_id" in data: prompt_message_id = data["prompt_message_id"] await message.bot.delete_message( chat_id=message.chat.id, message_id=prompt_message_id ) await message.delete() except Exception as e: if "message to delete not found" in str(e).lower(): pass # Ignore this error else: raise e take_profit = message.text if not is_number(take_profit): await message.answer( "Ошибка: введите валидное число.", reply_markup=kbi.profile_bybit, ) logger.debug( "User %s input invalid (not an valid number): %s", message.from_user.id, take_profit, ) return await state.update_data(take_profit=take_profit) await state.set_state(SetTradingStopState.stop_loss_state) msg = await message.answer(text="Введите стоп-лосс:", reply_markup=kbi.cancel) await state.update_data(prompt_message_id=msg.message_id) except Exception as e: logger.error("Error in set_take_profit_handler: %s", e) await message.answer( text="Произошла ошибка, попробуйте позже", reply_markup=kbi.profile_bybit ) @router_tp_sl_handlers.message(SetTradingStopState.stop_loss_state) async def set_stop_loss_handler(message: Message, state: FSMContext) -> None: """ Handles the 'stop_loss' state. Clears the current FSM state, sets the state to 'take_profit', and prompts the user to enter the take-profit. Args: message (Message): Incoming message from Telegram. state (FSMContext): Finite State Machine context for the current user session. Returns: None """ try: try: data = await state.get_data() if "prompt_message_id" in data: prompt_message_id = data["prompt_message_id"] await message.bot.delete_message( chat_id=message.chat.id, message_id=prompt_message_id ) await message.delete() except Exception as e: if "message to delete not found" in str(e).lower(): pass # Ignore this error else: raise e stop_loss = message.text if not is_number(stop_loss): await message.answer( "Ошибка: введите валидное число.", reply_markup=kbi.profile_bybit, ) logger.debug( "User %s input invalid (not an valid number): %s", message.from_user.id, stop_loss, ) return await state.update_data(stop_loss=stop_loss) data = await state.get_data() symbol = data["symbol"] take_profit = data["take_profit"] position_idx = data["position_idx"] res = await set_tp_sl_for_position( tg_id=message.from_user.id, symbol=symbol, take_profit_price=float(take_profit), stop_loss_price=float(stop_loss), position_idx=position_idx, ) if res: await message.answer(text="Тейк-профит и стоп-лосс установлены.") else: await message.answer(text="Тейк-профит и стоп-лосс не установлены.") await state.clear() except Exception as e: await message.answer( text="Произошла ошибка, попробуйте позже", reply_markup=kbi.profile_bybit ) logger.error("Error in set_stop_loss_handler: %s", e)