Mímisbrunnr知恵の泉

← 金融工学 一覧

🎓 レベル:基礎 | 重要度:A(必須)

📎 前提:金利と複利 | 数理:正規分布(標準正規・標準化)(統計)・中心極限定理(CLT)(統計)

要点(BLUF)

1. 単純リターンと対数リターン

時点 t1t-1 の価格 Pt1P_{t-1}ttPtP_t になったとき、リターンの測り方は2通りあります。

**単純リターン(simple / net return)**は「何%増えたか」そのものです。

Rt=PtPt1Pt1=PtPt11R_t = \frac{P_t - P_{t-1}}{P_{t-1}} = \frac{P_t}{P_{t-1}} - 1

**対数リターン(log return)**は価格比の自然対数をとります。

rt=lnPtPt1=ln(1+Rt)r_t = \ln\frac{P_t}{P_{t-1}} = \ln(1 + R_t)

両者は r=ln(1+R)r = \ln(1+R) で結ばれ、RR が小さいとき ln(1+R)RR22+R\ln(1+R) \approx R - \tfrac{R^2}{2} + \cdots \approx R なので、日次のような小さな変化ではほぼ一致します。実際に計算して見比べます。

import numpy as np

# 5日分の終値(合成データ)
prices = np.array([100.0, 102.0, 101.0, 105.0, 103.0])

simple_ret = prices[1:] / prices[:-1] - 1      # 単純リターン
log_ret = np.log(prices[1:] / prices[:-1])     # 対数リターン

print("単純リターン:", np.round(simple_ret, 4))
print("対数リターン:", np.round(log_ret, 4))

出力:

単純リターン: [ 0.02   -0.0098  0.0396 -0.019 ]
対数リターン: [ 0.0198 -0.0099  0.0388 -0.0192]

出力の意味:両者はどの日もほぼ同じ値です(+2.00% vs +1.98% など)。違いはわずかで、対数リターンは正のとき少し小さく、負のとき少し大きく(絶対値が)出ます。これは ln(1+R)\ln(1+R)RR の下に少し凸だからです。「日次なら単純でも対数でもほぼ同じ」——ではなぜ2つ使うのか。次の加法性に答えがあります。

2. 加法性:時間方向と資産方向

2つのリターンは、足せる方向が違います。これが使い分けの核心です。

時間方向(対数リターンが足せる):複数期間をまたぐと、グロスリターン(1+R1+R)は掛け算で累積します。

PTP0=t=1T(1+Rt)\frac{P_T}{P_0} = \prod_{t=1}^{T}(1+R_t)

ところが対数をとれば積は和になり、対数リターンはただ足すだけで全期間のリターンになります。

lnPTP0=t=1Tln(1+Rt)=t=1Trt\ln\frac{P_T}{P_0} = \sum_{t=1}^{T}\ln(1+R_t) = \sum_{t=1}^{T} r_t
import numpy as np

prices = np.array([100.0, 102.0, 101.0, 105.0, 103.0])

# 期間全体のグロスリターン(最初と最後だけで決まる)
total_gross = prices[-1] / prices[0]
print(f"全期間グロス: {total_gross:.4f}  (= {total_gross-1:.2%})")

# 対数リターンは「足す」だけで全期間に一致する
log_ret = np.log(prices[1:] / prices[:-1])
print(f"対数リターンの和: {log_ret.sum():.4f}")
print(f"exp(和):         {np.exp(log_ret.sum()):.4f}")

# 単純リターンは「掛ける」(1+R を累積)
simple_ret = prices[1:] / prices[:-1] - 1
print(f"(1+R)の積:       {np.prod(1 + simple_ret):.4f}")

出力:

全期間グロス: 1.0300  (= 3.00%)
対数リターンの和: 0.0296
exp(和):         1.0300
(1+R)の積:       1.0300

出力の意味:対数リターンを単純に足した 0.0296 を exp\exp すると、全期間グロス 1.0300 にぴたり一致します。単純リターンのほうは「掛け算((1+R)\prod(1+R))」で同じ 1.0300 に到達します。時系列の集計・年率換算・確率モデルでは対数リターンが圧倒的に楽——足し算で済み、金利と複利 の連続複利と同じ構造(指数の肩の足し算)だからです。正規分布の和がまた正規分布になる性質(中心極限定理(CLT)(統計))とも相性が良く、第3章の幾何ブラウン運動につながります。

資産方向(単純リターンが足せる):いっぽう、ある時点で複数資産を保有するポートフォリオのリターンは、単純リターンの加重平均で書けます。

Rp=iwiRi(wi:資産 i の構成比)R_p = \sum_{i} w_i R_i \qquad(w_i:\text{資産 } i \text{ の構成比})

対数リターンにはこの性質がありません(ln\ln は和に対して線形でない)。ポートフォリオを「横に足す」ときは単純リターンを使います——これが第2章のポートフォリオ理論で効いてきます。まとめると、時間で足すなら対数、資産で足すなら単純

3. 算術平均と幾何平均(ボラティリティ・ドラッグ)

「平均リターン」にも2種類あります。

資産が実際に何倍になったかを決めるのは幾何平均のほうです。そして両者には常に gRˉg \le \bar R という関係があり、リターンのばらつき(ボラティリティ)が大きいほど差が開きます。対数リターンが平均 μ\mu・標準偏差 σ\sigma の正規分布に近いとき、近似的に

gRˉσ22g \approx \bar R - \frac{\sigma^2}{2}

この目減り分 σ2/2\sigma^2/2ボラティリティ・ドラッグと呼びます。月次リターンを合成して確かめます。

import numpy as np

rng = np.random.default_rng(42)

# 月次対数リターン(平均0.8%/月, 標準偏差5%/月)を120ヶ月分
mu, sigma = 0.008, 0.05
log_rets = rng.normal(mu, sigma, size=120)
simple_rets = np.exp(log_rets) - 1                 # 単純リターンに変換

arith_mean = simple_rets.mean()                                  # 算術平均
geo_mean = np.prod(1 + simple_rets)**(1/len(simple_rets)) - 1    # 幾何平均
geo_from_log = np.exp(log_rets.mean()) - 1                       # 対数平均から

print(f"算術平均リターン: {arith_mean:.4%}/月")
print(f"幾何平均リターン: {geo_mean:.4%}/月")
print(f"対数平均から:     {geo_from_log:.4%}/月")
print(f"近似 算術-σ^2/2 : {arith_mean - sigma**2/2:.4%}/月")

出力:

算術平均リターン: 0.5759%/月
幾何平均リターン: 0.4992%/月
対数平均から:     0.4992%/月
近似 算術-σ^2/2 : 0.4509%/月

出力の意味:算術平均(0.5759%)より幾何平均(0.4992%)のほうが小さく、その差がボラティリティ・ドラッグです。幾何平均は「対数リターンの平均を exp\exp したもの」(0.4992%)と完全に一致します——対数リターンの算術平均こそが、複利での実際の成長率だからです。近似式 Rˉσ2/2\bar R - \sigma^2/2(0.4509%)も幾何平均の近くを指しています。「平均+10%、平均−10%を繰り返すと元本割れする」1.1×0.9=0.991.1\times0.9=0.99)のはこのドラッグのため。リターンを語るときは、どちらの平均かを意識する必要があります。

⚠️ よくある誤解

関連ノート