How to Code Dynamic Position Sizing in MQL5 – Step‑by‑Step
Table of Contents
- Introduction
- What Is Dynamic Position Sizing?
- Why Dynamic Position Sizing Matters for Traders and Investors
- Core Concepts
- Step‑by‑Step Guide
- Practical Tips for Better Results
- Common Mistakes to Avoid
- Frequently Asked Questions
- Conclusion
Introduction
When the EUR/USD broke out of a tight range last week, a scalper who kept a flat 0.01‑lot size saw a 30‑pip move evaporate into a series of small losses. The same trader could have preserved capital and captured the swing by letting the lot size expand with the market’s volatility.
Many MetaTrader 5 (MT5) users cling to static lot values because a single number is easy to type. The downside is a mismatch between risk exposure and the underlying price action. In volatile regimes a static lot can blow a margin account; in calm markets it leaves profit potential on the table.
This guide shows how to code dynamic position logic that reacts to ATR, equity percentage, and even Kelly‑derived risk. You will walk through the math, see two concrete forex EA examples, and get a ready‑to‑paste script outline that respects the CFTC’s margin rules and the broker’s minimum lot size.
What Is Dynamic Position Sizing?
Dynamic position sizing is the practice of calculating trade size at the moment of order placement based on current market conditions and account equity, rather than using a fixed lot.
For example, a scalping EA on GBP/JPY might read the 14‑period Average True Range (ATR) each tick, convert that volatility into a dollar risk amount (say 1 % of a $10,000 account), and then divide by the stop‑loss distance to produce a lot size that could range from 0.02 to 0.15 lots depending on the recent price swing. The lot size therefore expands when the market is tight and contracts when volatility spikes.
Why Dynamic Position Sizing Matters for Traders and Investors
Professional prop desks and hedge funds routinely adjust exposure to keep the probability of ruin low. Retail traders who ignore this principle often see their drawdowns swell when volatility spikes, forcing margin calls from brokers regulated by the CFTC or FCA.
A dynamic approach aligns three objectives:
1. Capital preservation – risk per trade stays within a predefined fraction of equity.
2. Scalability – the same script works on a $5,000 demo account and a $100,000 live account without manual retuning.
3. Regulatory compliance – many brokers enforce a maximum use per instrument; adaptive lot sizing keeps the effective use in check.
If you continue to trade with static lots, a sudden VIX‑driven risk‑off move can wipe out weeks of gains in a single session.
Risk‑of‑Ruination Formula – keeping the survival probability high
The risk‑of‑ruin (RoR) formula estimates the chance of depleting an account after a series of independent bets:
[
RoR = \left(\frac{1 – \frac{R}{W}}{1 + \frac{R}{W}}\right)^{N}
]
where R is the fractional risk per trade, W is the win‑loss ratio, and N is the number of trades.
Concrete scenario: a trader risks 1 % of equity per trade (R = 0.01) and expects a win‑loss ratio of 1.5 (average winner 1.5× average loser). Plugging the numbers for 200 trades yields a ruin probability below 2 %. By coding this calculation into MQL5, the EA can automatically tighten risk if the win‑loss ratio drifts downward.
Kelly Criterion Adaptation for Lot Sizing – balancing growth and volatility
The Kelly fraction (f^) maximizes logarithmic wealth growth:
[
f^ = \frac{bp – q}{b}
]
where b is the net odds (average win/average loss), p is win probability, and q = 1-p.
Concrete scenario: a breakout system on GBP/JPY shows a 55 % win rate (p = 0.55) with an average profit of 30 pips and average loss of 15 pips (b = 2). Kelly suggests risking (f^* = (2·0.55 – 0.45)/2 = 0.325) or 32.5 % of equity per trade – clearly too aggressive for most retail accounts. The script can cap Kelly at a safe fraction, such as 10 % of equity, and recalculate lot size each trade.
ATR‑Based Volatility Scaling – matching lot size to market noise
ATR measures the average true range over a look‑back period, providing a volatility estimate that is independent of price level.
Concrete scenario: an EUR/USD scalper uses a 14‑period ATR of 0.0009. The EA sets a stop‑loss at 1.5 × ATR (0.00135) and calculates lot size as
[
\text{Lot} = \frac{\text{Risk\ Amount}}{\text{Stop\Loss\ (pips)} \times \text{Pip\ Value}}
]
If the risk amount is 1 % of a $12,000 account ($120) and the pip value for a standard lot is $10, the resulting lot is roughly 0.09. When ATR widens to 0.0015 during a news burst, the lot automatically shrinks to protect the same dollar risk.
Equity‑Percentage Risk per Trade – the simplest adaptive rule
The most common rule is to risk a fixed percentage of current equity, regardless of instrument.
Concrete scenario: a swing trader on the S&P 500 futures (symbol: ES) decides to risk 0.8 % of equity per trade. With $50,000 equity, the risk amount is $400. If the stop is set 25 points away and each point is worth $12.50, the script computes a contract size of 1.28 contracts, rounded down to 1 contract to satisfy the exchange’s minimum.
Trailing‑Stop Driven Lot Adjustment – scaling out while the market moves
Some EAs adjust lot size mid‑trade based on trailing‑stop distance, effectively locking in profit and reducing exposure.
Concrete scenario: a CFD trader on the Nasdaq 100 (symbol: NDX) opens a 0.5‑lot position with a 30‑point trailing stop. As the price moves 60 points in favor, the script halves the lot size, leaving a smaller position that continues to trail. This reduces the chance of a reversal wiping out the accumulated profit.
Core Concepts
## Step 1 — Gather market data and account parameters
Begin by pulling the current account balance, free margin, and the instrument’s tick size. Use AccountInfoDouble(ACCOUNTEQUITY) for equity and SymbolInfoDouble(Symbol, SYMBOLTRADETICKVALUE) for pip value. Also request the latest ATR value with iATR(Symbol, PERIOD_CURRENT, 14, 0).
Step 2 — Choose a sizing model and compute risk amount
Decide whether you will use a fixed equity percentage, Kelly, or a hybrid. For a 1 % equity‑risk model:
riskamount = AccountInfoDouble(ACCOUNTEQUITY) * 0.01;
If you prefer Kelly, first estimate win probability and payoff ratio from backtest statistics, then apply the capped Kelly fraction.
Step 3 — Translate risk into lot size
Determine the stop‑loss distance in points. For ATR scaling, set
stoppoints = 1.5 * atrvalue / SymbolInfoDouble(Symbol, SYMBOLPOINT);
Then calculate the raw lot size:
rawlot = riskamount / (stoppoints * pipvalue);
Apply broker constraints: round down to the nearest SymbolInfoDouble(Symbol, SYMBOLVOLUMESTEP) and ensure the lot is above SYMBOLVOLUME_MIN.
Step 4 — Embed the logic into the EA’s order function
Replace any hard‑coded lot parameter in OrderSend() with the variable dynamiclot. Include a safety check that aborts the trade if dynamiclot falls below the minimum.
Step 5 — Add optional trailing‑stop lot reduction
After the order is filled, monitor price movement each tick. If the price exceeds a predefined multiple of the original stop distance, recalculate a reduced lot using the same risk‑per‑trade formula but based on the new equity (including unrealized profit). Issue an OrderModify() to adjust the volume.
Step 6 — Test across volatility regimes
Run the EA on historical data that includes both low‑volatility periods (e.g., summer months) and high‑volatility events (Fed announcements, ECB rate decisions). Verify that the lot size contracts during spikes and expands when the market quiets.
Step 7 — Deploy with a conservative max‑lot cap
Even with adaptive logic, a sudden market crash can generate an unexpectedly large lot if equity has surged. Set a hard ceiling, such as 0.2 lots for EUR/USD, to keep the effective use within the broker’s margin limits.
Practical Tips for Better Results
- Use a 14‑period ATR for intraday scalping; increase to 28 or 50 for swing‑trade timeframes.
- Cache the ATR value once per bar rather than every tick to reduce CPU load.
- When applying Kelly, always cap the fraction at 10 % of equity to avoid over‑aggressive exposure.
- Incorporate a “max drawdown” guard: if the account equity falls more than 15 % from its peak, force the lot size to the minimum for the next 10 trades.
- Align the stop‑loss distance with market structure; a volatility‑based stop that ignores support/resistance can lead to premature exits.
- Verify that the script respects the broker’s minimum distance for stop‑loss and take‑profit orders, especially on CFD instruments where spreads can be wide.
- Log each lot calculation to a file; reviewing the log helps spot periods where the model produced unusually large positions.
Common Mistakes to Avoid
- Hard‑coding lot size – eliminates the protective benefit of dynamic sizing.
- Using the same ATR period for all timeframes – mismatches volatility measurement and inflates risk.
- Ignoring broker’s minimum lot step – results in rejected orders and missed opportunities.
- Applying Kelly without a cap – can generate lot sizes that exceed margin limits during winning streaks.
- Recalculating lot size after the order is filled – changes the risk profile mid‑trade and may breach regulatory limits.
How to code dynamic position sizing in MQL5?
Start by reading account equity, selecting a risk model (percentage, Kelly, ATR), calculating stop‑loss distance, and converting the risk amount into a lot size that respects the symbol’s volume step. Insert the resulting variable into
OrderSend()and add optional trailing‑stop adjustments.
What is the best formula for dynamic lot size in MQL5?
There is no universal “best” formula; the most robust combines a fixed equity‑risk percentage with ATR‑based stop distance. This approach adapts to both account growth and changing market volatility while staying simple to maintain.
Why use volatility‑based position sizing?
Volatility determines how far a price typically moves. By scaling lot size to ATR, a trader keeps dollar risk constant whether the market is calm or jittery, reducing the chance of margin calls during spikes.
When should I adjust position size during a trade?
Adjust only when the trade’s equity changes significantly, such as after a large profit that raises the account balance, or when a trailing‑stop rule triggers a partial reduction. Frequent mid‑trade changes can erode the statistical edge.
Can I combine Kelly criterion with MQL5 scripts?
Yes. Compute win probability and payoff ratio from backtest results, apply the Kelly formula, then cap the resulting fraction (e.g., at 10 % of equity) before converting to lot size. The script can update the Kelly fraction periodically as performance metrics evolve.
Is dynamic position sizing safe for beginners?
It adds a layer of math, but the safety comes from limiting risk per trade. Beginners should start with a simple equity‑percentage rule (1 % or 0.5 %) and avoid aggressive Kelly fractions until they have a solid track record.
Conclusion
Dynamic position sizing aligns trade exposure with both account size and market volatility, turning risk management into a systematic engine rather than a guess. The single most important lesson is to let a predefined risk percentage drive every lot calculation, then layer volatility or Kelly adjustments on top only after the base rule is solid.
Your next step: copy the outlined script skeleton into MetaEditor, replace variables with your own ATR period and risk percentage, and run a 30‑day forward test on a demo account. Remember that no script can eliminate loss; always monitor drawdowns, respect broker margin limits, and keep the probability of ruin low.
Risk disclosure: Trading involves substantial risk of loss. The code examples are for educational purposes and do not guarantee profitability.
—
This article is for educational purposes only and does not constitute investment advice. Trading and investing carry risk of loss; never invest more than you can afford to lose.
Last reviewed: August 2026