Fixed
This commit is contained in:
@@ -5,6 +5,9 @@ import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
from pybit.unified_trading import HTTP
|
||||
import app.telegram.database.requests as rq
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
|
||||
from app.services.Bybit.functions.price_symbol import get_price
|
||||
from app.services.Bybit.functions.Futures import safe_float, calculate_total_budget, get_bybit_client
|
||||
from app.states.States import update_main_settings
|
||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||
|
||||
@@ -24,20 +27,54 @@ async def reg_new_user_default_main_settings(id, message):
|
||||
|
||||
|
||||
async def main_settings_message(id, message):
|
||||
data = await rq.get_user_main_settings(id)
|
||||
try:
|
||||
data = await rq.get_user_main_settings(id)
|
||||
tg_id = id
|
||||
|
||||
await message.answer(f"""<b>Основные настройки</b>
|
||||
|
||||
<b>- Режим торговли:</b> {data['trading_mode']}
|
||||
<b>- Режим свитч:</b> {data['switch_mode_enabled']}
|
||||
<b>- Состояние свитча:</b> {data['switch_state']}
|
||||
<b>- Тип маржи:</b> {data['margin_type']}
|
||||
<b>- Размер кредитного плеча:</b> х{data['size_leverage']}
|
||||
<b>- Начальная ставка:</b> {data['starting_quantity']}
|
||||
<b>- Коэффициент мартингейла:</b> {data['martingale_factor']}
|
||||
<b>- Количество ставок в серии:</b> {data['martingale_step']}
|
||||
<b>- Максимальное количество ставок в серии:</b> {data['maximal_quantity']}
|
||||
""", parse_mode='html', reply_markup=inline_markup.main_settings_markup)
|
||||
data_main_stgs = await rq.get_user_main_settings(id)
|
||||
data_risk_stgs = await rq.get_user_risk_management_settings(id)
|
||||
client = await get_bybit_client(tg_id)
|
||||
symbol = await rq.get_symbol(tg_id)
|
||||
max_martingale_steps = (data_main_stgs or {}).get('maximal_quantity', 0)
|
||||
commission_fee = (data_risk_stgs or {}).get('commission_fee')
|
||||
starting_quantity = safe_float((data_main_stgs or {}).get('starting_quantity'))
|
||||
martingale_factor = safe_float((data_main_stgs or {}).get('martingale_factor'))
|
||||
fee_info = client.get_fee_rates(category='linear', symbol=symbol)
|
||||
leverage = safe_float((data_main_stgs or {}).get('size_leverage'))
|
||||
price = await get_price(tg_id, symbol=symbol)
|
||||
entry_price = safe_float(price)
|
||||
|
||||
if commission_fee == "Да":
|
||||
commission_fee_percent = safe_float(fee_info['result']['list'][0]['takerFeeRate'])
|
||||
else:
|
||||
commission_fee_percent = 0.0
|
||||
|
||||
total_budget = await calculate_total_budget(
|
||||
starting_quantity=starting_quantity,
|
||||
martingale_factor=martingale_factor,
|
||||
max_steps=max_martingale_steps,
|
||||
commission_fee_percent=commission_fee_percent,
|
||||
leverage=leverage,
|
||||
current_price=entry_price,
|
||||
)
|
||||
|
||||
await message.answer(f"""<b>Основные настройки</b>
|
||||
|
||||
<b>- Режим торговли:</b> {data['trading_mode']}
|
||||
<b>- Состояние свитча:</b> {data['switch_state']}
|
||||
<b>- Направление последней сделки:</b> {data['last_side']}
|
||||
<b>- Тип маржи:</b> {data['margin_type']}
|
||||
<b>- Размер кредитного плеча:</b> х{data['size_leverage']}
|
||||
<b>- Начальная ставка:</b> {data['starting_quantity']}
|
||||
<b>- Коэффициент мартингейла:</b> {data['martingale_factor']}
|
||||
<b>- Количество ставок в серии:</b> {data['martingale_step']}
|
||||
<b>- Максимальное количество ставок в серии:</b> {data['maximal_quantity']}
|
||||
|
||||
<b>- Требуемый бюджет:</b> {total_budget:.2f} USDT
|
||||
""", parse_mode='html', reply_markup=inline_markup.main_settings_markup)
|
||||
except PermissionError as e:
|
||||
logger.error("Authenticated endpoints require keys: %s", e)
|
||||
await message.answer("Вы не авторизованы.", reply_markup=inline_markup.connect_bybit_api_message)
|
||||
|
||||
|
||||
async def trading_mode_message(message, state):
|
||||
@@ -49,7 +86,7 @@ async def trading_mode_message(message, state):
|
||||
|
||||
<b>Шорт</b> — метод продажи активов, взятых в кредит, чтобы получить прибыль от снижения цены.
|
||||
|
||||
<b>Смарт</b> — автоматизированный режим, который подбирает оптимальную стратегию в зависимости от текущих рыночных условий.
|
||||
<b>Свитч</b> — динамическое переключение между торговыми режимами для максимизации эффективности.
|
||||
|
||||
<em>Выберите ниже для изменений:</em>
|
||||
""", parse_mode='html', reply_markup=inline_markup.trading_mode_markup)
|
||||
@@ -77,12 +114,19 @@ async def state_trading_mode(callback: CallbackQuery, state):
|
||||
|
||||
await state.clear()
|
||||
|
||||
case 'trade_mode_switch':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['trading_mode']} → Switch")
|
||||
await rq.update_trade_mode_user(id, 'Switch')
|
||||
await main_settings_message(id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
|
||||
case 'trade_mode_smart':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['trading_mode']} → Smart")
|
||||
await rq.update_trade_mode_user(id, 'Smart')
|
||||
await main_settings_message(id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
await state.clear()
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
|
||||
@@ -91,45 +135,27 @@ async def switch_mode_enabled_message(message, state):
|
||||
await state.set_state(update_main_settings.switch_mode_enabled)
|
||||
|
||||
await message.edit_text(
|
||||
"""<b>Свитч</b> — динамическое переключение между торговыми режимами для максимизации эффективности.
|
||||
f"""<b> Состояние свитча</b>
|
||||
|
||||
<b>По направлению</b> - по направлению последней сделки предыдущей серии
|
||||
<b>Против направления</b> - против направления последней сделки предыдущей серии
|
||||
|
||||
<em>По умолчанию при первом запуске бота, направление сделки установлено на "Buy".</em>
|
||||
<em>Выберите ниже для изменений:</em>""", parse_mode='html',
|
||||
reply_markup=inline_markup.buttons_on_off_markup_for_switch)
|
||||
|
||||
|
||||
@router_main_settings.callback_query(lambda c: c.data in ["clb_on_switch", "clb_off_switch"])
|
||||
async def state_switch_mode_enabled(callback: CallbackQuery, state):
|
||||
await callback.answer()
|
||||
tg_id = callback.from_user.id
|
||||
val = "Включить" if callback.data == "clb_on_switch" else "Выключить"
|
||||
if val == "Включить":
|
||||
await rq.update_switch_mode_enabled(tg_id, "Включено")
|
||||
await callback.answer(f"Включено")
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
else:
|
||||
await rq.update_switch_mode_enabled(tg_id, "Выключено")
|
||||
await callback.answer(f"Выключено")
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
await state.clear()
|
||||
|
||||
|
||||
@router_main_settings.callback_query(lambda c: c.data in ["clb_switch_state"])
|
||||
async def state_switch_mode_enabled(callback: CallbackQuery):
|
||||
await callback.answer()
|
||||
await callback.message.answer("Выберите состояние свитча:", reply_markup=inline_markup.switch_state_markup)
|
||||
reply_markup=inline_markup.switch_state_markup)
|
||||
|
||||
|
||||
@router_main_settings.callback_query(lambda c: c.data in ["clb_long_switch", "clb_short_switch"])
|
||||
async def state_switch_mode_enabled(callback: CallbackQuery, state):
|
||||
await callback.answer()
|
||||
tg_id = callback.from_user.id
|
||||
val = "Long" if callback.data == "clb_long_switch" else "Short"
|
||||
if val == "Long":
|
||||
await rq.update_switch_state(tg_id, "Long")
|
||||
val = "По направлению" if callback.data == "clb_long_switch" else "Против направления"
|
||||
if val == "По направлению":
|
||||
await rq.update_switch_state(tg_id, "По направлению")
|
||||
await callback.message.answer(f"Состояние свитча: {val}")
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
else:
|
||||
await rq.update_switch_state(tg_id, "Short")
|
||||
await rq.update_switch_state(tg_id, "Против направления")
|
||||
await callback.message.answer(f"Состояние свитча: {val}")
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
await state.clear()
|
||||
@@ -144,23 +170,47 @@ async def size_leverage_message(message, state):
|
||||
|
||||
@router_main_settings.message(update_main_settings.size_leverage)
|
||||
async def state_size_leverage(message: Message, state):
|
||||
try:
|
||||
leverage = float(message.text)
|
||||
if leverage <= 0:
|
||||
raise ValueError("Неверное значение")
|
||||
except ValueError:
|
||||
await message.answer(
|
||||
"Ошибка: пожалуйста, введите положительное число для кредитного плеча."
|
||||
"\nПопробуйте снова."
|
||||
)
|
||||
return
|
||||
|
||||
await state.update_data(size_leverage=message.text)
|
||||
|
||||
data = await state.get_data()
|
||||
data_settings = await rq.get_user_main_settings(message.from_user.id)
|
||||
tg_id = message.from_user.id
|
||||
symbol = await rq.get_symbol(tg_id)
|
||||
leverage = data['size_leverage']
|
||||
client = await get_bybit_client(tg_id)
|
||||
|
||||
if data['size_leverage'].isdigit() and int(data['size_leverage']) <= 100:
|
||||
await message.answer(f"✅ Изменено: {data_settings['size_leverage']} → {data['size_leverage']}")
|
||||
instruments_resp = client.get_instruments_info(category="linear", symbol=symbol)
|
||||
info = instruments_resp.get("result", {}).get("list", [])
|
||||
|
||||
await rq.update_size_leverange(message.from_user.id, data['size_leverage'])
|
||||
max_leverage = safe_float(info[0].get("leverageFilter", {}).get("maxLeverage", 0))
|
||||
|
||||
if safe_float(leverage) > max_leverage:
|
||||
await message.answer(
|
||||
f"Запрошенное кредитное плечо {leverage} превышает максимальное {max_leverage} для {symbol}. "
|
||||
f"Устанавливаю максимальное.",
|
||||
reply_markup=inline_markup.back_to_main,
|
||||
)
|
||||
logger.info(
|
||||
f"Запрошенное кредитное плечо {leverage} превышает максимальное {max_leverage} для {symbol}. Устанавливаю максимальное.")
|
||||
|
||||
await rq.update_size_leverange(message.from_user.id, max_leverage)
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
await message.answer(
|
||||
f'⛔️ Ошибка: ваше значение ({data['size_leverage']}) или выше лимита (100) или вы вводите неверные символы')
|
||||
|
||||
await message.answer(f"✅ Изменено: {leverage}")
|
||||
await rq.update_size_leverange(message.from_user.id, safe_float(leverage))
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
await state.clear()
|
||||
|
||||
|
||||
async def martingale_factor_message(message, state):
|
||||
@@ -213,45 +263,55 @@ async def margin_type_message(message, state):
|
||||
|
||||
@router_main_settings.callback_query(update_main_settings.margin_type)
|
||||
async def state_margin_type(callback: CallbackQuery, state):
|
||||
tg_id = callback.from_user.id
|
||||
api_key = await rq.get_bybit_api_key(tg_id)
|
||||
secret_key = await rq.get_bybit_secret_key(tg_id)
|
||||
data_settings = await rq.get_user_main_settings(tg_id)
|
||||
client = HTTP(api_key=api_key, api_secret=secret_key)
|
||||
try:
|
||||
active_positions = client.get_positions(category='linear', settleCoin='USDT')
|
||||
callback_data = callback.data
|
||||
if callback_data in ['margin_type_isolated', 'margin_type_cross']:
|
||||
tg_id = callback.from_user.id
|
||||
api_key = await rq.get_bybit_api_key(tg_id)
|
||||
secret_key = await rq.get_bybit_secret_key(tg_id)
|
||||
data_settings = await rq.get_user_main_settings(tg_id)
|
||||
symbol = await rq.get_symbol(tg_id)
|
||||
client = HTTP(api_key=api_key, api_secret=secret_key)
|
||||
try:
|
||||
active_positions = client.get_positions(category='linear', settleCoin="USDT")
|
||||
|
||||
positions = active_positions.get('result', {}).get('list', [])
|
||||
except Exception as e:
|
||||
logger.error(f"error: {e}")
|
||||
positions = []
|
||||
positions = active_positions.get('result', {}).get('list', [])
|
||||
except Exception as e:
|
||||
logger.error(f"error: {e}")
|
||||
positions = []
|
||||
|
||||
for pos in positions:
|
||||
size = pos.get('size')
|
||||
if float(size) > 0:
|
||||
await callback.answer(
|
||||
"⚠️ Маржинальный режим нельзя менять при открытой позиции",
|
||||
show_alert=True
|
||||
)
|
||||
return
|
||||
try:
|
||||
match callback.data:
|
||||
case 'margin_type_isolated':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['margin_type']} → Isolated")
|
||||
for pos in positions:
|
||||
size = pos.get('size')
|
||||
if float(size) > 0:
|
||||
await callback.answer(
|
||||
"⚠️ Маржинальный режим нельзя менять при открытой позиции"
|
||||
)
|
||||
return
|
||||
|
||||
await rq.update_margin_type(tg_id, 'Isolated')
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
try:
|
||||
match callback.data:
|
||||
case 'margin_type_isolated':
|
||||
await callback.answer()
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['margin_type']} → Isolated")
|
||||
|
||||
await state.clear()
|
||||
case 'margin_type_cross':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['margin_type']} → Cross")
|
||||
await rq.update_margin_type(tg_id, 'Isolated')
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
|
||||
await rq.update_margin_type(tg_id, 'Cross')
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
await state.clear()
|
||||
case 'margin_type_cross':
|
||||
await callback.answer()
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['margin_type']} → Cross")
|
||||
|
||||
await state.clear()
|
||||
except Exception as e:
|
||||
logger.error(f"error: {e}")
|
||||
await rq.update_margin_type(tg_id, 'Cross')
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
except Exception as e:
|
||||
logger.error(f"error: {e}")
|
||||
else:
|
||||
await callback.answer()
|
||||
await main_settings_message(callback.from_user.id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
|
||||
|
||||
async def starting_quantity_message(message, state):
|
||||
|
Reference in New Issue
Block a user