Analyst Dojo
Lesson 2 of 5 11–14% of the exam

Historical simulation and historical value at risk

Historical simulation applies each past day's actual market moves to today's positions, giving one profit or loss per day with no distribution assumed. Rank those results: the 95% value at risk (VaR) is the loss at rank 5% × n from the worst, interpolated when the rank is not whole.

6 min cram, 30 min full read. Based on the 2027 CFA® Program Level I curriculum, Quantitative Methods, Learning Module 9.

Tailor this to you: take the self-assessment

Before this: Historical, bootstrap or Monte Carlo: the four-step engine, Value at risk from the normal distribution, Quartiles, percentiles and box plots

On the exam

  • Describe historical simulation and explain how it can be used in investment applications

Describe historical simulation and explain how it is used. Expect its implicit assumption (past changes are a fair guide to future ones), strengths and weaknesses, why bonds are simulated from yield changes, a scenario profit or loss from a log return, and locating the VaR scenario by rank.

How deeply to learn each part
Know the idea
Understand it in general. It frames other topics, but you will not calculate with it.
Use it
Understand it well enough to solve a question with it. Recognize when it applies.
Memorize
Learn it by heart. The exam will not give it to you.

You know this one. The full lesson is folded away. The takeaways, formulas and checkpoint below are your quick refresher, and the checkpoint is a fair test of whether you still do.

You tested strong here. The full lesson is folded away. The takeaways, formulas and checkpoint below are your quick refresher, and the checkpoint is a fair test of whether you still know it.

Cram mode: the one-screen version of this lesson. Switch to Full for the explanations, worked examples and interactives.

What is historical simulation?

Historical simulation takes the market moves that actually happened on each past day and applies them to the positions you hold today. With a year of daily data you get about 250 scenarios: “what today’s portfolio would have made or lost on each of those days”.

The implicit assumption of historical simulation is that past price changes are a reasonable guide to future ones. The method treats the past data as the whole population of possible outcomes.

No distribution is assumed, so whatever the data contain is kept: fat tails (excess kurtosis), skew and volatility clustering (calm and turbulent spells). Each past date is used once, as it happened. There is no random draw and no replacement.

Every result is tied to a date. “The portfolio would lose EUR 610,000 if markets moved as they did on day 202” is a sentence a board understands. That explainability is the method’s best-known strength.

The inputs are the daily log returns for shares, r~t=ln⁡(Pt÷Pt−1)\tilde r_t = \ln(P_t \div P_{t-1}), and, for bonds, changes in benchmark yields (see below).

How do you turn a past day into today’s profit or loss?

Use it

Multiply each position by the percentage change that day’s log return implies, and add the positions. The result is that day’s scenario profit and loss , written P/L.

Scenario profit or loss from a log return Use it
P/L=D(er~−1)\text{P/L} = D\left(e^{\tilde r} - 1\right)

Here DD is today’s position value and r~\tilde r the day’s log return. The exponential turns a log return back into a percentage change. Multiplying the position by the log return itself is a small but common slip.

Rearrange itScenario profit or loss from a log return: solve for any one
The question asks for
A fund holds a position worth 4,000,000.00. On a past day the position's log return was -2.04%. Applied to today's position, that scenario's profit or loss is closest to:

4,000,000.00 × (e^-0.0204 − 1) = -80,773.31

Scenario profit or loss, P/L-80,773.31

On your calculator
  1. 0.0204+|-2NDe^x−1=×4000000=

+|- change sign · 2ND second function (the shifted label above a key) · e^x e to the power x

  1. 0.0204CHSge^x1−4000000×

CHS change sign · g blue shift key · e^x e to the power x

How do you read VaR from the ranked results?

Use it

Sort the scenario results from the worst loss upward. Historical value at risk (VaR) for a confidence level cc and nn scenarios sits at rank (1−c)×n(1 - c) \times n from the worst. For 95% that is rank 0.05×n0.05 \times n.

Rank of the VaR scenario Use it
k=(1−c) nk = (1 - c)\,n

If the rank is not a whole number, either take the nearer neighbor or use rank and linear interpolation : take a weighted mix of the two neighboring losses, with weights that follow the fractional part of the rank.

Interpolated value at risk Use it
VaR=L⌊k⌋+(k−⌊k⌋)(L⌈k⌉−L⌊k⌋)\text{VaR} = L_{\lfloor k \rfloor} + (k - \lfloor k \rfloor)\left(L_{\lceil k \rceil} - L_{\lfloor k \rfloor}\right)

Here LjL_j is the jjth largest loss. In plain words: at rank 12.6, take 40% of the 12th loss and 60% of the 13th.

Taking the 12th or the 13th loss without interpolating (EUR 226,201 or EUR 224,432) is also accepted practice. The options in a question will show which rule is meant.

InteractiveHistorical value at risk (VaR): replay the year, rank the days

Try this 0 of 3

  • Switch to 99% and compare the two VaRs.
  • Use only the last 126 days.
  • Find the rank used for 95% VaR on 126 days.

Today's portfolio replayed through the full year (252 days): k = 12.6, 95% historical VaR EUR 225,140 against a parametric (normal) VaR of EUR 228,558, a gap of −1.5%. The worst past day lost EUR 609,595.

Profit or loss on each of 252 past days

−600−400−2000+200+400Profit or loss in a day (EUR thousands)5% of daysHistorical VaRNormal VaR
  • Past days
  • Worst 5% of days
  • Normal curve (parametric)

Each bar counts past days replayed on today's positions. The worst day lost EUR 609,595 (day 202).

The worst days, ranked

RankDayFund AFund BP/L (EUR)
1202−4.51%−9.02%−609,595
2239−2.17%−8.96%−471,610
378−3.82%−3.67%−369,016
4218−2.72%−3.48%−297,806
5129−3.03%−2.74%−287,185
6126−2.32%−3.17%−262,409
7152−2.14%−3.33%−258,043
8195−1.45%−4.30%−254,727
988−1.28%−4.56%−254,614
10133−1.63%−3.97%−252,696
11117−2.63%−2.07%−237,692
1253−1.56%−3.39%−226,201
13234−2.39%−2.09%−224,432
1463−2.41%−1.75%−212,263
15220−2.17%−1.95%−206,042

k = 12.6 falls between ranks 12 and 13 (highlighted).

VaR rank k = (1 − c) × n0.05 × 252 = 12.6
95% historical VaREUR 225,140
95% parametric (normal) VaREUR 228,558
Historical vs parametric−1.5%
Confidence level
Window of past days
Show working

Each past day, replayed on today's positions: profit or loss (P/L) = 6,000,000 × (e^r̃A − 1) + 4,000,000 × (e^r̃B − 1). Worst day 202: 6,000,000 × (e^−0.0451 − 1) + 4,000,000 × (e^−0.0902 − 1) = −609,595.

Rank the 252 results from the worst loss. k = (1 − c) × n = 0.05 × 252 = 12.6.

Interpolate between the 12th loss (226,201) and the 13th (224,432): VaR = 0.4 × 226,201 + 0.6 × 224,432 = 225,139.6. Taking the 12th or the 13th without interpolating is also accepted.

Parametric comparison, from the window's rounded inputs σ_A 1.34%, σ_B 1.79%, ρ 0.67: D_Aσ_A = 80,400, D_Bσ_B = 71,600.

σ_p = √(80,400² + 71,600² + 2 × 0.67 × 80,400 × 71,600) = EUR 138,941. Parametric VaR = 1.645 × 138,941 = EUR 228,558 (one-tailed z, mean 0).

Reading: on 5% of these past days the portfolio would have lost more than EUR 225,140. VaR is a threshold, not the most you can lose: the worst day lost EUR 609,595.

95% historical VaR (interpolation)
  1. 226201×0.4+(224432×0.6)=225,139.6
  1. 226201ENTER0.4×224432ENTER0.6×+225,139.6

ENTER enter (on the HP, puts the number on the stack)

Display: 225,139.6

95% parametric VaR
  1. 80400x²+(71600x²)+(2×0.67×80400×71600)=√x138,941.06
  2. ×1.645=228,558.04

x² square · √x square root

  1. 80400ENTER×71600ENTER×+2ENTER0.67×80400×71600×+g√x138,941.06
  2. 1.645×228,558.04

ENTER enter (on the HP, puts the number on the stack) · g blue shift key · √x square root

Display: 228,558.04

Historical VaR reads the loss straight off the days that happened; the normal curve can miss what the tail really held.

How does it compare with parametric VaR?

Parametric value at risk assumes normal returns and uses only the standard deviations and the correlation. Historical VaR uses the actual tail. When returns have fat tails, the two agree near the middle and part company far out in the tail.

For the same portfolio, the daily standard deviations are 1.34% for fund A and 1.79% for fund B, with a correlation of 0.67 (rounded from the data). In euros, the portfolio’s standard deviation combines the two positions as in Learning Module 8.

Two-position standard deviation in currency Know the idea
σp=D12σ12+D22σ22+2D1D2ρ σ1σ2\sigma_p = \sqrt{D_1^2\sigma_1^2 + D_2^2\sigma_2^2 + 2D_1D_2\rho\,\sigma_1\sigma_2}
  • Position risks: DAσAD_A\sigma_A = 6,000,000 × 0.0134 = 80,400 and DBσBD_B\sigma_B = 4,000,000 × 0.0179 = 71,600.
  • Variance: 80,400² + 71,600² + 2 × 0.67 × 80,400 × 71,600 = 6,464,160,000 + 5,126,560,000 + 7,713,897,600 = 19,304,617,600, so σp\sigma_p = EUR 138,941.
  • Parametric 95% VaR = 1.645 × 138,941 = EUR 228,558. Parametric 99% VaR = 2.33 × 138,941 = EUR 323,733. These are one-tailed z-values, as in Learning Module 7.
95%99%
Historical225,140418,261
Parametric (normal)228,558323,733

At 95% the two are within 2% of each other. At 99% the history shows a loss about 29% larger than the normal curve allows. The worst day, EUR 609,595, is 4.4 standard deviations of the portfolio’s daily result. A normal curve gives such a day about once in 175,000 days, yet it happened once in a single year of data.

Parametric VaR is normally computed with a mean daily return of zero, the zero-mean convention . A zero mean usually cannot be statistically rejected for daily data, and the daily standard deviation is far larger than the daily mean, so best practice leaves drift out of the parametric calculation. Historical simulation, by contrast, automatically contains whatever drift the data had (here the average daily P/L was −EUR 484, close to zero).

Exam tip A positive average return in the history does not tell you which VaR is larger. VaR lives in the loss tail, and a few large gains do not move it.

Two-position risk on your calculator
  1. 80400x²+71600x²+(2×0.67×80400×71600)=√x 138,941.06
  2. ×1.645= 228,558.04

x² square · √x square root

  1. 80400ENTER×71600ENTER×+2ENTER0.67×80400×71600×+g√x 138,941.06
  2. 1.645× 228,558.04

ENTER enter (on the HP, puts the number on the stack) · g blue shift key · √x square root

Not just VaR: replaying past forecast errors

Know the idea

The same idea works for any quantity with a track record. A private equity team has 40 past deals and, for each, the gap between forecast and actual revenue. Sorted, the five worst gaps are −31.2%, −24.5%, −20.1%, −18.4% and −15.9%. The 10th percentile sits at rank 0.10 × 40 = 4: −18.4%.

If the new deal’s base-case net present value (NPV) is USD 2,000,000 and each 1% revenue shortfall cuts it by USD 60,000, the 10th-percentile case is 2,000,000 − 18.4 × 60,000 = USD 896,000. History tempers over-optimistic forecasts: the downside comes from what actually happened, not from the model’s hopes.

What can go wrong with the data?

Know the idea

History is rarely complete. Asynchronous markets trade on different days and close on different holidays (or for unplanned reasons). Some securities did not exist for the whole window. Thinly traded securities have sparse or stale prices. The usual fix is a proxy : a similar instrument, or a weighted mix of several, stands in for the missing history.

Why past data can be missing or unreliable
Data gapswhat can go wrong with the history
  • Asynchronous markets different holidays and trading days, unplanned closures
  • Securities that did not exist listed or issued after the window starts
  • Thinly traded securities sparse or stale prices
  • Fix: a proxy Use it a similar instrument, or a weighted mix of several, stands in

Bonds need special care. Do not replay a bond’s own past price changes. A bond maturing next week would inherit last year’s price swings, when today it has almost no price risk left. Instead take the benchmark yield changes (for example the 1-month, 6-month, 1-year and 2-year yields) or changes in zero-coupon prices, apply them to today’s yield curve and reprice the bond’s remaining cash flows (CF): present value = ∑CFt÷(1+yt)t\sum CF_t \div (1 + y_t)^t.

A two-year history of a bond that now matures in three weeks would overstate its risk. A bond that has only existed for a month gives too few scenarios, so a proxy is needed.

Strengths and weaknesses

The strengths and weaknesses of historical simulation follow from one fact: it replays the data and nothing else.

Historical simulation: for and against
Historical simulationreplay the past on today’s positions
  • Strengths Memorize
    • Simple replays history; still used for complex securities
    • No distribution assumed fat tails and skew kept
    • Real-world data includes past extremes
    • No correlation model co-movements kept as they happened
    • Low computing cost no new scenarios generated
  • Weaknesses Memorize
    • Backward looking blind to shocks history never showed
    • Limited scenario variety only the window you chose
    • Data limitations missing, short or stale histories; new instruments

Because every day counts once, a single extreme day in the window moves the result a lot: historical simulation is sensitive to outliers and to the window you pick. It handles non-linear positions such as options without difficulty, since each scenario simply reprices them.

Memorize this

MemorizeHistorical simulation in one card

ItemRule
Scenarioseach past date once, applied to today’s positions
Assumespast changes are a fair guide to future ones
Scenario profit or loss (P/L)D(er~−1)D(e^{\tilde r} - 1), summed over positions
VaR rankk=(1−c) nk = (1 - c)\,n from the worst; interpolate if not whole
Bondssimulate benchmark yield changes, then reprice
Strengthssimple, no distribution, real data, no correlation model, cheap
Weaknessesbackward looking, limited scenarios, data gaps

Memory hook "Replay, rank, read": replay each day, rank the results, read the tail.

Know it cold 95% VaR on n days: rank 0.05n from the worst. One-tailed z for the parametric comparison: 1.645 at 95%, 2.33 at 99%.

Why past data can be missing or unreliable
Data gapswhat can go wrong with the history
  • Asynchronous markets different holidays and trading days, unplanned closures
  • Securities that did not exist listed or issued after the window starts
  • Thinly traded securities sparse or stale prices
  • Fix: a proxy Use it a similar instrument, or a weighted mix of several, stands in
Historical simulation: for and against
Historical simulationreplay the past on today’s positions
  • Strengths Memorize
    • Simple replays history; still used for complex securities
    • No distribution assumed fat tails and skew kept
    • Real-world data includes past extremes
    • No correlation model co-movements kept as they happened
    • Low computing cost no new scenarios generated
  • Weaknesses Memorize
    • Backward looking blind to shocks history never showed
    • Limited scenario variety only the window you chose
    • Data limitations missing, short or stale histories; new instruments
Scenario profit or loss from a log return Use it
P/L=D(er~−1)\text{P/L} = D\left(e^{\tilde r} - 1\right)
Quick example

A GBP 2,500,000 position and a past day with a log return of −1.80%. 2,500,000×(e−0.018−1)2{,}500{,}000 \times (e^{-0.018} - 1) = −GBP 44,597.

On your calculator
  1. 0.018+|-2NDe^x−1=×2500000= −44,597.42

+|- change sign · 2ND second function (the shifted label above a key) · e^x e to the power x

  1. 0.018CHSge^x1−2500000× −44,597.42

CHS change sign · g blue shift key · e^x e to the power x

Rank of the VaR scenario Use it
k=(1−c) nk = (1 - c)\,n
Quick example

300 daily scenarios, 99% VaR: k=0.01×300=3k = 0.01 \times 300 = 3, so VaR is the 3rd largest loss. At 95%, k=15k = 15.

Interpolated value at risk Use it
VaR=L⌊k⌋+(k−⌊k⌋)(L⌈k⌉−L⌊k⌋)\text{VaR} = L_{\lfloor k \rfloor} + (k - \lfloor k \rfloor)\left(L_{\lceil k \rceil} - L_{\lfloor k \rfloor}\right)
Quick example

185 days, 95%: k=9.25k = 9.25, between the 9th loss (520,000) and the 10th (496,000). VaR = 520,000 + 0.25 × (496,000 − 520,000) = 514,000.

On your calculator
  1. 496000−520000=×0.25+520000= 514,000
  1. 496000ENTER520000−0.25×520000+ 514,000

ENTER enter (on the HP, puts the number on the stack)

Two-position standard deviation in currency Know the idea
σp=D12σ12+D22σ22+2D1D2ρ σ1σ2\sigma_p = \sqrt{D_1^2\sigma_1^2 + D_2^2\sigma_2^2 + 2D_1D_2\rho\,\sigma_1\sigma_2}
Quick example

USD 3 million (σ 1.0%) and USD 2 million (σ 1.5%), ρ = 0.5: 30,0002+30,0002+2×0.5×30,0002\sqrt{30{,}000^2 + 30{,}000^2 + 2 \times 0.5 \times 30{,}000^2} = USD 51,962. One-tailed 95% parametric VaR = 1.645 × 51,962 = USD 85,477.

On your calculator
  1. 30000x²×3=√x 51,961.52
  2. ×1.645= 85,476.71

x² square · √x square root

  1. 30000ENTER×3×g√x 51,961.52
  2. 1.645× 85,476.71

ENTER enter (on the HP, puts the number on the stack) · g blue shift key · √x square root

How it is asked

  1. Implicit assumption

    Which assumption is built into historical simulation?

    Past price changes are a reasonable guide to future ones. A zero mean and a normal distribution belong to other methods.

  2. Find the VaR scenario

    500 days, 99% VaR?

    k=0.01×500=5k = 0.01 \times 500 = 5: the 5th largest loss.

  3. Interpolate

    185 days, 95%: 9th loss 520,000, 10th loss 496,000.

    k=9.25k = 9.25: 520,000 + 0.25 × (496,000 − 520,000) = 514,000.

  4. Bond nearing maturity

    Historical simulation from a short-dated bond’s own past prices most likely…

    Overstates its risk. Use benchmark yield changes and reprice.

  5. Limitation

    A share listed two weeks ago…

    Too little history: use a proxy. New risk factors are hard for historical simulation.

Exam traps

  • Multiplying the position by the log return. The percentage change is e^r̃ − 1.
  • Counting the VaR rank from the best result, or using 5% × n as a percentage of the total instead of a rank from the worst.
  • Saying historical simulation needs a correlation model or a distribution. Correlations and the shape of the data come with the history.
  • Replaying a bond's own past prices. Its risk falls as it nears maturity; simulate yield changes instead.
  • Using the two-tailed 1.96 for a 95% parametric VaR comparison. VaR is one-tailed: 1.645.

Checkpoint

3 exam-style questions. About 90 seconds each.

  1. 1A historical simulation produces 230 daily profit-and-loss scenarios for a portfolio. The 10th to 13th largest losses are USD 412,000, USD 398,000, USD 371,000 and USD 366,000. Using linear interpolation, the one-day 95% value at risk is closest to:

  2. 2A fund holds an INR 50,000,000 position in an equity index. On one historical day the index's log return was −2.40%. Applied to today's position, that scenario's profit or loss is closest to:

  3. 3A portfolio holds a government bond that matures in three weeks. To include it in a historical simulation, the analyst should most appropriately use:

Key takeaways

  • Historical simulation replays each past day's moves on today's positions, once each, assuming the past is a fair guide.
  • Scenario P/L = position × (e^r̃ − 1); add across positions.
  • 95% historical VaR: rank 0.05 × n from the worst loss, interpolated if needed.
  • No distribution and no correlation model, easy to explain; but backward looking and only as good as its data window.
Scenario profit or loss from a log return Use it
P/L=D(er~−1)\text{P/L} = D\left(e^{\tilde r} - 1\right)
Quick example

A GBP 2,500,000 position and a past day with a log return of −1.80%. 2,500,000×(e−0.018−1)2{,}500{,}000 \times (e^{-0.018} - 1) = −GBP 44,597.

On your calculator
  1. 0.018+|-2NDe^x−1=×2500000= −44,597.42

+|- change sign · 2ND second function (the shifted label above a key) · e^x e to the power x

  1. 0.018CHSge^x1−2500000× −44,597.42

CHS change sign · g blue shift key · e^x e to the power x

Rank of the VaR scenario Use it
k=(1−c) nk = (1 - c)\,n
Quick example

300 daily scenarios, 99% VaR: k=0.01×300=3k = 0.01 \times 300 = 3, so VaR is the 3rd largest loss. At 95%, k=15k = 15.

Interpolated value at risk Use it
VaR=L⌊k⌋+(k−⌊k⌋)(L⌈k⌉−L⌊k⌋)\text{VaR} = L_{\lfloor k \rfloor} + (k - \lfloor k \rfloor)\left(L_{\lceil k \rceil} - L_{\lfloor k \rfloor}\right)
Quick example

185 days, 95%: k=9.25k = 9.25, between the 9th loss (520,000) and the 10th (496,000). VaR = 520,000 + 0.25 × (496,000 − 520,000) = 514,000.

On your calculator
  1. 496000−520000=×0.25+520000= 514,000
  1. 496000ENTER520000−0.25×520000+ 514,000

ENTER enter (on the HP, puts the number on the stack)

Two-position standard deviation in currency Know the idea
σp=D12σ12+D22σ22+2D1D2ρ σ1σ2\sigma_p = \sqrt{D_1^2\sigma_1^2 + D_2^2\sigma_2^2 + 2D_1D_2\rho\,\sigma_1\sigma_2}
Quick example

USD 3 million (σ 1.0%) and USD 2 million (σ 1.5%), ρ = 0.5: 30,0002+30,0002+2×0.5×30,0002\sqrt{30{,}000^2 + 30{,}000^2 + 2 \times 0.5 \times 30{,}000^2} = USD 51,962. One-tailed 95% parametric VaR = 1.645 × 51,962 = USD 85,477.

On your calculator
  1. 30000x²×3=√x 51,961.52
  2. ×1.645= 85,476.71

x² square · √x square root

  1. 30000ENTER×3×g√x 51,961.52
  2. 1.645× 85,476.71

ENTER enter (on the HP, puts the number on the stack) · g blue shift key · √x square root

All Quantitative Methods formulas, every lesson

Practice exam-style questions on Simulating Prices and Returns

Questions about this lesson?

Where this comes back

Questions candidates ask

How do you calculate historical VaR?

Apply each past day's returns to today's positions to get one profit or loss per day, sort the results from worst to best, and read the loss at rank (1 − confidence) × n. With 252 days and 95%, the rank is 12.6: take 40% of the 12th loss plus 60% of the 13th.

What is the main assumption of historical simulation?

That past price changes are a reasonable guide to future ones. The method assumes no distribution, so it keeps the fat tails and clustering in the data, but it cannot show a shock that never happened in its window.

Why are bonds simulated from yield changes rather than their own prices?

A bond's price sensitivity shrinks as it nears maturity, so its own past price changes overstate today's risk. Simulating changes in benchmark yields and repricing the bond's remaining cash flows measures the risk it carries now.

Spotted an error? Tell us and we will fix it.

  1. Historical, bootstrap or Monte Carlo: the four-step engine
  2. Historical simulation and historical value at risk
  3. Bootstrapping: simulating from the data you have
  4. Monte Carlo simulation
  5. Simulating two correlated assets: the Cholesky step

Ask Sensei Listen instead

Questions on Historical simulation and historical value at risk

Learn with Sensei, out loud The voice tutor, in early access

Sensei teaches the lesson aloud and stops when you interrupt: "wait, why is the geometric mean lower?" It answers with the lesson's own example, then quizzes you by voice. Every account can try Sensei on one module, with one voice question.

USD 149 a month founding price (regular USD 199), kept for as long as you stay subscribed. Everything in Plus included.

In active development and improving every day. Send feedback · Plans and pricing

Analyst Dojo Plus

Your free review list holds 10 items.

Plus keeps everything you save, for USD 19 a month. To make room on the free plan, remove something from your review list.

See Plus

Lessons, checkpoints and the lesson questions in practice stay free. Compare plans