2026-06-09 21:41:18 +02:00
|
|
|
double M_CalculateLotSize(double riskPercent, double stopLossPoints, double Percentage, ENUM_ORDER_TYPE orderType)
|
2026-01-31 07:59:15 +01:00
|
|
|
{
|
|
|
|
|
// --- Safety checks
|
|
|
|
|
if(riskPercent <= 0 || stopLossPoints <= 0)
|
|
|
|
|
return 0.0;
|
|
|
|
|
|
|
|
|
|
// --- Account & symbol info
|
|
|
|
|
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
|
|
|
|
|
double tickSize = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_SIZE);
|
|
|
|
|
double tick_value = SymbolInfoDouble(_Symbol, SYMBOL_TRADE_TICK_VALUE);
|
|
|
|
|
|
|
|
|
|
double minLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MIN);
|
|
|
|
|
double maxLot = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_MAX);
|
|
|
|
|
double lotStep = SymbolInfoDouble(_Symbol, SYMBOL_VOLUME_STEP);
|
|
|
|
|
|
|
|
|
|
// --- Money to risk
|
|
|
|
|
double riskMoney = balance * riskPercent / 100.0;
|
2026-02-01 14:29:03 +01:00
|
|
|
|
|
|
|
|
double lot = riskMoney / stopLossPoints;
|
2026-06-09 21:41:18 +02:00
|
|
|
|
2026-02-01 14:29:03 +01:00
|
|
|
// --- Loss per Lot
|
2026-03-31 19:32:30 +02:00
|
|
|
double CalcedLoss = fLossPerLot * lot;
|
|
|
|
|
riskMoney = riskMoney - CalcedLoss;
|
|
|
|
|
lot = riskMoney / stopLossPoints;
|
2026-06-09 21:41:18 +02:00
|
|
|
|
|
|
|
|
double MaxLotMargin = M_CalcMaxLotMargin(orderType);
|
|
|
|
|
|
|
|
|
|
lot = MathMin(lot, MaxLotMargin);
|
|
|
|
|
|
|
|
|
|
// Scale lot
|
2026-06-14 13:23:39 +02:00
|
|
|
lot = lot * (Percentage / 100);
|
2026-01-31 07:59:15 +01:00
|
|
|
|
|
|
|
|
// --- Normalize to lot step
|
|
|
|
|
lot = MathFloor(lot / lotStep) * lotStep;
|
|
|
|
|
|
|
|
|
|
// --- Clamp to symbol limits
|
2026-06-09 21:41:18 +02:00
|
|
|
lot = MathMax(minLot, MathMin(lot, maxLot * stGVL.nNumberOfPositions)); // * Number of positions because afterwards it is split up
|
2026-01-31 07:59:15 +01:00
|
|
|
|
|
|
|
|
return NormalizeDouble(lot, 2);
|
|
|
|
|
}
|