σμ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 Academyロードマップ
Ctrl K
AO
+1.2k 人の学習者
ログイン参加する ↗
ロードマップ
AO
+1.2k 人の学習者
ログイン
  • English
  • Français
  • Español
  • العربية
  • Português
  • Deutsch
  • 日本語
  • 中文
Python ロードマップ›モジュール 2 · 市場データのためのNumPyとpandas›トピック 2.17·~45 分中級

コーポレートアクション:株式分割と配当

ロードマップ上の位置モジュール 2/11 · トピック 17/20
2.17 コーポレートアクション:株式分割と配当
—ラボスコア— / 100合計XP—連続日数—

嘘をつく価格履歴

企業が株式を4分割すると、株主は1株につき4株を受け取り、価格は4分の1になります。誰も損をしていませんが、生の履歴には-75%の日が現れます。現金配当も小さな規模で同じことが起き、権利落ち日に価格は配当額ほど下がります。生の価格を読む戦略は、誰も傷つかなかった暴落を見てしまいます。対策は履歴を調整することです。イベント前のすべての日を再スケールし、系列を連続させて今日の価格と比較できるようにします。

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

株式分割の調整

変わるのは分割の前の日だけで、価格を比率(4分割なら4)で割ります。現在の価格は取引されたままなので、調整後の系列は実際の現在価格で終わります。index >= split_date で真偽のマスクを作り(文字列は DatetimeIndex と比較できます)、where を使います。where はマスクが真の位置では元の値を残し、それ以外では置換値を採用します。出来高は逆方向で、分割後は4倍の株数が取引されるため、過去の出来高には比率を掛けます。株式併合は1未満の比率で同じ式を使います。

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]

配当の調整

配当は分割より小さいので、調整は1に近い係数になります。1 - 配当 / 直前の終値 で、直前の終値とは権利落ち日の前の最後の終値です。権利落ち日より前のすべての価格にこの係数を掛けます。すると権利落ち日直前の終値は配当額ちょうどだけ下がり、権利落ち日の値動きは市場が実際にした動きだけを示し、調整後の系列から計算したリターンには配当が含まれます。リターン計算に使うべきなのはこの調整後終値です。係数は小さな専用の関数にして、テストと再利用ができるようにしましょう。

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
リターンには調整後、取引には生の価格調整後価格はリターンの測定と時点間の比較のためのもので、実際に支払う金額ではありません。注文はその日に提示された生の価格で出され、古い調整後価格は当時の実際の取引価格より低くなることがあります。close と adj_close の両方を残し、各計算がどちらを使うかを明示しましょう。
  • 分割は過去の価格を比率で割り、過去の出来高に掛ける。変わるのは分割前の日だけ
  • 配当は権利落ち日より前の価格に 1 - 配当 / 直前の終値 を掛ける
  • ループではなくマスクで where(index >= date, 調整後) を使う。リターンは調整後価格で計算し、取引は生の価格で行う

次は matplotlib による折れ線グラフです。きれいになった価格系列を描きます。

ラボ:採点される内容

  • adjust_for_split で株式分割をまたいで価格を比較可能にする25点
  • adjust_volume_for_split で過去の出来高を換算する25点
  • dividend_factor で配当の調整係数を計算する25点
  • adjust_for_dividend で履歴から配当落ちの下げを取り除く25点
エクスプローラー · lab-50-1
▾ lab-50-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-50-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

このトピックをリセットしますか?

lab-50-1 の内容はすべてスターターファイルに戻り、ターミナルも消去されます。現在の解答は失われ、元に戻せません。

リセットされるもの
  • main.py → スターターコード
  • ターミナル履歴とテスト出力
  • 未提出の変更
保持されるもの
  • ラボの最高スコア
  • XPと連続日数
  • 講義の進捗とメモ

コードを実行するにはログインしてください。

レクチャーはすべて無料で読めます。コードの実行、テスト、ラボの提出にはアカウントの作成かログインが必要です。

  • ブラウザ内IDEとbashターミナル。インストール不要
  • 即時採点、XP、ロードマップでの現在地
アカウントを作成ログイン
または
GitHubで続ける