Files
stcs/app/services/Bybit/functions/functions.py
algizn97 eaf8458835 Update
2025-08-21 16:10:01 +05:00

211 lines
9.7 KiB
Python
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

from aiogram import F, Router
from app.services.Bybit.functions import Futures, func_min_qty
from app.services.Bybit.functions.Futures import open_market_order, open_limit_order
from app.services.Bybit.functions.balance import get_balance
import app.telegram.Keyboards.inline_keyboards as inline_markup
import app.telegram.database.requests as rq
from aiogram.types import Message, CallbackQuery
# FSM - Механизм состояния
from aiogram.fsm.state import State, StatesGroup
from aiogram.fsm.context import FSMContext
router_functions_bybit_trade = Router()
class state_update_symbol(StatesGroup):
symbol = State()
class state_update_entry_type(StatesGroup):
entry_type = State()
@router_functions_bybit_trade.callback_query(F.data.in_(['clb_start_trading', 'clb_back_to_main']))
async def clb_start_bybit_trade_message(callback: CallbackQuery, state: FSMContext):
api = await rq.get_bybit_api_key(callback.from_user.id)
secret = await rq.get_bybit_secret_key(callback.from_user.id)
balance = await get_balance(callback.from_user.id, callback.message)
if balance:
symbol = await rq.get_symbol(callback.from_user.id)
text = f'''💎 Торговля на Bybit
⚖️ Ваш баланс (USDT): {balance}
📊 Текущая торговая пара: {symbol}
Как начать торговлю?
1⃣ Проверьте и тщательно настройте все параметры в вашем профиле.
2⃣ Нажмите ниже кнопку 'Указать торговую пару' и введите торговую пару заглавными буквами, без лишних символов (например: BTCUSDT).
'''
await callback.message.edit_text(text=text, parse_mode='html', reply_markup=inline_markup.trading_markup)
async def start_bybit_trade_message(message, state):
api = await rq.get_bybit_api_key(message.from_user.id)
secret = await rq.get_bybit_secret_key(message.from_user.id)
balance = await get_balance(message.from_user.id, message)
if balance:
symbol = await rq.get_symbol(message.from_user.id)
text = f'''💎 Торговля на Bybit
⚖️ Ваш баланс (USDT): {balance}
📊 Текущая торговая пара: {symbol}
Как начать торговлю?
1⃣ Проверьте и тщательно настройте все параметры в вашем профиле.
2⃣ Нажмите ниже кнопку 'Указать торговую пару' и введите торговую пару заглавными буквами, без лишних символов (например: BTCUSDT).
'''
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.trading_markup)
@router_functions_bybit_trade.callback_query(F.data == 'clb_update_trading_pair')
async def update_symbol_for_trade_message(callback: CallbackQuery, state: FSMContext):
await state.set_state(state_update_symbol.symbol)
await callback.message.answer(text='Укажите торговую пару заглавными буквами без пробелов и лишних символов (пример: BTCUSDT): ')
@router_functions_bybit_trade.message(state_update_symbol.symbol)
async def update_symbol_for_trade(message: Message, state: FSMContext):
await state.update_data(symbol = message.text)
data = await state.get_data()
await message.answer('Пара была успешно обновлена')
await rq.update_symbol(message.from_user.id, data['symbol'])
await start_bybit_trade_message(message, state)
await state.clear()
@router_functions_bybit_trade.callback_query(F.data == 'clb_update_entry_type')
async def update_entry_type_message(callback: CallbackQuery, state: FSMContext):
await state.set_state(state_update_entry_type.entry_type)
await callback.message.answer("Выберите тип входа в позицию:", reply_markup=inline_markup.entry_order_type_markup)
await callback.answer()
@router_functions_bybit_trade.callback_query(lambda c: c.data and c.data.startswith('entry_order_type:'))
async def entry_order_type_callback(callback: CallbackQuery, state: FSMContext):
order_type = callback.data.split(':')[1]
if order_type not in ['Market', 'Limit']:
await callback.answer("Ошибка выбора", show_alert=True)
return
await state.update_data(entry_order_type=order_type)
await rq.update_entry_order_type(callback.from_user.id, order_type)
if order_type == 'Limit':
await callback.answer("Вы выбрали Limit. Введите цену для лимитного ордера.")
await callback.message.answer("Введите цену лимитного ордера:")
await state.update_data(awaiting_limit_price=True)
else:
await callback.answer("Вы выбрали Market. Нажмите кнопку ниже, чтобы открыть сделку.")
await callback.message.answer("Нажмите кнопку, чтобы открыть сделку.",
reply_markup=inline_markup.open_deal_markup)
await callback.message.delete()
@router_functions_bybit_trade.message()
async def process_limit_price_message(message: Message, state: FSMContext):
data = await state.get_data()
if not data.get('awaiting_limit_price'):
return
try:
price = float(message.text)
if price <= 0:
raise ValueError()
except ValueError:
await message.answer("Ошибка: введите корректное положительное число для цены.")
return
await state.update_data(limit_price=price, awaiting_limit_price=False)
await message.answer(f"Цена лимитного ордера установлена: {price}. Нажмите кнопку ниже, чтобы открыть сделку.",
reply_markup=inline_markup.open_deal_markup)
@router_functions_bybit_trade.callback_query(F.data == "clb_open_deal")
async def open_deal(callback: CallbackQuery, state: FSMContext):
data_main_stgs = await rq.get_user_main_settings(callback.from_user.id)
data = await state.get_data()
order_type = await rq.get_entry_order_type(callback.from_user.id)
api = await rq.get_bybit_api_key(callback.from_user.id)
secret = await rq.get_bybit_secret_key(callback.from_user.id)
qty = data_main_stgs['starting_quantity']
qty_min = await func_min_qty.get_min_qty(callback.from_user.id, callback.message)
if qty < qty_min:
await callback.message.edit_text(f"Количество вашей ставки ({qty}) меньше минимального количества ({qty_min}) для данной торговой пары")
await callback.answer()
return
if order_type == 'Market':
await open_market_order(callback.from_user.id, callback.message, api_key=api, secret_key=secret)
await rq.update_user_trades(callback.from_user.id, symbol=data.get('symbol'), side=order_type)
elif order_type == 'Limit':
price = data.get('limit_price')
if not price:
await callback.answer("Цена для лимитного ордера не задана. Введите сначала цену.")
return
await open_limit_order(callback.from_user.id, callback.message, price, api_key=api, secret_key=secret)
else:
await callback.answer("Неизвестный тип ордера.")
await callback.message.edit_reply_markup()
await state.clear()
@router_functions_bybit_trade.callback_query(F.data == "clb_my_deals")
async def show_my_trades_callback(callback: CallbackQuery):
tg_id = callback.from_user.id
trades = await rq.get_user_trades(tg_id)
if not trades:
await callback.message.answer("У вас ещё нет сделок.")
await callback.answer()
return
grouped = {}
for trade in trades:
symbol = trade['symbol'] if isinstance(trade, dict) else trade.symbol
grouped.setdefault(symbol, []).append(trade)
text_response = "Ваши сделки по валютным парам:\n\n"
for symbol, trade_list in grouped.items():
text_response += f"<b>{symbol}</b>\n"
for t in trade_list:
side = t['side'] if isinstance(t, dict) else t.side
text_response += f" - {side}\n"
text_response += "\n"
await callback.message.answer(text_response, parse_mode='html')
await callback.answer()
# @router_functions_bybit_trade.callback_query(F.data == 'clb_open_deal')
# async def make_deal_bybit (callback: CallbackQuery):
# data_main_stgs = await rq.get_user_main_settings(callback.from_user.id)
#
# trade_mode = data_main_stgs['trading_mode']
# qty = data_main_stgs['starting_quantity']
# margin_mode = data_main_stgs['margin_type']
qty_min = await func_min_qty.get_min_qty(callback.from_user.id, callback.message)
#
# if qty < qty_min:
# await callback.message.edit_text(f"Количество вашей ставки ({qty}) меньше минимального количества ({qty_min}) для данной торговой пары")
# else:
# match trade_mode:
# case 'Long':
# await Futures.contract_long(callback.from_user.id, callback.message, margin_mode)
# case 'Short':
# await Futures.contract_short(callback.from_user.id, callback.message, margin_mode)
# case 'Switch':
# await callback.message.edit_text('Режим Switch пока недоступен')
# case 'Smart':
# await callback.message.edit_text('Режим Smart пока недоступен')