σμ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.20·~35 分中級

ヒストグラムと分布

ロードマップ上の位置モジュール 2/11 · トピック 20/20
2.20 ヒストグラムと分布
—ラボスコア— / 100合計XP—連続日数—

区間ごとに数える

平均と標準偏差は1000個のリターンを2つの数に押し込めます。ヒストグラムは形を残します。値の範囲を区間(ビン)に区切り、各区間に入る観測数を数えます。中央が高く両端が低ければおなじみの釣鐘型で、偏った形や裾の重い形は警告です。np.histogram(values, bins=edges) は配列全体を処理して度数を返します。区間 i は edges[i] 以上 edges[i + 1] 未満の値を取り、最後の区間だけは右端も含みます。

import numpy as np

returns = np.array([-0.021, -0.012, -0.008, -0.004, -0.002, 0.000, 0.001, 0.003, 0.004, 0.006, 0.009, 0.015, 0.032])
edges = np.array([-0.03, -0.01, 0.0, 0.01, 0.03])      # four bins: -3%..-1%, -1%..0%, 0%..1%, 1%..3%

counts, _ = np.histogram(returns, bins=edges)
print(counts.tolist(), counts.sum(), len(returns))      # [2, 3, 6, 1] 12 13   the 3.2% return is outside every bin

# bins=4 asks numpy for 4 equal-width bins between the minimum and the maximum
counts, edges4 = np.histogram(returns, bins=4)
print(counts.tolist(), edges4.round(4).tolist())        # [3, 6, 3, 1] [-0.021, -0.0078, 0.0055, 0.0188, 0.032]

度数か密度か

度数は観測数と区間の幅に左右されるので、標本サイズの違う2つのヒストグラムは比べられません。密度はこれを解決します。各度数を数えた合計と区間の幅で割り、棒の面積の合計が1になるようにします。すると、正規分布の釣鐘のような理論曲線や別の標本と比較できます。np.histogram(values, bins=edges, density=True) がそれを行い、counts / (counts.sum() * np.diff(edges)) でも同じです。

counts, _ = np.histogram(returns, bins=edges)
density = counts / (counts.sum() * np.diff(edges))
print(density.round(2).tolist())              # [8.33, 25.0, 50.0, 4.17]
print((density * np.diff(edges)).sum())        # 1.0   the areas add up to 1

描画と裾の読み取り

ax.hist(values, bins=10) は数えて描くまでを1回で行い、区間ごとに棒が1本(ax.patches)でき、その高さが度数です。軸には必ずラベルを付けましょう。「日次リターン」という表示のないリターンのヒストグラムは意味を持ちません。大切なのは形で、痛いのは裾です。平均から標準偏差の k 倍より離れた観測の割合 np.mean(np.abs(x - mean) > k * std) を数えれば、極端な値がどれだけ起きるかがわかります。正規分布では約4.6%が2標準偏差の外、0.27%が3標準偏差の外にあります。市場はそれより悪く、次のトピックで見ます。

import matplotlib
matplotlib.use("Agg")
import matplotlib.pyplot as plt

fig, ax = plt.subplots()
ax.hist(returns, bins=5)
ax.set_xlabel("Daily return")
ax.set_ylabel("Frequency")
print(len(ax.patches), [round(p.get_height()) for p in ax.patches])   # 5 [2, 4, 5, 1, 1]   one bar per bin; the heights are the counts

# How often are the returns more than 1 standard deviation from the mean?
mean, std = returns.mean(), returns.std(ddof=1)
print(round(float(np.mean(np.abs(returns - mean) > 1 * std)), 3))     # 0.308   about 4 of 13 days
# The number of bins changes the picture: compare a few
for bins in (2, 4, 8):
    print(bins, np.histogram(returns, bins=bins)[0].tolist())
# 2 [9, 4]
# 4 [3, 6, 3, 1]
# 8 [1, 2, 2, 4, 2, 1, 0, 1]
区間の取り方で見え方が変わる区間が少なすぎると形が隠れ、多すぎるとノイズになります。唯一の正解はないので、いくつか試し、ヒストグラムは同じ境界で比べましょう。また、ヒストグラムは標本であり、次の標本は少し違って見えます。個々の棒ではなく全体の形で判断してください。
  • np.histogram(values, bins=edges) は各区間の値を数える。最後の区間は右端を含む
  • 密度は数えた合計と区間の幅で割る。面積の合計が1になり、標本どうしを比較できる
  • ax.hist(values, bins=n) で描き、np.mean(np.abs(x - mean) > k * std) で裾を測る。軸にラベルを付け、同じ境界で比べる

次はリターンの平均と分散です。分布を要約する2つの数を、定義から計算します。

ラボ:採点される内容

  • bin_counts で各区間のリターン数を数える25点
  • density で度数を密度に変換する25点
  • fraction_beyond で裾の割合を測る25点
  • plot_histogram でヒストグラムを描く25点
エクスプローラー · lab-53-1
▾ lab-53-1
…
bash · ブラウザ内
learner@quantcraft:~/lab-53-1$
Pythonは未読み込みPythonLn 1, Col 1Spaces: 4UTF-8

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

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

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

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

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

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