Money Management in MQL5 (Part 1): Kelly Position Sizing from the Strategy's Own Edge
Contents
- The problem: every sizer hands you a number
- What Kelly actually says
- The Kelly fraction
- The class: measuring your own edge
- Sizing a trade from the fraction
- Why you cannot just bet full Kelly
- The sweep: growth peaks, drawdown never stops
- The wall of ruin
- Half Kelly: most of the growth, a fraction of the pain
- The honest catch: your edge is an estimate
- Files and how to run it
- Limitations
- What Part 2 adds
- Conclusion
The problem: every sizer hands you a number
Open any position-sizing tool for MQL5 and it asks you for a number. Risk one percent. Risk half the ATR. Taper the size when the drawdown passes ten percent. These are fine rules, and a fixed percent is far better than a fixed lot, but they all share the same blind spot: the number comes from you, not from the strategy. You decide to risk two percent whether the strategy wins sixty percent of its trades or forty, whether its winners are twice its losers or half.
One classic method computes the number from the strategy itself: the Kelly criterion. This article is about that method. Kelly does not ask how much you feel like risking. It measures the strategy's edge, its win rate and average win versus average loss, and derives the bet size that maximizes long-run growth. It is the sizer that reads the strategy instead of asking the trader.
The distinction is not academic. A preset rule that risks two percent will size the same on a strategy that wins thirty-five percent of the time and one that wins sixty, even though the first should barely bet and the second could press. It cannot tell the difference because it never looks. Kelly looks first and sizes second, and that ordering is the whole idea. The tool that comes out of it is small, but it changes where the risk number comes from, and that is the part worth getting right.
This is the first part of a series on money management in native MQL5. Everything is built from scratch: no Python, no external libraries, only the terminal. This part delivers a reusable CKelly class that measures a strategy's edge and sizes from it, and it shows, with an honest simulation, why almost nobody should bet the full amount Kelly recommends. This is an educational article, not a strategy and not financial advice, and nothing here promises profit.
What Kelly actually says
The Kelly criterion answers one question: given a bet where you have an edge, what fraction of your capital should you put at risk each time to grow it as fast as possible? The answer is a balance between two failures. Bet too little and you leave growth on the table, crawling forward when you could stride. Bet too much and a normal losing streak digs a hole too deep to climb out of. The edge can be real and it still will not save you. Between those two mistakes sits one fraction that grows capital faster than any other, and Kelly is the formula for it.
The classic illustration is a coin that lands in your favor more often than not. If it comes up heads 54 percent of the time and pays even money, Kelly says to risk 8 percent of your capital on each flip. Not two, not fifty, eight. Risk less and you grow slower. Risk more and, past a point we will measure below, you actually grow slower again and eventually go broke, with the very same coin. The whole article is about seeing that peak and, more importantly, about why you should sit deliberately to the left of it.
The Kelly fraction
The formula itself is small. It takes the win probability and the payoff ratio, the average win divided by the average loss, and returns the fraction of capital to risk.

Full Kelly is the edge-optimal fraction from the win rate p and the payoff b. Fractional Kelly is simply a multiple of it below one, which is what you actually trade, for reasons the rest of the article makes concrete.
In code the formula is one line, guarded so that an edge of zero or worse returns a fraction of zero. That guard matters more than it looks: with no edge, the correct bet size is nothing, and a sizer that respects that will refuse to size up a strategy that has not earned it.
//+------------------------------------------------------------------+ //| Full Kelly fraction. Negative (no edge) is clamped to zero: with | //| no edge, the right bet size is nothing. | //+------------------------------------------------------------------+ double CKelly::FractionFromEdge(const double p, const double b) { if(b <= 0.0) return(0.0); double f = p - (1.0 - p) / b; return(f > 0.0 ? f : 0.0); }
The class: measuring your own edge
The point of CKelly is that you do not supply the win rate and the payoff by hand. The class measures them from the strategy's own closed history, so the size adapts to what the strategy is really doing rather than to what you hoped it would do. It walks the closed deals of the symbol, counts wins and losses, and averages the winning and losing amounts, always net of swap and commission.
//+------------------------------------------------------------------+ //| Measure win rate and payoff from the closed deals of this symbol | //+------------------------------------------------------------------+ bool CKelly::MeasureEdge(void) { if(!HistorySelect(0, TimeCurrent())) return(false); int total = HistoryDealsTotal(); int wins = 0; int losses = 0; double sumWin = 0.0; double sumLoss = 0.0; for(int i = 0; i < total; i++) { ulong ticket = HistoryDealGetTicket(i); if(ticket == 0) continue; if(HistoryDealGetInteger(ticket, DEAL_ENTRY) != DEAL_ENTRY_OUT) continue; if(HistoryDealGetString(ticket, DEAL_SYMBOL) != m_symbol) continue; if(m_magic != 0 && HistoryDealGetInteger(ticket, DEAL_MAGIC) != m_magic) continue; double net = HistoryDealGetDouble(ticket, DEAL_PROFIT) + HistoryDealGetDouble(ticket, DEAL_SWAP) + HistoryDealGetDouble(ticket, DEAL_COMMISSION); if(net > 0.0) { wins++; sumWin += net; } else if(net < 0.0) { losses++; sumLoss += -net; } } m_wins = wins; m_losses = losses; int n = wins + losses; if(n < 10) return(false); // not enough trades to trust the estimate m_p = (double)wins / n; double avgWin = (wins > 0) ? sumWin / wins : 0.0; double avgLoss = (losses > 0) ? sumLoss / losses : 0.0; m_b = (avgLoss > 0.0) ? avgWin / avgLoss : 0.0; return(true); }
It reads the history with HistorySelect and counts only closing deals, so opens are not mistaken for results. If there are fewer than ten closed trades it returns false rather than pretend to know an edge from a handful of samples, which is the first of several places the class refuses to overclaim.
Sizing a trade from the fraction
With the edge measured, sizing a trade is the same arithmetic any risk-based sizer uses, except the risk percentage is the Kelly fraction times your chosen multiplier rather than a fixed number you typed in. The multiplier is what turns full Kelly into fractional Kelly.
//+------------------------------------------------------------------+ //| Lot for a stop distance, risking (multiplier * Kelly) of equity | //+------------------------------------------------------------------+ double CKelly::Lots(const double stopDistance, const double multiplier) { double f = KellyFraction() * multiplier; if(f <= 0.0) return(0.0); double equity = AccountInfoDouble(ACCOUNT_EQUITY); double tickVal = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_VALUE); double tickSize = SymbolInfoDouble(m_symbol, SYMBOL_TRADE_TICK_SIZE); if(stopDistance <= 0.0 || tickVal <= 0.0 || tickSize <= 0.0) return(0.0); double riskMoney = equity * f; double lossPerLot = (stopDistance / tickSize) * tickVal; if(lossPerLot <= 0.0) return(0.0); return(NormalizeLot(riskMoney / lossPerLot)); }
The money at risk is the current equity times the fractional Kelly, and the lot follows from the stop distance the same way it would for a fixed percent, converting the stop to money with the tick value and tick size so the result is correct on any symbol. Pass a multiplier of one for full Kelly, a half for half Kelly, and so on. If the fraction is zero, because there is no edge, the method returns zero and the trade does not open.
Why you cannot just bet full Kelly
Full Kelly is growth-optimal, so the obvious question is why anyone would bet less. To answer it honestly you need a strategy whose edge you actually know, and no real backtest gives you that, its edge is only an estimate. So we do the clean thing and simulate a known edge: the 54 percent, even-money coin from earlier, whose full Kelly is 8 percent. We sweep the Kelly multiplier from zero to above one (overbetting). For each multiplier, we run thousands of Monte Carlo sequences of 200 trades and record median growth, median maximum drawdown, and the frequency of a 50 percent equity loss. The inner loop is the whole simulation.
double eq = 1.0, peak = 1.0, dd = 0.0; for(int t = 0; t < InpTrades; t++) { bool win = (MathRand() / 32767.0) < p; if(win) eq *= (1.0 + risk * b); else eq *= (1.0 - risk); if(eq < 0.0001) eq = 0.0001; if(eq > peak) peak = eq; double cur = (peak - eq) / peak; if(cur > dd) dd = cur; }
Each trade multiplies the equity up on a win and down on a loss by the risked fraction, exactly as real compounding works, and the sequence tracks its own running peak and worst drawdown. Run this across the whole sweep and the trade-off draws itself.
The sweep: growth peaks, drawdown never stops

Median terminal growth and median maximum drawdown across four thousand simulated sequences, as the Kelly multiplier runs from zero to twice full Kelly. Growth peaks exactly at full Kelly and then falls; drawdown climbs the entire way and never turns back.
Two things happen at once, and they are the heart of Kelly. Growth, the teal curve, rises to a peak precisely at full Kelly, where the median sequence ends at about 1.90 times its starting capital, and then it falls. Push past full Kelly and you grow less, not more, with the identical edge. By twice full Kelly the median sequence has actually lost money, ending below where it started. Meanwhile drawdown, the coral curve, does not share that peak. It climbs the whole way and never stops climbing: gentle at small fractions, 64 percent at full Kelly, over 90 percent out in the overbetting zone.
That asymmetry is the lesson. On the way up to full Kelly you are paid for the extra risk with extra growth. Past it you pay the risk and get nothing, then less than nothing. And even at the growth-optimal peak, the price of admission is a drawdown that would end most real trading accounts and most traders' nerve.
The wall of ruin
Drawdown is the pain you feel; ruin is the door you do not come back through. Counting how often a sequence is cut to half its starting capital sharpens the same warning.

How often the simulated account is halved, across the same sweep. Below half Kelly it almost never happens; it passes one in ten at full Kelly and one in three out in the overbetting zone.
Below about a third of full Kelly the account is essentially never halved. At half Kelly it happens about 2 percent of the time. At full Kelly, the growth-optimal bet, it happens 11 percent of the time, better than one sequence in ten halved on a strategy that genuinely has an edge. Out where the overbetting traders live, at twice Kelly, a third of all sequences are halved. The growth peak and the ruin wall sit close together, and the wall keeps rising after the growth is gone.
Half Kelly: most of the growth, a fraction of the pain
Put the landmarks side by side and the practical answer appears on its own.

Growth, drawdown and ruin at four bet sizes. Half Kelly keeps most of full Kelly's growth while roughly halving its drawdown and cutting its ruin rate to a fraction.
Half Kelly is the sweet spot almost everyone converges on, and the numbers show why. It keeps 1.62 times growth against full Kelly's 1.90, so about 85 percent of the growth, while cutting the drawdown from 64 percent to 37 and the ruin rate from 11 percent to 2. You give up a slice of growth you will barely notice over a career and you buy back a huge amount of survival. Quarter Kelly goes further still, trading a little more growth for a drawdown a real account can actually sit through. This is why fractional Kelly, not full Kelly, is what disciplined traders and funds actually use.
The honest catch: your edge is an estimate
There is a deeper reason to bet a fraction, and it is the one that matters most in real trading. The sweep above assumed we knew the edge exactly, because we defined it. In the market you never know it, you estimate it from past trades, and that estimate is noisy and drifts as conditions change. Betting full Kelly on a true edge is already brutal. Betting full Kelly on an overestimated edge is how accounts fail. In that case the true growth-optimal fraction is smaller than the one you computed, so you end up overbetting, where growth falls and ruin risk rises. Fractional Kelly is the margin of safety for the fact that your number is a guess.
How much less is a fair question, and the rough rule that falls out of the estimation problem is instructive. If you are only moderately confident in your measured edge, betting a half or a quarter of full Kelly is not timidity, it is the correct response to uncertainty about the number itself. A common way to see it: if your true edge could plausibly be anywhere from half to double what you measured, then the fraction that is growth-optimal across that whole range of possibilities sits well below the fraction that is optimal for your single point estimate. The noisier your edge, the smaller the safe fraction, and a real trading edge is very noisy.
This is also where CKelly stays honest about your particular strategy. Point it at a strategy with no real edge, a coin-flip entry that loses to costs, and MeasureEdge returns a win rate below the break-even point, KellyFraction returns zero, and Lots returns zero. The class will not size up something that has not earned it. Kelly is only ever as good as the edge you feed it, and most retail strategies, measured honestly, feed it very little. The tool does not manufacture an edge; it sizes the one you can prove you have, and then tells you to take less of it than the math says.
Files and how to run it
The library is one class; the demonstration is one script.
| File | What it holds |
|---|---|
| Kelly.mqh | The reusable CKelly class: measure the edge from history, compute the full and fractional Kelly fraction, and size a trade from it. This is the deliverable to drop into an expert advisor. |
| KellySweep.mq5 | A script that simulates a known edge and sweeps the Kelly multiplier, writing the median growth, drawdown and ruin per multiplier to CSV, so the trade-off curve is reproducible. |
To reproduce the sweep:
- Put both files in the same MQL5\Experts folder and compile the script.
- Drag KellySweep onto any chart and keep the defaults, or set your own win rate and payoff.
- Read the printout in the Experts tab and find the sweep written to the shared Files folder as a CSV, one row per multiplier.
Limitations
- The sweep uses a defined, stationary edge so the trade-off is visible and reproducible. A real strategy's edge is neither known nor stationary, which is an argument for a smaller fraction, not a larger one.
- The simulation compounds a single position at a time with a fixed payoff. Overlapping positions, variable payoffs and correlation all change the effective Kelly and are out of scope for this part.
- CKelly measures the edge from closed history, so it needs enough trades to mean anything, and it assumes the recent past resembles the near future.
- Kelly sizes the bet; it does not find the edge. On a strategy with no edge it correctly returns zero, which is a feature, not a result to work around.
What Part 2 adds
This part sized from a static measured edge. A real edge moves, so Part 2 turns to sizing that responds to the strategy's live equity curve, scaling down when the account slips below its own recent trend and back up as it recovers, using the same honest, native, dependency-free approach.
Conclusion
Most position sizers ask you for a number. Kelly computes it from what should drive bet size: the edge the strategy can actually demonstrate. Seeing the full sweep makes the discipline concrete: growth peaks at full Kelly and collapses past it, drawdown and ruin climb without a peak of their own, and half Kelly quietly keeps almost all of the growth for roughly half the pain. Add the fact that your edge is only ever an estimate, and the conclusion is not a matter of taste. Size from your measured edge, then deliberately take a fraction of what the math offers, because the math assumed a certainty you do not have.
A final note: this is an educational article, not financial advice, and nothing here is a promise of profit. The value is a reusable native sizer and an honest picture of how far up the growth curve it is wise to climb.
Warning: All rights to these materials are reserved by MetaQuotes Ltd. Copying or reprinting of these materials in whole or in part is prohibited.
This article was written by a user of the site and reflects their personal views. MetaQuotes Ltd is not responsible for the accuracy of the information presented, nor for any consequences resulting from the use of the solutions, strategies or recommendations described.
Implementing and Comparing Five Historical Volatility Estimators in MQL5
Creating a Cairo-Inspired Graphics Library for MetaTrader 5 (Part 5): Fill Rules, Holes and Borders
Intrinsic Time: From the Directional-Change Scaling Laws to the Alpha Engine
How to Implement Competition Among LLM Agents in MetaTrader 5
- Free trading apps
- Over 8,000 signals for copying
- Economic news for exploring financial markets
You agree to website policy and terms of use