07.4.3.17 — Unified Active Screen Lifecycle
This commit is contained in:
@@ -7,12 +7,13 @@ from aiogram.fsm.context import FSMContext
|
||||
from aiogram.types import CallbackQuery, InlineKeyboardMarkup, Message
|
||||
from aiogram.utils.keyboard import InlineKeyboardBuilder
|
||||
|
||||
from src.core.system_status import build_system_text, get_system_snapshot, has_system_alerts
|
||||
from src.core.config import load_settings
|
||||
from src.core.constants import APP_NAME, APP_VERSION
|
||||
from src.trading.journal.service import JournalService
|
||||
from src.core.system_status import build_system_text, get_system_snapshot, has_system_alerts
|
||||
from src.telegram.live.active_screen import ActiveScreenManager
|
||||
from src.telegram.live.runner import LiveScreenRunner, ScreenRegistry, StaticScreen
|
||||
from src.trading.auto.service import AutoTradeService
|
||||
from src.trading.auto.runner import AutoTradeRunner
|
||||
from src.trading.journal.service import JournalService
|
||||
|
||||
|
||||
router = Router(name="system")
|
||||
@@ -35,6 +36,57 @@ def _system_alert_keyboard() -> InlineKeyboardMarkup:
|
||||
return builder.as_markup()
|
||||
|
||||
|
||||
def _register_system_screen(message: Message, screen: str = "system") -> None:
|
||||
LiveScreenRunner.unregister_message(
|
||||
chat_id=message.chat.id,
|
||||
message_id=message.message_id,
|
||||
)
|
||||
ScreenRegistry.unregister_message(
|
||||
chat_id=message.chat.id,
|
||||
message_id=message.message_id,
|
||||
)
|
||||
|
||||
ScreenRegistry.register_screen(
|
||||
StaticScreen(
|
||||
screen=screen,
|
||||
bot=message.bot,
|
||||
chat_id=message.chat.id,
|
||||
message_id=message.message_id,
|
||||
)
|
||||
)
|
||||
|
||||
ActiveScreenManager.register(
|
||||
screen=screen,
|
||||
message=message,
|
||||
)
|
||||
|
||||
|
||||
async def _prepare_system_from_message(message: Message, screen: str = "system") -> None:
|
||||
await ActiveScreenManager.prepare_new_screen(
|
||||
screen=screen,
|
||||
bot=message.bot,
|
||||
chat_id=message.chat.id,
|
||||
)
|
||||
|
||||
|
||||
async def _prepare_system_from_callback(
|
||||
callback: CallbackQuery,
|
||||
screen: str = "system",
|
||||
) -> bool:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
return False
|
||||
|
||||
await ActiveScreenManager.prepare_new_screen(
|
||||
screen=screen,
|
||||
bot=callback.message.bot,
|
||||
chat_id=callback.message.chat.id,
|
||||
keep_message_id=callback.message.message_id,
|
||||
)
|
||||
|
||||
return True
|
||||
|
||||
|
||||
async def _render_system_screen(
|
||||
target_message: Message,
|
||||
*,
|
||||
@@ -43,8 +95,6 @@ async def _render_system_screen(
|
||||
chat_id: int | None,
|
||||
action: str,
|
||||
) -> None:
|
||||
AutoTradeRunner.set_current_screen("system")
|
||||
|
||||
journal = JournalService()
|
||||
|
||||
journal.log_ui_info(
|
||||
@@ -96,14 +146,19 @@ async def _render_system_screen(
|
||||
|
||||
if edit_mode:
|
||||
await target_message.edit_text(text, reply_markup=reply_markup)
|
||||
else:
|
||||
await target_message.answer(text, reply_markup=reply_markup)
|
||||
_register_system_screen(target_message, screen="system")
|
||||
return
|
||||
|
||||
sent_message = await target_message.answer(text, reply_markup=reply_markup)
|
||||
_register_system_screen(sent_message, screen="system")
|
||||
|
||||
|
||||
@router.message(F.text.in_({"🖥️ Система"}))
|
||||
async def open_system(message: Message, state: FSMContext) -> None:
|
||||
await state.clear()
|
||||
|
||||
await _prepare_system_from_message(message, screen="system")
|
||||
|
||||
user_id = message.from_user.id if message.from_user else None
|
||||
chat_id = message.chat.id if message.chat else None
|
||||
|
||||
@@ -120,8 +175,7 @@ async def open_system(message: Message, state: FSMContext) -> None:
|
||||
async def retry_system(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
await state.clear()
|
||||
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="system"):
|
||||
return
|
||||
|
||||
user_id = callback.from_user.id if callback.from_user else None
|
||||
@@ -139,8 +193,7 @@ async def retry_system(callback: CallbackQuery, state: FSMContext) -> None:
|
||||
|
||||
@router.callback_query(F.data == "system:management")
|
||||
async def open_system_management(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="system"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -155,29 +208,18 @@ async def open_system_management(callback: CallbackQuery) -> None:
|
||||
builder.button(text="🌍 Общие", callback_data="settings:general")
|
||||
builder.button(text="📒 Журнал", callback_data="settings:journal")
|
||||
builder.button(text="⬅️ Назад", callback_data="system:back")
|
||||
|
||||
builder.adjust(2, 2, 1)
|
||||
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="system")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto")
|
||||
async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
AutoTradeRunner.unregister_screen(
|
||||
chat_id=callback.message.chat.id,
|
||||
message_id=callback.message.message_id,
|
||||
)
|
||||
|
||||
state = AutoTradeService().get_state()
|
||||
|
||||
strategy_map = {
|
||||
@@ -192,10 +234,7 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
leverage_ready = state.leverage is not None
|
||||
|
||||
is_trend_strategy = (state.strategy or "").upper() == "TREND"
|
||||
sl_ready = (
|
||||
state.stop_loss_percent is not None
|
||||
and state.stop_loss_percent > 0
|
||||
)
|
||||
sl_ready = state.stop_loss_percent is not None and state.stop_loss_percent > 0
|
||||
|
||||
is_configured = (
|
||||
strategy_ready
|
||||
@@ -206,7 +245,6 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
)
|
||||
|
||||
strategy = strategy_map.get(state.strategy or "", "—")
|
||||
|
||||
symbol = "—"
|
||||
|
||||
if state.symbol:
|
||||
@@ -219,9 +257,8 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
if base.endswith(suffix) and len(base) > len(suffix):
|
||||
base = base[: -len(suffix)]
|
||||
break
|
||||
|
||||
symbol = base
|
||||
|
||||
|
||||
risk = f"{state.risk_percent:.1f}%" if state.risk_percent is not None else "—"
|
||||
leverage = f"x{state.leverage:g}" if state.leverage is not None else "—"
|
||||
max_reserved = (
|
||||
@@ -229,23 +266,9 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
if state.max_reserved_balance_percent is not None
|
||||
else "off"
|
||||
)
|
||||
sl = (
|
||||
f"{state.stop_loss_percent:g}%"
|
||||
if state.stop_loss_percent is not None
|
||||
else "off"
|
||||
)
|
||||
|
||||
tp = (
|
||||
f"{state.take_profit_percent:g}%"
|
||||
if state.take_profit_percent is not None
|
||||
else "off"
|
||||
)
|
||||
|
||||
ml = (
|
||||
f"{state.max_loss_usd:g} USD"
|
||||
if state.max_loss_usd is not None
|
||||
else "off"
|
||||
)
|
||||
sl = f"{state.stop_loss_percent:g}%" if state.stop_loss_percent is not None else "off"
|
||||
tp = f"{state.take_profit_percent:g}%" if state.take_profit_percent is not None else "off"
|
||||
ml = f"{state.max_loss_usd:g} USD" if state.max_loss_usd is not None else "off"
|
||||
|
||||
strategy_icon = "✅" if strategy_ready else "⚠️"
|
||||
symbol_icon = "✅" if symbol_ready else "⚠️"
|
||||
@@ -268,11 +291,7 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
f"✅ Max Loss · {ml}"
|
||||
)
|
||||
|
||||
config_status = (
|
||||
"✅ Все параметры настроены"
|
||||
if is_configured
|
||||
else "⚠️ Настрой все параметры"
|
||||
)
|
||||
config_status = "✅ Все параметры настроены" if is_configured else "⚠️ Настрой все параметры"
|
||||
|
||||
text = (
|
||||
"<b>🤖 Автоторговля</b>\n\n"
|
||||
@@ -298,14 +317,13 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2, 2, 2, 2)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto_strategy")
|
||||
async def open_auto_strategy_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -322,6 +340,7 @@ async def open_auto_strategy_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(3, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -330,22 +349,15 @@ async def set_auto_strategy(callback: CallbackQuery) -> None:
|
||||
strategy = callback.data.split(":", 2)[2]
|
||||
AutoTradeService().set_strategy(strategy.upper())
|
||||
|
||||
if callback.message is not None:
|
||||
await open_auto_settings(callback)
|
||||
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
await open_auto_settings(callback)
|
||||
await callback.answer("Стратегия обновлена")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto_symbol")
|
||||
async def open_auto_symbol_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
settings = load_settings()
|
||||
|
||||
text = (
|
||||
"<b>💱 Актив</b>\n\n"
|
||||
"<b>СИСТЕМА</b> · Настройки · Автоторговля\n\n"
|
||||
@@ -353,32 +365,15 @@ async def open_auto_symbol_settings(callback: CallbackQuery) -> None:
|
||||
)
|
||||
|
||||
builder = InlineKeyboardBuilder()
|
||||
|
||||
builder.button(
|
||||
text="BTC",
|
||||
callback_data="settings:auto_symbol:BTC/USD_LEVERAGE",
|
||||
)
|
||||
|
||||
builder.button(
|
||||
text="ETH",
|
||||
callback_data="settings:auto_symbol:ETH/USD_LEVERAGE",
|
||||
)
|
||||
|
||||
builder.button(
|
||||
text="LTC",
|
||||
callback_data="settings:auto_symbol:LTC/USD_LEVERAGE",
|
||||
)
|
||||
|
||||
builder.button(
|
||||
text="XRP",
|
||||
callback_data="settings:auto_symbol:XRP/USD_LEVERAGE",
|
||||
)
|
||||
|
||||
builder.button(text="BTC", callback_data="settings:auto_symbol:BTC/USD_LEVERAGE")
|
||||
builder.button(text="ETH", callback_data="settings:auto_symbol:ETH/USD_LEVERAGE")
|
||||
builder.button(text="LTC", callback_data="settings:auto_symbol:LTC/USD_LEVERAGE")
|
||||
builder.button(text="XRP", callback_data="settings:auto_symbol:XRP/USD_LEVERAGE")
|
||||
builder.button(text="⬅️ Назад", callback_data="settings:auto")
|
||||
|
||||
builder.adjust(2, 2, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -387,18 +382,13 @@ async def set_auto_symbol(callback: CallbackQuery) -> None:
|
||||
symbol = callback.data.split(":", 2)[2]
|
||||
AutoTradeService().set_symbol(symbol)
|
||||
|
||||
if callback.message is not None:
|
||||
await open_auto_settings(callback)
|
||||
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
await open_auto_settings(callback)
|
||||
await callback.answer("Актив обновлён")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto_risk")
|
||||
async def open_auto_risk_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -415,6 +405,7 @@ async def open_auto_risk_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(3, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -423,19 +414,13 @@ async def set_auto_risk(callback: CallbackQuery) -> None:
|
||||
risk = float(callback.data.split(":", 2)[2])
|
||||
AutoTradeService().set_risk_percent(risk)
|
||||
|
||||
if callback.message is not None:
|
||||
await open_auto_settings(callback)
|
||||
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
await open_auto_settings(callback)
|
||||
await callback.answer("Риск обновлён")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto_leverage")
|
||||
async def open_auto_leverage_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -455,6 +440,7 @@ async def open_auto_leverage_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(3, 3, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -463,17 +449,13 @@ async def set_auto_leverage(callback: CallbackQuery) -> None:
|
||||
leverage = float(callback.data.split(":", 2)[2])
|
||||
AutoTradeService().set_leverage(leverage)
|
||||
|
||||
if callback.message is not None:
|
||||
await open_auto_settings(callback)
|
||||
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
await open_auto_settings(callback)
|
||||
await callback.answer("Плечо обновлено")
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:trade")
|
||||
async def open_trade_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_trade"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -491,13 +473,13 @@ async def open_trade_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_trade")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:general")
|
||||
async def open_general_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_general"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -514,13 +496,13 @@ async def open_general_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_general")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:journal")
|
||||
async def open_journal_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_journal"):
|
||||
return
|
||||
|
||||
service = JournalService()
|
||||
@@ -544,17 +526,14 @@ async def open_journal_settings(callback: CallbackQuery) -> None:
|
||||
builder.button(text="📒 Журнал", callback_data="journal:1")
|
||||
builder.adjust(2, 2, 2)
|
||||
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_journal")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:journal_archive")
|
||||
async def open_journal_archive_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_journal"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -572,13 +551,13 @@ async def open_journal_archive_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_journal")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:journal_limit")
|
||||
async def open_journal_limit_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_journal"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -597,13 +576,13 @@ async def open_journal_limit_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2, 2, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_journal")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:journal_retention")
|
||||
async def open_journal_retention_settings(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_journal"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -622,6 +601,7 @@ async def open_journal_retention_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2, 2, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_journal")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -635,8 +615,7 @@ async def journal_settings_stub(callback: CallbackQuery) -> None:
|
||||
|
||||
@router.callback_query(F.data == "system:back")
|
||||
async def back_to_system(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="system"):
|
||||
return
|
||||
|
||||
user_id = callback.from_user.id if callback.from_user else None
|
||||
@@ -654,8 +633,7 @@ async def back_to_system(callback: CallbackQuery) -> None:
|
||||
|
||||
@router.callback_query(F.data == "system:about")
|
||||
async def open_system_about(callback: CallbackQuery) -> None:
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="system_about"):
|
||||
return
|
||||
|
||||
settings = load_settings()
|
||||
@@ -685,19 +663,14 @@ async def open_system_about(callback: CallbackQuery) -> None:
|
||||
builder.button(text="⬅️ Назад", callback_data="system:back")
|
||||
builder.adjust(1)
|
||||
|
||||
await callback.message.edit_text(
|
||||
text,
|
||||
reply_markup=builder.as_markup(),
|
||||
)
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="system_about")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@router.callback_query(F.data == "settings:auto_max_reserved")
|
||||
async def open_auto_max_reserved_settings(callback: CallbackQuery) -> None:
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
|
||||
if callback.message is None:
|
||||
await callback.answer("Сообщение не найдено", show_alert=True)
|
||||
if not await _prepare_system_from_callback(callback, screen="settings_auto"):
|
||||
return
|
||||
|
||||
text = (
|
||||
@@ -716,6 +689,7 @@ async def open_auto_max_reserved_settings(callback: CallbackQuery) -> None:
|
||||
builder.adjust(2, 2, 1, 1)
|
||||
|
||||
await callback.message.edit_text(text, reply_markup=builder.as_markup())
|
||||
_register_system_screen(callback.message, screen="settings_auto")
|
||||
await callback.answer()
|
||||
|
||||
|
||||
@@ -726,8 +700,5 @@ async def set_auto_max_reserved(callback: CallbackQuery) -> None:
|
||||
value = None if raw_value == "off" else float(raw_value)
|
||||
AutoTradeService().set_max_reserved_balance_percent(value)
|
||||
|
||||
if callback.message is not None:
|
||||
await open_auto_settings(callback)
|
||||
|
||||
AutoTradeRunner.set_current_screen("settings_auto")
|
||||
await open_auto_settings(callback)
|
||||
await callback.answer("Max Reserved обновлён")
|
||||
Reference in New Issue
Block a user