07.4.3.13 - Risk-based Sizing and Margin Protection

This commit is contained in:
2026-05-06 16:15:43 +03:00
parent b1513a28ef
commit ee78f9774a
9 changed files with 1142 additions and 194 deletions

View File

@@ -197,6 +197,11 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
symbol = state.symbol or ""
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 = (
f"{state.max_reserved_balance_percent:g}%"
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"
@@ -220,6 +225,7 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
f"{symbol_icon} Инструмент: {symbol}\n"
f"{risk_icon} Риск на сделку: {risk}\n"
f"{leverage_icon} Плечо: {leverage}\n\n"
f"✅ Max Reserved: {max_reserved}\n"
f"✅ Risk Controls: {risk_controls}\n\n"
f"{config_status}"
)
@@ -233,9 +239,10 @@ async def open_auto_settings(callback: CallbackQuery) -> None:
builder.button(text="🛡️ Риск на сделку", callback_data="settings:auto_risk")
builder.button(text="⚙️ Плечо", callback_data="settings:auto_leverage")
builder.button(text="⚠️ Risk Controls", callback_data="auto:risk")
builder.button(text="🏦 Max Reserved", callback_data="settings:auto_max_reserved")
builder.button(text="🤖 Автоторговля", callback_data="auto:home")
builder.button(text="⬅️ Назад", callback_data="system:management")
builder.adjust(2, 2, 1, 2)
builder.adjust(2, 2, 2, 2)
await callback.message.edit_text(text, reply_markup=builder.as_markup())
await callback.answer()
@@ -610,4 +617,45 @@ async def open_system_about(callback: CallbackQuery) -> None:
text,
reply_markup=builder.as_markup(),
)
await callback.answer()
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)
return
text = (
"<b>🏦 Max Reserved</b>\n\n"
"<b>СИСТЕМА</b> · Настройки · Автоторговля\n\n"
"Максимальная доля баланса, которую можно зарезервировать под позицию:"
)
builder = InlineKeyboardBuilder()
builder.button(text="25%", callback_data="settings:auto_max_reserved:25")
builder.button(text="50%", callback_data="settings:auto_max_reserved:50")
builder.button(text="75%", callback_data="settings:auto_max_reserved:75")
builder.button(text="100%", callback_data="settings:auto_max_reserved:100")
builder.button(text="off", callback_data="settings:auto_max_reserved:off")
builder.button(text="⬅️ Назад", callback_data="settings:auto")
builder.adjust(2, 2, 1, 1)
await callback.message.edit_text(text, reply_markup=builder.as_markup())
await callback.answer()
@router.callback_query(F.data.startswith("settings:auto_max_reserved:"))
async def set_auto_max_reserved(callback: CallbackQuery) -> None:
raw_value = callback.data.split(":", 2)[2]
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 callback.answer("Max Reserved обновлён")