Ask an EA developer what lot size their expert trades and you get one number. Look at the account statement and you often find another. The gap is rarely a bug in the strategy; it is the sum of small adjustments between the moment the EA decides a size and the moment the broker fills it. This guide shows where the lot changes, how to log it so the difference is visible, and what tolerance is reasonable before you treat it as a problem.

Four numbers, not one

The lot chain
StageWhat it isWho changes it
Base lotWhat the strategy would trade with no adjustment: fixed size, or risk % divided by stop distance.Strategy logic
MultiplierAny factor applied on top: equity scaling, volatility filter, recovery logic, a manual "risk x0.5" input.Risk module, operator
Requested lotBase × multiplier, as sent in the order request.EA
Final lotWhat was actually filled.Broker: volume step, min/max, margin, partial fills

Most EAs log only the requested lot, if anything. The audit needs all four, per trade, with a timestamp.

Where the broker changes your size

  • Volume step. A requested 0.137 on a symbol with step 0.01 becomes 0.13 or 0.14 depending on how the EA rounds. Always normalise yourself with SYMBOL_VOLUME_STEP, and round down when the size comes from a risk budget.
  • Minimum and maximum. Below SYMBOL_VOLUME_MIN the order is rejected ("invalid volume"); after a drawdown, risk-based sizing on a small account can fall under the minimum and the EA silently stops trading. Above SYMBOL_VOLUME_MAX or the prop firm's cap, it is rejected or, worse, split.
  • Margin. With several positions open, free margin may not cover the requested size. Some EAs retry with a smaller lot; if yours does, that reduction must be logged.
  • Partial fills. On ECN accounts and large sizes the fill can come in pieces, or only partly. Read the result from the deal, not from your request.

Logging it in MQL5

Record the chain at the moment of sending, then read back what was executed:

double NormalizeLot(const string sym, double lot)
{
   double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
   double vmin = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
   double vmax = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
   lot = MathFloor(lot / step) * step;          // round down: never exceed the risk budget
   if(lot < vmin) return 0.0;                   // caller must treat 0 as "do not trade"
   return MathMin(lot, vmax);
}

// after OrderSend succeeds:
double finalLot = 0.0;
if(HistoryDealSelect(result.deal))
   finalLot = HistoryDealGetDouble(result.deal, DEAL_VOLUME);

PrintFormat("LOT_AUDIT sym=%s base=%.2f mult=%.2f requested=%.2f final=%.2f",
            _Symbol, baseLot, multiplier, requestedLot, finalLot);

Returning zero instead of bumping the size up to the minimum is deliberate. An EA that quietly trades 0.01 when its risk model asked for 0.004 is taking two and a half times the intended risk, on exactly the account that can least afford it.

What tolerance is reasonable

Compare the final lot with the expected lot (base × the multiplier you believe is configured). A difference of up to 5% is explained by step rounding on normal sizes. Beyond that, something else is happening, and the usual suspects are:

  1. A multiplier input changed on one chart and not on the others.
  2. Recovery or martingale logic left enabled in a preset meant for a prop account.
  3. Two instances of the EA on the same symbol and magic, each opening its own position.
  4. Equity-based scaling reading the wrong account currency or an outdated balance.
  5. A different preset after an update: the new version shipped with different defaults.

Rounding errors are symmetrical and small. A deviation that is always upward, or that appears only after losing trades, is a pattern, and it is the pattern a prop firm's reviewer looks for.

Auditing a fleet instead of one account

On one account you can read the Experts tab. On ten, you need the four numbers sent somewhere they can be compared. Quantisentry's telemetry contract carries base, requested and final lot plus the applied multiplier and its source on every report, applies the 5% tolerance automatically and flags the rows that exceed it, per EA and per account. Because the platform is read-only, the record cannot be accused of having influenced the trades it describes, which matters when the audit is for someone else.

This article is educational and is not investment advice.

Frequently asked questions

Why is my EA trading a different lot than it calculated?

Between calculation and execution the size passes through a risk multiplier, broker volume-step rounding, minimum and maximum volume limits, margin checks and possibly partial fills. Each step can change it.

Should an EA round the lot up to the broker minimum?

No. If the risk model asks for less than the minimum volume, trading the minimum multiplies the intended risk. Return zero and skip the trade instead.

What deviation between expected and executed lot is acceptable?

Up to about 5% is explained by volume-step rounding on normal sizes. Larger or one-sided deviations point to a changed multiplier, recovery logic, duplicate EA instances or a wrong preset.

How do I read the executed volume in MQL5?

After OrderSend succeeds, select the deal with HistoryDealSelect(result.deal) and read DEAL_VOLUME, rather than trusting the volume in your own request.