How to Build a Trading Risk Calculator for Lot Size, Stop Loss and Account Risk
Last checked: 12 October 2026. This guide draws on MQL5 community articles on position sizing and on the MQL5 reference for SymbolInfoDouble. Code is a teaching example. Test on a demo account and check results against your broker’s own calculator. This is not financial advice.
Most beginners choose a lot size by feel. A risk calculator replaces feel with arithmetic: decide how much money you accept losing, measure the distance to your stop loss, and let the formula return the lot size. This guide explains the formula, why a naive version breaks on gold or indices, and how to write the calculation in MQL5.
The formula
MQL5 community guides give the same core steps:
- Risk money = account balance multiplied by risk percentage.
- Stop distance in ticks = distance from entry to stop divided by tick size.
- Lots = risk money divided by (stop distance in ticks multiplied by the value of one tick for one lot).
A worked example: a 10,000 dollar account risking 1 percent has a risk budget of 100 dollars. If the stop is 50 pips away on a pair where one pip is worth 10 dollars per standard lot, a full lot would lose 500 dollars. Dividing 100 by 500 gives 0.20 lots. Always check the figures against your own broker, because contract sizes and tick values differ.
Why the symbol’s own data matters
The hard part is “the value of one tick for one lot in your account currency”. You do not guess it. You read it from the terminal. SymbolInfoDouble returns SYMBOL_TRADE_TICK_SIZE, the tick value properties, and the volume limits SYMBOL_VOLUME_MIN, SYMBOL_VOLUME_MAX and SYMBOL_VOLUME_STEP. MQL5 also provides a separate tick value for losses, SYMBOL_TRADE_TICK_VALUE_LOSS, which is the right one to use when you are sizing a stop. One practitioner write-up on MQL5.com reports that a symbol property read in OnInit() on a Sunday, when the market is closed, can come back as zero and cause a division by zero, so the code must check these values before dividing.

Round down, never up
Brokers allow only certain volumes, such as multiples of 0.01. The calculated lot size rarely lands exactly on a step, so you must round. Rounding to the nearest step can push risk above your limit. The safe method is to round down to the step. If the result is smaller than the broker’s minimum lot, the honest answer is that the trade does not fit your risk, because forcing the minimum lot would risk more than you decided.
The function
// Returns lots for a given risk in account currency and a stop distance in price units.
// Returns 0.0 when the trade cannot be sized safely.
double LotsForRisk(const string sym, const double riskMoney, const double stopDistance)
{
if(riskMoney <= 0.0 || stopDistance <= 0.0) return(0.0);
double tickSize = SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_SIZE);
double tickValue = SymbolInfoDouble(sym, SYMBOL_TRADE_TICK_VALUE_LOSS);
if(tickSize <= 0.0 || tickValue <= 0.0) return(0.0); // market closed or bad data
double minLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MIN);
double maxLot = SymbolInfoDouble(sym, SYMBOL_VOLUME_MAX);
double step = SymbolInfoDouble(sym, SYMBOL_VOLUME_STEP);
if(step <= 0.0) return(0.0);
double lossPerLot = (stopDistance / tickSize) * tickValue;
if(lossPerLot <= 0.0) return(0.0);
double lots = riskMoney / lossPerLot;
lots = MathFloor(lots / step) * step; // round DOWN to the step
if(lots < minLot) return(0.0); // does not fit the risk
if(lots > maxLot) lots = maxLot;
int digits = (int)MathMax(0, MathCeil(-MathLog10(step)));
return(NormalizeDouble(lots, digits));
}
void OnStart()
{
double balance = AccountInfoDouble(ACCOUNT_BALANCE);
double risk = balance * 0.01; // 1 percent
double entry = SymbolInfoDouble(_Symbol, SYMBOL_ASK);
double stop = entry - 50 * 10 * _Point; // example: 50 pips on a 5-digit pair
double lots = LotsForRisk(_Symbol, risk, MathAbs(entry - stop));
PrintFormat("%s risk %.2f %s, stop distance %.5f, lots %.2f",
_Symbol, risk, AccountInfoString(ACCOUNT_CURRENCY),
MathAbs(entry - stop), lots);
}
Check the stop before you size
Brokers set a minimum stop distance (the stops level). A stop that is closer than this is rejected at order time, so a calculator that ignores it can output a lot size for an order that will never be accepted. You can read the limit with SymbolInfoInteger and the SYMBOL_TRADE_STOPS_LEVEL property.
Hidden costs
- Commission and spread add to real risk, so the true loss at the stop is slightly larger than the formula says.
- Slippage can fill a stop at a worse price, especially around news.
- With a small account, the broker’s minimum lot may force you to risk more than your target. In that case, skip the trade or reduce the stop distance.
Verify it
- Run the script on EURUSD, USDJPY and XAUUSD on a demo account.
- For each, work the answer out by hand using the broker’s contract specification (right-click the symbol in Market Watch, then Specification).
- Place a demo trade with the calculated lots and compare the actual loss at the stop with your risk figure.
Turning the function into a tool you use daily
The function above is the heart of a calculator, but you also need a way to feed it your stop distance. There are two common approaches. The first is a script with inputs for risk percentage and stop distance in pips; you run it before you open a trade and read the lot size from the Experts tab. The second is a chart tool that reads two horizontal lines you drag to your entry and stop levels, and updates the lot size as you move them. Either way, the same function does the arithmetic, and the interface is only a convenience.
Converting pips to price distance
If you type the stop in pips, convert carefully. On a five-digit forex symbol one pip is ten points, so the price distance is pips multiplied by ten multiplied by the symbol’s point size. On a three-digit yen pair the same rule applies. For gold and indices the meaning of a pip varies by broker, so many tools ask for the stop in points or in price instead. Whichever unit you choose, label the input clearly, because a unit mix-up silently changes your risk by a factor of ten.
Using a percentage of equity or balance
The example uses balance. Some traders prefer equity, which includes floating profit and loss, so risk shrinks when a trade is already losing. Neither is universally right. If you hold several trades at once, also think about total open risk: three trades each risking one percent can lose three percent together if they move against you in a correlated way, for example several dollar pairs at the same time.
What we could not confirm
- That SYMBOL_TRADE_TICK_VALUE_LOSS is populated identically by every broker. Check on yours.
- How cross-currency accounts behave on exotic pairs. Test before relying on it.
Frequently asked questions
What risk percentage should I use? That is a personal decision. Many educators suggest keeping it small, but there is no universal correct number.
Why not use a fixed lot size? Because the same lot size risks very different amounts with different stop distances.
Key takeaways
Start from the money you accept losing, derive lots from stop distance and the symbol’s own tick data, round down to the broker’s step and refuse trades that do not fit.
Sources checked
- MQL5.com blog, “How to Calculate Position Size in MetaTrader 5” (August 2026)
- MQL5.com blog, “Three lot size bugs that survive every backtest” (July 2026)
- MQL5 Reference, SymbolInfoDouble, mql5.com
Educational content only — not financial advice. Income and savings results vary and are never guaranteed. How we write
Enjoyed this story?
Get the best stories delivered weekly.


