TradingView Backtesting

Volatility Targeting: Lagged Estimates, Leverage Caps and Turnover

Volatility targeting changes the size of a whole strategy using an estimate of its return volatility. Divide the volatility target by an estimate available before the next holding period, then apply exposure limits. A 10% annual target and a 20% annual estimate imply a 0.5× strategy multiplier. The target is an estimate of future variability, not a maximum loss: a sudden gap can arrive while the strategy still carries yesterday's high exposure.

See the decision guide

Scale the strategy return stream, not one trade's stop distance

Let uₜ be the daily simple return of a fixed, unscaled reference strategy, before the additional overlay costs modeled here. Keep its signal, holdings rule and original sizing definition unchanged. A nonnegative multiplier Lₜ scales that reference exposure. If the reference goes short, its direction stays short; the overlay changes magnitude. It does not create a momentum entry signal.

  • ATR position sizing budgets cash against one trade's stop distance. Volatility targeting estimates variation in the whole strategy's periodic returns, including interactions among positions. An account with several positions needs a combined return series or a covariance-aware model.
  • A 2× multiplier means twice the reference exposure. It means 200% gross notional only when the reference has 100% gross notional. If the reference already has 150%, a 2× overlay produces 300%; enforce absolute gross, net, margin and concentration limits as well.
  • Estimate from the unscaled reference. Feeding the already scaled account returns back into this formula changes the controller and can create oscillating exposure. Keep a separate reference series when testing the overlay.
  • Man Group's research describes increasing exposure in calm periods and reducing it in volatile periods. Its historical results differ by asset class. Neither that research nor this arithmetic establishes improved returns for a new TradingView strategy.

Write the lag, estimator and bounds as one rule

For N completed daily returns ending at t - 1, calculate the sample standard deviation sₜ₋₁ = sqrt[Σ(uᵢ - mean(u))² / (N - 1)]. The annual estimate is σ̂ₜ₋₁ = sₜ₋₁ × sqrt(A), where A is the declared number of observations per year. With positive σ̂, set Lₜ = min(Lmax, max(Lmin, target / σ̂ₜ₋₁)) at a scheduled rebalance. All volatilities use decimal returns and the same annualization convention.

  • The 0.25× floor is an example constraint, not a recommended minimum. Setting Lmin to zero allows smaller allocations; a positive floor deliberately sacrifices target tracking in high volatility.
  • Require N ≥ 2 valid observations before allocating. The three-observation window below is intentionally short to make every calculation inspectable; it is not a proposed production lookback.
  • Square-root annualization assumes a variance scaling convention. Serial dependence and changing volatility can break the interpretation as a future annual risk forecast. Choose 252, 365 or another calendar from the actual sampling schedule and document it.
Input or boundaryIllustrative ruleConsequence
Target and calendar10% annual; A = 252 daily observationsA modeling convention for this example, not a forecast
Lower boundLmin = 0.25×Keeps exposure even when the estimate calls for less
Upper boundLmax = 2.00×Prevents an arbitrarily large multiplier in calm periods
20% annual estimate10% / 20% = 0.50×Estimated scaled volatility is 10%
2% annual estimateRaw 5.00×; capped at 2.00×Estimated scaled volatility is only 4%
80% annual estimateRaw 0.125×; floored at 0.25×Estimated scaled volatility is 20%, above target
Zero estimateSet 0× on that rebalanceExplicit exception to the lower bound; never divide by zero
Missing or invalid dataReject the calculation and flag the gapDo not turn missing observations into calm zero returns

A calm window followed by a gap defeats the target

This synthetic example starts with $10,000 immediately before period 4. Periods 1, 2 and 3 are warm-up observations of -0.10%, 0.00% and +0.10%. Rebalance each period using only the previous three returns. Assume the multiplier is executable before that period begins. The -8% shock in period 4 then occurs after exposure is set. The costs below are deliberately explicit approximations, not actual fills.

  • For period 4, sample daily volatility is 0.10%; annualized, 0.001 × sqrt(252) = 1.58745%. The raw multiplier is 0.10 / 0.0158745 = 6.2994, reduced to 2×. The later -8% return therefore loses 16% before costs.
  • Period 5 uses [0%, +0.1%, -8%], so its raw multiplier falls to 0.13553× and the floor raises it to 0.25×. Only 2% of the next +8% recovery reaches the scaled account before costs. The high exposure preceded the crash; the low exposure preceded the rebound.
  • At the period-5 estimate, the floor implies 0.25 × 73.7837% = 18.4459% estimated annual volatility. A 10% target was never an enforceable ceiling.
  • Using period 4's -8% inside the estimate that sizes period 4 would reduce its multiplier to 0.25× and its gross loss to 2%. That apparent protection uses information unavailable when exposure was chosen.
PeriodPrior annual estimateMultiplierLater base returnNet overlay returnEnding equity
41.5875%2.00× (upper cap)-8.00%-16.2159%$8,378.41
573.7837%0.25× (lower floor)+8.00%+1.8250%$8,531.32
6126.9994%0.25× (lower floor)0.00%0.0000%$8,531.32

Reproduce the arithmetic and separate cost assumptions

For this example only, use Rₜ = Lₜuₜ - c|Lₜ - Lₜ₋₁| - (f / A)max(Lₜ - 1, 0), then Eₜ = Eₜ₋₁(1 + Rₜ). Set c = 0.001, meaning 10 basis points per unit of multiplier change, and f = 0.04 annual financing on exposure above 1×. Start with Lprevious = 0. Idle cash earns zero. These assumptions describe a linear 1× reference exposure; actual instruments may require different funding and cash-flow models.

  • Period 4 pays 0.001 × |2 - 0| = 0.20% in modeled adjustment cost and 0.04 / 252 = 0.015873% in financing. Its net return is -16% - 0.20% - 0.015873% = -16.215873%.
  • Period 5 pays 0.001 × |0.25 - 2| = 0.175%; its net return is 2% - 0.175% = 1.825%. Dollar costs are based on the equity at the start of each period.
  • |Lₜ - Lₜ₋₁| is a multiplier-change cost proxy, not total traded notional. It excludes exposure drift, resizing to changed equity, turnover inside the base strategy, spreads that vary with stress, market impact and final liquidation. A constant multiplier can still require trades.
  • For an execution backtest, compute turnover from actual quantity changes at actual fills, include point values and currency conversions, and charge the broker's costs on those amounts. Recompute base-strategy costs at the scaled quantities; multiplying a net return by leverage generally does not model fixed fees or nonlinear impact correctly.
Python 3 arithmetic demonstration using fixed synthetic inputs. It does not submit orders or reconstruct TradingView execution.python
from math import sqrt
from statistics import stdev

# Synthetic reference returns, with three warm-up observations.
u = [-0.001, 0.0, 0.001, -0.08, 0.08, 0.0]
target, lower, upper = 0.10, 0.25, 2.0
annual, cost, funding = 252, 0.001, 0.04

def run(every=1):
    equity, previous = 10000.0, 0.0
    for t in range(3, len(u)):
        # Slice ends before u[t]: the current return cannot size itself.
        sigma = stdev(u[t-3:t]) * sqrt(annual)
        if (t - 3) % every == 0:
            weight = (0.0 if sigma == 0 else
                      min(upper, max(lower, target / sigma)))
        else:
            weight = previous
        fee = cost * abs(weight - previous)
        financing = funding / annual * max(weight - 1, 0)
        net = weight * u[t] - fee - financing
        if 1 + net <= 0:
            raise ValueError("Insolvency: stop and model liquidation")
        equity *= 1 + net
        print(t + 1, round(weight, 5), round(equity, 2))
        previous = weight

run()       # 4: 2.0, 8378.41; 5: 0.25, 8531.32; 6: 0.25, 8531.32
run(2)      # 4: 2.0, 8378.41; 5: 2.0, 9717.63; 6: 0.25, 9700.62

A slower rebalance trades less often but keeps stale risk

Changing the rebalance interval changes the strategy. With updates only in periods 4 and 6, the example holds 2× through period 5 and ends at $9,700.62 after the same modeled costs. Daily updates end at $8,531.32. This path rewards delayed deleveraging because a recovery immediately follows the crash. If period 5 were another -8% loss, the stale 2× multiplier would magnify that loss instead.

  • Both schedules happen to have a total absolute multiplier change of 3.75 in this three-period example. The timing differs, and so do dollar costs because the equity bases differ. Fewer scheduled decisions do not guarantee lower realized turnover in every sample.
  • Define the trading calendar and rebalance event explicitly: every close, the first executable bar of a week, or another fixed event. Between events, distinguish holding a multiplier constant from holding actual quantities constant; their exposures drift differently.
  • A no-trade band can suppress small adjustments. Specify its threshold and whether an exposure-limit breach overrides it. Compare such a rule with the same history and cost assumptions, rather than selecting the most profitable schedule after seeing the result.
  • At minimum report realized volatility, maximum drawdown, gross exposure, time at each cap, traded notional, financing and net return. A lower target usually changes expected return as well as risk, so a return-only ranking cannot assess the overlay.

Align TradingView decisions with the executable return interval

TradingView's strategy documentation states that orders normally fill on the next available tick; with ordinary bar-close calculation, a market order created at a bar close usually fills at the next bar's open. A multiplier estimated at today's close therefore does not automatically apply to the entire close-to-close return ending tomorrow.

  • If exposure is resized at the next open, the old position bears the overnight gap. Split P&L into old-position close-to-open P&L, execution costs at the open, and new-position open-to-close P&L. Do not retroactively apply the new size to the overnight move.
  • Freeze a timestamped record of the last return available, volatility estimate, target multiplier, existing quantity, order time and simulated fill time. Reconcile these fields for the shock and recovery periods before comparing aggregate performance.
  • Use standard price charts and explicit commission, slippage, margin and fill settings. A leverage cap is not permission to borrow at that amount; margin constraints and forced liquidation can bind earlier. A stop or a fresh volatility estimate cannot guarantee an exit price across a gap.
  • Export the relevant Strategy Tester tab deliberately. TradingView documents separate exports for its report tabs. A list of closed trades does not by itself provide a complete daily account series with open-position valuations; reconstruct or record the required marked equity before estimating daily risk.

Keep the independent calculation beside the supported report

Backtest Deep Report imports TradingView trade CSV files. Its parser reads trade timestamps, prices, quantities and P&L; its current equity-curve calculation adds each closed trade's net P&L to initial capital. Use it to reconcile the exported trades and supported report results, while maintaining the daily reference returns and volatility-targeting ledger separately.

  • This page supplies an independent formula and reproducible calculation. It does not claim that Backtest Deep Report has a built-in volatility-targeting backtest, rebalance engine or full daily mark-to-market reconstruction.
  • When using Pine Script AI Coding Agent to draft or review an implementation, provide the base strategy, reference return definition, estimator, decision/fill timestamps, cap and floor, invalid-data policy and cost model. Check the generated quantities and timing against an independent ledger.
  • Compare the original and scaled strategies over the same out-of-sample dates. Stress a gap after calm observations, a fast recovery, prolonged high volatility and near-zero estimates. Successful syntax validation would establish compilation, not the economic correctness of that test.
Where Pineify fits

Backtest Deep Report

Reconcile TradingView trade CSV inputs and supported report results before comparing them with your separate volatility-targeting calculation.

Also useful: Pine Script AI Coding Agent. Draft or review strategy sizing with explicit reference returns, exposure bounds, execution timing and cost assumptions.

Review the trade report workflow

Frequently asked questions

Educational information, not investment advice. All numerical returns, targets, limits and costs are hypothetical assumptions. The arithmetic example is not an observed backtest or an execution simulation. Volatility targeting can increase losses and does not guarantee a risk level or future return.

Sources and verification

Published by Pineify. Pineify is an independent product and is not affiliated with TradingView. Sources support the technical explanations; examples do not establish trading performance.