September 12, 2026 · risk

Five sizing rules, one signal: the part of your backtest doing the real work

Five sizing rules, one signal: the part of your backtest doing the real work

Your entry signal is probably the least consequential thing in your backtest. I can take one mediocre momentum rule, leave every entry and exit timestamp untouched, change only the function that decides how many contracts to hold, and move net Sharpe from 0.41 to 0.71 and max drawdown from 31% to 13%. Same trades. Same fills. Different strategy.

That claim annoys people, and it should, because it implies most of the time spent tuning lookbacks and filter thresholds is spent on the small term. So let me show the actual runs, then give the critics their due, because there's a version of this argument that's wrong and it's worth knowing which version I'm making.

One signal, six ways to hold it

The signal: ETHUSDT perpetual on Binance USDⓈ-M, 1-hour bars, long when the 12-hour EMA is above the 96-hour EMA, flat otherwise, no shorts. July 2022 through June 2026. 431 round trips. Taker fees both sides at 5.0 bps, funding paid or received every eight hours on the actual position, slippage modelled off top-of-book depth. It's a deliberately boring signal — I picked it because nobody would defend it, which makes it a clean test surface.

Every row below shares identical entry and exit bar timestamps. The only difference is the sizing function.

Sizing ruleNet SharpeMax DDNotional traded/yr (× avg position)Costs as % of gross PnLPeak leverage
Fixed $10k notional0.4118.2%246×14%1.0×
Fixed fraction, 100% of equity0.4430.8%251×15%1.0×
Inverse 20-day realized vol0.6814.1%690×29%4.4×
20% annualized vol target, hourly rebalance, uncapped0.7112.9%1,180×41%6.3×
20% vol target, 20% no-trade band, 3× leverage cap0.6615.3%402×19%3.0×
Half-Kelly on 60-day rolling mean/variance0.5224.6%830×33%8.1×
0.41 → 0.71net Sharpe, identical entries
41%of gross PnL eaten by hourly rebalancing
6.3×peak leverage the best-Sharpe run quietly used

Look at the spread. Between the worst and best rows there's a 73% relative difference in Sharpe and a factor of 2.4 in drawdown. Now go find me an entry-signal parameter on this dataset that moves Sharpe by 0.30 without also being obvious overfitting. I've looked. The EMA pair length moves it by about 0.12 across the entire plausible grid, and most of that movement is noise you can't hold onto out of sample.

Why inverse-vol looks so good, and how much of it is real

The mechanism is not mysterious. Under fixed notional, your position size is uncorrelated with realized volatility, which means your dollar risk per trade is proportional to whatever vol happens to be that week. On ETH over this window, 20-day realized vol ranged from 31% to 118% annualized. The fixed-notional run took 3.8× more dollar risk in March 2024 than in July 2023, not because the signal was more confident, but because the market was louder. Almost all of its drawdown is concentrated in the top vol quintile. Inverse-vol sizing removes that coupling, and removing it is a genuine improvement in the shape of the return stream.

But part of the Sharpe gain is a measurement artifact, and if you don't separate the two you'll make bad decisions downstream. Sharpe divides by the standard deviation of returns. Vol targeting is, definitionally, an operation that stabilizes the standard deviation of returns. You are optimizing the denominator directly. A rule that scales positions to hit constant ex-ante vol will improve Sharpe on almost any return stream with vol clustering, including streams with zero edge. I've verified that on shuffled signals: randomize the entry timestamps, keep the vol-target overlay, and Sharpe still improves by roughly 0.06 relative to fixed notional on a zero-mean base. Small, but nonzero, and it's pure mechanics.

So when I compare sizing rules internally, Sharpe is never the only number on the sheet. I want Calmar, I want net PnL per unit of average deployed notional, and I want the gross-to-net waterfall, because those three together are much harder to game with a denominator trick.

The vol estimate is a model, and it leaks like one

The single most common way a good sizing result turns out to be fake: the volatility estimate uses information from the bar it's sizing. If your vol series is computed with a centered window, or with pandas' default `rolling().std()` applied after a resample that includes the current partial bar, or from a full-sample standardization, you have leakage. It's subtle because vol is persistent, so the leak is small on any given row and the equity curve still looks plausible. It just looks a little too smooth in exactly the weeks that matter.

Our agents check four things on every sizing rule before a result gets promoted to the paper-trading queue:

  1. Decision-time availability. The size used on the bar opening at 14:00 must be computable from data whose close timestamp is ≤ 13:59:59.999. We assert this by recomputing the size series from a truncated frame at a random sample of 200 decision points and diffing.
  2. Estimator lookback is a real parameter. A 20-day vol window and a 60-day vol window are two different strategies. The lookback goes into the walk-forward grid with everything else, and if the result only works at one window length, that's a finding about fragility.
  3. Leverage path, not just leverage peak. Print the full distribution of gross leverage. The uncapped vol-target run above spent 4% of its hours above 5×, which is the kind of thing that never appears in a summary table and completely determines whether the strategy is implementable.
  4. Sizing sensitivity as a robustness test. If Sharpe collapses when you change the vol target from 20% to 25%, the strategy isn't vol-targeted, it's leverage-tuned, and you've found your edge by picking a number.

The leverage cap is not a risk-management garnish, it's part of the strategy definition. Binance's ETHUSDT tiers cut max leverage as position notional grows, and the maintenance margin rate steps up with it. A backtest that lets the vol-target rule run to 6.3× at a $400k notional is describing a position the venue will not let you hold at that margin. The capped row in the table costs 0.05 Sharpe and is the only one of the two that describes something real.

Rebalancing is where the money goes

Notice the cost column. Hourly rebalancing to a vol target gave the best headline Sharpe and also handed 41% of gross PnL to the exchange. That's 1,180× average position notional traded per year at 5 bps a side plus spread and impact. The naive fix is to rebalance less often, on a schedule. The better fix is a no-trade band: only resize when the current position deviates from target by more than some threshold.

A 20% band cut annual traded notional from 1,180× to 402× — a 66% reduction — and cost 0.05 of Sharpe. I've run this on eight signals now and the shape repeats: bands between 15% and 25% recover most of the risk-control benefit at a third of the turnover, and anything below 10% is just paying fees for cosmetic precision in a quantity you're estimating with a 20-day window anyway. You don't get to rebalance to three decimal places against a number that has a standard error of 15%.

We had a run in February where the report an agent wrote credited a 0.22 Sharpe improvement to "the improved entry filter." The diff was one line in the sizing module. The filter hadn't changed. I now make the report print the sizing config hash at the top, because attribution is a discipline and models are as happy to tell a tidy story as anyone else.

What paper trading does to your sizing rule

This is where the gap between backtest and paper opens widest, and it's mostly arithmetic. Vol-responsive sizing means your position size swings by a factor of 4 to 8 across the sample. Both ends of that range hit venue constraints the backtest never modelled.

At the small end: step size and minimum notional. ETHUSDT perp has a 0.001 quantity step and a $5 minimum. If your low-vol-regime size is 0.0004 ETH, the backtest holds it and paper holds nothing. That sounds like a corner case until you realize a vol-target rule puts its smallest sizes in the calmest markets, which on a trend signal is frequently where the good entries are. At the large end: position limits, margin tiers, and the fact that a 6× position needs isolated-margin discipline you didn't backtest a liquidation model for.

We caught one where the paper equity curve tracked the backtest to within 3% for six weeks and then diverged hard. The cause was rounding: `int()` truncation instead of rounding-to-step in the order sizer, applied to positions that averaged 1.4 steps. The backtest was sizing in continuous space and the live sizer was losing 20-30% of the intended position on every small trade. No fill-model exotica, no latency story. Truncation.

Where the critics are right

Three objections land, and I don't want to sell past them.

First, and most important: sizing allocates edge, it can't manufacture it. If your signal's gross expectancy is at or below zero after realistic fees and funding, every rule in that table loses money — the fancy ones just lose it with a prettier variance profile. I chose a signal with a small but positive net edge on this window. Run the same six rules on a signal with −1.2 bps per trade net and the ranking is preserved while every terminal equity is below the starting point. Sizing is a multiplier on something. You still need the something.

Second, vol targeting has a real and well-documented failure mode: it delevers into the bottom of a fast selloff and relevers after the snap-back. In a sharp V, fixed notional wins, sometimes by a lot. March 2020 in equities and the August 2024 crypto unwind both punished vol-responsive sizing on the recovery leg. My four-year ETH window happens to contain more vol-clustered grinding than V-shaped whipsaw, which flatters the inverse-vol rows. A different window flips some of the ordering, and if I'd led with a table from 2020 I'd be making a weaker version of this argument.

Third, the sizing rule is as overfittable as anything else. Half-Kelly on rolling estimates is the tell in my table: it looks sophisticated, it's theoretically motivated, and it produced the second-worst drawdown because the rolling mean estimate of a noisy return series is garbage and Kelly is brutally sensitive to it. Any sizing rule that takes an expected-return estimate as an input inherits the error in that estimate, amplified. Rules that use only a variance estimate are much better behaved, because variance is the one moment you can actually estimate from four years of hourly data.

What I'd keep from all this: when a backtest result surprises you, check the sizing module before you go looking for cleverness in the signal. And when you report a Sharpe, report the leverage path and the cost waterfall next to it, because a number that depends this heavily on a sizing decision is not a property of the signal at all.

position sizingvolatility targetingsharpe ratiorisk managementbacktesting
← All posts