forked from kodorvan/stcs
The entire database has been changed to PostgresSQL. The entire code has been updated.
This commit is contained in:
278
app/telegram/handlers/settings.py
Normal file
278
app/telegram/handlers/settings.py
Normal file
@@ -0,0 +1,278 @@
|
||||
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
|
||||
import database.request as rq
|
||||
from app.bybit import get_bybit_client
|
||||
from app.bybit.get_functions.get_tickers import get_tickers
|
||||
from app.helper_functions import calculate_total_budget, get_base_currency, safe_float
|
||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||
|
||||
logging.config.dictConfig(LOGGING_CONFIG)
|
||||
logger = logging.getLogger("settings")
|
||||
|
||||
router_settings = Router(name="settings")
|
||||
|
||||
|
||||
@router_settings.callback_query(F.data == "additional_settings")
|
||||
async def additional_settings(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
Handler for the "additional_settings" command.
|
||||
Sends a message with additional settings options.
|
||||
"""
|
||||
try:
|
||||
await state.clear()
|
||||
tg_id = callback_query.from_user.id
|
||||
symbol = await rq.get_user_symbol(tg_id=tg_id)
|
||||
additional_data = await rq.get_user_additional_settings(tg_id=tg_id)
|
||||
|
||||
if not additional_data:
|
||||
await rq.create_user(
|
||||
tg_id=tg_id, username=callback_query.from_user.username
|
||||
)
|
||||
await rq.create_user_additional_settings(tg_id=tg_id)
|
||||
await rq.create_user_risk_management(tg_id=tg_id)
|
||||
await rq.create_user_conditional_settings(tg_id=tg_id)
|
||||
await additional_settings(callback_query=callback_query, state=state)
|
||||
return
|
||||
|
||||
trade_mode_map = {
|
||||
"Merged_Single": "Односторонний режим",
|
||||
"Both_Sides": "Хеджирование",
|
||||
}
|
||||
margin_type_map = {
|
||||
"ISOLATED_MARGIN": "Изолированная",
|
||||
"REGULAR_MARGIN": "Кросс",
|
||||
}
|
||||
order_type_map = {"Market": "Рыночный", "Limit": "Лимитный"}
|
||||
|
||||
trade_mode = additional_data.trade_mode or ""
|
||||
margin_type = additional_data.margin_type or ""
|
||||
order_type = additional_data.order_type or ""
|
||||
|
||||
trade_mode_rus = trade_mode_map.get(trade_mode, trade_mode)
|
||||
margin_type_rus = margin_type_map.get(margin_type, margin_type)
|
||||
order_type_rus = order_type_map.get(order_type, "Условный")
|
||||
|
||||
def f(x):
|
||||
return safe_float(x)
|
||||
|
||||
leverage = f(additional_data.leverage)
|
||||
leverage_to_buy = f(additional_data.leverage_to_buy)
|
||||
leverage_to_sell = f(additional_data.leverage_to_sell)
|
||||
martingale = f(additional_data.martingale_factor)
|
||||
max_bets = additional_data.max_bets_in_series
|
||||
quantity = f(additional_data.order_quantity)
|
||||
limit_price = f(additional_data.limit_price)
|
||||
trigger_price = f(additional_data.trigger_price) or 0
|
||||
|
||||
tickers = await get_tickers(tg_id=tg_id, symbol=symbol)
|
||||
price_symbol = safe_float(tickers.get("lastPrice")) or 0
|
||||
bid = f(tickers.get("bid1Price")) or 0
|
||||
ask = f(tickers.get("ask1Price")) or 0
|
||||
|
||||
sym = get_base_currency(symbol)
|
||||
|
||||
if trade_mode == "Merged_Single":
|
||||
leverage_str = f"{leverage:.2f}x"
|
||||
else:
|
||||
if margin_type == "ISOLATED_MARGIN":
|
||||
leverage_str = f"{leverage_to_buy:.2f}x:{leverage_to_sell:.2f}x"
|
||||
else:
|
||||
leverage_str = f"{leverage:.2f}x"
|
||||
|
||||
conditional_order_type = additional_data.conditional_order_type or ""
|
||||
conditional_order_type_rus = (
|
||||
"Лимитный"
|
||||
if conditional_order_type == "Limit"
|
||||
else (
|
||||
"Рыночный"
|
||||
if conditional_order_type == "Market"
|
||||
else conditional_order_type
|
||||
)
|
||||
)
|
||||
|
||||
conditional_order_type_text = (
|
||||
f"- Тип условного ордера: {conditional_order_type_rus}\n"
|
||||
if order_type == "Conditional"
|
||||
else ""
|
||||
)
|
||||
|
||||
limit_price_text = ""
|
||||
trigger_price_text = ""
|
||||
|
||||
if order_type == "Limit":
|
||||
limit_price_text = f"- Цена лимитного ордера: {limit_price:.4f} USDT\n"
|
||||
elif order_type == "Conditional":
|
||||
if conditional_order_type == "Limit":
|
||||
limit_price_text = f"- Цена лимитного ордера: {limit_price:.4f} USDT\n"
|
||||
trigger_price_text = f"- Триггер цена: {trigger_price:.4f} USDT\n"
|
||||
|
||||
risk_management_data = await rq.get_user_risk_management(tg_id=tg_id)
|
||||
commission_fee = risk_management_data.commission_fee
|
||||
client = await get_bybit_client(tg_id=tg_id)
|
||||
fee_info = client.get_fee_rates(category="linear", symbol=symbol)
|
||||
|
||||
if commission_fee == "Yes_commission_fee":
|
||||
commission_fee_percent = safe_float(
|
||||
fee_info["result"]["list"][0]["takerFeeRate"]
|
||||
)
|
||||
|
||||
else:
|
||||
commission_fee_percent = 0.0
|
||||
|
||||
if order_type == "Conditional":
|
||||
if conditional_order_type == "Limit":
|
||||
entry_price = limit_price
|
||||
ask_price = limit_price
|
||||
bid_price = limit_price
|
||||
else:
|
||||
ask_price = trigger_price
|
||||
bid_price = trigger_price
|
||||
entry_price = trigger_price
|
||||
else:
|
||||
if order_type == "Limit":
|
||||
entry_price = limit_price
|
||||
ask_price = limit_price
|
||||
bid_price = limit_price
|
||||
else:
|
||||
entry_price = price_symbol
|
||||
ask_price = ask
|
||||
bid_price = bid
|
||||
|
||||
durability_buy = quantity * bid_price
|
||||
durability_sell = quantity * ask_price
|
||||
quantity_price = quantity * entry_price
|
||||
total_commission = quantity_price * commission_fee_percent
|
||||
total_budget = await calculate_total_budget(
|
||||
quantity=durability_buy,
|
||||
martingale_factor=martingale,
|
||||
max_steps=max_bets,
|
||||
commission_fee_percent=total_commission,
|
||||
)
|
||||
text = (
|
||||
f"Основные настройки:\n\n"
|
||||
f"- Режим позиции: {trade_mode_rus}\n"
|
||||
f"- Тип маржи: {margin_type_rus}\n"
|
||||
f"- Размер кредитного плеча: {leverage_str}\n"
|
||||
f"- Тип ордера: {order_type_rus}\n"
|
||||
f"- Количество ордера: {quantity} {sym}\n"
|
||||
f"- Коэффициент мартингейла: {martingale:.2f}\n"
|
||||
f"{conditional_order_type_text}"
|
||||
f"{trigger_price_text}"
|
||||
f"{limit_price_text}"
|
||||
f"- Максимальное кол-во ставок в серии: {max_bets}\n\n"
|
||||
f"- Стоимость: {durability_buy:.2f}/{durability_sell:.2f} USDT\n"
|
||||
f"- Рекомендуемый бюджет: {total_budget:.4f} USDT\n"
|
||||
)
|
||||
|
||||
keyboard = kbi.get_additional_settings_keyboard(
|
||||
current_order_type=order_type, conditional_order=conditional_order_type
|
||||
)
|
||||
await callback_query.message.edit_text(text=text, reply_markup=keyboard)
|
||||
logger.debug(
|
||||
"Command additional_settings processed successfully for user: %s", tg_id
|
||||
)
|
||||
except Exception as e:
|
||||
await callback_query.message.edit_text(
|
||||
text="Произошла ошибка. Пожалуйста, попробуйте ещё раз.",
|
||||
reply_markup=kbi.profile_bybit,
|
||||
)
|
||||
logger.error(
|
||||
"Error processing command additional_settings for user %s: %s",
|
||||
callback_query.from_user.id,
|
||||
e,
|
||||
)
|
||||
|
||||
|
||||
@router_settings.callback_query(F.data == "risk_management")
|
||||
async def risk_management(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
Handler for the "risk_management" command.
|
||||
Sends a message with risk management options.
|
||||
"""
|
||||
try:
|
||||
await state.clear()
|
||||
risk_management_data = await rq.get_user_risk_management(
|
||||
tg_id=callback_query.from_user.id
|
||||
)
|
||||
if risk_management_data:
|
||||
take_profit_percent = risk_management_data.take_profit_percent or ""
|
||||
stop_loss_percent = risk_management_data.stop_loss_percent or ""
|
||||
max_risk_percent = risk_management_data.max_risk_percent or ""
|
||||
commission_fee = risk_management_data.commission_fee or ""
|
||||
commission_fee_rus = (
|
||||
"Да" if commission_fee == "Yes_commission_fee" else "Нет"
|
||||
)
|
||||
|
||||
await callback_query.message.edit_text(
|
||||
text=f"Риск-менеджмент:\n\n"
|
||||
f"- Процент изменения цены для фиксации прибыли: {take_profit_percent}%\n"
|
||||
f"- Процент изменения цены для фиксации убытка: {stop_loss_percent}%\n\n"
|
||||
f"- Максимальный риск на сделку (в % от баланса): {max_risk_percent}%\n\n"
|
||||
f"- Комиссия биржи для расчета прибыли: {commission_fee_rus}\n\n",
|
||||
reply_markup=kbi.risk_management,
|
||||
)
|
||||
logger.debug(
|
||||
"Command main_settings processed successfully for user: %s",
|
||||
callback_query.from_user.id,
|
||||
)
|
||||
else:
|
||||
await rq.create_user(
|
||||
tg_id=callback_query.from_user.id,
|
||||
username=callback_query.from_user.username,
|
||||
)
|
||||
await rq.create_user_additional_settings(tg_id=callback_query.from_user.id)
|
||||
await rq.create_user_risk_management(tg_id=callback_query.from_user.id)
|
||||
await rq.create_user_conditional_settings(tg_id=callback_query.from_user.id)
|
||||
await risk_management(callback_query=callback_query, state=state)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error processing command main_settings for user %s: %s",
|
||||
callback_query.from_user.id,
|
||||
e,
|
||||
)
|
||||
|
||||
|
||||
@router_settings.callback_query(F.data == "conditional_settings")
|
||||
async def conditions(callback_query: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
Handler for the "conditions" command.
|
||||
Sends a message with trading conditions options.
|
||||
"""
|
||||
try:
|
||||
await state.clear()
|
||||
conditional_settings_data = await rq.get_user_conditional_settings(
|
||||
tg_id=callback_query.from_user.id
|
||||
)
|
||||
if conditional_settings_data:
|
||||
start_timer = conditional_settings_data.timer_start or 0
|
||||
stop_timer = conditional_settings_data.timer_end or 0
|
||||
await callback_query.message.edit_text(
|
||||
text="Условия торговли:\n\n"
|
||||
f"- Таймер для старта: {start_timer} мин.\n"
|
||||
f"- Таймер для остановки: {stop_timer} мин.\n",
|
||||
reply_markup=kbi.conditions,
|
||||
)
|
||||
logger.debug(
|
||||
"Command main_settings processed successfully for user: %s",
|
||||
callback_query.from_user.id,
|
||||
)
|
||||
else:
|
||||
await rq.create_user(
|
||||
tg_id=callback_query.from_user.id,
|
||||
username=callback_query.from_user.username,
|
||||
)
|
||||
await rq.create_user_additional_settings(tg_id=callback_query.from_user.id)
|
||||
await rq.create_user_risk_management(tg_id=callback_query.from_user.id)
|
||||
await rq.create_user_conditional_settings(tg_id=callback_query.from_user.id)
|
||||
await conditions(callback_query=callback_query, state=state)
|
||||
except Exception as e:
|
||||
logger.error(
|
||||
"Error processing command main_settings for user %s: %s",
|
||||
callback_query.from_user.id,
|
||||
e,
|
||||
)
|
Reference in New Issue
Block a user