Files

54 lines
1.5 KiB
Python
Raw Permalink Normal View History

"""Margin helpers — uses MT5 order_calc_margin for realistic portfolio sizing."""
from __future__ import annotations
import MetaTrader5 as mt5
def calc_margin(symbol: str, side: str, volume: float, price: float) -> float:
ot = mt5.ORDER_TYPE_BUY if side == "BUY" else mt5.ORDER_TYPE_SELL
m = mt5.order_calc_margin(ot, symbol, volume, price)
return float(m) if m is not None and m > 0 else 0.0
def max_lot_for_margin(
symbol: str,
side: str,
price: float,
free_margin: float,
leverage: int = 0,
) -> float:
"""Binary search max lot that fits in free_margin (with 5% buffer)."""
info = mt5.symbol_info(symbol)
if info is None or free_margin <= 0:
return 0.0
vmin = float(info.volume_min)
vmax = float(info.volume_max)
step = float(info.volume_step) or vmin
budget = free_margin * 0.95
lo, hi = vmin, vmax
best = 0.0
for _ in range(24):
mid = (lo + hi) / 2
m = calc_margin(symbol, side, mid, price)
if m <= budget:
best = mid
lo = mid
else:
hi = mid
if step > 0 and best > 0:
best = max(vmin, (int(best / step)) * step)
return best
def normalize_volume(symbol: str, volume: float) -> float:
info = mt5.symbol_info(symbol)
if info is None:
return volume
vmin = float(info.volume_min)
vmax = float(info.volume_max)
step = float(info.volume_step) or vmin
if step > 0:
volume = (int(volume / step)) * step
return max(vmin, min(vmax, volume))