169 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
			
		
		
	
	
			169 lines
		
	
	
		
			6.2 KiB
		
	
	
	
		
			Python
		
	
	
	
	
	
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)
 |