Added documentation

This commit is contained in:
algizn97
2025-08-23 14:33:33 +05:00
parent 2da06481f7
commit afe61ea7d6
3 changed files with 101 additions and 23 deletions

View File

@@ -0,0 +1,40 @@
import logging.config
from pybit.unified_trading import HTTP
import app.telegram.database.requests as rq
from logger_helper.logger_helper import LOGGING_CONFIG
logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("get_valid_symbol")
async def get_valid_symbols(user_id: int, symbol: str) -> bool:
"""
Проверяет существование торговой пары на Bybit в категории 'linear'.
Эта функция получает API-ключи пользователя из базы данных и
с помощью Bybit API проверяет наличие данного символа в списке
торговых инструментов категории 'linear'.
Args:
user_id (int): Идентификатор пользователя Telegram.
symbol (str): Торговый символ (валютная пара), например "BTCUSDT".
Returns:
bool: Возвращает True, если торговая пара существует, иначе False.
Raises:
Исключения подавляются и вызывается False, если произошла ошибка запроса к API.
"""
api_key = await rq.get_bybit_api_key(user_id)
secret_key = await rq.get_bybit_secret_key(user_id)
client = HTTP(api_key=api_key, api_secret=secret_key)
try:
resp = client.get_instruments_info(category='linear', symbol=symbol)
# Проверка наличия результата и непустого списка инструментов
if resp.get('retCode') == 0 and resp.get('result') and resp['result'].get('list'):
return len(resp['result']['list']) > 0
return False
except Exception as e:
logging.error(f"Ошибка при получении списка инструментов: {e}")
return False

View File

@@ -1,23 +1,52 @@
from app.services.Bybit.functions import price_symbol import math
import logging.config
from app.services.Bybit.functions.price_symbol import get_price
import app.telegram.database.requests as rq import app.telegram.database.requests as rq
from logger_helper.logger_helper import LOGGING_CONFIG
from pybit.unified_trading import HTTP from pybit.unified_trading import HTTP
client = HTTP() logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("min_qty")
async def get_min_qty(tg_id): def round_up_qty(value: float, step: float) -> float:
"""
Округление value вверх до ближайшего кратного step.
"""
return math.ceil(value / step) * step
async def get_min_qty(tg_id: int) -> float:
"""
Получает минимальный объем (количество) ордера для символа пользователя на Bybit,
округленное с учетом шага количества qtyStep.
:param tg_id: int - идентификатор пользователя Telegram
:return: float - минимальное количество лота для ордера
"""
api_key = await rq.get_bybit_api_key(tg_id) api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id) secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id) symbol = await rq.get_symbol(tg_id)
client = HTTP( client = HTTP(api_key=api_key, api_secret=secret_key)
api_key=api_key,
api_secret=secret_key
)
price = await price_symbol(tg_id) price = await get_price(tg_id)
json_data = client.get_instruments_info(symbol=SYMBOL, category='linear')
min_qty = int(5 / price * 1.1) # <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 1% <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD> <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 5 USDT response = client.get_instruments_info(symbol=symbol, category='linear')
return min_qty instrument = response['result'][0]
lot_size_filter = instrument.get('lotSizeFilter', {})
min_order_qty = float(lot_size_filter.get('minOrderQty', 0))
min_notional_value = float(lot_size_filter.get('minNotionalValue', 0))
qty_step = float(lot_size_filter.get('qtyStep', 1))
calculated_qty = (5 / price) * 1.1
min_qty = max(min_order_qty, calculated_qty)
min_qty_rounded = round_up_qty(min_qty, qty_step)
logger.debug(f"tg_id={tg_id}: price={price}, min_order_qty={min_order_qty}, "
f"min_notional_value={min_notional_value}, qty_step={qty_step}, "
f"calculated_qty={calculated_qty}, min_qty_rounded={min_qty_rounded}")
return min_qty_rounded

View File

@@ -1,24 +1,33 @@
import app.telegram.database.requests as rq import app.telegram.database.requests as rq
import logging.config
from logger_helper.logger_helper import LOGGING_CONFIG
from pybit import exceptions from pybit import exceptions
from pybit.unified_trading import HTTP from pybit.unified_trading import HTTP
client = HTTP() logging.config.dictConfig(LOGGING_CONFIG)
logger = logging.getLogger("price_symbol")
async def get_price(tg_id, message):
async def get_price(tg_id: int) -> float:
"""
Асинхронно получает текущую цену символа пользователя на Bybit.
:param tg_id: int - ID пользователя Telegram
:return: float - текущая цена символа
"""
api_key = await rq.get_bybit_api_key(tg_id) api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id) secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id) symbol = await rq.get_symbol(tg_id)
client = HTTP( client = HTTP(
api_key=api_key, api_key=api_key,
api_secret=secret_key api_secret=secret_key
) )
try:
price = float(client.get_tickers(category='linear', symbol=SYMBOL).get('result').get('list')[0].get('ask1Price'))
try:
price = float(
client.get_tickers(category='linear', symbol=symbol).get('result').get('list')[0].get('ask1Price'))
return price return price
except exceptions.InvalidRequestError as e: except exceptions.InvalidRequestError as e:
await message.answer('Неверно указана торговая пара') logger.error(f"Ошибка при получении цены: {e}")
return 1.0 return 1.0