σμ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.17·~45 minIntermédiaire

Opérations sur titres : fractionnements et dividendes

Position dans le parcoursModule 2 sur 11 · Sujet 17 sur 20
2.17 Opérations sur titres : fractionnements et dividendes
—Score du lab— / 100XP total—Série—

Un historique de prix qui ment

Quand une société fractionne ses actions 4 pour 1, chaque porteur reçoit quatre actions pour une et le prix tombe au quart. Personne n'a rien perdu, mais l'historique brut affiche une journée à -75 %. Un dividende en espèces fait la même chose à plus petite échelle : à la date de détachement, le prix baisse d'environ le montant du dividende. Une stratégie qui lit les prix bruts verra des krachs qui n'ont fait de mal à personne. Le remède est d'ajuster l'historique : remettre à l'échelle tous les jours avant l'événement pour que la série soit continue et comparable aux prix d'aujourd'hui.

import pandas as pd

index = pd.bdate_range("2026-03-02", periods=6)
raw = pd.Series([480.0, 484.0, 488.0, 123.0, 124.5, 126.0], index=index, name="close")   # 4-for-1 split on 5 March

print(raw.pct_change().round(4).tolist())
# [nan, 0.0083, 0.0083, -0.748, 0.0122, 0.012]    the -74.8% day never happened to anyone

Ajuster un fractionnement

Seuls les jours avant le fractionnement changent : divisez leurs prix par le ratio (4 pour un fractionnement 4 pour 1). Les prix actuels restent tels que cotés, donc la série ajustée finit au vrai prix courant. Construisez un masque Vrai/Faux avec index >= split_date (une chaîne fonctionne face à un DatetimeIndex) et utilisez where, qui garde une valeur là où le masque est Vrai et prend le remplacement ailleurs. Le volume va dans l'autre sens : quatre fois plus d'actions s'échangent après le fractionnement, donc les anciens volumes sont multipliés par le ratio. Un regroupement d'actions utilise un ratio inférieur à 1 et les mêmes formules.

split_date = "2026-03-05"
adjusted = raw.where(raw.index >= split_date, raw / 4)    # the days before the split, divided by 4

print(adjusted.tolist())                      # [120.0, 121.0, 122.0, 123.0, 124.5, 126.0]
print(adjusted.pct_change().round(4).tolist())   # [nan, 0.0083, 0.0083, 0.0082, 0.0122, 0.012]   no more crash
# Volume goes the other way: older days are multiplied
volume = pd.Series([1000, 1100, 900, 4200, 4000, 4300], index=index)
print(volume.where(volume.index >= split_date, volume * 4).tolist())   # [4000, 4400, 3600, 4200, 4000, 4300]

Ajuster un dividende

Un dividende est plus petit qu'un fractionnement, l'ajustement est donc un facteur proche de 1 : 1 - dividende / clôture précédente, la clôture précédente étant la dernière clôture avant la date de détachement. Multipliez chaque prix antérieur à cette date par ce facteur. La clôture juste avant le détachement baisse alors exactement du montant du dividende, le mouvement du jour de détachement ne montre que ce que le marché a réellement fait, et les rendements calculés sur la série ajustée incluent le dividende. C'est ce cours de clôture ajusté qu'il faut utiliser pour les calculs de rendement. Mettez le facteur dans sa propre petite fonction pour pouvoir le tester et le réutiliser.

def dividend_factor(prev_close, dividend):
    return 1 - dividend / prev_close


prices = pd.Series([100.0, 101.0, 102.0, 100.8, 101.5, 102.5], index=index)   # a 1.50 dividend, ex-date 5 March
ex_date, dividend = "2026-03-05", 1.5

prev_close = prices[prices.index < ex_date].iloc[-1]       # 102.0, the last close before the ex-date
factor = dividend_factor(prev_close, dividend)
print(round(factor, 6))                                    # 0.985294

adjusted = prices.where(prices.index >= ex_date, prices * factor)
print(adjusted.round(4).tolist())                          # [98.5294, 99.5147, 100.5, 100.8, 101.5, 102.5]
print(prices.pct_change().round(4).tolist()[3], adjusted.pct_change().round(4).tolist()[3])   # -0.0118 0.003
Ajusté pour les rendements, brut pour négocierLes prix ajustés servent à mesurer des rendements et à comparer dans le temps. Ce n'est pas ce que vous payez : un ordre est passé au prix brut coté ce jour-là, et un ancien prix ajusté peut être inférieur au prix réel auquel le titre s'échangeait. Gardez les deux colonnes (close et adj_close) et précisez laquelle un calcul utilise.
  • Un fractionnement divise les anciens prix par le ratio et multiplie les anciens volumes par ce ratio ; seuls les jours avant le fractionnement changent.
  • Un dividende multiplie les prix avant la date de détachement par 1 - dividende / clôture précédente.
  • Utilisez where(index >= date, ajusté) avec un masque, pas une boucle ; calculez les rendements sur les prix ajustés, négociez aux prix bruts.

À suivre : les courbes avec matplotlib, pour dessiner la série de prix propre dont vous disposez maintenant.

Lab : ce qui est noté

  • Rendre les prix comparables à travers un fractionnement avec adjust_for_split25 pts
  • Mettre à l'échelle les anciens volumes avec adjust_volume_for_split25 pts
  • Calculer le facteur d'ajustement d'un dividende avec dividend_factor25 pts
  • Retirer la baisse due au dividende de l'historique avec adjust_for_dividend25 pts
Explorateur · lab-50-1
▾ lab-50-1
…
bash · dans le navigateur
learner@quantcraft:~/lab-50-1$
Python pas encore chargéPythonLn 1, Col 1Spaces: 4UTF-8

Réinitialiser ce sujet ?

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