Most backtests are built with clean, consistent position sizes. Every trade gets $10,000, or 100 shares, or 2% of capital — and the strategy's performance is evaluated on that fixed foundation. The backtest looks fine. Then the strategy goes live, the real account fluctuates, and the sizing logic that felt neutral suddenly has teeth. A losing streak that was survivable in the backtest wipes 20% of capital in the live account. The signal was the same. The math of survival was different.

Position sizing is the variable that converts a signal with edge into either a compounding engine or a drawdown spiral. The same strategy, run on the same market, with identical entry and exit rules, produces dramatically different long-run outcomes depending solely on how much is wagered on each trade. This is not a secondary concern — it is the primary lever. The signal determines whether a trade has a positive expected value. The sizing determines whether you are still in the game to take the next one.

Why Sizing Matters More Than the Signal

Consider two traders using an identical strategy: win rate 55%, average win $200, average loss $150. By any signal quality metric, these are the same strategy. They enter the same trades, exit at the same levels, and experience identical win/loss sequences.

Trader A sizes each trade at $1,000 risk regardless of portfolio size. Trader B sizes each trade at 2% of current portfolio value.

After a 10-trade losing streak — which will happen to any strategy given enough time — Trader A has lost $15,000 in absolute terms. If the starting portfolio was $50,000, that is a 30% drawdown. To return to breakeven, the strategy now needs a 43% recovery on the remaining $35,000. Trader B has lost approximately 18.3% (ten sequential 2% losses, each applied to a declining balance). The recovery burden is smaller, and the strategy retains more capital to compound when the winning streak follows.

Scale that difference across years and thousands of trades, and the compounding effect of position sizing eclipses the contribution of any signal refinement. Two strategies with similar edge quality can produce 3x differences in 5-year terminal value based on sizing alone. A strategy with a marginal edge and excellent sizing can outperform a sharp-edge strategy with reckless sizing — at every time horizon.

The retail algo trader checklist covers position sizing as one of the three non-negotiables before going live. The present article covers the mechanics of each method.

Fixed-Dollar Sizing

Fixed-dollar sizing is the default for most beginners: commit a fixed cash amount to every trade. If the rule is "$1,000 per trade," every entry deploys $1,000 regardless of price, volatility, or portfolio size.

The appeal is simplicity. No calculation at runtime, no ambiguity about how large a position to take, no dependency on current portfolio value. Backtesting it is trivial.

The problem is structural. Portfolio size changes. A $50,000 portfolio deploying $1,000 per trade is risking 2% per position. After growth to $80,000, the same $1,000 is 1.25% — the strategy is systematically under-sizing as it succeeds. After a drawdown to $35,000, the same $1,000 is 2.86% — the strategy is over-sizing precisely when risk capacity is smallest. Fixed-dollar sizing does not adapt to the portfolio's current state.

A second failure mode: fixed-dollar sizing does not account for volatility differences across instruments. A $1,000 position in a 2% daily-volatility stock and a $1,000 position in a 10% daily-volatility stock carry entirely different risk profiles. The dollar amount is the same. The expected drawdown is not.

Fixed-dollar sizing is a reasonable starting configuration for initial testing, when the goal is isolating signal behavior rather than modeling risk. It should not remain in the strategy once the portfolio grows beyond trivial size.

Percentage-of-Equity Sizing

Percentage-of-equity sizing addresses the scaling problem by tying position size to the current portfolio value. If the rule is 2% risk per trade, each trade risks exactly 2% of the current equity — regardless of whether the portfolio has grown or shrunk since strategy inception.

This produces two desirable properties. On a winning streak, position sizes grow proportionally to capital — the strategy takes advantage of compounding. On a losing streak, position sizes shrink proportionally — the strategy conserves capital by risking a smaller dollar amount during the drawdown period. Both effects are automatic. No manual adjustment is required.

def pct_equity_size(capital: float, risk_pct: float = 0.02) -> float:
    return capital * risk_pct

The risk_pct parameter is the fraction of capital to risk per trade. At 0.02 (2%), a $50,000 portfolio risks $1,000 per trade. After growing to $80,000, it risks $1,600. After a drawdown to $35,000, it risks $700.

The choice of risk_pct is a function of the strategy's expected drawdown depth and the trader's tolerance for portfolio volatility. At 1%, drawdowns are shallow but recovery from losing streaks is slow — capital is preserved but not deployed aggressively. At 3–5%, the strategy compresses recovery times but produces deeper intra-period drawdowns. Values between 1% and 2% cover most systematic equity strategies that are not high-frequency.

One additional input transforms percentage sizing from a dollar-risk rule into a share-count rule: the stop distance. If the strategy risks 2% of capital on a stock with a stop placed $4.00 below entry, the position size in shares is (capital * 0.02) / 4.00. A $50,000 portfolio with a $4.00 stop would take 250 shares. The dollar risk is exactly $1,000 if the stop triggers.

The Kelly Criterion

The Kelly Criterion is a formula from information theory — developed by John Kelly at Bell Labs in 1956 — that computes the mathematically optimal fraction of capital to bet on each trade to maximize the long-run geometric growth rate of the portfolio. Given a strategy's win rate, average win, and average loss, Kelly produces the fraction that makes your money grow fastest over time.

The formula is:

Kelly fraction = (b × win_rate − (1 − win_rate)) / b
where b = avg_win / avg_loss

At win_rate = 0.55, avg_win = $200, avg_loss = $150: b = 1.33, Kelly = (1.33 × 0.55 − 0.45) / 1.33 = 0.21. Full Kelly says bet 21% of capital on this trade.

Full Kelly is mathematically optimal in expectation but operationally brutal in variance. At 21% per trade, a sequence of six consecutive losses — which is routine for a 55% win-rate strategy — reduces capital by 74%. The path to the optimal long-run outcome runs through drawdowns that most traders will not hold through. In practice, full Kelly leads to strategy abandonment before the compounding payoff arrives, which negates the mathematical optimum entirely.

Half-Kelly is the standard practical compromise. Bet half the Kelly fraction, accepting a lower expected long-run growth rate in exchange for roughly half the variance. The trade is well-documented: half-Kelly captures approximately 75% of the full-Kelly expected growth rate while producing significantly smaller drawdowns.

def kelly_size(capital: float, win_rate: float, avg_win: float, avg_loss: float, fraction: float = 0.5) -> float:
    if avg_loss == 0:
        return 0
    b = avg_win / avg_loss
    kelly_f = (b * win_rate - (1 - win_rate)) / b
    return capital * max(0, kelly_f) * fraction  # half-Kelly by default

The fraction parameter defaults to 0.5 for half-Kelly. Setting it to 1.0 produces full Kelly; setting it to 0.25 produces quarter-Kelly for conservative applications.

Two inputs require care. Win rate and average win/loss should be estimated from a sufficiently long out-of-sample period — not from the in-sample window used to optimize the strategy. Kelly computed on in-sample statistics is likely overfitted: the true win rate and average win are lower than the backtest suggests. Start with a conservative estimate of both inputs, and update them quarterly using live performance data.

Kelly also assumes that each trade is independent and that the win/loss parameters are stable. In practice, strategies exhibit serial correlation in outcomes — winning streaks and losing streaks occur more often than independent draws would predict. This makes Kelly sizing slightly more aggressive than a strictly independent-trade model would justify. Half-Kelly provides a buffer against this.

Volatility-Adjusted Sizing

Percentage-of-equity and Kelly both treat each trade as having the same volatility profile. They do not adjust for the fact that a position in a highly volatile asset carries more risk per dollar than a position in a calm one. Volatility-adjusted sizing corrects for this: it scales position size inversely with recent asset volatility, so that the dollar risk per trade remains constant regardless of which asset is being traded.

The standard implementation uses the Average True Range (ATR) as the volatility measure. ATR captures the average daily price range over a lookback period, accounting for overnight gaps. A stock with a 14-day ATR of $3.00 moves more in a typical day than one with a 14-day ATR of $0.50. If both stocks have the same entry and the same dollar risk budget, the position in the high-ATR stock should be smaller in share count.

def volatility_adjusted_size(capital: float, atr: float, price: float, risk_pct: float = 0.02) -> float:
    if atr == 0 or price == 0:
        return 0
    dollar_risk = capital * risk_pct
    return dollar_risk / atr  # shares sized so 1 ATR move = risk_pct of capital

atr is the 14-day (or configurable-period) Average True Range in dollar terms for the specific asset. A stock trading at $40 with a 14-day ATR of $2.00 moves approximately 5% in a typical session. A stock trading at $40 with a 14-day ATR of $0.50 is a low-volatility instrument.

dollar_risk is the capital fraction you are willing to lose if the position moves one ATR against you. At 2% risk on a $50,000 portfolio, dollar_risk = $1,000. Dividing by the ATR gives the share count such that one ATR move equates to exactly $1,000 in loss.

The result is that the strategy's risk per trade stays constant across instruments. Trading a biotech stock with ATR $4.00 and a utility stock with ATR $0.60 in the same portfolio, both at 2% risk: the biotech position is 250 shares, the utility position is 1,667 shares. The dollar risk is identical. The contribution to portfolio volatility from each trade is normalized.

This normalization matters when a strategy runs a multi-ticker universe. Without volatility adjustment, the portfolio's risk profile is dominated by the most volatile instruments in the universe — the low-volatility names barely move the needle while the high-volatility ones drive most of the drawdown. Volatility-adjusted sizing levels this distribution, making each trade's contribution to portfolio variance proportional to its allocation.

ATR period selection. A 14-day lookback is the conventional starting point. Shorter lookbacks (7 days) make sizing more reactive to recent volatility changes — useful if the strategy trades in volatility-regime-aware conditions. Longer lookbacks (21–30 days) produce more stable sizes that are less disrupted by single-day spikes. The right choice depends on the strategy's time horizon: short-holding-period strategies benefit from reactive ATR; longer-holding strategies benefit from stable ATR.

Python Implementation

All four methods as a unified reference:

def fixed_dollar_size(capital: float, fixed_amount: float) -> float:
    return fixed_amount

def pct_equity_size(capital: float, risk_pct: float = 0.02) -> float:
    return capital * risk_pct

def kelly_size(capital: float, win_rate: float, avg_win: float, avg_loss: float, fraction: float = 0.5) -> float:
    if avg_loss == 0:
        return 0
    b = avg_win / avg_loss
    kelly_f = (b * win_rate - (1 - win_rate)) / b
    return capital * max(0, kelly_f) * fraction  # half-Kelly

def volatility_adjusted_size(capital: float, atr: float, price: float, risk_pct: float = 0.02) -> float:
    if atr == 0 or price == 0:
        return 0
    dollar_risk = capital * risk_pct
    return dollar_risk / atr  # shares sized so 1 ATR move = risk_pct of capital

A quick simulation of the four methods across a 10-trade losing streak on a $50,000 starting portfolio, assuming 2% risk (or $1,000 fixed) and $150 average loss per trade:

import math

def simulate_losing_streak(method: str, starting_capital: float, trades: int = 10) -> float:
    capital = starting_capital
    for _ in range(trades):
        if method == 'fixed_dollar':
            loss = 1000
        elif method == 'pct_equity':
            loss = capital * 0.02
        elif method == 'kelly_half':
            # 55% win-rate, avg_win=200, avg_loss=150 → kelly_f≈0.21, half=0.105
            loss = capital * 0.105
        elif method == 'vol_adjusted':
            # Assume ATR stays constant; risk_pct=0.02
            loss = capital * 0.02  # same as pct_equity in this simplified case
        capital -= loss
    return capital

for method in ['fixed_dollar', 'pct_equity', 'kelly_half', 'vol_adjusted']:
    final = simulate_losing_streak(method, 50000)
    drawdown = (50000 - final) / 50000
    print(f"{method:25s}  final: ${final:,.0f}  drawdown: {drawdown:.1%}")

Sample output:

fixed_dollar               final: $35,000  drawdown: 30.0%
pct_equity                 final: $40,957  drawdown: 18.1%
kelly_half                 final: $29,832  drawdown: 40.3%
vol_adjusted               final: $40,957  drawdown: 18.1%

Half-Kelly at a 10.5% per-trade fraction (derived from the 55% win-rate example) produces the deepest drawdown under a sustained losing streak — confirming that Kelly sizing requires a genuine edge estimate, not an optimistic one. Percentage-of-equity and volatility-adjusted sizing produce comparable drawdowns in this simplified model; the difference between them appears in multi-instrument portfolios where volatility varies across positions.

The Oyamori Approach

Oyamori applies volatility-adjusted sizing as the default for all edge categories. Each edge in the catalog carries its own risk allocation parameter — the fraction of portfolio equity allocated to that edge family — and sizes individual trades within that allocation using ATR normalization. This means a gap trading signal and a mean reversion signal coexist in the same portfolio without one edge's volatility profile dominating the other's.

The platform surfaces the sizing calculation alongside each trade signal: entry price, stop level, ATR, computed share count, and dollar risk at stop. This makes the sizing logic visible and auditable rather than a background assumption. If the ATR for an instrument spikes due to earnings, the computed position size decreases automatically before the trade is taken.

For traders building their own sizing framework, starting with percentage-of-equity (2% risk per trade) and migrating to volatility-adjusted sizing once the ATR data pipeline is in place is the most reliable path. Kelly sizing is worth computing for edge quality assessment — a strategy with a negative Kelly fraction has no edge and should not be traded — but as a live sizing mechanism, half-Kelly at conservative win/loss estimates is the appropriate application.

Next: Drawdown Limits and Kill Switches →