🎓 レベル:標準 | 重要度:A(必須)
📎 前提:時間価値と現在価値・割引・金利と複利 | 関連:デュレーションとコンベクシティ
要点(BLUF)
- 債券価格は将来のクーポンと元本を割り引いて合計したもの。時間価値と現在価値・割引 の NPV そのものです。クーポン率 > 利回りなら額面超(プレミアム債)、逆ならディスカウント債。
- **最終利回り(YTM)**は、その債券の市場価格を再現する単一の割引率。価格から逆算します(価格と利回りは1対1)。
- 各満期のスポットレート(ゼロレート)の集合がイールドカーブ。これが各時点の割引係数を与え、あらゆる債券・デリバティブの価格づけの基礎になります。
1. 債券価格=割引現在価値
額面 、年クーポン率 、満期 年の債券は、毎年 のクーポンを払い、満期に元本 を返します。価格はこれらを利回り で割り引いた合計です。
第1項がクーポンの現在価値(等比数列=年金)、第2項が元本の現在価値です。利回り とクーポン率 の大小で、価格が額面の上か下かが決まります。
2. 最終利回り(YTM)
**最終利回り(YTM: Yield to Maturity)**は、市場価格 を上の式に当てはめたとき成り立つ単一の です。クーポンを YTM で再投資できると仮定したときの、満期までの実効利回りに相当します。価格と YTM は1対1なので、brentq で逆算できます。
import numpy as np
from scipy.optimize import brentq
def bond_price(face, coupon_rate, ytm, n, freq=1):
N = n*freq
c = face*coupon_rate/freq # 1回あたりのクーポン
t = np.arange(1, N+1)
cf = np.full(N, c, dtype=float)
cf[-1] += face # 満期は元本も返る
return np.sum(cf/(1 + ytm/freq)**t)
face, coupon_rate, n = 100.0, 0.05, 10 # 額面100, クーポン5%, 10年
for y in [0.03, 0.04, 0.05, 0.06]:
print(f"YTM={y:.0%}: 価格 {bond_price(face, coupon_rate, y, n):.4f}")
# 価格から YTM を逆算(価格と利回りは1対1)
mkt_price = bond_price(face, coupon_rate, 0.04, n)
ytm = brentq(lambda y: bond_price(face, coupon_rate, y, n) - mkt_price, 0.001, 0.5)
print(f"価格 {mkt_price:.4f} から逆算した YTM = {ytm:.4%}")
出力:
YTM=3%: 価格 117.0604
YTM=4%: 価格 108.1109
YTM=5%: 価格 100.0000
YTM=6%: 価格 92.6399
価格 108.1109 から逆算した YTM = 4.0000%
出力の意味:YTM がクーポン率 5% に等しいとき、価格はちょうど額面 100。YTM がそれより低い(3〜4%)と価格は額面超(プレミアム)、高い(6%)と額面割れ(ディスカウント)。「利回りが下がると価格は上がる」という逆相関が読めます。価格 108.11 から逆算すると YTM = 4.00% がぴたり戻り、価格と利回りが表裏一体だと分かります。これは インプライドボラティリティ の逆算と同じ発想です。
3. スポットレートとイールドカーブ
YTM は「その債券1本の平均的な利回り」ですが、より基礎的なのは各満期ごとの割引率=スポットレート(ゼロレート) です。満期 のスポットレートは、その時点だけのキャッシュフロー(ゼロクーポン債)を割り引く率で、満期ごとに を並べたものがイールドカーブ。連続複利なら割引係数は です。
import numpy as np
import matplotlib.pyplot as plt
import japanize_matplotlib
def bond_price(face, coupon_rate, ytm, n, freq=1):
N = n*freq
c = face*coupon_rate/freq
t = np.arange(1, N+1)
cf = np.full(N, c, dtype=float); cf[-1] += face
return np.sum(cf/(1 + ytm/freq)**t)
# 価格・利回り曲線(逆相関・下に凸=コンベクシティ)
ys = np.linspace(0.01, 0.10, 100)
prices = [bond_price(100, 0.05, y, 10) for y in ys]
plt.figure(figsize=(7, 4))
plt.plot(ys*100, prices, lw=2)
plt.axhline(100, color="gray", ls=":", label="額面 100")
plt.scatter([5], [100], color="crimson", zorder=5, label="クーポン=YTM(額面)")
plt.xlabel("最終利回り YTM (%)"); plt.ylabel("債券価格")
plt.title("価格・利回りの関係(逆相関・下に凸)")
plt.legend(); plt.grid(alpha=0.3); plt.tight_layout(); plt.show()
# スポットレート(ゼロレート)→ 割引係数(連続複利)
maturities = np.array([1, 2, 3, 5, 10])
spot_rates = np.array([0.02, 0.025, 0.03, 0.035, 0.04])
discount_factors = np.exp(-spot_rates*maturities)
print("満期 :", maturities)
print("スポット率:", spot_rates)
print("割引係数 :", np.round(discount_factors, 4))
出力:
満期 : [ 1 2 3 5 10]
スポット率: [0.02 0.025 0.03 0.035 0.04 ]
割引係数 : [0.9802 0.9512 0.9139 0.8395 0.6703]
出力の意味:満期が延びるほどスポットレートが上がる(2%→4%)右肩上がりの順イールドで、割引係数は 0.98→0.67 と逓減します。10年後の1円はいまの 0.67 円。このカーブが決まれば、任意の債券は「各クーポン×その満期の割引係数」を足すだけで価格づけできます。市場の債券価格からこのカーブを逆算する作業をブートストラップと呼び、デリバティブ評価の出発点になります(順イールドが普通ですが、景気後退の予兆として逆イールド=右肩下がりが注目されます・要最新確認)。価格・利回り曲線が下に凸である点は、次の デュレーションとコンベクシティ のコンベクシティそのものです。
⚠️ よくある誤解
- 「YTM は確実に得られる利回り」ではない:YTM はクーポンを同じ YTM で再投資できる前提の利回り。実際の再投資金利が違えば実現利回りはズレます(再投資リスク)。
- YTM とスポットレートは別物:YTM は1本の債券の平均的な割引率、スポットレートは満期ごとの割引率。クーポン債の YTM は、各キャッシュフローのスポットレートの複雑な加重平均です。
- 価格と利回りは非線形:価格・利回り曲線は直線でなく下に凸。大きな金利変動では「デュレーションだけ」の直線近似が外れ、コンベクシティ補正が要ります(デュレーションとコンベクシティ)。
関連ノート
- 第7章 金利モデルと債券 目次
- 時間価値と現在価値・割引 — 前提:割引現在価値と NPV
- デュレーションとコンベクシティ — 次のトピック:金利リスクの測り方
- 金融工学テキスト 全体目次