σμ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 2 · NumPy et pandas pour les données de marché›Sujet 2.11·~35 minIntermédiaire

Rendements logarithmiques

Position dans le parcoursModule 2 sur 11 · Sujet 11 sur 20
2.11 Rendements logarithmiques
—Score du lab— / 100XP total—Série—

Le logarithme du rapport de prix

Un rendement logarithmique est le logarithme népérien du rapport entre deux prix. Au lieu de P_t / P_{t-1} - 1, on calcule ln(P_t / P_{t-1}). Pour de petits mouvements, les deux sont presque égaux (une hausse de 2 % donne 0,0198 en logs), mais la version logarithmique a des propriétés qui en font le choix standard en statistique et en modélisation. Avec pandas, prenez le logarithme de toute la Series de prix avec np.log, puis appliquez diff : soustraire des logarithmes revient à diviser des prix.

r_t = ln(P_t / P_{t-1}) = ln(P_t) - ln(P_{t-1})
import numpy as np
import pandas as pd

prices = pd.Series([100.0, 102.0, 100.98, 103.0], index=["Mon", "Tue", "Wed", "Thu"])

log_ret = np.log(prices).diff()
print(log_ret.round(4))
# Mon       NaN
# Tue    0.0198
# Wed   -0.0101
# Thu    0.0198
# dtype: float64

print(prices.pct_change().round(4).tolist())   # [nan, 0.02, -0.01, 0.02]   the simple returns, for comparison

Les rendements logarithmiques s'additionnent dans le temps

C'est la principale raison de les utiliser. Comme ln(a) - ln(c) = (ln(a) - ln(b)) + (ln(b) - ln(c)), le rendement logarithmique sur plusieurs périodes est simplement la somme des rendements par période, sans composition. Le rendement sur deux jours est la somme de deux rendements quotidiens, le rendement mensuel est la somme des quotidiens, et exp(total) - 1 ramène le résultat à un rendement simple. Les rendements logarithmiques sont aussi symétriques : un prix qui double puis est divisé par deux a des rendements logarithmiques de +0,6931 et -0,6931, qui s'annulent, alors que les rendements simples étaient +100 % et -50 %.

# The sum of the daily log returns is the log return over the whole period
print(round(log_ret.sum(), 6))                         # 0.029559
print(round(np.log(prices.iloc[-1] / prices.iloc[0]), 6))   # 0.029559   end price over start price

# exp(total) - 1 is the simple return of the whole period
print(round(np.exp(log_ret.sum()) - 1, 6))             # 0.03
# Symmetry: the price doubles, then halves
doubling = pd.Series([100.0, 200.0, 100.0])
print(doubling.pct_change().tolist())               # [nan, 1.0, -0.5]
print(np.log(doubling).diff().round(4).tolist())    # [nan, 0.6931, -0.6931]

Conversion, et mouvements sur plusieurs jours

Pour revenir à un rendement simple, utilisez np.exp(r) - 1 (ou np.expm1(r), plus précis pour de très petites valeurs). Les deux concordent bien pour de petits mouvements et divergent pour de grands : un rendement simple de +50 % vaut 0,4055 en logs. np.log et np.exp travaillent sur une Series entière, donc pas de boucle. Pour mesurer un mouvement sur plusieurs jours, diff accepte un nombre de périodes : np.log(prices).diff(5) est le rendement logarithmique sur cinq jours, égal à la somme de cinq rendements logarithmiques quotidiens.

# Small moves agree with the simple return, big moves do not
for simple in [0.01, 0.1, 0.5, -0.5]:
    print(simple, round(np.log1p(simple), 4))   # log1p(r) is ln(1 + r)
# 0.01 0.01
# 0.1 0.0953
# 0.5 0.4055
# -0.5 -0.6931

# Back to simple returns, on the whole Series at once
print((np.exp(log_ret) - 1).round(4).tolist())   # [nan, 0.02, -0.01, 0.02]

# The log return over 2 days: diff takes a number of periods
print(np.log(prices).diff(2).round(4).tolist())   # [nan, nan, 0.0098, 0.0098]
Additionnez-les dans le temps, pas entre actifsLes rendements logarithmiques s'additionnent d'une période à l'autre, mais le rendement d'un portefeuille est la somme pondérée des rendements simples de ses actifs. Deux lignes égales avec des rendements logarithmiques de +10 % et -10 % ne donnent pas un portefeuille à 0 % : en simple, elles font +10,5 % et -9,5 %, donc le portefeuille gagne +0,5 %. Convertissez d'abord en rendements simples, pondérez, puis reconvertissez si vous voulez des logs.
  • Un rendement logarithmique vaut ln(prix / prix précédent) : np.log(prices).diff() ; la première entrée est NaN.
  • Dans le temps, ils s'additionnent simplement : log_ret.sum(), et np.exp(total) - 1 donne le rendement simple.
  • diff(k) donne le mouvement sur k périodes ; entre actifs, pondérez les rendements simples, pas les logarithmiques.

À suivre : DatetimeIndex et indexation temporelle, pour donner de vraies dates à une série de prix et la découper par mois ou par jour de la semaine.

Lab : ce qui est noté

  • Transformer des prix en rendements logarithmiques avec log_returns25 pts
  • Reconvertir des rendements logarithmiques en rendements simples avec simple_from_log25 pts
  • Additionner les rendements logarithmiques par période avec total_log_return25 pts
  • Mesurer le mouvement sur plusieurs jours avec multi_day_log_return25 pts
Explorateur · lab-44-1
▾ lab-44-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-44-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

Tout le contenu de lab-44-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