σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
σμimplied vol · KKmax(S−K,0)udβρᵢⱼfat tailsPnL · drawdownyield · TdSₜ = μSₜ dt + σSₜ dWₜC = S·N(d₁) − K·e⁻ʳᵀ·N(d₂)σₚ² = wᵀΣwd₁ = [ln(S/K) + (r + σ²⁄2)T] ⁄ σ√T∂V/∂t + ½σ²S²·∂²V/∂S² + rS·∂V/∂S − rV = 0Sharpe = (Rₚ − R_f) ⁄ σₚVaR₉₉ = μ − 2.33σρ = Cov(X,Y) ⁄ σₓσᵧE[Rₚ] = Σ wᵢ·E[Rᵢ]φ(x) = e^(−x²/2) ⁄ √2πE[Rᵢ] = R_f + βᵢ(E[Rₘ] − R_f)dXₜ = θ(μ − Xₜ)dt + σ dWₜσ²ₜ = ω + α·ε²ₜ₋₁ + β·σ²ₜ₋₁C − P = S − K·e⁻ʳᵀΔ = ∂V/∂S Γ = ∂²V/∂S²p = (e^(rΔt) − d) ⁄ (u − d)rₜ = ln(Pₜ ⁄ Pₜ₋₁)E[Xₜ₊₁ | ℱₜ] = Xₜf* = (bp − q) ⁄ bz = (x − μ) ⁄ σP(N=k) = λᵏe^(−λ) ⁄ k!Θ = −∂V/∂Tν = S·φ(d₁)·√Tmin wᵀΣw s.t. wᵀμ = μ*∫Σ∂∞λ
uantCraft AcademyRoadmapsSkills
Ctrl K
AO
+1.2k Learners
LoginJoin ↗
RoadmapsSkills
AO
+1.2k Learners
Login
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
SciPy skill›Module 3 · Matrices, signals and structure›Topic 3.5·~1 hr 30 minAdvanced

Capstone: calibrating a Nelson–Siegel yield curve and a volatility smile

Skill positionModule 3 of 3 · Topic 5 of 5
3.5 Capstone: calibrating a Nelson–Siegel yield curve and a volatility smile
—Lab score— / 100Total XP—Streak—

Four numbers for a whole curve

The market quotes US Treasury yields at ten maturities, from 3 months to 30 years, but a bank needs a rate for every date. In this capstone you describe the whole curve with the four numbers of the Nelson–Siegel model: a long-run level β₀, a slope β₁, a hump β₂ and a decay length λ in years. You calibrate them to the quotes with scipy.optimize.least_squares, starting from several values of λ because the curve is not linear in it, and keep the fit with the lowest cost. From the fitted curve you read a forward rate, and you integrate the instantaneous forward curve with integrate.quad to get a discount factor D(T)=e^(-A/100), where A is the area under the forward curve in percent.

The same curve prices a bond. Each cash flow is discounted with the yield of its own maturity, P=Σcᵢ e^(-y(tᵢ)tᵢ/100), and the yield to maturity is the single rate that gives back the price, found with optimize.brentq. Options work the same way: the implied volatility is the root of bs_call(σ)-price, again found with brentq. Real option quotes are not part of the shared data, so you test the smile on prices you generate yourself with the provided bs_call, and fit the smile σ(m)=a+b m+c m² in log-moneyness m=ln(K/S) by least squares. Every function is graded on random inputs against an independent reference, and the last test runs your whole study on the real Treasury file.

y(τ)=β₀+β₁g+β₂ (g-e^(-x)), x=τ/λ, g=(1-e^(-x))/x, D(T)=e^(-A/100)
What the real curve saysOn 9 October 2026 the ten quoted yields are matched by a curve with β₀=5.75%, β₁=-1.52, β₂≈0 and λ=2.7 years, with an average error of 7.3 basis points. The forward rate between 5 and 10 years is 5.64%, the 10-year discount factor is 0.586 and a 5% annual 10-year bond costs 96.70, a yield of 5.29%. On 31 March 2020, in the middle of the market panic, the level was 1.87%, the fit error only 1.7 basis points, the 5-to-10-year forward 1.02%, the 10-year discount factor 0.931 and the same bond yielded 0.67%.
  • Calibrate from several starts: the decay length makes the fit non-linear, so one start can stop at a poor curve.
  • Check with a second route: the discount factor from the integrated forward curve must equal the one from the yield.
  • Roots price the market: a yield to maturity and an implied volatility are both roots found with brentq on a pricing error.

Lab · what's graded

  • The quoted curve of a day5 pts
  • The Nelson–Siegel yield10 pts
  • Calibrating the curve15 pts
  • A forward rate10 pts
  • A discount factor from forwards10 pts
  • A bond price from the curve10 pts
  • A yield to maturity10 pts
  • An implied volatility10 pts
  • A quadratic smile10 pts
  • The whole calibration10 pts
Explorer · lab-sp-11
▾ lab-sp-11
▾ data
…
bash · in-browser
learner@quantcraft:~/lab-sp-11$
Python not loaded yetPythonLn 1, Col 1Spaces: 4UTF-8

Reset this topic?

Everything in lab-sp-11 goes back to the starter files and the terminal is cleared. Your current solution will be lost — this can't be undone.

Will be reset
  • main.py → starter code
  • Terminal history and test output
  • Unsubmitted changes
Will be kept
  • Best lab score
  • Your XP and streak
  • Lecture progress and notes

Log in to run your code.

Every lecture is free to read. Create an account or log in to run code, run tests and submit this lab.

  • In-browser IDE with a bash terminal — nothing to install
  • Instant grading, XP and your place on the skill
Create an accountLog in
OR
Continue with GitHub