σμ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ᵀμ = μ*∫Σ∂∞λ
σμ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 AcademyParcours
Ctrl K
AO
+1,2 k apprenants
ConnexionRejoindre ↗
Parcours
AO
+1,2 k apprenants
Connexion
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Parcours Python›Module 4 · Valorisation des produits de taux et d'options›Sujet 4.5·~50 minIntermédiaire

Courbes de taux et interpolation

Position dans le parcoursModule 4 sur 11 · Sujet 5 sur 16
4.5 Courbes de taux et interpolation
—Score du lab— / 100XP total—Série—

Un taux par échéance

Jusqu'ici un seul rendement actualisait tous les paiements d'une obligation. En réalité, l'argent prêté 6 mois, 2 ans et 10 ans rapporte des taux différents, et le profil selon les échéances est la courbe des taux. Un taux zéro-coupon est le taux annuel d'un paiement unique à une date donnée, sans coupons intermédiaires. En général la courbe monte avec l'échéance (les investisseurs veulent plus pour attendre plus longtemps), mais elle peut être plate ou inversée, quand les taux courts dépassent les longs, ce que les marchés lisent comme un signal d'alerte sur la croissance.

import numpy as np

maturities = np.array([0.5, 1, 2, 5, 10, 30])                      # years where the market quotes a rate
rates = np.array([0.040, 0.042, 0.045, 0.048, 0.050, 0.052])       # an upward-sloping curve

# The rate at 3 years is not quoted: interpolate linearly between 2 years (4.5%) and 5 years (4.8%)
print(float(np.interp(3, maturities, rates)))                        # 0.046
print(np.interp([0.25, 7, 40], maturities, rates).tolist())          # [0.04, 0.0488, 0.052]   flat outside the quoted range

Facteurs d'actualisation et taux à terme

Un taux zéro-coupon r pour l'échéance t donne le facteur d'actualisation (1 + r) ** -t : ce que vaut aujourd'hui une unité payée en t. La courbe cache aussi des anticipations. Prêter 2 ans à 4,5 % doit égaler prêter 1 an à 4,2 % puis prêter à nouveau un an à un taux convenu f : (1 + 4,5 %)² = (1 + 4,2 %)(1 + f), donc f = 4,80 %. Ce taux à terme est le taux d'équilibre de la deuxième année, fixé aujourd'hui. En général f = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1.

def discount_factor(rate, t):
    return (1 + rate) ** -t

print(round(float(discount_factor(0.045, 2)), 5))                  # 0.91573   one unit paid in 2 years

r1, t1, r2, t2 = 0.042, 1, 0.045, 2
forward = ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1
print(round(forward, 5))                                            # 0.04801   the rate for year 2, implied by the curve
print(round((1 + r1) ** t1 * (1 + forward) ** (t2 - t1), 5), round((1 + r2) ** t2, 5))   # 1.09 1.09   both routes agree

Valoriser sur toute la courbe

Valoriser avec un rendement unique traite pareillement un paiement à 1 an et un paiement à 10 ans. L'approche par la courbe est plus fidèle : pour chaque paiement, lisez le taux zéro-coupon de sa propre date (en interpolant si besoin), transformez-le en facteur d'actualisation et sommez flux * facteur. Deux obligations aux mêmes flux doivent avoir le même prix quels que soient leurs rendements cotés, et c'est ainsi que les banques valorisent les obligations au prix de marché. Pour une obligation à 3 ans à 5 % sur notre courbe, le prix est de 1011,25, contre 1010,98 avec un 4,6 % plat : proche ici car la courbe est douce, mais les obligations réagissent différemment quand la courbe se tord.

times = np.array([1.0, 2.0, 3.0])
flows = np.array([50.0, 50.0, 1050.0])                              # a 3-year 5% bond with annual coupons

zero = np.interp(times, maturities, rates)
print(zero.tolist())                                                 # [0.042, 0.045, 0.046]
print((discount_factor(zero, times)).round(5).tolist())              # [0.95969, 0.91573, 0.87379]
print(round(float((flows * discount_factor(zero, times)).sum()), 4))   # 1011.2462   on the curve
print(round(float((flows / 1.046 ** times).sum()), 4))               # 1010.9752   with one flat 4.6% instead
# The forward rates between the quoted maturities, in one array expression
t = np.array([1.0, 2.0, 5.0])
r = np.array([0.042, 0.045, 0.048])
forwards = ((1 + r[1:]) ** t[1:] / (1 + r[:-1]) ** t[:-1]) ** (1 / np.diff(t)) - 1
print(forwards.round(5).tolist())       # [0.04801, 0.05]   year 2 and years 3 to 5: an upward-sloping curve implies rising forwards
L'interpolation est un choix de modélisationL'interpolation linéaire des taux zéro-coupon est la règle la plus simple, mais pas la seule : les praticiens interpolent aussi les logarithmes des facteurs d'actualisation ou utilisent des splines, et ce choix modifie les taux à terme et les prix entre les points cotés. Au-delà de la dernière échéance cotée, np.interp maintient le taux plat, ce qui est une convention, pas un fait. Précisez la méthode chaque fois que vous publiez une courbe.
  • Une courbe des taux est le taux zéro-coupon par échéance ; lisez les échéances manquantes par interpolation (np.interp, plat hors de la plage).
  • Facteur d'actualisation (1 + r) ** -t ; taux à terme ((1 + r2) ** t2 / (1 + r1) ** t1) ** (1 / (t2 - t1)) - 1.
  • Prix = somme de flux * facteur d'actualisation, chaque flux au taux zéro-coupon de sa date ; précisez la méthode d'interpolation.

À suivre : les gains des options, ce que paie un call ou un put à l'échéance, point de départ de la valorisation des options.

Lab : ce qui est noté

  • Lire un taux entre les échéances cotées avec interpolate_rate25 pts
  • Transformer un taux en facteur d'actualisation avec discount_factor25 pts
  • Lire le taux futur caché dans la courbe avec forward_rate25 pts
  • Valoriser un flux de paiements sur toute la courbe avec price_on_curve25 pts
Explorateur · lab-70-1
▾ lab-70-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-70-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-70-1 revient aux fichiers de départ et le terminal est vidé. Votre solution actuelle sera perdue : cette action est irréversible.

Sera réinitialisé
  • main.py → code de départ
  • Historique du terminal et sortie des tests
  • Modifications non soumises
Sera conservé
  • Meilleur score du lab
  • Votre XP et votre série
  • Progression du cours et notes

Connectez-vous pour exécuter votre code.

Tous les cours sont gratuits à lire. Créez un compte ou connectez-vous pour exécuter du code, lancer les tests et soumettre ce lab.

  • IDE dans le navigateur avec terminal bash — rien à installer
  • Correction instantanée, XP et votre place dans le parcours
Créer un compteSe connecter
OU
Continuer avec GitHub