3 Commits

20 changed files with 893 additions and 119 deletions

View File

@@ -6,8 +6,11 @@ from aiogram.types import Message
from app.telegram.database.models import async_main from app.telegram.database.models import async_main
from app.telegram.handlers.handlers import router # Для вызова событий from app.telegram.handlers.handlers import router
from app.telegram.functions.main_settings.settings import router_main_settings # Для вызова событий from app.telegram.functions.main_settings.settings import router_main_settings
from app.telegram.functions.risk_management_settings.settings import router_risk_management_settings
from app.services.Bybit.functions.Add_Bybit_API import router_register_bybit_api
from app.services.Bybit.functions.functions import router_functions_bybit_trade
from config import TOKEN_TG_BOT from config import TOKEN_TG_BOT
@@ -21,6 +24,9 @@ async def main():
dp.include_router(router) dp.include_router(router)
dp.include_router(router_main_settings) dp.include_router(router_main_settings)
dp.include_router(router_risk_management_settings)
dp.include_router(router_register_bybit_api)
dp.include_router(router_functions_bybit_trade)
await dp.start_polling(bot) await dp.start_polling(bot)

View File

@@ -21,6 +21,13 @@
<EnableUnmanagedDebugging>false</EnableUnmanagedDebugging> <EnableUnmanagedDebugging>false</EnableUnmanagedDebugging>
</PropertyGroup> </PropertyGroup>
<ItemGroup> <ItemGroup>
<Compile Include="app\services\Bybit\config.py" />
<Compile Include="app\services\Bybit\functions\Add_Bybit_API.py" />
<Compile Include="app\services\Bybit\functions\balance.py" />
<Compile Include="app\services\Bybit\functions\functions.py" />
<Compile Include="app\services\Bybit\functions\func_min_qty.py" />
<Compile Include="app\services\Bybit\functions\Futures.py" />
<Compile Include="app\services\Bybit\functions\price_symbol.py" />
<Compile Include="app\telegram\functions\additional_settings\settings.py" /> <Compile Include="app\telegram\functions\additional_settings\settings.py" />
<Compile Include="app\telegram\functions\condition_settings\settings.py" /> <Compile Include="app\telegram\functions\condition_settings\settings.py" />
<Compile Include="app\telegram\functions\functions.py" /> <Compile Include="app\telegram\functions\functions.py" />
@@ -37,6 +44,9 @@
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<Folder Include="app\" /> <Folder Include="app\" />
<Folder Include="app\services\Bybit\" />
<Folder Include="app\services\" />
<Folder Include="app\services\Bybit\functions\" />
<Folder Include="app\telegram\database\" /> <Folder Include="app\telegram\database\" />
<Folder Include="app\telegram\functions\condition_settings\" /> <Folder Include="app\telegram\functions\condition_settings\" />
<Folder Include="app\telegram\functions\additional_settings\" /> <Folder Include="app\telegram\functions\additional_settings\" />

View File

@@ -1 +1,20 @@
abobus # Чат-робот STCS
__
**Функционал:**
+ **Настройки**
+ Основные параметры *(Настроен, работает)*
+ Режим торговли Лонг/Шорт *(настроены)*, Switch/Smart *(не настроены)*
+ Тип маржи: Изолированная / Кросс *(настроено)*
+ Размер кредитного плеча: от x1 до x100 *(настроено)*
+ Начальная ставка: числовое значение *(настроено)*
+ Коэффициент мартингейла: число *(настроено)*
+ Максимальное количество ставок в серии: число *(настроено)*
+ Риск-менеджмент (Настроен, работает)
+ Процент изменения цены для фиксации прибыли (TP%): число *(настроено)*
+ Процент изменения цены для фиксации убытков (SL%): число (пример: 1%) *(настроено)*
+ Максимальный риск на сделку (в % от баланса): число (опционально) *(настроено)*
+ Условия запуска *(Не настроен)*
+ Дополнительные параметры *(Не настроен)*
+ Подключение Bybit *(настроено)*
+ Информация о правильном получении и сохранении Bybit-API keys *(настроено)*

View File

@@ -0,0 +1,73 @@
from aiogram import F, Router
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_register_bybit_api = Router()
class state_reg_bybit_api(StatesGroup):
api_key = State()
secret_key = State()
@router_register_bybit_api.callback_query(F.data == 'clb_new_user_connect_bybit_api_message')
async def info_for_bybit_api_message(callback: CallbackQuery):
text = '''<b>Подключение Bybit аккаунта</b>
<b>1. Зарегистрируйтесь или войдите в свой аккаунт на Bybit (https://www.bybit.com/).</b>
<b>2. В личном кабинете выберите раздел API. </b>
<b>3. Создание нового API ключа</b>
- Нажмите кнопку Create New Key (Создать новый ключ).
- Выберите системно-сгенерированный ключ.
- Укажите название API ключа (любое).
- Выберите права доступа для торговли (Trade).
- Можно ограничить доступ по IP для безопасности.
<b>4. Подтверждение создания</b>
- Подтвердите создание ключа.
- Отправьте чат-роботу.
<b>Важно: сохраните отдельно API Key и Secret Key в надежном месте. Secret ключ отображается только один раз. </b>
'''
await callback.message.answer(text=text, parse_mode='html', reply_markup=inline_markup.connect_bybit_api_markup)
await callback.answer()
@router_register_bybit_api.callback_query(F.data == 'clb_new_user_connect_bybit_api')
async def add_api_key_message(callback: CallbackQuery, state: FSMContext):
await state.set_state(state_reg_bybit_api.api_key)
text = 'Отправьте KEY_API ниже: '
await callback.message.answer(text=text)
@router_register_bybit_api.message(state_reg_bybit_api.api_key)
async def add_api_key_and_message_for_secret_key(message: Message, state: FSMContext):
await state.update_data(api_key = message.text)
text = 'Отправьте SECRET_KEY ниже'
await message.answer(text=text)
await state.set_state(state_reg_bybit_api.secret_key)
@router_register_bybit_api.message(state_reg_bybit_api.secret_key)
async def add_secret_key(message: Message, state: FSMContext):
await state.update_data(secret_key = message.text)
data = await state.get_data()
await rq.update_api_key(message.from_user.id, data['api_key'])
await rq.update_secret_key(message.from_user.id, data['secret_key'])
await rq.set_new_user_symbol(message.from_user.id)
await state.clear()
await message.answer('Данные добавлены, нажмите на профиль и начните торговлю!')

View File

@@ -0,0 +1,286 @@
import time
from typing import Optional
from asyncio import Handle
from annotated_types import T
from pybit import exceptions
from pybit.unified_trading import HTTP
from pybit.unified_trading import WebSocket
from app.services.Bybit.functions import price_symbol
import app.services.Bybit.functions.balance as balance_g
import app.telegram.database.requests as rq
import logging
logging.basicConfig(level=logging.DEBUG)
def handle_message(message):
print(message)
async def info_access_open_deal(message, symbol, trade_mode, margin_mode, leverage, qty):
match margin_mode:
case 'ISOLATED_MARGIN':
margin_mode = 'Isolated'
case 'REGULAR_MARGIN':
margin_mode = 'Cross'
text = f'''Позиция была успешна открыта!
Торговая пара: {symbol}
Движение: {trade_mode}
Тип-маржи: {margin_mode}
Кредитное плечо: {leverage}
Количество: {qty}
'''
await message.answer(text=text, parse_mode='html')
async def error_max_step(message):
await message.answer('Сделка не была совершена, превышен лимит максимального количества ставок')
async def error_max_risk(message):
await message.answer('Сделка не была совершена, слишком высокий риск')
async def contract_long(tg_id, message, margin_mode):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id)
data_main_stgs = await rq.get_user_main_settings(tg_id)
data_risk_management_stgs = await rq.get_user_risk_management_settings(tg_id)
match margin_mode:
case 'Isolated':
margin_mode = 'ISOLATED_MARGIN'
case 'Cross':
margin_mode = 'REGULAR_MARGIN'
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
try:
balance = 0
price = 0
balance = await balance_g.get_balance(tg_id)
price = await price_symbol.get_price(tg_id, message)
client.set_margin_mode(
setMarginMode=margin_mode # margin_type
)
martingale_factor = float(data_main_stgs['martingale_factor'])
max_martingale_steps = int(data_main_stgs['maximal_quantity'])
starting_quantity = float(data_main_stgs['starting_quantity'])
max_risk_percent = float(data_risk_management_stgs['max_risk_deal'])
loss_profit = float(data_risk_management_stgs['price_loss'])
takeProfit= float(data_risk_management_stgs['price_profit'])
# Инициализация переменных
next_quantity = starting_quantity
last_quantity = starting_quantity
realised_pnl = 0.0
current_martingale_step = 0 # Текущая ставка в серии
next_quantity = 0
realised_pnl = 0
last_quantity = starting_quantity
# Пример расчёта следующего размера позиции
try:
position_info = client.get_positions(category='linear', symbol=SYMBOL)
position = position_info['result']['list'][0] # или другой нужный индекс
realised_pnl = float(position['unrealisedPnl'])
if realised_pnl > 0:
print(f'''
=====================
=====Сделка=========
===уСПЕШНЕАЯ================
===================
=================
{realised_pnl}
===============
===============
=============
===============
==============
''')
starting_quantity = next_quantity
current_martingale_step = 0
elif not realised_pnl:
next_quantity = starting_quantity
current_martingale_step += 1
else:
current_martingale_step += 1
next_quantity = last_quantity * martingale_factor
starting_quantity = next_quantity
print(f'''
======СДЕЛКА===============
=====УБЫТОЧНАЯ==============
===================
===================
=================
{realised_pnl}
===============
===============
=============
===============
==============
''')
except Exception as e:
print("Не получены позиции")
next_quantity = starting_quantity
potential_loss = (next_quantity * float(price)) * (loss_profit / 100)
allowed_loss = float(balance) * (max_risk_percent / 100)
if current_martingale_step >= max_martingale_steps:
print("Достигнут максимум ставок в серии (8)!")
print("Торговля не продолжится")
await error_max_step(message)
else:
if potential_loss > allowed_loss:
print(f"ОШИБКА: Риск превышен!")
print(f"Ручной qty = {next_quantity} → Убыток = {potential_loss} USDT")
print(f"Разрешено = {allowed_loss} USDT (1% от баланса)")
await error_max_risk(message)
else:
print(f"Риск в допустимых пределах. Qty = {next_quantity}")
r = client.place_order(
category='linear',
symbol=SYMBOL,
side='Buy',
orderType="Market",
leverage=int(data_main_stgs['size_leverage']),
qty=next_quantity,
takeProfit=takeProfit, # TP - закрывает позицию, когда цена достигает нужного уровня
stopProfit=float(data_risk_management_stgs['price_loss']), # SL - закрывает позицию, когда убыток достигает нужного уровня
orderLinkId=f"deal_{SYMBOL}_{time.time()}"
)
await info_access_open_deal(message, SYMBOL, data_main_stgs['trading_mode'], margin_mode, data_main_stgs['size_leverage'], next_quantity)
except exceptions.InvalidRequestError as e:
await message.answer('Недостаточно баланса')
except Exception as e:
await message.answer('Непредвиденная оишбка')
async def contract_short(tg_id, message, margin_mode):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id)
data_main_stgs = await rq.get_user_main_settings(tg_id)
data_risk_management_stgs = await rq.get_user_risk_management_settings(tg_id)
match margin_mode:
case 'Isolated':
margin_mode = 'ISOLATED_MARGIN'
case 'Cross':
margin_mode = 'REGULAR_MARGIN'
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
try:
balance = 0
price = 0
balance = await balance_g.get_balance(tg_id)
price = await price_symbol.get_price(tg_id, message)
client.set_margin_mode(
setMarginMode=margin_mode # margin_type
)
martingale_factor = float(data_main_stgs['martingale_factor'])
max_martingale_steps = int(data_main_stgs['maximal_quantity'])
starting_quantity = float(data_main_stgs['starting_quantity'])
max_risk_percent = float(data_risk_management_stgs['max_risk_deal'])
loss_profit = float(data_risk_management_stgs['price_loss'])
takeProfit = float(data_risk_management_stgs['price_profit'])
# Инициализация переменных
next_quantity = starting_quantity
last_quantity = starting_quantity
realised_pnl = 0.0
current_martingale_step = 0 # Текущая ставка в серии
next_quantity = 0
realised_pnl = 0
last_quantity = starting_quantity
# Пример расчёта следующего размера позиции
try:
position_info = client.get_positions(category='linear', symbol=SYMBOL)
position = position_info['result']['list'][0] # или другой нужный индекс
realised_pnl = float(position['unrealisedPnl'])
if realised_pnl > 0: # Прибыльная сделка
starting_quantity = next_quantity
current_martingale_step = 0
elif not realised_pnl:
next_quantity = starting_quantity
current_martingale_step += 1
else: # Убыточная сделка
current_martingale_step += 1
next_quantity = last_quantity * martingale_factor
starting_quantity = next_quantity
except Exception as e:
print("Не получены позиции")
next_quantity = starting_quantity
potential_loss = (next_quantity * float(price)) * (loss_profit / 100)
allowed_loss = float(balance) * (max_risk_percent / 100)
if current_martingale_step >= max_martingale_steps:
print("Достигнут максимум ставок в серии (8)!")
print("Торговля не продолжится")
await error_max_step(message)
else:
if potential_loss > allowed_loss:
print(f"ОШИБКА: Риск превышен!")
print(f"Ручной qty = {next_quantity} → Убыток = {potential_loss} USDT")
print(f"Разрешено = {allowed_loss} USDT (1% от баланса)")
await error_max_risk(message)
else:
print(f"Риск в допустимых пределах. Qty = {next_quantity}")
r = client.place_order(
category='linear',
symbol=SYMBOL,
side='Sell',
orderType="Market",
leverage=int(data_main_stgs['size_leverage']),
qty=next_quantity,
orderLinkId=f"deal_{SYMBOL}_{time.time()}"
)
await info_access_open_deal(message, SYMBOL, data_main_stgs['trading_mode'], margin_mode, data_main_stgs['size_leverage'], next_quantity)
except exceptions.InvalidRequestError as e:
await message.answer('Недостаточно баланса')
except Exception as e:
await message.answer('Непредвиденная оишбка')

View File

@@ -0,0 +1,22 @@
import app.telegram.database.requests as rq
from pybit.unified_trading import HTTP
client = HTTP()
async def get_balance(tg_id, message):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
try:
balance = client.get_wallet_balance(accountType='UNIFIED', coin='USDT')['result']['list'][0]['coin'][0]['walletBalance']
return balance
except Exception as e:
await message.answer('Баланс не был получен, подключите платформу')
return 0

View File

@@ -0,0 +1,21 @@
import app.telegram.database.requests as rq
import app.services.Bybit.functions.price_symbol as price_s
from pybit.unified_trading import HTTP
client = HTTP()
async def get_min_qty(tg_id, message):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id)
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
price = await price_s.get_price(tg_id, message)
min_qty = int(5 / price * 1.1)
return min_qty

View File

@@ -0,0 +1,103 @@
from aiogram import F, Router
from app.services.Bybit.functions import Futures, func_min_qty
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()
@router_functions_bybit_trade.callback_query(F.data == 'clb_start_trading')
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)
if api and secret:
balance = await get_balance(callback.from_user.id, callback.message)
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)
else:
callback.message.answer('Перед началом работы, в настройках подключите bybit')
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)
if api and secret:
balance = await get_balance(message.from_user.id, message)
symbol = await rq.get_symbol(message.from_user.id)
text = f'''Торговля на Bybit
<b>ваш баланс (USDT):</b> {balance}
<b>Текущая торговая пара: </b> {symbol}
Как начать торговлю?
1. Внимательно проверьте и настройте все параметры в вашем профиле
2. Ниже нажмите 'Указать торговую пару' и отправьте торговую пару заглавными буквами, указав два актива без всяких лишних символов! (Пример: BTCUSDT)
'''
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.trading_markup)
else:
await message.answer('Перед началом работы, в настройках подключите bybit')
@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 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_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 пока недоступен')

View File

@@ -0,0 +1,23 @@
from app.services.Bybit.functions import price_symbol
import app.telegram.database.requests as rq
from pybit.unified_trading import HTTP
client = HTTP()
async def get_min_qty(tg_id):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id)
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
price = await price_symbol(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
return min_qty

View File

@@ -0,0 +1,24 @@
import app.telegram.database.requests as rq
from pybit import exceptions
from pybit.unified_trading import HTTP
client = HTTP()
async def get_price(tg_id, message):
api_key = await rq.get_bybit_api_key(tg_id)
secret_key = await rq.get_bybit_secret_key(tg_id)
SYMBOL = await rq.get_symbol(tg_id)
client = HTTP(
api_key=api_key,
api_secret=secret_key
)
try:
price = float(client.get_tickers(category='linear', symbol=SYMBOL).get('result').get('list')[0].get('ask1Price'))
return price
except exceptions.InvalidRequestError as e:
await message.answer('Неверно указана торговая пара')
return 1.0

View File

@@ -1,15 +1,15 @@
from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup from aiogram.types import InlineKeyboardButton, InlineKeyboardMarkup
start_markup = InlineKeyboardMarkup(inline_keyboard=[ start_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Зарегистрироваться", callback_data="callback_registration")], [InlineKeyboardButton(text="🔥 Начать торговлю", callback_data="clb_start_chatbot_message")]
[InlineKeyboardButton(text="Авторизоваться", callback_data="callback_autorisation")]
]) ])
settings_markup = InlineKeyboardMarkup(inline_keyboard=[ settings_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Настройки", callback_data='clb_settings_message')] [InlineKeyboardButton(text="Настройки", callback_data='clb_settings_message')],
[InlineKeyboardButton(text="Запуск", callback_data='clb_start_trading')]
]) ])
back_btn_profile = [InlineKeyboardButton(text="Назад", callback_data='callback_autorisation')] back_btn_profile = [InlineKeyboardButton(text="Назад", callback_data='callback_profile')]
special_settings_markup = InlineKeyboardMarkup(inline_keyboard=[ special_settings_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Основные настройки", callback_data='clb_change_main_settings'), [InlineKeyboardButton(text="Основные настройки", callback_data='clb_change_main_settings'),
@@ -18,9 +18,20 @@ special_settings_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Условия запуска", callback_data='clb_change_condition_settings'), [InlineKeyboardButton(text="Условия запуска", callback_data='clb_change_condition_settings'),
InlineKeyboardButton(text="Дополнительные параметры", callback_data='clb_change_additional_settings')], InlineKeyboardButton(text="Дополнительные параметры", callback_data='clb_change_additional_settings')],
[InlineKeyboardButton(text="Подключить Bybit", callback_data='clb_new_user_connect_bybit_api_message')],
back_btn_profile back_btn_profile
]) ])
connect_bybit_api_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Подключить Bybit", callback_data='clb_new_user_connect_bybit_api')]
])
trading_markup = InlineKeyboardMarkup(inline_keyboard=[
[InlineKeyboardButton(text="Указать торговую пару", callback_data='clb_update_trading_pair')],
[InlineKeyboardButton(text="Совершить сделку", callback_data='clb_open_deal')]
])
back_btn_list_settings = [InlineKeyboardButton(text="Назад", callback_data='clb_back_to_special_settings_message')] # Кнопка для возврата к списку каталога настроек back_btn_list_settings = [InlineKeyboardButton(text="Назад", callback_data='clb_back_to_special_settings_message')] # Кнопка для возврата к списку каталога настроек
back_btn_list_settings_markup = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="Назад", callback_data='clb_back_to_special_settings_message')]]) # Клавиатура для возврата к списку каталога настроек back_btn_list_settings_markup = InlineKeyboardMarkup(inline_keyboard=[[InlineKeyboardButton(text="Назад", callback_data='clb_back_to_special_settings_message')]]) # Клавиатура для возврата к списку каталога настроек
@@ -86,3 +97,16 @@ margin_type_markup = InlineKeyboardMarkup(inline_keyboard=[
back_btn_list_settings back_btn_list_settings
]) ])
trigger_markup = InlineKeyboardMarkup(inline_keyboard=[ # ИЗМЕНИТЬ НА INLINE
[InlineKeyboardButton(text='Ручной', callback_data="clb_trigger_ruchnoy"), InlineKeyboardButton(text='TradingView', callback_data="clb_trigger_tradingview")],
[InlineKeyboardButton(text="Автоматический", callback_data="clb_trigger_auto")]
])
buttons_yes_no_markup = InlineKeyboardMarkup(inline_keyboard=[ # ИЗМЕНИТЬ НА INLINE
[InlineKeyboardButton(text='Да', callback_data="clb_yes"), InlineKeyboardButton(text='Нет', callback_data="clb_yes")]
])
buttons_on_off_markup = InlineKeyboardMarkup(inline_keyboard=[ # ИЗМЕНИТЬ НА INLINE
[InlineKeyboardButton(text='Включить', callback_data="clb_on"), InlineKeyboardButton(text='Выключить', callback_data="clb_off")]
])

View File

@@ -4,16 +4,3 @@ base_buttons_markup = ReplyKeyboardMarkup(keyboard=[
[KeyboardButton(text="👤 Профиль")], [KeyboardButton(text="👤 Профиль")],
# [KeyboardButton(text="Настройки")] # [KeyboardButton(text="Настройки")]
], resize_keyboard=True) ], resize_keyboard=True)
trigger_markup = ReplyKeyboardMarkup(keyboard=[ # ИЗМЕНИТЬ НА INLINE
[KeyboardButton(text='Ручной'), KeyboardButton(text='TradingView')],
[KeyboardButton(text="Автоматический")]
], resize_keyboard=True)
buttons_yes_no_markup = ReplyKeyboardMarkup(keyboard=[ # ИЗМЕНИТЬ НА INLINE
[KeyboardButton(text='Да'), KeyboardButton(text='Нет')]
], resize_keyboard=True)
buttons_on_off_markup = ReplyKeyboardMarkup(keyboard=[ # ИЗМЕНИТЬ НА INLINE
[KeyboardButton(text='Включить'), KeyboardButton(text='Выключить')]
], resize_keyboard=True)

View File

@@ -21,6 +21,25 @@ class User_Telegram_Id(Base):
tg_id = mapped_column(BigInteger) tg_id = mapped_column(BigInteger)
class User_Bybit_API(Base):
__tablename__ = 'user_bybit_api'
id: Mapped[int] = mapped_column(primary_key=True)
tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id"))
api_key = mapped_column(String(18), default='None')
secret_key = mapped_column(String(36), default='None')
class User_Symbol(Base):
__tablename__ = 'user_symbols'
id: Mapped[int] = mapped_column(primary_key=True)
tg_id = mapped_column(ForeignKey("user_telegram_id.tg_id"))
symbol = mapped_column(String(18), default='PENGUUSDT')
class Trading_Mode(Base): class Trading_Mode(Base):
__tablename__ = 'trading_modes' __tablename__ = 'trading_modes'
@@ -105,7 +124,7 @@ async def async_main():
logger.info("Заполение таблицы режима торговли") logger.info("Заполение таблицы режима торговли")
await conn.execute(Trading_Mode.__table__.insert().values(mode=mode)) await conn.execute(Trading_Mode.__table__.insert().values(mode=mode))
types = ['Изолированный', 'Кросс'] types = ['Isolated', 'Cross']
for type in types: for type in types:
result = await conn.execute(select(Margin_type).where(Margin_type.type == type)) result = await conn.execute(select(Margin_type).where(Margin_type.type == type))
if not result.first(): if not result.first():

View File

@@ -4,6 +4,8 @@ logger = logging.getLogger(__name__)
from app.telegram.database.models import async_session 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_Telegram_Id as UTi
from app.telegram.database.models import User_Main_Settings as UMS 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_Risk_Management_Settings as URMS
from app.telegram.database.models import User_Condition_Settings as UCS 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 User_Additional_Settings as UAS
@@ -27,6 +29,32 @@ 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 with async_session() as session:
user = await session.scalar(select(UBA).where(UBA.tg_id == tg_id))
if not user:
session.add(UBA(
tg_id=tg_id,
))
logger.info(f"Bybit был успешно подключен")
await session.commit()
async def set_new_user_symbol(tg_id):
async with async_session() as session:
user = await session.scalar(select(User_Symbol).where(User_Symbol.tg_id == tg_id))
if not user:
session.add(User_Symbol(
tg_id=tg_id
))
logger.info(f"Symbol был успешно добавлен")
await session.commit()
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:
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))
@@ -88,6 +116,21 @@ async def check_user(tg_id):
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 with async_session() as session:
api_key = await session.scalar(select(UBA.api_key).where(UBA.tg_id == tg_id))
return api_key
async def get_bybit_secret_key(tg_id):
async with async_session() as session:
secret_key = await session.scalar(select(UBA.secret_key).where(UBA.tg_id == tg_id))
return secret_key
async def get_symbol(tg_id):
async with async_session() as session:
symbol = await session.scalar(select(User_Symbol.symbol).where(User_Symbol.tg_id == tg_id))
return symbol
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))
@@ -128,7 +171,45 @@ async def get_user_main_settings(tg_id):
return data return data
# UPDATE_DB async def get_user_risk_management_settings(tg_id):
async with async_session() as session:
user = await session.scalar(select(URMS).where(URMS.tg_id == tg_id))
if user:
logger.info("Получение риск-менеджмента настроек пользователя")
price_profit = await session.scalar(select(URMS.price_profit).where(URMS.tg_id == tg_id))
price_loss = await session.scalar(select(URMS.price_loss).where(URMS.tg_id == tg_id))
max_risk_deal = await session.scalar(select(URMS.max_risk_deal).where(URMS.tg_id == tg_id))
data = {
'price_profit': price_profit,
'price_loss': price_loss,
'max_risk_deal': max_risk_deal
}
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 def update_trade_mode_user(tg_id, trading_mode) -> None:
async with async_session() as session: async with async_session() as session:
mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.mode == trading_mode)) mode = await session.scalar(select(Trading_Mode.mode).where(Trading_Mode.mode == trading_mode))
@@ -172,3 +253,23 @@ async def update_maximal_quantity(tg_id, num):
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 with async_session() as session:
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_profit = num))
await session.commit()
async def update_price_loss(tg_id, num):
async with async_session() as session:
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(price_loss = num))
await session.commit()
async def update_max_risk_deal(tg_id, num):
async with async_session() as session:
await session.execute(update(URMS).where(URMS.tg_id == tg_id).values(max_risk_deal = num))
await session.commit()

View File

@@ -1,5 +1,4 @@
import app.telegram.Keyboards.inline_keyboards as inline_markup import app.telegram.Keyboards.inline_keyboards as inline_markup
import app.telegram.Keyboards.reply_keyboards as reply_markup
import app.telegram.database.requests as rq import app.telegram.database.requests as rq
@@ -8,34 +7,32 @@ async def reg_new_user_default_additional_settings(id, message):
await rq.set_new_user_default_additional_settings(tg_id) await rq.set_new_user_default_additional_settings(tg_id)
async def main_settings_message(message): async def main_settings_message(id, message, state):
text = '''<b>Дополнительные параметры</b> text = '''<b>Дополнительные параметры</b>
Сохранить как шаблон стратегии: да / нет <b>- Сохранить как шаблон стратегии:</b> да / нет
<b>- Автозапуск после сохранения:</b> да / нет
<b>- Уведомления в Telegram:</b> включено / отключено '''
Автозапуск после сохранения: да / нет await message.edit_text(text=text, parse_mode='html', reply_markup=inline_markup.additional_settings_markup)
Уведомления в Telegram: включено / отключено '''
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.additional_settings_markup)
async def save_pattern_message(message, state): async def save_pattern_message(message, state):
text = '''<b>Сохранение шаблона</b> text = '''<b>Сохранение шаблона</b>
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_yes_no_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
async def auto_start_message(message, state): async def auto_start_message(message, state):
text = '''<b>Автозапуск</b> text = '''<b>Автозапуск</b>
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_yes_no_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
async def notifications_message(message, state): async def notifications_message(message, state):
text = '''<b>Уведомления</b> text = '''<b>Уведомления</b>
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_on_off_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_on_off_markup)

View File

@@ -1,5 +1,4 @@
import app.telegram.Keyboards.inline_keyboards as inline_markup import app.telegram.Keyboards.inline_keyboards as inline_markup
import app.telegram.Keyboards.reply_keyboards as reply_markup
import app.telegram.database.requests as rq import app.telegram.database.requests as rq
@@ -10,25 +9,17 @@ async def reg_new_user_default_condition_settings(id, message):
await rq.set_new_user_default_condition_settings(tg_id, trigger) await rq.set_new_user_default_condition_settings(tg_id, trigger)
async def main_settings_message(message): async def main_settings_message(id, message, state):
text = """ <b>Условия запуска</b> text = """ <b>Условия запуска</b>
Триггер: Ручной запуск / Сигнал TradingView / Полностью автоматический <b>- Триггер:</b> Ручной запуск / Сигнал TradingView / Полностью автоматический
<b>- Фильтр времени: </b> диапазон по дням недели и времени суток
Фильтр времени: диапазон по дням недели и времени суток <b>- Фильтр волатильности / объёма: </b> включить/отключить
<b>- Интеграции и внешние сигналы: </b>
Фильтр волатильности / объёма: включить/отключить <b>- Использовать сигналы TradingView:</b> да / нет
<b>- Использовать AI-аналитику от ChatGPT:</b> да / не
Интеграции и внешние сигналы: <b>- Webhook URL для сигналов (если используется TradingView): </b>
Использовать сигналы TradingView: да / нет
Использовать AI-аналитику от ChatGPT: да / нет
Webhook URL для сигналов (если используется TradingView).
""" """
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.condition_settings_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.condition_settings_markup)
async def trigger_message(message, state): async def trigger_message(message, state):
@@ -36,7 +27,7 @@ async def trigger_message(message, state):
Описание ручного запуска, сигналов, автоматического режима ''' Описание ручного запуска, сигналов, автоматического режима '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.trigger_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.trigger_markup)
async def filter_time_message(message, state): async def filter_time_message(message, state):
text = '''Фильтр времени text = '''Фильтр времени
@@ -51,7 +42,7 @@ async def filter_volatility_message(message, state):
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_on_off_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_on_off_markup)
async def external_cues_message(message, state): async def external_cues_message(message, state):
text = '''<b>Внешние сигналы</b> text = '''<b>Внешние сигналы</b>
@@ -65,7 +56,7 @@ async def trading_cues_message(message, state):
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_yes_no_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
async def webhook_message(message, state): async def webhook_message(message, state):
text = '''Скиньте ссылку на <b>webhook</b> (если есть trading view): ''' text = '''Скиньте ссылку на <b>webhook</b> (если есть trading view): '''
@@ -77,6 +68,6 @@ async def ai_analytics_message(message, state):
Описание... ''' Описание... '''
await message.answer(text=text, parse_mode='html', reply_markup=reply_markup.buttons_yes_no_markup) await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)

View File

@@ -2,33 +2,36 @@
import app.telegram.Keyboards.reply_keyboards as reply_markup import app.telegram.Keyboards.reply_keyboards as reply_markup
async def start_message(message): async def start_message(message):
await message.answer(f""" Привет <b>{message.from_user.username}</b>! 👋 username = ''
Добро пожаловать в бот по трейдингу на Bibyt — вашего надежного помощника для анализа рынка и принятия взвешенных решений. Здесь вы получите: if message.from_user.first_name == None:
username = message.from_user.last_name
elif message.from_user.last_name == None:
username = message.from_user.first_name
else:
username = f'{message.from_user.first_name} {message.from_user.last_name}'
await message.answer(f""" Привет <b>{username}</b>! 👋
Добро пожаловать в чат-робот по трейдингу на Bybit — вашего надежного помощника для анализа рынка и принятия взвешенных решений.
Здесь вы получите:
<b> <b>
📊 Анализ текущих трендов 📊 Анализ текущих трендов
📈 Инструменты для прогнозирования и оценки рисков 📈 Инструменты для прогнозирования и оценки рисков
⚡️ Сигналы и рекомендации по сделкам ⚡️ Сигналы и рекомендации по сделкам
🔔 Уведомления о важных изменениях и новостях 🔔 Уведомления о важных изменениях и новостях
</b> </b>
Просто отправляйте интересующий вас инструмент или команду, и бот быстро предоставит актуальную информацию и аналитику.
Начнем торговать умно и эффективно вместе! 🚀
""", parse_mode='html', reply_markup=inline_markup.start_markup) """, parse_mode='html', reply_markup=inline_markup.start_markup)
async def profile_message(username, message): async def profile_message(username, message):
await message.answer(f""" <b>{username}</b> await message.answer(f""" <b>@{username}</b>
Баланс: Баланс
⭐️ 0 ⭐️ 0
Описание:
Активный трейдер на платформе Bibyt с индивидуальной стратегией и аналитикой в реальном времени. Постоянно улучшает навыки и следит за рыночными тенденциями для максимальной прибыли.
""", parse_mode='html', reply_markup=inline_markup.settings_markup) """, parse_mode='html', reply_markup=inline_markup.settings_markup)
async def check_profile_message(message): async def check_profile_message(message):
await message.answer(f'Добро пожаловать {message.from_user.username}!', reply_markup=reply_markup.base_buttons_markup) await message.answer(f'Добро пожаловать {message.from_user.first_name} {message.from_user.last_name}!', reply_markup=reply_markup.base_buttons_markup)
async def settings_message(message): async def settings_message(message):
await message.edit_text("Выберите что настроить", reply_markup=inline_markup.special_settings_markup) await message.edit_text("Выберите что настроить", reply_markup=inline_markup.special_settings_markup)

View File

@@ -12,12 +12,12 @@ from aiogram.fsm.state import State, StatesGroup
router_main_settings = Router() router_main_settings = Router()
class update_main_settings(StatesGroup): class update_main_settings(StatesGroup):
trading_mode = State() # + trading_mode = State()
size_leverage = State() # size_leverage = State()
margin_type = State() # margin_type = State()
martingale_factor = State() # martingale_factor = State()
starting_quantity = State() # starting_quantity = State()
maximal_quantity = State() # maximal_quantity = State()
async def reg_new_user_default_main_settings(id, message): async def reg_new_user_default_main_settings(id, message):
tg_id = id tg_id = id
@@ -32,17 +32,13 @@ async def main_settings_message(id, message, state):
data = await rq.get_user_main_settings(id) data = await rq.get_user_main_settings(id)
await message.answer(f"""<b>Основные настройки</b> await message.answer(f"""<b>Основные настройки</b>
Режим торговли: <b>{data['trading_mode']}</b>
Тип маржи: <b>{data['margin_type']}</b> <b>- Режим торговли:</b> {data['trading_mode']}
<b>- Тип маржи:</b> {data['margin_type']}
Размер кредитного плеча: <b>х{data['size_leverage']}</b> <b>- Размер кредитного плеча:</b> х{data['size_leverage']}
<b>- Начальная ставка:</b> {data['starting_quantity']}
Начальная ставка: <b>{data['starting_quantity']}</b> <b>- Коэффициент мартингейла:</b> {data['martingale_factor']}
<b>- Максимальное количесиво ставок в серии:</b> {data['maximal_quantity']}
Коэффициент мартингейла: <b>{data['martingale_factor']}</b>
Максимальное количесиво ставок в серии: <b>{data['maximal_quantity']}</b>
""", parse_mode='html', reply_markup=inline_markup.main_settings_markup) """, parse_mode='html', reply_markup=inline_markup.main_settings_markup)
async def trading_mode_message(message, state): async def trading_mode_message(message, state):
@@ -66,7 +62,6 @@ async def state_trading_mode(callback: CallbackQuery, state):
await callback.answer() await callback.answer()
id = callback.from_user.id id = callback.from_user.id
print(f"sdljfngdjklfg ## {callback.data}")
try: try:
match callback.data: match callback.data:
@@ -160,12 +155,12 @@ async def state_margin_type(callback: CallbackQuery, state):
try: try:
match callback.data: match callback.data:
case 'margin_type_isolated': case 'margin_type_isolated':
await rq.update_margin_type(id, 'Изолированный') await rq.update_margin_type(id, 'Isolated')
await main_settings_message(id, callback.message, state) await main_settings_message(id, callback.message, state)
await state.clear() await state.clear()
case 'margin_type_cross': case 'margin_type_cross':
await rq.update_margin_type(id, 'Кросс') await rq.update_margin_type(id, 'Cross')
await main_settings_message(id, callback.message, state) await main_settings_message(id, callback.message, state)
await state.clear() await state.clear()
@@ -183,7 +178,7 @@ async def state_starting_quantity(message: Message, state):
data = await state.get_data() data = await state.get_data()
if data['starting_quantity'].isdigit() and int(data['starting_quantity']) <= 100: if data['starting_quantity'].isdigit():
await rq.update_starting_quantity(message.from_user.id, data['starting_quantity']) await rq.update_starting_quantity(message.from_user.id, data['starting_quantity'])
await main_settings_message(message.from_user.id, message, state) await main_settings_message(message.from_user.id, message, state)

View File

@@ -1,37 +1,95 @@
import app.telegram.Keyboards.inline_keyboards as inline_markup from aiogram import Router
import app.telegram.Keyboards.inline_keyboards as inline_markup
import app.telegram.Keyboards.reply_keyboards as reply_markup import app.telegram.Keyboards.reply_keyboards as reply_markup
import app.telegram.database.requests as rq import app.telegram.database.requests as rq
from aiogram.types import Message, CallbackQuery
# FSM - Механизм состояния
from aiogram.fsm.state import State, StatesGroup
router_risk_management_settings = Router()
class update_risk_management_settings(StatesGroup):
price_profit = State()
price_loss = State()
max_risk_deal = State()
async def reg_new_user_default_risk_management_settings(id, message): async def reg_new_user_default_risk_management_settings(id, message):
tg_id = id tg_id = id
await rq.set_new_user_default_risk_management_settings(tg_id) await rq.set_new_user_default_risk_management_settings(tg_id)
async def main_settings_message(id, message, state):
data = await rq.get_user_risk_management_settings(id)
async def main_settings_message(message):
text = f"""<b>Риск менеджмент</b>, text = f"""<b>Риск менеджмент</b>,
Процент изменения цены для фиксации прибыли: 0 <b>- Процент изменения цены для фиксации прибыли:</b> {data['price_profit']}
<b>- Процент изменения цены для фиксации убытков:</b> {data['price_loss']}
Процент изменения цены для фиксации убытков: 0 <b>- Максимальный риск на сделку (в % от баланса):</b> {data['max_risk_deal']}
Максимальный риск на сделку (в % от баланса): 0
""" """
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.risk_management_settings_markup)
await message.edit_text(text=text, parse_mode='html', reply_markup=inline_markup.risk_management_settings_markup)
async def price_profit_message(message, state): async def price_profit_message(message, state):
await state.set_state(update_risk_management_settings.price_profit)
text = 'Введите число изменения цены для фиксации прибыли: ' text = 'Введите число изменения цены для фиксации прибыли: '
await message.answer(text=text, parse_mode='html', reply_markup=None) await message.answer(text=text, parse_mode='html', reply_markup=None)
@router_risk_management_settings.message(update_risk_management_settings.price_profit)
async def state_price_profit(message: Message, state):
await state.update_data(price_profit = message.text)
data = await state.get_data()
if data['price_profit'].isdigit() and int(data['price_profit']) <= 100:
await rq.update_price_profit(message.from_user.id, data['price_profit'])
await main_settings_message(message.from_user.id, message, state)
await state.clear()
else:
await main_settings_message(message.from_user.id, message, state)
async def price_loss_message(message, state): async def price_loss_message(message, state):
await state.set_state(update_risk_management_settings.price_loss)
text = 'Введите число изменения цены для фиксации убытков: ' text = 'Введите число изменения цены для фиксации убытков: '
await message.answer(text=text, parse_mode='html', reply_markup=None) await message.answer(text=text, parse_mode='html', reply_markup=None)
@router_risk_management_settings.message(update_risk_management_settings.price_loss)
async def state_price_loss(message: Message, state):
await state.update_data(price_loss = message.text)
data = await state.get_data()
if data['price_loss'].isdigit() and int(data['price_loss']) <= 100:
await rq.update_price_loss(message.from_user.id, data['price_loss'])
await main_settings_message(message.from_user.id, message, state)
await state.clear()
else:
await main_settings_message(message.from_user.id, message, state)
async def max_risk_deal_message(message, state): async def max_risk_deal_message(message, state):
await state.set_state(update_risk_management_settings.max_risk_deal)
text = 'Введите число (процент от баланса) для изменения максимального риска на сделку: ' text = 'Введите число (процент от баланса) для изменения максимального риска на сделку: '
await message.answer(text=text, parse_mode='html', reply_markup=None) await message.answer(text=text, parse_mode='html', reply_markup=None)
@router_risk_management_settings.message(update_risk_management_settings.max_risk_deal)
async def state_max_risk_deal(message: Message, state):
await state.update_data(max_risk_deal = message.text)
data = await state.get_data()
if data['max_risk_deal'].isdigit() and int(data['max_risk_deal']) <= 100:
await rq.update_max_risk_deal(message.from_user.id, data['max_risk_deal'])
await main_settings_message(message.from_user.id, message, state)
await state.clear()
else:
await main_settings_message(message.from_user.id, message, state)

View File

@@ -19,6 +19,8 @@ router = Router()
@router.message(CommandStart()) @router.message(CommandStart())
async def start_message(message: Message): async def start_message(message: Message):
await rq.set_new_user_bybit_api(message.from_user.id)
await func.start_message(message) await func.start_message(message)
@router.message(F.text == "👤 Профиль") @router.message(F.text == "👤 Профиль")
@@ -35,27 +37,37 @@ async def settings_msg(message: Message):
if user: if user:
await func.settings_message(message) await func.settings_message(message)
@router.callback_query(F.data == "callback_registration") @router.callback_query(F.data == "clb_start_chatbot_message")
async def clb_func_reg (callback: CallbackQuery): async def clb_func_reg (callback: CallbackQuery):
user = await rq.check_user(callback.from_user.id)
if user:
await callback.message.answer(f'С возвращением, {callback.from_user.username}!', reply_markup=reply_markup.base_buttons_markup)
await func.profile_message(callback.from_user.username, callback.message)
else:
await rq.save_tg_id_new_user(callback.from_user.id) await rq.save_tg_id_new_user(callback.from_user.id)
print(callback.from_user.id)
await func_main_settings.reg_new_user_default_main_settings(callback.from_user.id, callback.message) await func_main_settings.reg_new_user_default_main_settings(callback.from_user.id, callback.message)
await func_rmanagement_settings.reg_new_user_default_risk_management_settings(callback.from_user.id, callback.message) await func_rmanagement_settings.reg_new_user_default_risk_management_settings(callback.from_user.id, callback.message)
await func_condition_settings.reg_new_user_default_condition_settings(callback.from_user.id, callback.message) await func_condition_settings.reg_new_user_default_condition_settings(callback.from_user.id, callback.message)
await func_additional_settings.reg_new_user_default_additional_settings(callback.from_user.id, callback.message) await func_additional_settings.reg_new_user_default_additional_settings(callback.from_user.id, callback.message)
await callback.message.answer(f'Регистрация прошла успешно, здравствуйте {callback.from_user.username}!', reply_markup=reply_markup.base_buttons_markup) await callback.message.answer(f'Регистрация прошла успешно, перейдите в профиль нажав на кнопку!', reply_markup=reply_markup.base_buttons_markup)
await func.profile_message(callback.from_user.username, callback.message)
await callback.answer() await callback.answer()
@router.callback_query(F.data == "callback_autorisation") @router.callback_query(F.data == "callback_profile")
async def clb_func_reg (callback: CallbackQuery): async def clb_profile_message (callback: CallbackQuery):
user = await rq.check_user(callback.from_user.id) user = await rq.check_user(callback.from_user.id)
if user: if user:
await func.profile_message(callback.from_user.username, callback.message) await func.profile_message(callback.from_user.username, callback.message)
await callback.answer()
# Настройки торговли # Настройки торговли
@router.callback_query(F.data == "clb_settings_message") @router.callback_query(F.data == "clb_settings_message")
async def clb_settings_msg (callback: CallbackQuery): async def clb_settings_msg (callback: CallbackQuery):