Skip to content

Portfolio construction and risk · Intermediate

Volatility targeting

Sizing positions by forecast risk to keep the risk carried roughly constant, and where the rule stops protecting.

27 min read21 referencesIntroduction to the series

Educational material only. Not investment advice.

Contents
  1. 01The rule
  2. 02Forecasting volatility
  3. 03What it achieves, and where
  4. 04A worked example
  5. 05A century of US data
  6. 06An interactive laboratory
  7. 07Costs, turnover and leverage caps
  8. 08Failure modes
  9. 09Implementation checklist
  10. —References

Abstract

Volatility targeting sizes each position as target volatility divided by forecast volatility. The rule stabilises risk in each asset class studied, but raises the Sharpe ratio mainly where expected returns do not rise with volatility, as in equities and credit. Judged against a constant exposure with the same volatility, nearly a century of US data shows a modest gain on the market, too small to be statistically distinguished from zero, and a large, clear one on the momentum factor.

Key takeaways

  • Returns are hard to forecast but volatility is not, because it clusters; volatility targeting uses that to size positions.
  • Choose one way to state the estimator’s memory (span, half-life or decay factor) and convert the others to it; an EWMA with a half-life of a few weeks is a sensible default.
  • The rule reliably stabilises risk and reduces extreme losses. It improves the Sharpe ratio mainly where expected returns do not rise with volatility, notably equities and credit.
  • Judge it against a constant exposure with the same volatility, not against the unscaled asset.
  • The rule reacts after the event, cannot see jumps or gradual declines, and is most exposed after long calm periods.

Before you start

  • Daily returns, standard deviation and annualisation by the square root of time
  • Leverage, and how it scales both return and risk
  • Indicators and the 200-day moving average, for the backtest conventions and the realised-volatility function

Volatility targeting sizes a position in inverse proportion to its forecast volatility, so that the risk carried stays roughly constant: less exposure when an asset is turbulent, more when it is calm. It works because volatility clusters and is far easier to forecast than returns. The risk control it delivers is dependable. The improvement in risk-adjusted return is not, and depends on the asset. There are also conditions, such as sudden jumps and slow, quiet declines, in which the rule offers little protection at all.

The rule

Choose a target volatility, forecast the asset’s volatility, and size the position as their ratio:

wt  =  min( L,  σtarget / σt )
exposure held over day t

Here σtarget is the annualised volatility the strategy aims to run at, σt is the annualised forecast made at the close of day t − 1 from returns up to that close, and L is a cap on leverage. With a 10% target and an asset running at 20%, the rule holds half a unit of exposure; if the asset calms to 8%, it holds one and a quarter, subject to the cap.

Figure 1The daily sizing loop
Sizing loop: returns to forecast to target weight to band check to order to position, feeding back the next returntomorrow’s inputReturnsup to close t−1Forecast σ̂ₜEWMA, span sTarget weightmin(L, σtarget / σ̂ₜ)Band checktrade if |Δw| > b·wOrderat the closePosition over day tearns rₜ, pays costs
Information flows left to right once a day. The forecast and the weight use returns up to the close of day t − 1; the order executes and the position earns day t’s return. The no-trade band sits between the target weight and the order.

The rule relies on an asymmetry in what can be forecast. Tomorrow’s return is very hard to predict; tomorrow’s volatility is substantially more predictable, because volatility clusters: large moves tend to follow large moves and quiet days tend to follow quiet days. Mandelbrot documented the pattern in commodity prices in the 1960s, and it is among the best-established regularities in financial returns.1,2 Volatility targeting uses that forecasting power for the one decision it can inform: the size of the position.

Scaling by 1/σ holds volatility constant. Scaling by 1/σ2, the weight a mean-variance investor would choose if expected returns did not change, varies exposure much more aggressively; that is the form studied by Moreira and Muir, discussed below.3

Forecasting volatility

Most of the design choices concern the forecast in the denominator. Every estimator trades responsiveness against noise: one that reacts quickly to a new regime also reacts to random fluctuations, and each reaction is a trade that must be paid for.

Rolling window

The root mean square of the last n daily returns (a standard deviation measured about zero), annualised by multiplying by the square root of the number of trading days in a year: 252 today, and about 294 before 1952, when US markets also opened on Saturdays (the real-data code counts them from the calendar). It is simple to explain and to audit. (On real data the laboratory uses the ordinary standard deviation about the mean, the realised_vol function listed in Indicators and the 200-day moving average. The two differ little except for the shortest windows, where subtracting the mean of a handful of returns adds noise: a 5-day window misses the next month’s volatility by a typical factor of 1.74 about the mean and 1.65 about zero, on the measure of Figure 3.) Its weakness is that every day in the window carries equal weight and then drops out at once, so the estimate jumps when an old shock leaves the window, weeks after anything actually happened.

Exponentially weighted moving average (EWMA)

Each day the daily variance estimate vt moves a fixed fraction of the way towards the latest squared return:

vt  =  λ · vt−1  +  (1 − λ) · rt−12,     σt = √(252 vt)
EWMA update; annualised with 252 trading days a year (the calendar’s count on real data)

Recent days count most and old days fade smoothly, so there is no cliff when a shock ages out. The memory can be described in three equivalent ways, and this note uses them consistently: the decay factor λ; the span s, with λ = 1 − 2/(s + 1); and the half-life, the number of days after which a return’s weight has halved, ln 0.5 / ln λ. J.P. Morgan’s RiskMetrics document popularised λ = 0.94 for daily data,4 a half-life of about 11 trading days. That value was calibrated for one-day value-at-risk. For sizing positions a longer memory is usually preferable, because it trades less: a half-life of roughly two to six weeks (about 10 to 30 trading days) is a reasonable range, and the laboratory below defaults to a span of 60 days, a half-life of 21.

site_research/fieldnotes/voltarget.py, backtest.py
def sessions_per_year(index: pd.DatetimeIndex) -> pd.Series:
    """Trading sessions in the year up to each date: the number that turns a daily volatility
    into an annual one AT THAT TIME.

    252 is right only for the modern calendar. Before 1952 US markets also traded on Saturdays
    (about 294 sessions a year), and a forecast annualised with the square root of 252 then
    understates annual volatility. Counted over the trailing 365.25 days, which uses only dates
    already seen; before a full year has passed, the sessions seen so far are scaled up to a year
    (counting the rest of the first year would use dates not yet seen).
    """
    days = index.values.astype("datetime64[D]").astype(np.int64)
    lo = np.searchsorted(days, days - 365.25, side="right")
    n = (np.arange(len(days)) - lo + 1).astype(float)
    elapsed = days - days[0] + 1
    n = np.where(elapsed <= 365.25, n * 365.25 / elapsed, n)
    return pd.Series(n, index=index)


def ewma_vol(ret: pd.Series, span: int = 60, periods=None, seed_days: int = 20) -> pd.Series:
    """Annualised EWMA volatility with decay lambda = 1 - 2 / (span + 1).

    v_t = lambda * v_{t-1} + (1 - lambda) * r_t^2, seeded with the mean square of the first
    `seed_days` returns. The mean is taken as zero, which costs little at daily frequency.
    `periods` defaults to the sessions per year at each date (`sessions_per_year`), the same
    calendar basis `backtest.stats` reports realised volatility on.
    """
    periods = sessions_per_year(ret.index).to_numpy() if periods is None else periods
    lam = 1.0 - 2.0 / (span + 1.0)
    r2 = ret.pow(2).to_numpy()
    v = np.empty_like(r2)
    v[: seed_days] = np.nan
    acc = r2[:seed_days].mean()
    for t in range(seed_days, len(r2)):
        acc = lam * acc + (1.0 - lam) * r2[t]
        v[t] = acc
    return pd.Series(np.sqrt(v * periods), index=ret.index)
The estimator used for every real-data number in this note, with the calendar’s count of trading days that annualises it. The value in row t includes rₜ, so row t is the forecast the notation calls σ̂ₜ₊₁; the backtest applies the weight it produces from t + 1.

GARCH and related models

Engle’s ARCH model and Bollerslev’s generalisation, GARCH, make volatility clustering an explicit statistical model in which forecasts revert towards a long-run level.5,6 The GJR variant allows negative returns to raise volatility more than positive returns of the same size.7 An EWMA is the special case with no reversion. GARCH can therefore produce better multi-day forecasts; for a one-day-ahead sizing decision the two often differ little, and GARCH’s parameters must be estimated and can drift.

Range-based and intraday estimators

Closing prices discard most of what happens during the day. Estimators built from the daily open, high, low and close use more of it. Under idealised assumptions Parkinson’s high-low estimator is about five times, and Garman and Klass’s about seven times, as efficient as the close-to-close estimator;8,9 both are biased by discrete sampling and by overnight moves, which Yang and Zhang’s estimator is designed to handle.10 With intraday data, squared five-minute returns can be summed into a realised variance, and Andersen, Bollerslev, Diebold and Labys showed that realised volatility can be modelled and forecast directly.11 The five-minute interval is a compromise against market-microstructure noise. Corsi’s HAR model, a regression on daily, weekly and monthly realised volatility, is a simple and robust way to forecast it.12 Better inputs give a less noisy forecast for the same responsiveness, which reduces turnover.

EstimatorResponse to a new regimeNoise in the estimateData required
Rolling windowSlow, then drops shocks abruptlyHigh for short windowsDaily closes
EWMASmooth; speed set by the half-lifeModerateDaily closes
GARCH familySmooth, with mean reversionLower, if the model fitsParameter estimation
Range-basedAs for its windowLower than close-to-closeOpen, high, low, close
Realised (intraday)FastLowest, if microstructure noise is handledClean intraday data

What it achieves, and where

Holding risk constant is, first, a risk-management device, and for most assets that is most of what it achieves. For some assets it also improves return per unit of risk. The evidence repays careful reading, because the headline results and the details differ.

Stable risk and a thinner left tail

Because volatility persists, a position scaled by a recent estimate carries much more stable risk than a fixed position: the realised volatility of a targeted strategy stays far closer to its target than the asset’s own volatility stays to its average. In the broadest study of the subject, Harvey and co-authors found that volatility targeting reduced the likelihood of extreme returns in every asset class they examined.13 This benefit is largely mechanical. It is also conditional: it depends on turbulence building up over several days, and it does not apply to a sudden jump that arrives while the position is large (see Failure modes).

When the Sharpe ratio improves

Whether volatility targeting also raises the Sharpe ratio depends on how an asset’s expected return moves with its volatility. If expected returns rose in proportion to variance, the square of volatility, a constant exposure would already be the best choice, and cutting exposure in turbulent periods would lower the Sharpe ratio. If they rose in proportion to volatility itself, the reward per unit of risk would be the same every day; holding risk constant captures it exactly and still beats a constant exposure. If expected returns do not rise with volatility, or fall, exposure is being cut precisely when the reward for bearing risk is lowest, and the Sharpe ratio improves by more. Even with a constant expected return part of the gain is mechanical, because the average of 1/σ exceeds 1/√(average of σ2).

In equities the evidence points to the favourable case. Black and Christie documented that stock prices and volatility tend to move in opposite directions, the so-called leverage effect;14,15 the name is partly a misnomer, since Christie found that financial leverage explains only part of it, and a competing explanation, volatility feedback, runs from higher volatility to lower prices through a higher required return.16 (The leverage effect is unrelated to the leverage cap in the rule above.) Moreira and Muir found that portfolios scaled by the inverse of recent variance earned positive and mostly significant alphas relative to the unmanaged versions of the market and several equity factors, because expected returns did not rise in step with variance.3 Earlier, Fleming, Kirby and Ostdiek showed that investors would pay a meaningful fee to time volatility in an asset-allocation setting,17 and Barroso and Santa-Clara found that scaling equity momentum by its own recent volatility largely removed its crashes and roughly doubled its Sharpe ratio in their sample.18

Harvey and co-authors, working across more than sixty assets, found Sharpe-ratio improvements for equities and credit, which they attributed to the leverage effect, and little change for government bonds, currencies and commodities.13 Their results are a reasonable baseline expectation.

The sceptical evidence

Two cautions apply to the stronger claims. Moreira and Muir’s scaling constant, and the combination of managed and unmanaged portfolios implied by their alphas, are estimated over the full sample. Cederburg, O’Doherty, Wang and Yan tested variance-managed versions of 103 equity strategies and found that, once those choices had to be made in real time, the managed versions did not systematically outperform.19 On balance, the evidence supports volatility targeting as a reliable way to stabilise risk and reduce the frequency of extreme losses, and as a conditional, asset-dependent way to improve the Sharpe ratio.

A worked example

A single day of arithmetic shows the mechanism, and why the rule reacts after the event. Take a 12% target and an EWMA forecast with λ = 0.94. The current daily volatility estimate is 1.00%, which annualises to 15.9%. The position is therefore 12% / 15.9% = 0.76 units of exposure.

The asset then falls 3% in a day. The position loses 0.76 × 3% = 2.27% of capital: the rule could not anticipate the move, so the first day of turbulence is always taken at the previous size. At the close the estimate updates:

v  =  0.94 × (1.00%)2  +  0.06 × (3%)2  =  0.000148

That is a daily volatility of 1.22%, or 19.3% annualised, so the next day’s position becomes 12% / 19.3% = 0.62. One large day reduced exposure by about 18%, and exposure recovers only as subsequent calm days dilute the shock.

Before the moveAfter the move
Daily volatility estimate1.00%1.22%
Annualised (× √252)15.9%19.3%
Position for a 12% target0.76×0.62×

Values computed from the formulas above.

A century of US data

The rule is easy to test on public data. The Kenneth R. French Data Library publishes the daily total return of the US stock market (the CRSP value-weighted index) and of the momentum factor back to 1926, with the one-month Treasury bill return. Applying the rule with a 12% target, an EWMA with a 60-day span, a 2× cap, a ±10% no-trade band and 5 bp per unit traded, from 5 May 1927 to 31 August 2026 (momentum from 3 September 1927), gives the following. Unused capital earns T-bills; the momentum factor is self-financing and holds no cash leg. The results are historical and hypothetical: a textbook rule applied to an index, not the returns of any account.20 The momentum factor is itself a paper portfolio: its own rebalancing costs and short-borrow fees are not charged here (only the 5 bp on each change in the overlay’s weight), and a weight of 1× in it means one unit long and one unit short, so the 2× cap corresponds to about 4× of gross stock positions. Its returns are therefore higher than an investor could have earned. The comparison with the matched exposure carries over better, although the targeted version, at an average weight of 1.34×, would have borne more of those costs.

US market, Sharpe ratio
0.57
matched constant exposure 0.46
US market, worst drawdown
−52%
matched −71%, unscaled −84%
Momentum, Sharpe ratio
1.04
matched constant exposure 0.49
Momentum, worst drawdown
−38%
matched −68%, unscaled −72%
Market 1 ×Market, matchedMarket, targetedMomentum 1 ×Momentum, matchedMomentum, targeted
Annual return10.2%8.4%9.8%5.7%5.2%11.9%
Annual volatility17.5%12.3%12.3%12.9%11.6%11.6%
Sharpe ratio0.460.460.570.490.491.04
Worst drawdown−84.1%−70.9%−52.5%−72.3%−67.8%−38.4%
Worst day−17.4%−12.2%−10.4%−18.5%−16.6%−11.3%
Turnover a year——1.8×——1.7×

Kenneth R. French Data Library, daily: the market 5 May 1927 to 31 August 2026, momentum 3 September 1927 to 31 August 2026. Market Sharpe ratios are of returns in excess of T-bills; momentum returns are long-short returns earning no interest on collateral, so their annual returns and drawdowns are not comparable with the market’s (their Sharpe ratios are, since both are returns in excess of cash). “Matched” is a constant exposure scaled after the fact to the targeted path’s volatility (0.70× for the market, 0.90× for momentum); a constant scaling leaves the Sharpe ratio unchanged, so the matched column’s equals the unscaled column’s by construction, and what it changes is return, volatility and drawdown. Annualised from the calendar (see Forecasting volatility).

Two results stand out, and both agree with the literature. On the market, the targeted rule beat the volatility-matched constant exposure on Sharpe ratio (0.57 against 0.46) and on drawdown. The gain, about 0.10, is modest relative to its uncertainty: resampling whole calendar years gives it a standard error of about 0.06, so a 95% interval runs from roughly −0.02 to 0.22. It includes zero: on its own the gain is suggestive, not significant at the 5% level. It is not concentrated in the famous crashes: summed by decade, the targeted rule’s excess return over the matched exposure was largest in the 1940s and 1950s and was negative in the 1930s, the 1970s and the 2020s, when volatility spiked and then fell before the rule had rebuilt its exposure. The improvement is a long-run average.

On momentum the effect is much larger and much clearer: against the matched exposure the Sharpe ratio roughly doubled (0.49 to 1.04, standard error of the gain about 0.08), close to the doubling Barroso and Santa-Clara reported (0.53 to 0.97) with a six-month realised-variance estimator and monthly rebalancing,18 and the worst drawdown fell from 68% to 38%, because momentum’s crashes arrive in high-volatility rebounds.21 (The unscaled factor’s worst drawdown lasted a decade, from 1932 to 1942; the momentum series in Market anomalies shows it.)

These are full-sample, single-path results with parameters chosen in advance rather than tuned; the laboratory below lets the reader vary them and see how much the conclusions depend on the choices.

The market’s worst drawdown in the table, and the targeted rule’s, both came in the decline that began in 1929.

Step by stepHow scaling reshaped the drawdown of 1929–32
0.000.250.500.751.00Growth, the 1929 high = 119301931193219333 Sep 19298 Jul 1932Drawdown from the 1929 high0%−25%−50%−75%−84.1%Forecast volatility, annualised (EWMA, 60-day span)0%20%40%60%80%100%12% target78%, 15 Nov 1929Exposure held = target / previous forecast, banded0.0×0.5×1.0×0.69×0.16×0.73×Drawdowns from the 1929 high0%−25%−50%−75%−84%−71%−52%
  1. Step 1 of 4

    The raw series

    On 3 September 1929 the US market closed at its high. Held at exposure one, with dividends reinvested, it then lost 84.1% by 8 July 1932: the deepest drawdown in the record, and the one in the table’s first column.

  2. Step 2 of 4

    The forecast

    The rule’s forecast of annual volatility stood at 16% on the day of the high. The crash of October 1929 drove it to 78% by 15 November 1929, 6.5 times the 12% target.

  3. Step 3 of 4

    The scaled series

    The exposure held is set from the previous close’s forecast, and re-traded only outside the ±10% band: 0.69× at the high, and 0.16× by 15 November 1929, so much of the fall that followed was taken with a small position. When volatility subsided in the spring of 1930 the rule rebuilt its exposure to 0.73× by 21 April 1930, shortly before the next leg of the decline, and it shared in that leg.

  4. Step 4 of 4

    The drawdowns compared

    From the 1929 high the market at exposure one fell 84.1%. A constant 0.70× exposure, matched to the targeted strategy’s volatility over the whole century, fell 70.9%, and the targeted strategy 52.5%. Holding less on average accounts for 13.2 percentage points of the improvement; holding less when the forecast was high accounts for the other 18.4.

US market total return and one-month T-bills, Kenneth R. French Data Library, daily, January 1929 to December 1933. The rule of the table above: a 12% target, an EWMA forecast with a 60-day span, a 2× cap, a ±10% no-trade band and 5 bp per unit traded, each day’s exposure decided at the previous close. Every path is rebased to 1 on the market’s 1929 high. Without script, or with reduced motion, the figure shows its final state.

The whole backtest is two functions: the sizing rule with its band, and a loop that lags the weight, charges costs and holds cash.

site_research/fieldnotes/voltarget.py
def target_weights(forecast: pd.Series, target: float = 0.12, cap: float = 2.0,
                   band: float = 0.0) -> pd.Series:
    """w = min(cap, target / forecast), traded only when it moves more than `band` (a fraction of
    the current weight) away from the weight held."""
    raw = (target / forecast).clip(upper=cap)
    held = np.full(len(raw), np.nan)
    cur = np.nan
    for i, x in enumerate(raw.to_numpy()):
        if np.isnan(x):
            continue
        if np.isnan(cur) or abs(x - cur) > band * cur:
            cur = x
        held[i] = cur
    return pd.Series(held, index=raw.index).fillna(0.0)
site_research/fieldnotes/backtest.py
def run(ret: pd.Series, weight: pd.Series, cash: pd.Series | None = None,
        cost: float = 0.0, lag: int = 1) -> pd.DataFrame:
    """Daily P&L of holding `weight` in `ret`, the rest in `cash`.

    lag=1: the weight decided at close t earns the return of t+1 (trade at the signal's close).
    lag=2: trade one period later.  lag=0: LOOK-AHEAD (the signal earns its own day's return).
    cost:  a fraction of capital charged on every unit of exposure traded (0.001 = 10 bp).
    """
    w = weight.shift(lag).fillna(0.0)
    cash = pd.Series(0.0, index=ret.index) if cash is None else cash.reindex(ret.index).fillna(0.0)
    traded = w.diff().abs().fillna(w.abs())
    pnl = w * ret + (1.0 - w) * cash - cost * traded
    return pd.DataFrame({"ret": pnl, "weight": w, "traded": traded})
site_research/fieldnotes/backtest.py
def years_spanned(index: pd.DatetimeIndex) -> float:
    """Calendar years covered by a daily index, counting the last day in full."""
    return ((index[-1] - index[0]).days + 1) / 365.25


def stats(pnl: pd.Series, cash: pd.Series, periods: float | None = None,
          weight: pd.Series | None = None) -> dict:
    """The summary every table in the notes reports.

    periods=None annualises from the calendar: observations per year are counted from the
    dates, which matters for US data before 1952, when markets also traded on Saturdays.
    """
    wealth = (1.0 + pnl).cumprod()
    years = years_spanned(pnl.index) if periods is None else len(pnl) / periods
    periods = len(pnl) / years
    excess = pnl - cash.reindex(pnl.index).fillna(0.0)
    vol = pnl.std(ddof=1) * np.sqrt(periods)
    out = {
        "cagr": wealth.iloc[-1] ** (1.0 / years) - 1.0,
        "vol": vol,
        "sharpe": excess.mean() * periods / (excess.std(ddof=1) * np.sqrt(periods)),
        "max_dd": (wealth / wealth.cummax().clip(lower=1.0) - 1.0).min(),
        "worst_day": pnl.min(),
    }
    if weight is not None:
        out["time_in_market"] = weight.mean()
        out["switches"] = int((weight.diff().abs() > 1e-12).sum())
        out["turnover"] = weight.diff().abs().sum() / years
    return out
Every backtest table in the series reports these statistics, annualised from the calendar. Drawdowns are measured from a starting value of one, so an early loss counts.

An interactive laboratory

The laboratory runs the same computation in the browser, ported line for line from the Python above (the site’s build checks that the port reproduces the table). Choose the US market, the momentum factor, or twelve years (eleven after warm-up) of synthetic returns from a volatility-clustering process with fat tails, a stronger volatility response to falls than to rises and two one-day jumps that no forecast could anticipate. The synthetic series holds the expected return constant, so it isolates the mechanical effect of volatility clustering. In every case the weight for a day is set from returns up to the previous close.

The fair comparison is a constant exposure scaled to the same realised volatility as the targeted strategy (scaled after the fact, so it is a yardstick rather than a strategy anyone could have run). The asset at exposure one, at about 18% volatility (the US market here; the synthetic series is built around 18%), is simply a riskier position than a 12% target. The difference between the targeted strategy and the matched exposure is the value of timing the exposure. Across 40 synthetic histories with a 12% target, a 60-day span, a 2× cap and no band, the targeted strategy’s Sharpe ratio exceeded the matched constant exposure’s by +0.03 on average, with a standard deviation of 0.11, and was higher in 26 of the 40. Over eleven years, a difference of that size cannot be distinguished from zero on any single history, which is why the real-data results above, a century long, carry more weight. The synthetic history shown first is a median draw.

Figure 2A volatility-targeting laboratory
Data
Estimator
Leverage cap
No-trade band
Trading cost

5 May 1927 to 31 August 2026 (99 years): targeting 12%, realised volatility came in at 12.3% and 63-day volatility stayed within a quarter of the target 83% of the time. Against a constant exposure with the same volatility, the Sharpe ratio was 0.57 versus 0.46 and the worst drawdown −52.5% versus −70.9%, for 1.8× turnover a year.

Growth of 1 (log scale)1101001k10kRealised volatility, 63-day, annualisedtarget 12%0%20%40%60%80%Exposure held0×1×2×3×cap 2×1930194019501960197019801990200020102020
Exposure 1×Volatility-targetedConstant exposure, matched volatilityTarget
5 May 1927 to 31 August 2026 (99 years)Exposure 1×Constant, matched volVol-targeted
Annual return compound10.2%8.4%9.8%
Annual volatility realised17.5%12.3%12.3%
Sharpe ratio excess over T-bills0.460.460.57
Worst drawdown peak to trough−84.1%−70.9%−52.5%
Worst day−17.4%−12.2%−10.4%
Average exposure1.00×0.70×0.97×
Turnover a year one-way——1.8×

Kenneth R. French Data Library (Dartmouth): daily Fama–French factors and momentum factor, CRSP-based. mkt = Mkt-RF + RF (US market total return); rf = one-month T-bill; mom = momentum factor. Weights are decided at each close from returns up to that close and applied from the next day. The matched column is a constant exposure scaled after the fact to the vol-targeted path’s volatility: a yardstick, not a strategy anyone could have run. A constant scaling leaves the Sharpe ratio unchanged, so the matched column’s equals exposure 1×’s by construction.

US market and momentum: Kenneth R. French Data Library, daily, full history. Top: growth of one unit at exposure one, for the volatility-targeted strategy, and for a constant exposure matched to its realised volatility. Middle: realised 63-day volatility against the target. Bottom: the exposure held, and its cap. Suggested experiments: shorten the span and watch turnover rise; remove the band and watch it rise again; switch to the momentum factor and find the 1932 and 2009 crashes; on synthetic data, draw further histories and watch how much the comparison with the matched exposure varies.

Two properties recur. On the synthetic histories and on the market, realised volatility runs somewhat above the target: on the synthetic histories by about 5% of the target on average (a 12% target realising about 12.6%), and on the market 12.3% against 12%, because estimation noise in the denominator, fat tails and jumps all push in the same direction; a practitioner may set the target slightly below the level actually wanted. Both the forecast and the realised figure count the trading days in each year from the calendar; annualising with 252 throughout would understate the pre-1952 years and add roughly another quarter of a percentage point of overshoot. On momentum it lands slightly below (11.6%), because the 2× cap binds in its calmest stretches. And the stability of risk, visible in the middle panel, is far more reliable than any improvement in return.

Costs, turnover and leverage caps

Every change in the forecast is a trade, so the estimator’s noise becomes a cost. In the laboratory’s synthetic history with no band, an EWMA with a 10-day span turns over about 22 times capital a year (one-way), which costs roughly 112 bp of return a year at 5 bp per unit traded; a 120-day span turns over about 1.9 times.

A century of the US market shows the same trade-off, and how little accuracy a longer memory gives up. Holding the rule of the table fixed and changing only the estimator’s memory, the EWMA forecast the next month’s volatility best at a span of 40 days, off by a typical factor of 1.436. Between spans of 20 and 120 days its typical miss barely moved, from 1.447 to 1.457, while the rule’s turnover fell from 7.8 to 0.8 times a year, and from a span of 20 days upwards its Sharpe ratio after costs stayed between 0.55 and 0.58. The rolling window forecast less accurately than the EWMA at every memory tested. The best memory lengthens with how far ahead the forecast looks (20 days for the next week, 120 for the next quarter), and part of every miss is the noise in a single month’s realised volatility, which no forecast can remove.

Figure 3A longer memory trades far less for almost the same accuracy
Estimator
Episode
Typical forecast miss
×1.440
root mean square of ln(forecast / next month) = 0.365
Average bias
+6%
forecasts ran above the month that followed
Turnover a year
1.8×
the table’s rule sized by this forecast
Sharpe ratio after costs
0.57
5 bp a unit traded; the table’s rule 0.57
The forecast at each close against the volatility of the 21 sessions that followed, 20080%20%40%60%80%Jun 2008Sep 2008Dec 2008Mar 2009Jun 2009
Forecast miss against turnover: each point one memory length×1.40×1.50×1.60×1.70×1.800.3×1×3×10×30×turnover a year, one-way (log scale)5d10d20d40d60d120d250d

The EWMA with a 60-day span (half-life 21 days) missed the next month’s volatility by a typical factor of 1.440 and made the rule turn over 1.8× a year. The most accurate span was 40 days (×1.436); short memories chase every bump and trade constantly, long ones remember a crisis for months after it has passed.

Realised volatility of the next monthForecast; EWMA pointsEWMA 60-day span; rolling-window pointsCurrent choice
US market total return, Kenneth R. French Data Library, daily, from 5 May 1927 (the table’s sample). Top: the forecast made at each close against the realised volatility of the 21 sessions that followed (root mean square, annualised on the calendar’s count of sessions). Bottom: for each estimator and memory, the forecast’s typical miss (the exponential of the root-mean-square log error) against the turnover of the table’s rule sized by it: a 12% target, a 2× cap, a ±10% band and 5 bp per unit traded. Suggested experiments: slide the EWMA’s span from 5 to 250 days through 1987 and watch the forecast go from jittery to late; find the span with the smallest miss, then ask what the next one saves in trading; switch to the rolling window and watch the October 1987 crash drop out of the window all at once, weeks after it happened. Selecting a point on the lower chart picks that estimator and memory.
site_research/fieldnotes/voltarget.py
def forecast_error(forecast: pd.Series, ret: pd.Series, days_ahead: int = 21, periods=None,
                   start: int = 0) -> dict:
    """How well a volatility forecast predicted the volatility that followed.

    The forecast in row t (made at the close of t) is compared with the realised volatility of
    the next `days_ahead` returns, r_(t+1) .. r_(t+days_ahead): the root mean square about zero,
    annualised with the sessions per year at t. The error of one forecast is ln(forecast /
    realised), so a forecast twice too high and one half too low are equally wrong. Returns the
    root mean square of that error (exp of it is the typical factor a forecast was off by) and
    its mean (positive: forecasts ran above what followed). Rows before `start`, and the last
    `days_ahead` rows, which have no complete future, are left out.
    """
    periods = sessions_per_year(ret.index).to_numpy() if periods is None else np.broadcast_to(periods, len(ret))
    r2 = pd.Series(ret.pow(2).to_numpy())
    ahead = r2.rolling(days_ahead).mean().shift(-days_ahead).to_numpy()   # mean of r_(t+1..t+days_ahead)^2
    realised = np.sqrt(ahead * periods)
    f = forecast.to_numpy()
    ok = np.isfinite(f) & np.isfinite(realised) & (realised > 0) & (f > 0) & (np.arange(len(f)) >= start)
    e = np.log(f[ok] / realised[ok])
    return {"rmse": float(np.sqrt(np.mean(e ** 2))), "bias": float(np.mean(e)), "n": int(ok.sum())}
How the figure scores a forecast: against the volatility of the month that followed, on a log scale so that a forecast twice too high and one half too low are equally wrong.

Three practices keep turnover under control.

  • Use a longer memory than intuition suggests. A fast estimator reacts sooner to a crash but also to every false signal. In the synthetic tests here, half-lives of a few weeks (the best was about two weeks) outperformed half-lives of a few days after costs.
  • Trade only when the difference is material. A no-trade band, for example rebalancing only when the target exposure differs from the current one by more than 10% of the current position, removes most of the small adjustments that pay the spread for little benefit.
  • Cap leverage, and consider a floor. In very calm markets the rule calls for high leverage precisely when volatility is most likely to rise from a low base. A cap limits this, and a minimum exposure can prevent a strategy from remaining almost flat for months after a single shock. The backtests here finance leverage at the T-bill rate; a real account pays a spread over it, and rebalancing the drift of prices back to the target weight is a further cost these tables leave out (small at these turnovers).

Failure modes

Volatility targeting reduces risk on average. It is not insurance, and its failures are predictable enough to plan for.

  • It reacts after the event. The forecast is built from past returns, so the first day of a volatility spike is taken at the previous size, as the worked example shows. The rule protects against the second week of a crisis, not its first day.
  • It cannot see jumps. A price gap after an announcement, or while the market is closed, occurs between two forecasts, and no stop order can execute inside it. Across 40 synthetic histories, the targeted strategy’s single worst day was worse than the matched constant exposure’s in 27, because a jump can arrive while exposure is elevated after a calm spell (in the median synthetic history the two were almost identical: −5.9% against −6.0%).
  • Exposure is highest after calm periods. Low realised volatility produces the largest positions, and long calm periods can end abruptly. This is the case for a leverage cap and for scepticism about very low forecasts.
  • Gradual declines pass unnoticed. A market that falls steadily in small steps can keep realised volatility low while prices fall a long way. The rule reads this as calm and remains fully invested.
  • Similar rules may trade together. Many investors use related rules. After a shock they may all reduce exposure at once, which can add to the move they are responding to, and execution is likely to be worst when the rule is most active.
  • Backtests can use information not yet available. Sizing a position with a volatility estimate that includes the same day’s return is look-ahead and flatters every result. Size on information available before the trade, and charge the cost of every adjustment.

Implementation checklist

  1. Choose one estimator and a moderate memory (an EWMA with a half-life of a few weeks is a sensible start), and do not tune it to the backtest.
  2. Compute the forecast from data up to the previous close, state when the trade executes, and record both.
  3. Set a leverage cap before looking at results, and a no-trade band sized to trading costs.
  4. Judge the rule first on realised volatility against target, drawdowns and the left tail, compared with a constant exposure of the same volatility, and only then on the Sharpe ratio.
  5. Stress-test it with jumps and gradual declines, the two situations it cannot detect.
  6. When running several strategies, decide whether to target each one, the portfolio, or both, and record why.

References

  1. Mandelbrot, B. (1963). The variation of certain speculative prices. Journal of Business, 36(4), 394–419. https://doi.org/10.1086/294632
  2. Cont, R. (2001). Empirical properties of asset returns: Stylized facts and statistical issues. Quantitative Finance, 1(2), 223–236. https://doi.org/10.1080/713665670
  3. Moreira, A., & Muir, T. (2017). Volatility-managed portfolios. Journal of Finance, 72(4), 1611–1644. https://doi.org/10.1111/jofi.12513
  4. J.P. Morgan / Reuters (1996). RiskMetrics: Technical document (4th ed.). Morgan Guaranty Trust Company, New York.
  5. Engle, R. F. (1982). Autoregressive conditional heteroscedasticity with estimates of the variance of United Kingdom inflation. Econometrica, 50(4), 987–1007. https://doi.org/10.2307/1912773
  6. Bollerslev, T. (1986). Generalized autoregressive conditional heteroskedasticity. Journal of Econometrics, 31(3), 307–327. https://doi.org/10.1016/0304-4076(86)90063-1
  7. Glosten, L. R., Jagannathan, R., & Runkle, D. E. (1993). On the relation between the expected value and the volatility of the nominal excess return on stocks. Journal of Finance, 48(5), 1779–1801. https://doi.org/10.1111/j.1540-6261.1993.tb05128.x
  8. Parkinson, M. (1980). The extreme value method for estimating the variance of the rate of return. Journal of Business, 53(1), 61–65. https://doi.org/10.1086/296071
  9. Garman, M. B., & Klass, M. J. (1980). On the estimation of security price volatilities from historical data. Journal of Business, 53(1), 67–78. https://doi.org/10.1086/296072
  10. Yang, D., & Zhang, Q. (2000). Drift-independent volatility estimation based on high, low, open, and close prices. Journal of Business, 73(3), 477–492. https://doi.org/10.1086/209650
  11. Andersen, T. G., Bollerslev, T., Diebold, F. X., & Labys, P. (2003). Modeling and forecasting realized volatility. Econometrica, 71(2), 579–625. https://doi.org/10.1111/1468-0262.00418
  12. Corsi, F. (2009). A simple approximate long-memory model of realized volatility. Journal of Financial Econometrics, 7(2), 174–196. https://doi.org/10.1093/jjfinec/nbp001
  13. Harvey, C. R., Hoyle, E., Korgaonkar, R., Rattray, S., Sargaison, M., & Van Hemert, O. (2018). The impact of volatility targeting. Journal of Portfolio Management, 45(1), 14–33. https://doi.org/10.3905/jpm.2018.45.1.014
  14. Black, F. (1976). Studies of stock price volatility changes. Proceedings of the 1976 Meetings of the American Statistical Association, Business and Economic Statistics Section, 177–181.
  15. Christie, A. A. (1982). The stochastic behavior of common stock variances: Value, leverage and interest rate effects. Journal of Financial Economics, 10(4), 407–432. https://doi.org/10.1016/0304-405x(82)90018-6
  16. Campbell, J. Y., & Hentschel, L. (1992). No news is good news: An asymmetric model of changing volatility in stock returns. Journal of Financial Economics, 31(3), 281–318. https://doi.org/10.1016/0304-405x(92)90037-x
  17. Fleming, J., Kirby, C., & Ostdiek, B. (2001). The economic value of volatility timing. Journal of Finance, 56(1), 329–352. https://doi.org/10.1111/0022-1082.00327
  18. Barroso, P., & Santa-Clara, P. (2015). Momentum has its moments. Journal of Financial Economics, 116(1), 111–120. https://doi.org/10.1016/j.jfineco.2014.11.010
  19. Cederburg, S., O’Doherty, M. S., Wang, F., & Yan, X. (2020). On the performance of volatility-managed portfolios. Journal of Financial Economics, 138(1), 95–117. https://doi.org/10.1016/j.jfineco.2020.04.015
  20. French, K. R. (n.d.). Data Library: Fama/French factors (daily) and momentum factor (daily). Tuck School of Business, Dartmouth College. mba.tuck.dartmouth.edu/pages/faculty/ken.french/data_library.html
  21. Daniel, K., & Moskowitz, T. J. (2016). Momentum crashes. Journal of Financial Economics, 122(2), 221–247. https://doi.org/10.1016/j.jfineco.2015.12.002