リスクを1つの数で
ボラティリティはリターンの標準偏差で、資産を比べられるよう年率で表します。株価指数で約15〜20%、個別株で30〜60%、現金はほぼ0です。ポジションのサイズ決定、オプションの価格付け、リスク限度の設定に使われます。最も単純な推定は窓内の実現ボラティリティで、リターンの標本標準偏差に sqrt(年間期間数) を掛けたものです。窓の中のすべての日を同じ重みで扱うため、安定している(長所)一方で反応が遅い(短所)という特徴があります。
import math
import numpy as np
# Eight quiet days, one -3% shock, three more days
returns = np.array([0.004, -0.002, 0.001, 0.003, -0.004, 0.002, 0.006, -0.001, -0.030, 0.004, 0.002, -0.003])
print(round(returns[:8].std(ddof=1) * math.sqrt(252), 4)) # 0.0526 before the shock: 5.3% a year
print(round(returns.std(ddof=1) * math.sqrt(252), 4)) # 0.1505 with the shock: 15.1% a year素早く反応する:EWMA
ボラティリティはクラスターを作ります。穏やかな時期と荒れた時期はそれぞれしばらく続くので、昨日のショックは1か月前の静かな日より明日についてよく語ります。指数加重移動平均(EWMA)(RiskMetricsで普及)は毎日分散を更新します:分散_t = lam * 分散_(t-1) + (1 - lam) * リターン_t²。lam = 0.94 なら最新のリターンの重みは6%で、古いものは幾何級数的に薄れます。推定値はショックで跳ね上がり徐々に減衰するため、ショックが窓から出るまで高止まりして一気に下がる、ということがありません。
lam = 0.94
variance = np.empty(len(returns))
variance[0] = returns[0] ** 2
for t in range(1, len(returns)):
variance[t] = lam * variance[t - 1] + (1 - lam) * returns[t] ** 2 # the recursion needs the previous value
ewma = np.sqrt(variance)
print(ewma.round(5).tolist())
# [0.004, 0.00391, 0.0038, 0.00375, 0.00377, 0.00369, 0.00387, 0.00376, 0.0082, 0.00801, 0.00778, 0.00758]
# ^ the shock doubles the estimate, then it fades
print(round(ewma[-1] * math.sqrt(252), 4)) # 0.1204 today's annualised estimate値幅の利用と目標ボラティリティ
終値は日中に起きたことを無視します。日中の高値と安値はより多くの情報を持ちます。パーキンソン推定量 sqrt(mean(ln(high/low)²) / (4 ln 2)) は終値間の推定より数倍効率的で、同じ精度を大幅に少ない日数で得られます(日をまたぐ大きなギャップがないと仮定します)。ボラティリティ推定の実用例がボラティリティ・ターゲティングです。リスク10%を望み、実現ボラティリティが15%なら、ポジションを 10 / 15 = 0.67 保有します。荒れた時はレバレッジが縮み、穏やかな時は大きくなります。
high = np.array([101.5, 102.0, 103.2, 102.8, 104.0])
low = np.array([99.8, 100.9, 101.7, 101.1, 102.4])
parkinson = math.sqrt(np.mean(np.log(high / low) ** 2) / (4 * math.log(2)))
print(round(parkinson, 5)) # 0.00905 per-day volatility from the daily ranges
target = 0.10
realized = returns.std(ddof=1) * math.sqrt(252)
print(round(target / realized, 3)) # 0.664 hold two thirds of the position to run at 10% risk# Close-to-close versus range: the same five days
close = np.array([100.0, 101.2, 102.5, 101.9, 103.4])
print(round(float(np.diff(np.log(close)).std(ddof=1)), 5)) # 0.00955 from the closes only
print(round(parkinson, 5)) # 0.00905 from the high-low ranges of the same days- 実現ボラティリティ:標本標準偏差 ×
sqrt(年間期間数)。安定しているが反応は遅い - EWMA:
分散_t = lam * 分散_(t-1) + (1 - lam) * リターン_t²。直近のショックほど重く、幾何級数的に薄れる - パーキンソンは日中の高値・安値の幅を使う。ボラティリティ・ターゲティングは
目標 / 実現でポジションを調整する
次はシャープレシオです。リスク1単位あたりの報酬と、それをどこまで信頼できるかを学びます。
ラボ:採点される内容
realized_volatilityで年率ボラティリティを測る25点ewma_volatilityで直近のショックをより重くみる25点parkinson_volatilityで日中の値幅を使う25点volatility_target_leverageでリスク予算に合わせてポジションを調整する25点