forked from kodorvan/stcs
Added documentation, added websocket and tasks
This commit is contained in:
@@ -1,12 +1,9 @@
|
|||||||
import asyncio
|
import asyncio
|
||||||
import nest_asyncio
|
|
||||||
|
|
||||||
import time
|
import time
|
||||||
|
import json
|
||||||
import logging.config
|
import logging.config
|
||||||
from pybit import exceptions
|
from pybit import exceptions
|
||||||
from pybit.unified_trading import HTTP, WebSocket
|
from pybit.unified_trading import HTTP
|
||||||
from websocket import WebSocketConnectionClosedException
|
|
||||||
|
|
||||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||||
import app.services.Bybit.functions.price_symbol as price_symbol
|
import app.services.Bybit.functions.price_symbol as price_symbol
|
||||||
import app.services.Bybit.functions.balance as balance_g
|
import app.services.Bybit.functions.balance as balance_g
|
||||||
@@ -16,8 +13,6 @@ import app.telegram.Keyboards.inline_keyboards as inline_markup
|
|||||||
logging.config.dictConfig(LOGGING_CONFIG)
|
logging.config.dictConfig(LOGGING_CONFIG)
|
||||||
logger = logging.getLogger("futures")
|
logger = logging.getLogger("futures")
|
||||||
|
|
||||||
nest_asyncio.apply()
|
|
||||||
|
|
||||||
|
|
||||||
def safe_float(val) -> float:
|
def safe_float(val) -> float:
|
||||||
"""
|
"""
|
||||||
@@ -33,6 +28,53 @@ def safe_float(val) -> float:
|
|||||||
return 0.0
|
return 0.0
|
||||||
|
|
||||||
|
|
||||||
|
def format_trade_details_position(data):
|
||||||
|
"""
|
||||||
|
Форматирует информацию о сделке в виде строки.
|
||||||
|
"""
|
||||||
|
msg = data.get('data', [{}])[0]
|
||||||
|
|
||||||
|
closed_size = float(msg.get('closedSize', 0))
|
||||||
|
symbol = msg.get('symbol', 'N/A')
|
||||||
|
entry_price = float(msg.get('execPrice', 0))
|
||||||
|
qty = float(msg.get('execQty', 0))
|
||||||
|
order_type = msg.get('orderType', 'N/A')
|
||||||
|
side = msg.get('side', '')
|
||||||
|
commission_fee = float(msg.get('execFee', 0))
|
||||||
|
pnl = float(msg.get('execPnl', 0))
|
||||||
|
|
||||||
|
movement = ''
|
||||||
|
if side.lower() == 'buy':
|
||||||
|
movement = 'Покупка'
|
||||||
|
elif side.lower() == 'sell':
|
||||||
|
movement = 'Продажа'
|
||||||
|
else:
|
||||||
|
movement = side
|
||||||
|
|
||||||
|
if closed_size > 0:
|
||||||
|
return (
|
||||||
|
f"Сделка закрыта:\n"
|
||||||
|
f"Торговая пара: {symbol}\n"
|
||||||
|
f"Цена исполнения: {entry_price:.6f}\n"
|
||||||
|
f"Количество: {qty}\n"
|
||||||
|
f"Закрыто позиций: {closed_size}\n"
|
||||||
|
f"Тип ордера: {order_type}\n"
|
||||||
|
f"Движение: {movement}\n"
|
||||||
|
f"Комиссия за сделку: {commission_fee:.6f}\n"
|
||||||
|
f"Реализованная прибыль: {pnl:.6f} USDT"
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
return (
|
||||||
|
f"Сделка открыта:\n"
|
||||||
|
f"Торговая пара: {symbol}\n"
|
||||||
|
f"Цена исполнения: {entry_price:.6f}\n"
|
||||||
|
f"Количество: {qty}\n"
|
||||||
|
f"Тип ордера: {order_type}\n"
|
||||||
|
f"Движение: {movement}\n"
|
||||||
|
f"Комиссия за сделку: {commission_fee:.6f}"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
def parse_pnl_from_msg(msg) -> float:
|
def parse_pnl_from_msg(msg) -> float:
|
||||||
"""
|
"""
|
||||||
Извлекает реализованную прибыль/убыток из сообщения.
|
Извлекает реализованную прибыль/убыток из сообщения.
|
||||||
@@ -49,8 +91,6 @@ async def handle_execution_message(message, msg: dict) -> None:
|
|||||||
Обработчик сообщений об исполнении сделки.
|
Обработчик сообщений об исполнении сделки.
|
||||||
Логирует событие и проверяет условия для мартингейла и TP.
|
Логирует событие и проверяет условия для мартингейла и TP.
|
||||||
"""
|
"""
|
||||||
logger.info(f"Исполнена сделка: {msg}")
|
|
||||||
await message.answer(f"Исполнена сделка: {msg}")
|
|
||||||
|
|
||||||
pnl = parse_pnl_from_msg(msg)
|
pnl = parse_pnl_from_msg(msg)
|
||||||
tg_id = message.from_user.id
|
tg_id = message.from_user.id
|
||||||
@@ -66,6 +106,9 @@ async def handle_execution_message(message, msg: dict) -> None:
|
|||||||
positions_list = positions_resp.get('result', {}).get('list', [])
|
positions_list = positions_resp.get('result', {}).get('list', [])
|
||||||
position = positions_list[0] if positions_list else None
|
position = positions_list[0] if positions_list else None
|
||||||
|
|
||||||
|
trade_info = format_trade_details_position(msg)
|
||||||
|
await message.answer(f"{trade_info}", reply_markup=inline_markup.back_to_main)
|
||||||
|
|
||||||
liquidation_threshold = -100
|
liquidation_threshold = -100
|
||||||
|
|
||||||
if pnl <= liquidation_threshold:
|
if pnl <= liquidation_threshold:
|
||||||
@@ -94,64 +137,6 @@ async def handle_execution_message(message, msg: dict) -> None:
|
|||||||
await rq.update_martingale_step(tg_id, 0)
|
await rq.update_martingale_step(tg_id, 0)
|
||||||
|
|
||||||
|
|
||||||
async def start_execution_ws(tg_id, message) -> None:
|
|
||||||
"""
|
|
||||||
Запускает WebSocket для отслеживания исполнения сделок в режиме реального времени.
|
|
||||||
Переподключается при ошибках.
|
|
||||||
"""
|
|
||||||
api_key = await rq.get_bybit_api_key(tg_id)
|
|
||||||
api_secret = await rq.get_bybit_secret_key(tg_id)
|
|
||||||
|
|
||||||
reconnect_delay = 5
|
|
||||||
|
|
||||||
while True:
|
|
||||||
try:
|
|
||||||
ws = WebSocket(api_key=api_key,
|
|
||||||
api_secret=api_secret,
|
|
||||||
testnet=False,
|
|
||||||
channel_type="private")
|
|
||||||
|
|
||||||
async def on_execution(msg):
|
|
||||||
await handle_execution_message(message, msg)
|
|
||||||
|
|
||||||
def on_execution_sync(msg):
|
|
||||||
asyncio.create_task(on_execution(msg))
|
|
||||||
|
|
||||||
ws.execution_stream(on_execution_sync)
|
|
||||||
|
|
||||||
while True:
|
|
||||||
await asyncio.sleep(1)
|
|
||||||
|
|
||||||
except WebSocketConnectionClosedException:
|
|
||||||
logging.warning("WebSocket закрыт, переподключение через 5 секунд...")
|
|
||||||
await asyncio.sleep(reconnect_delay)
|
|
||||||
|
|
||||||
except Exception as e:
|
|
||||||
logging.error(f"Ошибка WebSocket: {e}")
|
|
||||||
await asyncio.sleep(reconnect_delay)
|
|
||||||
|
|
||||||
|
|
||||||
async def info_access_open_deal(message, symbol, trade_mode, margin_mode, leverage, qty, tp, sl, entry_price,
|
|
||||||
limit_price, order_type) -> None:
|
|
||||||
"""
|
|
||||||
Отправляет сообщение об успешном открытии позиции или выставлении лимитного ордера.
|
|
||||||
"""
|
|
||||||
human_margin_mode = 'Isolated' if margin_mode == 'ISOLATED_MARGIN' else 'Cross'
|
|
||||||
text = (
|
|
||||||
f"{'Позиция была успешна открыта' if order_type == 'Market' else 'Лимитный ордер установлен'}!\n"
|
|
||||||
f"Торговая пара: {symbol}\n"
|
|
||||||
f"Цена входа: {entry_price if order_type == 'Market' else round(limit_price, 5)}\n"
|
|
||||||
f"Движение: {trade_mode}\n"
|
|
||||||
f"Тип-маржи: {human_margin_mode}\n"
|
|
||||||
f"Кредитное плечо: {leverage}x\n"
|
|
||||||
f"Количество: {qty}\n"
|
|
||||||
f"Тейк-профит: {round(tp, 5)}\n"
|
|
||||||
f"Стоп-лосс: {round(sl, 5)}\n"
|
|
||||||
)
|
|
||||||
|
|
||||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.create_close_deal_markup(symbol))
|
|
||||||
|
|
||||||
|
|
||||||
async def error_max_step(message) -> None:
|
async def error_max_step(message) -> None:
|
||||||
"""
|
"""
|
||||||
Сообщение об ошибке превышения максимального количества шагов мартингейла.
|
Сообщение об ошибке превышения максимального количества шагов мартингейла.
|
||||||
@@ -340,10 +325,6 @@ async def open_position(tg_id, message, side: str, margin_mode: str, tpsl_mode='
|
|||||||
)
|
)
|
||||||
|
|
||||||
if response.get('retCode', -1) == 0:
|
if response.get('retCode', -1) == 0:
|
||||||
await info_access_open_deal(message, symbol, data_main_stgs.get('trading_mode', ''),
|
|
||||||
bybit_margin_mode,
|
|
||||||
data_main_stgs.get('size_leverage', 1), next_quantity, take_profit_price,
|
|
||||||
stop_loss_price, entry_price, limit_price, order_type=order_type)
|
|
||||||
await rq.update_martingale_step(tg_id, current_martingale_step)
|
await rq.update_martingale_step(tg_id, current_martingale_step)
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
@@ -417,7 +398,7 @@ async def set_take_profit_stop_loss(tg_id: int, message, take_profit_price: floa
|
|||||||
return
|
return
|
||||||
|
|
||||||
client = HTTP(api_key=api_key, api_secret=secret_key)
|
client = HTTP(api_key=api_key, api_secret=secret_key)
|
||||||
await cancel_all_tp_sl_orders(client, symbol)
|
await cancel_all_tp_sl_orders(tg_id, symbol)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
try:
|
try:
|
||||||
@@ -648,15 +629,6 @@ async def close_user_trade(tg_id: int, symbol: str, message):
|
|||||||
if include_fee:
|
if include_fee:
|
||||||
pnl -= trade_fee
|
pnl -= trade_fee
|
||||||
pnl_percent = (pnl / (entry_price * qty)) * 100 if entry_price * qty > 0 else 0
|
pnl_percent = (pnl / (entry_price * qty)) * 100 if entry_price * qty > 0 else 0
|
||||||
|
|
||||||
text = (
|
|
||||||
f"Сделка {symbol} успешно закрыта.\n"
|
|
||||||
f"Цена входа: {entry_price if entry_price else limit_price}\n"
|
|
||||||
f"Цена закрытия: {current_price}\n"
|
|
||||||
f"Прибыль: {pnl:.4f} USDT ({pnl_percent:.2f}%)\n"
|
|
||||||
f"{'Включая комиссию биржи' if include_fee else 'Без учета комиссии'}"
|
|
||||||
)
|
|
||||||
await message.answer(text)
|
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
if message:
|
if message:
|
||||||
|
@@ -1,14 +1,12 @@
|
|||||||
import asyncio
|
import logging.config
|
||||||
import logging.config
|
|
||||||
from aiogram import F, Router
|
from aiogram import F, Router
|
||||||
|
|
||||||
from app.tasks.tasks import active_close_tasks, active_start_tasks
|
from app.tasks.tasks import handle_stop_close_trade, handle_start_close_trade, handle_stop_trading, handle_start_trading
|
||||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||||
|
|
||||||
from app.services.Bybit.functions.Futures import (close_user_trade, close_trade_after_delay,
|
from app.services.Bybit.functions.Futures import (close_user_trade, open_position, set_take_profit_stop_loss, \
|
||||||
trading_cycle, open_position, set_take_profit_stop_loss, \
|
|
||||||
get_active_positions_by_symbol, get_active_orders_by_symbol,
|
get_active_positions_by_symbol, get_active_orders_by_symbol,
|
||||||
start_execution_ws)
|
)
|
||||||
from app.services.Bybit.functions.balance import get_balance
|
from app.services.Bybit.functions.balance import get_balance
|
||||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||||
|
|
||||||
@@ -35,15 +33,16 @@ async def clb_start_bybit_trade_message(callback: CallbackQuery) -> None:
|
|||||||
Обработка нажатия кнопок запуска торговли или возврата в главное меню.
|
Обработка нажатия кнопок запуска торговли или возврата в главное меню.
|
||||||
Отправляет информацию о балансе, символе, цене и инструкциях по торговле.
|
Отправляет информацию о балансе, символе, цене и инструкциях по торговле.
|
||||||
"""
|
"""
|
||||||
balance = await get_balance(callback.from_user.id, callback.message)
|
user_id = callback.from_user.id
|
||||||
price = await get_price(callback.from_user.id)
|
balance = await get_balance(user_id, callback.message)
|
||||||
|
price = await get_price(user_id)
|
||||||
|
|
||||||
if balance:
|
if balance:
|
||||||
symbol = await rq.get_symbol(callback.from_user.id)
|
symbol = await rq.get_symbol(user_id)
|
||||||
|
|
||||||
text = (
|
text = (
|
||||||
f"💎 Торговля на Bybit\n\n"
|
f"💎 Торговля на Bybit\n\n"
|
||||||
f"⚖️ Ваш баланс (USDT): {balance}\n"
|
f"⚖️ Ваш баланс (USDT): {float(balance):.2f}\n"
|
||||||
f"📊 Текущая торговая пара: {symbol}\n"
|
f"📊 Текущая торговая пара: {symbol}\n"
|
||||||
f"$$$ Цена: {price}\n\n"
|
f"$$$ Цена: {price}\n\n"
|
||||||
"Как начать торговлю?\n\n"
|
"Как начать торговлю?\n\n"
|
||||||
@@ -52,7 +51,6 @@ async def clb_start_bybit_trade_message(callback: CallbackQuery) -> None:
|
|||||||
"3️⃣ Нажмите кнопку 'Выбрать тип входа' и после нажмите начать торговлю.\n"
|
"3️⃣ Нажмите кнопку 'Выбрать тип входа' и после нажмите начать торговлю.\n"
|
||||||
)
|
)
|
||||||
await callback.message.edit_text(text=text, parse_mode='html', reply_markup=inline_markup.trading_markup)
|
await callback.message.edit_text(text=text, parse_mode='html', reply_markup=inline_markup.trading_markup)
|
||||||
asyncio.create_task(start_execution_ws(callback.from_user.id, callback.message))
|
|
||||||
|
|
||||||
|
|
||||||
async def start_bybit_trade_message(message: Message) -> None:
|
async def start_bybit_trade_message(message: Message) -> None:
|
||||||
@@ -240,6 +238,7 @@ async def start_trading_process(callback: CallbackQuery) -> None:
|
|||||||
|
|
||||||
await message.answer("Начинаю торговлю с использованием текущих настроек...")
|
await message.answer("Начинаю торговлю с использованием текущих настроек...")
|
||||||
|
|
||||||
|
|
||||||
timer_data = await rq.get_user_timer(tg_id)
|
timer_data = await rq.get_user_timer(tg_id)
|
||||||
if isinstance(timer_data, dict):
|
if isinstance(timer_data, dict):
|
||||||
timer_minute = timer_data.get('timer_minutes', 0)
|
timer_minute = timer_data.get('timer_minutes', 0)
|
||||||
@@ -247,15 +246,7 @@ async def start_trading_process(callback: CallbackQuery) -> None:
|
|||||||
timer_minute = timer_data or 0
|
timer_minute = timer_data or 0
|
||||||
|
|
||||||
if timer_minute > 0:
|
if timer_minute > 0:
|
||||||
old_task = active_start_tasks.get(tg_id)
|
await handle_start_trading(tg_id, message)
|
||||||
if old_task and not old_task.done():
|
|
||||||
old_task.cancel()
|
|
||||||
try:
|
|
||||||
await old_task
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
logger.info(f"Старая задача торговли для пользователя {tg_id} отменена")
|
|
||||||
task = asyncio.create_task(trading_cycle(tg_id, message))
|
|
||||||
active_start_tasks[tg_id] = task
|
|
||||||
await message.answer(f"Торговля начнётся через {timer_minute} мин. Для отмены нажмите кнопку ниже.",
|
await message.answer(f"Торговля начнётся через {timer_minute} мин. Для отмены нажмите кнопку ниже.",
|
||||||
reply_markup=inline_markup.cancel_start_markup)
|
reply_markup=inline_markup.cancel_start_markup)
|
||||||
await rq.update_user_timer(tg_id, minutes=0)
|
await rq.update_user_timer(tg_id, minutes=0)
|
||||||
@@ -281,6 +272,9 @@ async def show_my_trades(callback: CallbackQuery) -> None:
|
|||||||
|
|
||||||
@router_functions_bybit_trade.callback_query(F.data == "clb_open_deals")
|
@router_functions_bybit_trade.callback_query(F.data == "clb_open_deals")
|
||||||
async def show_my_trades_callback(callback: CallbackQuery):
|
async def show_my_trades_callback(callback: CallbackQuery):
|
||||||
|
"""
|
||||||
|
Показывает открытые позиции пользователя по символу.
|
||||||
|
"""
|
||||||
await callback.answer()
|
await callback.answer()
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -373,13 +367,9 @@ async def cancel_start_callback(callback: CallbackQuery) -> None:
|
|||||||
Отменяет задачу старта торговли по таймеру, если она активна.
|
Отменяет задачу старта торговли по таймеру, если она активна.
|
||||||
"""
|
"""
|
||||||
tg_id = callback.from_user.id
|
tg_id = callback.from_user.id
|
||||||
task = active_start_tasks.get(tg_id)
|
await handle_stop_close_trade(tg_id)
|
||||||
if task:
|
|
||||||
task.cancel()
|
|
||||||
del active_start_tasks[tg_id]
|
|
||||||
await callback.message.answer("Торговля по таймеру отменена.", reply_markup=inline_markup.back_to_main)
|
await callback.message.answer("Торговля по таймеру отменена.", reply_markup=inline_markup.back_to_main)
|
||||||
else:
|
|
||||||
await callback.message.answer("Нет активности для отмены.", reply_markup=inline_markup.back_to_main)
|
|
||||||
await callback.answer()
|
await callback.answer()
|
||||||
|
|
||||||
|
|
||||||
@@ -394,7 +384,7 @@ async def close_trade_callback(callback: CallbackQuery) -> None:
|
|||||||
result = await close_user_trade(tg_id, symbol, message=callback.message)
|
result = await close_user_trade(tg_id, symbol, message=callback.message)
|
||||||
|
|
||||||
if result:
|
if result:
|
||||||
await callback.message.answer("Сделка успешно закрыта.", reply_markup=inline_markup.back_to_main)
|
await handle_stop_trading(tg_id)
|
||||||
logger.info(f"Сделка {symbol} успешно закрыта.")
|
logger.info(f"Сделка {symbol} успешно закрыта.")
|
||||||
else:
|
else:
|
||||||
logger.error(f"Не удалось закрыть сделку {symbol}.")
|
logger.error(f"Не удалось закрыть сделку {symbol}.")
|
||||||
@@ -436,17 +426,7 @@ async def process_close_delay(message: Message, state: FSMContext) -> None:
|
|||||||
|
|
||||||
delay = delay_minutes * 60
|
delay = delay_minutes * 60
|
||||||
|
|
||||||
if tg_id in active_close_tasks:
|
await handle_start_close_trade(tg_id, message, symbol, delay)
|
||||||
old_task = active_close_tasks[tg_id]
|
|
||||||
if not old_task.done():
|
|
||||||
old_task.cancel()
|
|
||||||
try:
|
|
||||||
await old_task
|
|
||||||
except asyncio.CancelledError:
|
|
||||||
logger.info(f"Предыдущая задача закрытия сделки пользователя {tg_id} отменена")
|
|
||||||
|
|
||||||
task = asyncio.create_task(close_trade_after_delay(tg_id, message, symbol, delay))
|
|
||||||
active_close_tasks[tg_id] = task
|
|
||||||
|
|
||||||
await message.answer(f"Закрытие сделки {symbol} запланировано через {delay} секунд.",
|
await message.answer(f"Закрытие сделки {symbol} запланировано через {delay} секунд.",
|
||||||
reply_markup=inline_markup.cancel_start_markup)
|
reply_markup=inline_markup.cancel_start_markup)
|
||||||
@@ -458,11 +438,9 @@ async def reset_martingale(callback: CallbackQuery) -> None:
|
|||||||
"""
|
"""
|
||||||
Сбрасывает шаги мартингейла пользователя.
|
Сбрасывает шаги мартингейла пользователя.
|
||||||
"""
|
"""
|
||||||
await callback.answer()
|
|
||||||
tg_id = callback.from_user.id
|
tg_id = callback.from_user.id
|
||||||
await rq.update_martingale_step(tg_id, 0)
|
await rq.update_martingale_step(tg_id, 0)
|
||||||
await callback.message.answer("Сброс шагов выполнен.",
|
await callback.answer("Сброс шагов выполнен.")
|
||||||
reply_markup=inline_markup.back_to_main)
|
|
||||||
|
|
||||||
|
|
||||||
@router_functions_bybit_trade.callback_query(F.data == "clb_cancel")
|
@router_functions_bybit_trade.callback_query(F.data == "clb_cancel")
|
||||||
|
@@ -3,29 +3,37 @@ from logger_helper.logger_helper import LOGGING_CONFIG
|
|||||||
from datetime import datetime, timedelta
|
from datetime import datetime, timedelta
|
||||||
from typing import Any
|
from typing import Any
|
||||||
|
|
||||||
|
from app.telegram.database.models import (
|
||||||
|
async_session,
|
||||||
|
User_Telegram_Id as UTi,
|
||||||
|
User_Main_Settings as UMS,
|
||||||
|
User_Bybit_API as UBA,
|
||||||
|
User_Symbol,
|
||||||
|
User_Risk_Management_Settings as URMS,
|
||||||
|
User_Condition_Settings as UCS,
|
||||||
|
User_Additional_Settings as UAS,
|
||||||
|
Trading_Mode,
|
||||||
|
Margin_type,
|
||||||
|
Trigger,
|
||||||
|
USER_DEALS,
|
||||||
|
UserTimer,
|
||||||
|
)
|
||||||
|
|
||||||
|
from sqlalchemy import select, update
|
||||||
|
|
||||||
logging.config.dictConfig(LOGGING_CONFIG)
|
logging.config.dictConfig(LOGGING_CONFIG)
|
||||||
logger = logging.getLogger("requests")
|
logger = logging.getLogger("requests")
|
||||||
|
|
||||||
from app.telegram.database.models import async_session
|
|
||||||
from app.telegram.database.models import User_Telegram_Id as UTi
|
|
||||||
from app.telegram.database.models import User_Main_Settings as UMS
|
|
||||||
from app.telegram.database.models import User_Bybit_API as UBA
|
|
||||||
from app.telegram.database.models import User_Symbol
|
|
||||||
from app.telegram.database.models import User_Risk_Management_Settings as URMS
|
|
||||||
from app.telegram.database.models import User_Condition_Settings as UCS
|
|
||||||
from app.telegram.database.models import User_Additional_Settings as UAS
|
|
||||||
from app.telegram.database.models import Trading_Mode
|
|
||||||
from app.telegram.database.models import Margin_type
|
|
||||||
from app.telegram.database.models import Trigger
|
|
||||||
from app.telegram.database.models import USER_DEALS, UserTimer
|
|
||||||
|
|
||||||
import app.telegram.functions.functions as func # functions
|
# --- Функции сохранения в БД ---
|
||||||
|
|
||||||
from sqlalchemy import select, delete, update
|
async def save_tg_id_new_user(tg_id) -> None:
|
||||||
|
"""
|
||||||
|
Сохраняет Telegram ID нового пользователя в базу, если такого ещё нет.
|
||||||
|
|
||||||
|
Args:
|
||||||
# SET_DB
|
tg_id (int): Telegram ID пользователя.
|
||||||
async def save_tg_id_new_user(tg_id):
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(UTi).where(UTi.tg_id == tg_id))
|
user = await session.scalar(select(UTi).where(UTi.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -37,26 +45,33 @@ async def save_tg_id_new_user(tg_id):
|
|||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
async def set_new_user_bybit_api(tg_id):
|
async def set_new_user_bybit_api(tg_id) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт запись API пользователя Bybit, если её ещё нет.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(UBA).where(UBA.tg_id == tg_id))
|
user = await session.scalar(select(UBA).where(UBA.tg_id == tg_id))
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
session.add(UBA(
|
session.add(UBA(tg_id=tg_id))
|
||||||
tg_id=tg_id,
|
|
||||||
))
|
|
||||||
|
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
async def set_new_user_symbol(tg_id):
|
async def set_new_user_symbol(tg_id) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт запись торгового символа пользователя, если её нет.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(User_Symbol).where(User_Symbol.tg_id == tg_id))
|
user = await session.scalar(select(User_Symbol).where(User_Symbol.tg_id == tg_id))
|
||||||
|
|
||||||
if not user:
|
if not user:
|
||||||
session.add(User_Symbol(
|
session.add(User_Symbol(tg_id=tg_id))
|
||||||
tg_id=tg_id
|
|
||||||
))
|
|
||||||
|
|
||||||
logger.info(f"Symbol был успешно добавлен %s", tg_id)
|
logger.info(f"Symbol был успешно добавлен %s", tg_id)
|
||||||
|
|
||||||
@@ -64,6 +79,14 @@ async def set_new_user_symbol(tg_id):
|
|||||||
|
|
||||||
|
|
||||||
async def set_new_user_default_main_settings(tg_id, trading_mode, margin_type) -> None:
|
async def set_new_user_default_main_settings(tg_id, trading_mode, margin_type) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт основные настройки пользователя по умолчанию.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
trading_mode (str): Режим торговли.
|
||||||
|
margin_type (str): Тип маржи.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
settings = await session.scalar(select(UMS).where(UMS.tg_id == tg_id))
|
settings = await session.scalar(select(UMS).where(UMS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -80,6 +103,12 @@ async def set_new_user_default_main_settings(tg_id, trading_mode, margin_type) -
|
|||||||
|
|
||||||
|
|
||||||
async def set_new_user_default_risk_management_settings(tg_id) -> None:
|
async def set_new_user_default_risk_management_settings(tg_id) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт настройки риск-менеджмента по умолчанию.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
settings = await session.scalar(select(URMS).where(URMS.tg_id == tg_id))
|
settings = await session.scalar(select(URMS).where(URMS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -94,6 +123,13 @@ async def set_new_user_default_risk_management_settings(tg_id) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def set_new_user_default_condition_settings(tg_id, trigger) -> None:
|
async def set_new_user_default_condition_settings(tg_id, trigger) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт условные настройки по умолчанию.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
trigger (Any): Значение триггера по умолчанию.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
settings = await session.scalar(select(UCS).where(UCS.tg_id == tg_id))
|
settings = await session.scalar(select(UCS).where(UCS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -109,6 +145,12 @@ async def set_new_user_default_condition_settings(tg_id, trigger) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def set_new_user_default_additional_settings(tg_id) -> None:
|
async def set_new_user_default_additional_settings(tg_id) -> None:
|
||||||
|
"""
|
||||||
|
Создаёт дополнительные настройки по умолчанию.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
settings = await session.scalar(select(UAS).where(UAS.tg_id == tg_id))
|
settings = await session.scalar(select(UAS).where(UAS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -122,32 +164,46 @@ async def set_new_user_default_additional_settings(tg_id) -> None:
|
|||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
# GET_DB
|
# --- Функции получения данных из БД ---
|
||||||
|
|
||||||
async def check_user(tg_id):
|
async def check_user(tg_id):
|
||||||
|
"""
|
||||||
|
Проверяет наличие пользователя в базе.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
tg_id (int): Telegram ID пользователя.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
Optional[UTi]: Пользователь или None.
|
||||||
|
"""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(UTi).where(UTi.tg_id == tg_id))
|
user = await session.scalar(select(UTi).where(UTi.tg_id == tg_id))
|
||||||
return user
|
return user
|
||||||
|
|
||||||
|
|
||||||
async def get_bybit_api_key(tg_id):
|
async def get_bybit_api_key(tg_id):
|
||||||
|
"""Получить API ключ Bybit пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
api_key = await session.scalar(select(UBA.api_key).where(UBA.tg_id == tg_id))
|
api_key = await session.scalar(select(UBA.api_key).where(UBA.tg_id == tg_id))
|
||||||
return api_key
|
return api_key
|
||||||
|
|
||||||
|
|
||||||
async def get_bybit_secret_key(tg_id):
|
async def get_bybit_secret_key(tg_id):
|
||||||
|
"""Получить секретный ключ Bybit пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
secret_key = await session.scalar(select(UBA.secret_key).where(UBA.tg_id == tg_id))
|
secret_key = await session.scalar(select(UBA.secret_key).where(UBA.tg_id == tg_id))
|
||||||
return secret_key
|
return secret_key
|
||||||
|
|
||||||
|
|
||||||
async def get_symbol(tg_id):
|
async def get_symbol(tg_id):
|
||||||
|
"""Получить символ пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
symbol = await session.scalar(select(User_Symbol.symbol).where(User_Symbol.tg_id == tg_id))
|
symbol = await session.scalar(select(User_Symbol.symbol).where(User_Symbol.tg_id == tg_id))
|
||||||
return symbol
|
return symbol
|
||||||
|
|
||||||
|
|
||||||
async def get_user_trades(tg_id):
|
async def get_user_trades(tg_id):
|
||||||
|
"""Получить сделки пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
query = select(USER_DEALS.symbol, USER_DEALS.side).where(USER_DEALS.tg_id == tg_id)
|
query = select(USER_DEALS.symbol, USER_DEALS.side).where(USER_DEALS.tg_id == tg_id)
|
||||||
result = await session.execute(query)
|
result = await session.execute(query)
|
||||||
@@ -155,14 +211,63 @@ async def get_user_trades(tg_id):
|
|||||||
return trades
|
return trades
|
||||||
|
|
||||||
|
|
||||||
|
async def get_entry_order_type(tg_id: object) -> str | None | Any:
|
||||||
|
"""Получить тип входного ордера пользователя."""
|
||||||
|
async with async_session() as session:
|
||||||
|
order_type = await session.scalar(
|
||||||
|
select(UMS.entry_order_type).where(UMS.tg_id == tg_id)
|
||||||
|
)
|
||||||
|
# Если в базе не установлен тип — возвращаем значение по умолчанию
|
||||||
|
return order_type or 'Market'
|
||||||
|
|
||||||
|
|
||||||
|
# --- Функции обновления данных ---
|
||||||
|
|
||||||
async def update_user_trades(tg_id, **kwargs):
|
async def update_user_trades(tg_id, **kwargs):
|
||||||
|
"""Обновить сделки пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
query = update(USER_DEALS).where(USER_DEALS.tg_id == tg_id).values(**kwargs)
|
query = update(USER_DEALS).where(USER_DEALS.tg_id == tg_id).values(**kwargs)
|
||||||
await session.execute(query)
|
await session.execute(query)
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def update_symbol(tg_id: int, symbol: str) -> None:
|
||||||
|
"""Обновить торговый символ пользователя."""
|
||||||
|
async with async_session() as session:
|
||||||
|
await session.execute(update(User_Symbol).where(User_Symbol.tg_id == tg_id).values(symbol=symbol))
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def update_api_key(tg_id: int, api: str) -> None:
|
||||||
|
"""Обновить API ключ пользователя."""
|
||||||
|
async with async_session() as session:
|
||||||
|
await session.execute(update(UBA).where(UBA.tg_id == tg_id).values(api_key=api))
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
async def update_secret_key(tg_id: int, api: str) -> None:
|
||||||
|
"""Обновить секретный ключ пользователя."""
|
||||||
|
async with async_session() as session:
|
||||||
|
await session.execute(update(UBA).where(UBA.tg_id == tg_id).values(secret_key=api))
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
|
# --- Более мелкие обновления и запросы по настройкам ---
|
||||||
|
|
||||||
|
async def update_trade_mode_user(tg_id, trading_mode) -> None:
|
||||||
|
"""Обновить режим торговли пользователя."""
|
||||||
|
async with async_session() as session:
|
||||||
|
mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.mode == trading_mode))
|
||||||
|
|
||||||
|
if mode:
|
||||||
|
logger.info("Изменён торговый режим для пользователя %s", tg_id)
|
||||||
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(trading_mode=mode))
|
||||||
|
|
||||||
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
async def delete_user_trade(tg_id: int, symbol: str):
|
async def delete_user_trade(tg_id: int, symbol: str):
|
||||||
|
"""Удалить сделку пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(
|
await session.execute(
|
||||||
USER_DEALS.__table__.delete().where(
|
USER_DEALS.__table__.delete().where(
|
||||||
@@ -173,24 +278,28 @@ async def delete_user_trade(tg_id: int, symbol: str):
|
|||||||
|
|
||||||
|
|
||||||
async def get_for_registration_trading_mode():
|
async def get_for_registration_trading_mode():
|
||||||
|
"""Получить режим торговли по умолчанию."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.id == 1))
|
mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.id == 1))
|
||||||
return mode
|
return mode
|
||||||
|
|
||||||
|
|
||||||
async def get_for_registration_margin_type():
|
async def get_for_registration_margin_type():
|
||||||
|
"""Получить тип маржи по умолчанию."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
type = await session.scalar(select(Margin_type.type).where(Margin_type.id == 1))
|
type = await session.scalar(select(Margin_type.type).where(Margin_type.id == 1))
|
||||||
return type
|
return type
|
||||||
|
|
||||||
|
|
||||||
async def get_for_registration_trigger():
|
async def get_for_registration_trigger():
|
||||||
|
"""Получить триггер по умолчанию."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
trigger = await session.scalar(select(Trigger.trigger).where(Trigger.id == 1))
|
trigger = await session.scalar(select(Trigger.trigger).where(Trigger.id == 1))
|
||||||
return trigger
|
return trigger
|
||||||
|
|
||||||
|
|
||||||
async def get_user_main_settings(tg_id):
|
async def get_user_main_settings(tg_id):
|
||||||
|
"""Получить основные настройки пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(UMS).where(UMS.tg_id == tg_id))
|
user = await session.scalar(select(UMS).where(UMS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -223,6 +332,7 @@ async def get_user_main_settings(tg_id):
|
|||||||
|
|
||||||
|
|
||||||
async def get_user_risk_management_settings(tg_id):
|
async def get_user_risk_management_settings(tg_id):
|
||||||
|
"""Получить риск-менеджмента настройки пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
user = await session.scalar(select(URMS).where(URMS.tg_id == tg_id))
|
user = await session.scalar(select(URMS).where(URMS.tg_id == tg_id))
|
||||||
|
|
||||||
@@ -244,41 +354,8 @@ async def get_user_risk_management_settings(tg_id):
|
|||||||
return data
|
return data
|
||||||
|
|
||||||
|
|
||||||
# UPDATE_SYMBOL
|
|
||||||
async def update_symbol(tg_id, symbol) -> None:
|
|
||||||
async with async_session() as session:
|
|
||||||
await session.execute(update(User_Symbol).where(User_Symbol.tg_id == tg_id).values(symbol=symbol))
|
|
||||||
|
|
||||||
await session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
async def update_api_key(tg_id, api):
|
|
||||||
async with async_session() as session:
|
|
||||||
api_key = await session.execute(update(UBA).where(UBA.tg_id == tg_id).values(api_key=api))
|
|
||||||
|
|
||||||
await session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
async def update_secret_key(tg_id, api):
|
|
||||||
async with async_session() as session:
|
|
||||||
secret_key = await session.execute(update(UBA).where(UBA.tg_id == tg_id).values(secret_key=api))
|
|
||||||
|
|
||||||
await session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
# UPDATE_MAIN_SETTINGS_DB
|
|
||||||
async def update_trade_mode_user(tg_id, trading_mode) -> None:
|
|
||||||
async with async_session() as session:
|
|
||||||
mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.mode == trading_mode))
|
|
||||||
|
|
||||||
if mode:
|
|
||||||
logger.info("Изменен трейд мод %s", tg_id)
|
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(trading_mode=mode))
|
|
||||||
|
|
||||||
await session.commit()
|
|
||||||
|
|
||||||
|
|
||||||
async def update_margin_type(tg_id, margin_type) -> None:
|
async def update_margin_type(tg_id, margin_type) -> None:
|
||||||
|
"""Обновить тип маржи пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
type = await session.scalar(select(Margin_type.type).where(Margin_type.type == margin_type))
|
type = await session.scalar(select(Margin_type.type).where(Margin_type.type == margin_type))
|
||||||
|
|
||||||
@@ -290,6 +367,7 @@ async def update_margin_type(tg_id, margin_type) -> None:
|
|||||||
|
|
||||||
|
|
||||||
async def update_size_leverange(tg_id, num):
|
async def update_size_leverange(tg_id, num):
|
||||||
|
"""Обновить размер левеража пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(size_leverage=num))
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(size_leverage=num))
|
||||||
|
|
||||||
@@ -297,6 +375,7 @@ async def update_size_leverange(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_starting_quantity(tg_id, num):
|
async def update_starting_quantity(tg_id, num):
|
||||||
|
"""Обновить размер левеража пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(starting_quantity=num))
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(starting_quantity=num))
|
||||||
|
|
||||||
@@ -304,6 +383,7 @@ async def update_starting_quantity(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_martingale_factor(tg_id, num):
|
async def update_martingale_factor(tg_id, num):
|
||||||
|
"""Обновить размер левеража пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(martingale_factor=num))
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(martingale_factor=num))
|
||||||
|
|
||||||
@@ -311,15 +391,17 @@ async def update_martingale_factor(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_maximal_quantity(tg_id, num):
|
async def update_maximal_quantity(tg_id, num):
|
||||||
|
"""Обновить размер левеража пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(maximal_quantity=num))
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(maximal_quantity=num))
|
||||||
|
|
||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
# UPDATE_RISK_MANAGEMENT_SETTINGS_DB
|
# ОБНОВЛЕНИЕ НАСТРОЕК РИСК-МЕНЕДЖМЕНТА
|
||||||
|
|
||||||
async def update_price_profit(tg_id, num):
|
async def update_price_profit(tg_id, num):
|
||||||
|
"""Обновить цену тейк-профита (прибыль) пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_profit=num))
|
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_profit=num))
|
||||||
|
|
||||||
@@ -327,6 +409,7 @@ async def update_price_profit(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_price_loss(tg_id, num):
|
async def update_price_loss(tg_id, num):
|
||||||
|
"""Обновить цену тейк-лосса (убыток) пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_loss=num))
|
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_loss=num))
|
||||||
|
|
||||||
@@ -334,6 +417,7 @@ async def update_price_loss(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_max_risk_deal(tg_id, num):
|
async def update_max_risk_deal(tg_id, num):
|
||||||
|
"""Обновить максимальную сумму риска пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(max_risk_deal=num))
|
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(max_risk_deal=num))
|
||||||
|
|
||||||
@@ -341,6 +425,7 @@ async def update_max_risk_deal(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def update_entry_order_type(tg_id, order_type):
|
async def update_entry_order_type(tg_id, order_type):
|
||||||
|
"""Обновить тип входного ордера пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(
|
await session.execute(
|
||||||
update(UMS)
|
update(UMS)
|
||||||
@@ -350,16 +435,8 @@ async def update_entry_order_type(tg_id, order_type):
|
|||||||
await session.commit()
|
await session.commit()
|
||||||
|
|
||||||
|
|
||||||
async def get_entry_order_type(tg_id: object) -> str | None | Any:
|
|
||||||
async with async_session() as session:
|
|
||||||
order_type = await session.scalar(
|
|
||||||
select(UMS.entry_order_type).where(UMS.tg_id == tg_id)
|
|
||||||
)
|
|
||||||
# Если в базе не установлен тип — возвращаем значение по умолчанию
|
|
||||||
return order_type or 'Market'
|
|
||||||
|
|
||||||
|
|
||||||
async def get_limit_price(tg_id):
|
async def get_limit_price(tg_id):
|
||||||
|
"""Получить лимитную цену пользователя как float, либо None."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
result = await session.execute(
|
result = await session.execute(
|
||||||
select(UMS.limit_order_price)
|
select(UMS.limit_order_price)
|
||||||
@@ -375,6 +452,7 @@ async def get_limit_price(tg_id):
|
|||||||
|
|
||||||
|
|
||||||
async def update_limit_price(tg_id, price):
|
async def update_limit_price(tg_id, price):
|
||||||
|
"""Обновить лимитную цену пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(
|
await session.execute(
|
||||||
update(UMS)
|
update(UMS)
|
||||||
@@ -385,6 +463,7 @@ async def update_limit_price(tg_id, price):
|
|||||||
|
|
||||||
|
|
||||||
async def update_commission_fee(tg_id, num):
|
async def update_commission_fee(tg_id, num):
|
||||||
|
"""Обновить комиссию пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(commission_fee=num))
|
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(commission_fee=num))
|
||||||
|
|
||||||
@@ -392,6 +471,7 @@ async def update_commission_fee(tg_id, num):
|
|||||||
|
|
||||||
|
|
||||||
async def get_user_timer(tg_id):
|
async def get_user_timer(tg_id):
|
||||||
|
"""Получить данные о таймере пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
result = await session.execute(select(UserTimer).where(UserTimer.tg_id == tg_id))
|
result = await session.execute(select(UserTimer).where(UserTimer.tg_id == tg_id))
|
||||||
user_timer = result.scalars().first()
|
user_timer = result.scalars().first()
|
||||||
@@ -422,9 +502,9 @@ async def get_user_timer(tg_id):
|
|||||||
|
|
||||||
|
|
||||||
async def update_user_timer(tg_id, minutes: int):
|
async def update_user_timer(tg_id, minutes: int):
|
||||||
|
"""Обновить данные о таймере пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
try:
|
try:
|
||||||
async with async_session() as session:
|
|
||||||
timer_start = None
|
timer_start = None
|
||||||
timer_end = None
|
timer_end = None
|
||||||
|
|
||||||
@@ -454,6 +534,7 @@ async def update_user_timer(tg_id, minutes: int):
|
|||||||
|
|
||||||
|
|
||||||
async def get_martingale_step(tg_id):
|
async def get_martingale_step(tg_id):
|
||||||
|
"""Получить шаг мартингейла пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
result = await session.execute(select(UMS).where(UMS.tg_id == tg_id))
|
result = await session.execute(select(UMS).where(UMS.tg_id == tg_id))
|
||||||
user_settings = result.scalars().first()
|
user_settings = result.scalars().first()
|
||||||
@@ -461,6 +542,7 @@ async def get_martingale_step(tg_id):
|
|||||||
|
|
||||||
|
|
||||||
async def update_martingale_step(tg_id, step):
|
async def update_martingale_step(tg_id, step):
|
||||||
|
"""Обновить шаг мартингейла пользователя."""
|
||||||
async with async_session() as session:
|
async with async_session() as session:
|
||||||
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(martingale_step=step))
|
await session.execute(update(UMS).where(UMS.tg_id == tg_id).values(martingale_step=step))
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user