Deleted
This commit is contained in:
@@ -1,38 +0,0 @@
|
||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
|
||||
import app.telegram.database.requests as rq
|
||||
|
||||
async def reg_new_user_default_additional_settings(id, message):
|
||||
tg_id = id
|
||||
|
||||
await rq.set_new_user_default_additional_settings(tg_id)
|
||||
|
||||
async def main_settings_message(id, message):
|
||||
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)
|
||||
|
||||
async def save_pattern_message(message, state):
|
||||
text = '''<b>Сохранение шаблона</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
|
||||
|
||||
async def auto_start_message(message, state):
|
||||
text = '''<b>Автозапуск</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
|
||||
|
||||
async def notifications_message(message, state):
|
||||
text = '''<b>Уведомления</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_on_off_markup)
|
@@ -1,208 +0,0 @@
|
||||
import logging.config
|
||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
from aiogram import Router, F
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
from aiogram.fsm.context import FSMContext
|
||||
import app.telegram.database.requests as rq
|
||||
from app.states.States import condition_settings
|
||||
from app.states.States import state_limit_price, state_update_entry_type, state_trigger_price
|
||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||
|
||||
logging.config.dictConfig(LOGGING_CONFIG)
|
||||
logger = logging.getLogger("condition_settings")
|
||||
|
||||
condition_settings_router = Router()
|
||||
|
||||
|
||||
async def reg_new_user_default_condition_settings(id):
|
||||
tg_id = id
|
||||
|
||||
trigger = await rq.get_for_registration_trigger(tg_id)
|
||||
|
||||
await rq.set_new_user_default_condition_settings(tg_id, trigger)
|
||||
|
||||
|
||||
async def main_settings_message(id, message):
|
||||
data = await rq.get_user_main_settings(id)
|
||||
entry_order_type = data['entry_order_type']
|
||||
|
||||
if entry_order_type == "Market":
|
||||
entry_order_type_rus = "Маркет"
|
||||
elif entry_order_type == "Limit":
|
||||
entry_order_type_rus = "Лимит"
|
||||
else:
|
||||
entry_order_type_rus = "Условный"
|
||||
|
||||
trigger_price = data['trigger_price'] or 0.0
|
||||
limit_price = data['limit_order_price'] or 0.0
|
||||
|
||||
text = f""" <b>Условия запуска</b>
|
||||
<b>- Таймер: </b> установить таймер / удалить таймер
|
||||
<b>- Тип позиции:</b> {entry_order_type_rus}
|
||||
<b>- Триггер цена: </b> {trigger_price:,.4f}
|
||||
<b>- Лимит цена: </b> {limit_price:,.4f}
|
||||
"""
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.condition_settings_markup)
|
||||
|
||||
|
||||
async def timer_message(id, message: Message, state: FSMContext):
|
||||
await state.set_state(condition_settings.timer)
|
||||
|
||||
timer_info = await rq.get_user_timer(id)
|
||||
if timer_info is None:
|
||||
await message.answer("Таймер не установлен.", reply_markup=inline_markup.timer_markup)
|
||||
return
|
||||
|
||||
await message.answer(
|
||||
f"Таймер установлен на: {timer_info['timer_minutes']} мин\n",
|
||||
reply_markup=inline_markup.timer_markup
|
||||
)
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(F.data == "clb_set_timer")
|
||||
async def set_timer_callback(callback: CallbackQuery, state: FSMContext):
|
||||
await state.set_state(condition_settings.timer) # состояние для ввода времени
|
||||
await callback.message.answer("Введите время работы в минутах (например, 60):", reply_markup=inline_markup.cancel)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@condition_settings_router.message(condition_settings.timer)
|
||||
async def process_timer_input(message: Message, state: FSMContext):
|
||||
try:
|
||||
minutes = int(message.text)
|
||||
if minutes <= 0:
|
||||
await message.reply("Введите число больше нуля.")
|
||||
return
|
||||
|
||||
await rq.update_user_timer(message.from_user.id, minutes)
|
||||
logger.info("Timer set for user %s: %s minutes", message.from_user.id, minutes)
|
||||
await timer_message(message.from_user.id, message, state)
|
||||
await state.clear()
|
||||
except ValueError:
|
||||
await message.reply("Пожалуйста, введите корректное число.")
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(F.data == "clb_delete_timer")
|
||||
async def delete_timer_callback(callback: CallbackQuery, state: FSMContext):
|
||||
await state.clear()
|
||||
await rq.update_user_timer(callback.from_user.id, 0)
|
||||
logger.info("Timer deleted for user %s", callback.from_user.id)
|
||||
await timer_message(callback.from_user.id, callback.message, state)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(F.data == 'clb_update_entry_type')
|
||||
async def update_entry_type_message(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
Запрашивает у пользователя тип входа в позицию (Market или Limit).
|
||||
"""
|
||||
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()
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(lambda c: c.data and c.data.startswith('entry_order_type:'))
|
||||
async def entry_order_type_callback(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
"""
|
||||
Обработка выбора типа входа в позицию.
|
||||
Если Limit, запрашивает цену лимитного ордера.
|
||||
Если Market — обновляет настройки.
|
||||
"""
|
||||
order_type = callback.data.split(':')[1]
|
||||
|
||||
if order_type not in ['Market', 'Limit']:
|
||||
await callback.answer("Ошибка выбора", show_alert=True)
|
||||
return
|
||||
|
||||
if order_type == 'Limit':
|
||||
order_type_rus = 'Лимит'
|
||||
else:
|
||||
order_type_rus = 'Маркет'
|
||||
try:
|
||||
await state.update_data(entry_order_type=order_type)
|
||||
await rq.update_entry_order_type(callback.from_user.id, order_type)
|
||||
await callback.message.answer(f"Выбран тип входа {order_type_rus}",
|
||||
reply_markup=inline_markup.back_to_condition_settings)
|
||||
await callback.answer()
|
||||
except Exception as e:
|
||||
logger.error("Произошла ошибка при обновлении типа входа в позицию: %s", e)
|
||||
await callback.message.answer("Произошла ошибка при обновлении типа входа в позицию",
|
||||
reply_markup=inline_markup.back_to_condition_settings)
|
||||
await state.clear()
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(F.data == 'clb_change_limit_price')
|
||||
async def set_limit_price_callback(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
await state.set_state(state_limit_price.price)
|
||||
await callback.message.answer("Введите цену лимитного ордера:", reply_markup=inline_markup.cancel)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@condition_settings_router.message(state_limit_price.price)
|
||||
async def process_limit_price_input(message: Message, state: FSMContext) -> None:
|
||||
try:
|
||||
price = float(message.text)
|
||||
await state.update_data(price=price)
|
||||
await rq.update_limit_price(tg_id=message.from_user.id, price=price)
|
||||
await message.answer(f"Цена лимитного ордера установлена: {price}", reply_markup=inline_markup.back_to_condition_settings)
|
||||
await state.clear()
|
||||
except ValueError:
|
||||
await message.reply("Пожалуйста, введите корректную цену.")
|
||||
|
||||
|
||||
@condition_settings_router.callback_query(F.data == 'clb_change_trigger_price')
|
||||
async def change_trigger_price_callback(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
await state.set_state(state_trigger_price.price)
|
||||
await callback.message.answer("Введите цену триггера:", reply_markup=inline_markup.cancel)
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@condition_settings_router.message(state_trigger_price.price)
|
||||
async def process_trigger_price_input(message: Message, state: FSMContext) -> None:
|
||||
try:
|
||||
price = float(message.text)
|
||||
await state.update_data(price=price)
|
||||
await rq.update_trigger_price(tg_id=message.from_user.id, price=price)
|
||||
await message.answer(f"Цена триггера установлена: {price}", reply_markup=inline_markup.back_to_condition_settings)
|
||||
await state.clear()
|
||||
except ValueError:
|
||||
await message.reply("Пожалуйста, введите корректную цену.")
|
||||
|
||||
|
||||
|
||||
async def filter_volatility_message(message, state):
|
||||
text = '''Фильтр волатильности
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_on_off_markup)
|
||||
|
||||
|
||||
async def external_cues_message(message, state):
|
||||
text = '''<b>Внешние сигналы</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=None)
|
||||
|
||||
|
||||
async def trading_cues_message(message, state):
|
||||
text = '''<b>Использование сигналов</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
|
||||
|
||||
|
||||
async def webhook_message(message, state):
|
||||
text = '''Скиньте ссылку на <b>webhook</b> (если есть trading view): '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html')
|
||||
|
||||
|
||||
async def ai_analytics_message(message, state):
|
||||
text = '''<b>ИИ - Аналитика</b>
|
||||
|
||||
Описание... '''
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.buttons_yes_no_markup)
|
@@ -1,29 +0,0 @@
|
||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
import app.telegram.Keyboards.reply_keyboards as reply_markup
|
||||
|
||||
async def start_message(message):
|
||||
username = ''
|
||||
|
||||
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>! 👋""", parse_mode='html')
|
||||
await message.answer("Добро пожаловать в чат-робот для автоматизации трейдинга — вашего надежного помощника для анализа рынка и принятия взвешенных решений.",
|
||||
parse_mode='html', reply_markup=inline_markup.start_markup)
|
||||
|
||||
async def profile_message(username, message):
|
||||
await message.answer(f""" <b>@{username}</b>
|
||||
|
||||
Баланс
|
||||
⭐️ 0
|
||||
|
||||
""", parse_mode='html', reply_markup=inline_markup.settings_markup)
|
||||
|
||||
async def check_profile_message(message, username):
|
||||
await message.answer(f'С возвращением, {username}!', reply_markup=reply_markup.base_buttons_markup)
|
||||
|
||||
async def settings_message(message):
|
||||
await message.edit_text("Выберите что настроить", reply_markup=inline_markup.special_settings_markup)
|
@@ -1,375 +0,0 @@
|
||||
from aiogram import Router
|
||||
import logging.config
|
||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
|
||||
import app.telegram.database.requests as rq
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
|
||||
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
|
||||
|
||||
logging.config.dictConfig(LOGGING_CONFIG)
|
||||
logger = logging.getLogger("main_settings")
|
||||
|
||||
router_main_settings = Router()
|
||||
|
||||
|
||||
def is_number(value: str) -> bool:
|
||||
"""
|
||||
Checks if a given string represents a number.
|
||||
|
||||
Args:
|
||||
value (str): The string to check.
|
||||
|
||||
Returns:
|
||||
bool: True if the string represents a number, False otherwise.
|
||||
"""
|
||||
try:
|
||||
# Convert the string to a float
|
||||
num = float(value)
|
||||
# Check if the number is positive
|
||||
if num <= 0:
|
||||
return False
|
||||
# Check if the string contains "+" or "-"
|
||||
if "+" in value or "-" in value:
|
||||
return False
|
||||
# Check if the string contains only digits
|
||||
allowed_chars = set("0123456789.")
|
||||
if not all(ch in allowed_chars for ch in value):
|
||||
return False
|
||||
return True
|
||||
except ValueError:
|
||||
return False
|
||||
|
||||
|
||||
async def reg_new_user_default_main_settings(id, message):
|
||||
tg_id = id
|
||||
|
||||
trading_mode = await rq.get_for_registration_trading_mode()
|
||||
margin_type = await rq.get_for_registration_margin_type()
|
||||
|
||||
await rq.set_new_user_default_main_settings(tg_id, trading_mode, margin_type)
|
||||
|
||||
|
||||
async def main_settings_message(id, message):
|
||||
try:
|
||||
data = await rq.get_user_main_settings(id)
|
||||
tg_id = id
|
||||
|
||||
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)
|
||||
|
||||
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,
|
||||
)
|
||||
|
||||
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):
|
||||
await state.set_state(update_main_settings.trading_mode)
|
||||
|
||||
await message.edit_text("""<b>Режим торговли</b>
|
||||
|
||||
<b>Лонг</b> — стратегия, ориентированная на покупку актива с целью заработать на повышении его стоимости.
|
||||
|
||||
<b>Шорт</b> — метод продажи активов, взятых в кредит, чтобы получить прибыль от снижения цены.
|
||||
|
||||
<b>Свитч</b> — динамическое переключение между торговыми режимами для максимизации эффективности.
|
||||
|
||||
<em>Выберите ниже для изменений:</em>
|
||||
""", parse_mode='html', reply_markup=inline_markup.trading_mode_markup)
|
||||
|
||||
|
||||
@router_main_settings.callback_query(update_main_settings.trading_mode)
|
||||
async def state_trading_mode(callback: CallbackQuery, state):
|
||||
await callback.answer()
|
||||
|
||||
id = callback.from_user.id
|
||||
data_settings = await rq.get_user_main_settings(id)
|
||||
|
||||
try:
|
||||
match callback.data:
|
||||
case 'trade_mode_long':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['trading_mode']} → Long")
|
||||
await rq.update_trade_mode_user(id, 'Long')
|
||||
await main_settings_message(id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
case 'trade_mode_short':
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['trading_mode']} → Short")
|
||||
await rq.update_trade_mode_user(id, 'Short')
|
||||
await main_settings_message(id, callback.message)
|
||||
|
||||
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()
|
||||
except Exception as e:
|
||||
logger.error("Ошибка при обновлении режима торговли: %s", e)
|
||||
|
||||
|
||||
async def switch_mode_enabled_message(message, state):
|
||||
await state.set_state(update_main_settings.switch_mode_enabled)
|
||||
|
||||
await message.edit_text(
|
||||
f"""<b> Состояние свитча</b>
|
||||
|
||||
<b>По направлению</b> - по направлению последней сделки предыдущей серии
|
||||
<b>Против направления</b> - против направления последней сделки предыдущей серии
|
||||
|
||||
<em>По умолчанию при первом запуске бота, направление сделки установлено на "Buy".</em>
|
||||
<em>Выберите ниже для изменений:</em>""", parse_mode='html',
|
||||
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 = "По направлению" 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, "Против направления")
|
||||
await callback.message.answer(f"Состояние свитча: {val}")
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
await state.clear()
|
||||
|
||||
|
||||
async def size_leverage_message(message, state):
|
||||
await state.set_state(update_main_settings.size_leverage)
|
||||
|
||||
await message.edit_text("Введите размер <b>кредитного плеча</b> (от 1 до 100): ", parse_mode='html',
|
||||
reply_markup=inline_markup.back_btn_list_settings_markup)
|
||||
|
||||
|
||||
@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()
|
||||
tg_id = message.from_user.id
|
||||
symbol = await rq.get_symbol(tg_id)
|
||||
leverage = data['size_leverage']
|
||||
client = await get_bybit_client(tg_id)
|
||||
|
||||
instruments_resp = client.get_instruments_info(category="linear", symbol=symbol)
|
||||
info = instruments_resp.get("result", {}).get("list", [])
|
||||
|
||||
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"✅ Изменено: {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):
|
||||
await state.set_state(update_main_settings.martingale_factor)
|
||||
|
||||
await message.edit_text("Введите <b>коэффициент Мартингейла:</b>", parse_mode='html',
|
||||
reply_markup=inline_markup.back_btn_list_settings_markup)
|
||||
|
||||
|
||||
@router_main_settings.message(update_main_settings.martingale_factor)
|
||||
async def state_martingale_factor(message: Message, state):
|
||||
await state.update_data(martingale_factor=message.text)
|
||||
|
||||
data = await state.get_data()
|
||||
data_settings = await rq.get_user_main_settings(message.from_user.id)
|
||||
|
||||
if data['martingale_factor'].isdigit() and int(data['martingale_factor']) <= 100:
|
||||
await message.answer(f"✅ Изменено: {data_settings['martingale_factor']} → {data['martingale_factor']}")
|
||||
|
||||
await rq.update_martingale_factor(message.from_user.id, data['martingale_factor'])
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
val = data['martingale_factor']
|
||||
await message.answer(
|
||||
f"⛔️ Ошибка: ваше значение ({val}) или выше лимита (100) или вы вводите неверные символы")
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
|
||||
async def margin_type_message(message, state):
|
||||
await state.set_state(update_main_settings.margin_type)
|
||||
|
||||
await message.edit_text("""<b>Тип маржи</b>
|
||||
|
||||
<b>Изолированная маржа</b>
|
||||
Этот тип маржи позволяет ограничить риск конкретной позиции.
|
||||
При использовании изолированной маржи вы выделяете определённую сумму средств только для одной позиции.
|
||||
Если позиция начинает приносить убытки, ваши потери ограничиваются этой суммой,
|
||||
и остальные средства на счёте не затрагиваются.
|
||||
|
||||
<b>Кросс-маржа</b>
|
||||
Кросс-маржа объединяет весь маржинальный баланс на счёте и использует все доступные средства для поддержания открытых позиций.
|
||||
В случае убытков средства с других позиций или баланса автоматически покрывают дефицит,
|
||||
снижая риск ликвидации, но увеличивая общий риск потери капитала.
|
||||
|
||||
<em>Выберите ниже для изменений:</em>
|
||||
""", parse_mode='html', reply_markup=inline_markup.margin_type_markup)
|
||||
|
||||
|
||||
@router_main_settings.callback_query(update_main_settings.margin_type)
|
||||
async def state_margin_type(callback: CallbackQuery, state):
|
||||
callback_data = callback.data
|
||||
if callback_data in ['margin_type_isolated', 'margin_type_cross']:
|
||||
tg_id = callback.from_user.id
|
||||
data_settings = await rq.get_user_main_settings(tg_id)
|
||||
|
||||
try:
|
||||
match callback.data:
|
||||
case 'margin_type_isolated':
|
||||
await callback.answer()
|
||||
await callback.message.answer(f"✅ Изменено: {data_settings['margin_type']} → Isolated")
|
||||
|
||||
await rq.update_margin_type(tg_id, 'Isolated')
|
||||
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 rq.update_margin_type(tg_id, 'Cross')
|
||||
await main_settings_message(tg_id, callback.message)
|
||||
|
||||
await state.clear()
|
||||
except Exception as e:
|
||||
logger.error("Ошибка при изменении типа маржи: %s", 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):
|
||||
await state.set_state(update_main_settings.starting_quantity)
|
||||
|
||||
await message.edit_text("Введите <b>ставку:</b>", parse_mode='html',
|
||||
reply_markup=inline_markup.back_btn_list_settings_markup)
|
||||
|
||||
|
||||
@router_main_settings.message(update_main_settings.starting_quantity)
|
||||
async def state_starting_quantity(message: Message, state):
|
||||
await state.update_data(starting_quantity=message.text)
|
||||
|
||||
data = await state.get_data()
|
||||
data_settings = await rq.get_user_main_settings(message.from_user.id)
|
||||
|
||||
if is_number(data['starting_quantity']):
|
||||
await message.answer(f"✅ Изменено: {data_settings['starting_quantity']} → {data['starting_quantity']}")
|
||||
|
||||
await rq.update_starting_quantity(message.from_user.id, data['starting_quantity'])
|
||||
await rq.update_base_quantity(tg_id=message.from_user.id, num=data['starting_quantity'])
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
await message.answer("⛔️ Ошибка: вы вводите неверные символы")
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
|
||||
async def maximum_quantity_message(message, state):
|
||||
await state.set_state(update_main_settings.maximal_quantity)
|
||||
|
||||
await message.edit_text("Введите максимальное количество серии ставок:",
|
||||
reply_markup=inline_markup.back_btn_list_settings_markup)
|
||||
|
||||
|
||||
@router_main_settings.message(update_main_settings.maximal_quantity)
|
||||
async def state_maximal_quantity(message: Message, state):
|
||||
await state.update_data(maximal_quantity=message.text)
|
||||
|
||||
data = await state.get_data()
|
||||
data_settings = await rq.get_user_main_settings(message.from_user.id)
|
||||
|
||||
if data['maximal_quantity'].isdigit() and int(data['maximal_quantity']) <= 100:
|
||||
await message.answer(f"✅ Изменено: {data_settings['maximal_quantity']} → {data['maximal_quantity']}")
|
||||
|
||||
await rq.update_maximal_quantity(message.from_user.id, data['maximal_quantity'])
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
val = data['maximal_quantity']
|
||||
await message.answer(
|
||||
f'⛔️ Ошибка: ваше значение ({val}) или выше лимита (100) или вы вводите неверные символы')
|
||||
logger.error(f'⛔️ Ошибка: ваше значение ({val}) или выше лимита (100) или вы вводите неверные символы')
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
@@ -1,160 +0,0 @@
|
||||
from aiogram import Router
|
||||
import app.telegram.Keyboards.inline_keyboards as inline_markup
|
||||
import logging.config
|
||||
import app.telegram.database.requests as rq
|
||||
from aiogram.types import Message, CallbackQuery
|
||||
|
||||
from app.states.States import update_risk_management_settings
|
||||
|
||||
from logger_helper.logger_helper import LOGGING_CONFIG
|
||||
|
||||
logging.config.dictConfig(LOGGING_CONFIG)
|
||||
logger = logging.getLogger("risk_management_settings")
|
||||
|
||||
router_risk_management_settings = Router()
|
||||
|
||||
|
||||
async def reg_new_user_default_risk_management_settings(id, message):
|
||||
tg_id = id
|
||||
|
||||
await rq.set_new_user_default_risk_management_settings(tg_id)
|
||||
|
||||
|
||||
async def main_settings_message(id, message):
|
||||
data = await rq.get_user_risk_management_settings(id)
|
||||
|
||||
text = f"""<b>Риск менеджмент</b>,
|
||||
|
||||
<b>- Процент изменения цены для фиксации прибыли:</b> {data.get('price_profit', 0)}%
|
||||
<b>- Процент изменения цены для фиксации убытков:</b> {data.get('price_loss', 0)}%
|
||||
<b>- Максимальный риск на сделку (в % от баланса):</b> {data.get('max_risk_deal', 0)}%
|
||||
<b>- Комиссия биржи для расчета прибыли:</b> {data.get('commission_fee', "Да")}
|
||||
"""
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.risk_management_settings_markup)
|
||||
|
||||
|
||||
async def price_profit_message(message, state):
|
||||
await state.set_state(update_risk_management_settings.price_profit)
|
||||
|
||||
text = 'Введите число изменения цены для фиксации прибыли: '
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.cancel)
|
||||
|
||||
|
||||
@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()
|
||||
data_settings = await rq.get_user_risk_management_settings(message.from_user.id)
|
||||
|
||||
if data['price_profit'].isdigit() and int(data['price_profit']) <= 100:
|
||||
await message.answer(f"✅ Изменено: {data_settings['price_profit']}% → {data['price_profit']}%")
|
||||
|
||||
await rq.update_price_profit(message.from_user.id, data['price_profit'])
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
val = data['price_profit']
|
||||
await message.answer(
|
||||
f'⛔️ Ошибка: ваше значение ({val}%) или выше лимита (100) или вы вводите неверные символы')
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
|
||||
async def price_loss_message(message, state):
|
||||
await state.set_state(update_risk_management_settings.price_loss)
|
||||
|
||||
text = 'Введите число изменения цены для фиксации убытков: '
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.cancel)
|
||||
|
||||
|
||||
@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()
|
||||
data_settings = await rq.get_user_risk_management_settings(message.from_user.id)
|
||||
|
||||
if data['price_loss'].isdigit() and int(data['price_loss']) <= 100:
|
||||
new_price_loss = int(data['price_loss'])
|
||||
old_price_loss = int(data_settings.get('price_loss', 0))
|
||||
|
||||
current_price_profit = data_settings.get('price_profit')
|
||||
# Пробуем перевести price_profit в число, если это возможно
|
||||
try:
|
||||
current_price_profit_num = int(current_price_profit)
|
||||
except Exception as e:
|
||||
logger.error(e)
|
||||
current_price_profit_num = 0
|
||||
|
||||
# Флаг, если price_profit изначально равен 0 или совпадает со старым стоп-лоссом
|
||||
should_update_profit = (current_price_profit_num == 0) or (current_price_profit_num == abs(old_price_loss))
|
||||
|
||||
# Обновляем стоп-лосс
|
||||
await rq.update_price_loss(message.from_user.id, new_price_loss)
|
||||
|
||||
# Если нужно, меняем тейк-профит
|
||||
if should_update_profit:
|
||||
new_price_profit = abs(new_price_loss)
|
||||
await rq.update_price_profit(message.from_user.id, new_price_profit)
|
||||
await message.answer(f"✅ Стоп-лосс изменён: {old_price_loss}% → {new_price_loss}%\n"
|
||||
f"Тейк-профит автоматически установлен в: {new_price_profit}%")
|
||||
else:
|
||||
await message.answer(f"✅ Стоп-лосс изменён: {old_price_loss}% → {new_price_loss}%")
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
await state.clear()
|
||||
else:
|
||||
val = data['price_loss']
|
||||
await message.answer(
|
||||
f'⛔️ Ошибка: ваше значение ({val}%) выше лимита (100) или содержит неверные символы')
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
|
||||
async def max_risk_deal_message(message, state):
|
||||
await state.set_state(update_risk_management_settings.max_risk_deal)
|
||||
|
||||
text = 'Введите число (процент от баланса) для изменения максимального риска на сделку: '
|
||||
|
||||
await message.answer(text=text, parse_mode='html', reply_markup=inline_markup.cancel)
|
||||
|
||||
|
||||
@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()
|
||||
data_settings = await rq.get_user_risk_management_settings(message.from_user.id)
|
||||
|
||||
if data['max_risk_deal'].isdigit() and int(data['max_risk_deal']) <= 100:
|
||||
await message.answer(f"✅ Изменено: {data_settings['max_risk_deal']}% → {data['max_risk_deal']}%")
|
||||
|
||||
await rq.update_max_risk_deal(message.from_user.id, data['max_risk_deal'])
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
await state.clear()
|
||||
else:
|
||||
val = data['max_risk_deal']
|
||||
await message.answer(
|
||||
f'⛔️ Ошибка: ваше значение ({val}%) или выше лимита (100) или вы вводите неверные символы')
|
||||
|
||||
await main_settings_message(message.from_user.id, message)
|
||||
|
||||
|
||||
async def commission_fee_message(message, state):
|
||||
await state.set_state(update_risk_management_settings.commission_fee)
|
||||
await message.answer(text="Хотите учитывать комиссию биржи:", parse_mode='html',
|
||||
reply_markup=inline_markup.buttons_yes_no_markup)
|
||||
|
||||
|
||||
@router_risk_management_settings.callback_query(lambda c: c.data in ["clb_yes", "clb_no"])
|
||||
async def process_commission_fee_callback(callback: CallbackQuery, state):
|
||||
val = "Да" if callback.data == "clb_yes" else "Нет"
|
||||
await rq.update_commission_fee(callback.from_user.id, val)
|
||||
await callback.message.answer(f"✅ Изменено: {val}")
|
||||
await callback.answer()
|
||||
await main_settings_message(callback.from_user.id, callback.message)
|
||||
await state.clear()
|
Reference in New Issue
Block a user