fix: use isolated margin to prevent cross-position liquidation risk

Add set_margin_type("ISOLATED") call before each position entry.
With cross margin, a single bad trade's loss draws from the entire
account balance. Isolated margin caps loss to the position's allocated
margin only.

Binance returns -4046 if already ISOLATED, which is silently ignored.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
21in7
2026-03-22 20:58:34 +09:00
parent 4fef073b0a
commit aa5c0afce6
2 changed files with 16 additions and 0 deletions

View File

@@ -437,6 +437,7 @@ class TradingBot:
return
side = "BUY" if signal == "LONG" else "SELL"
await self.exchange.set_margin_type("ISOLATED")
await self.exchange.set_leverage(self.config.leverage)
await self.exchange.place_order(side=side, quantity=quantity)

View File

@@ -107,6 +107,21 @@ class BinanceFuturesClient:
),
)
async def set_margin_type(self, margin_type: str = "ISOLATED") -> None:
"""마진 타입을 변경한다. 이미 동일 타입이면 무시."""
try:
await self._run_api(
lambda: self.client.futures_change_margin_type(
symbol=self.symbol, marginType=margin_type
),
)
logger.info(f"[{self.symbol}] 마진 타입 변경: {margin_type}")
except BinanceAPIException as e:
if e.code == -4046: # "No need to change margin type."
logger.debug(f"[{self.symbol}] 마진 타입 이미 {margin_type}")
else:
raise
async def get_balance(self) -> float:
balances = await self._run_api(self.client.futures_account_balance)
for b in balances: