イールドカーブのシフトを比較する

7.2.6

イールドカーブのシフトを比較する

最終更新 2020-04-08 読了時間 2 分
まとめ
  • 複数時点のイールドカーブを重ね描きし、金利のパラレルシフトやツイストを視覚化する。
  • スプレッド(10年と2年の差)の時系列を追跡し、逆イールドなど景気後退シグナルを検知する。
  • カーブの形状変化(スティープニング・フラットニング)から金融政策の影響を読み取る。

直感 #

イールドカーブ(利回り曲線)は、残存期間ごとの国債利回りをプロットした曲線で、金融政策や景気見通しを反映します。通常は期間が長いほど利回りが高い「順イールド」ですが、短期金利が長期を上回る「逆イールド」は景気後退の先行指標として知られています。複数の時点を重ねて描くと、どの年限がどの程度シフトしたかがよくわかります。

詳細な解説 #

複数時点のカーブ比較 #

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from pathlib import Path

plt.style.use("scripts/k_dm.mplstyle")
tenors = np.array([0.25, 0.5, 1, 2, 3, 5, 7, 10, 30])

snapshots = pd.DataFrame(
    {
        "2023-06": [0.012, 0.013, 0.015, 0.018, 0.021, 0.025, 0.026, 0.027, 0.030],
        "2023-09": [0.014, 0.016, 0.018, 0.021, 0.024, 0.027, 0.029, 0.031, 0.033],
        "2023-12": [0.016, 0.018, 0.020, 0.024, 0.027, 0.030, 0.032, 0.034, 0.036],
    },
    index=tenors,
)

fig, ax = plt.subplots(figsize=(9, 4.5))
colors = ["#0ea5e9", "#6366f1", "#f97316"]

for (label, values), color in zip(snapshots.items(), colors):
    ax.plot(
        snapshots.index,
        np.array(values) * 100,
        marker="o",
        linewidth=2,
        label=label,
        color=color,
    )

ax.set_xscale("log")
ax.set_xticks(tenors)
ax.set_xticklabels(["3M", "6M", "1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "30Y"])
ax.set_ylabel("利回り(%)")
ax.set_title("主要金利のカーブシフト比較(サンプルデータ)")
ax.grid(True, which="both", linestyle="--", alpha=0.3)
ax.legend()

output = Path("static/images/finance/visualize/yield_curve_shift.svg")
output.parent.mkdir(parents=True, exist_ok=True)
fig.tight_layout()
fig.savefig(output)

複数時点の利回り曲線を重ねて政策効果を把握


スプレッド(10年-2年)の算出 #

10年債と2年債の利回り差(ターム・スプレッド)は景気サイクルの代表的な指標です。スプレッドがマイナス(逆イールド)になると、過去の多くの景気後退に先行しています。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
spread = (snapshots.loc[10] - snapshots.loc[2]) * 100

fig, ax = plt.subplots(figsize=(8, 3.5))
ax.bar(spread.index, spread.values,
       color=["#10b981" if v > 0 else "#ef4444" for v in spread.values])
ax.axhline(0, color="#64748b", linewidth=0.8)
ax.set_ylabel("10Y-2Yスプレッド(%)")
ax.set_title("ターム・スプレッドの推移")
ax.grid(axis="y", alpha=0.3)

for i, (label, val) in enumerate(zip(spread.index, spread.values)):
    ax.text(i, val + 0.02, f"{val:.2f}%", ha="center", fontsize=10)

fig.tight_layout()
plt.show()

カーブの変化量をヒートマップで可視化 #

各年限でのシフト幅を色で表現すると、パラレルシフト(全年限が均等に変動)とツイスト(短期と長期で方向が異なる変動)を区別できます。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
shift_06_to_09 = (snapshots["2023-09"] - snapshots["2023-06"]) * 10000  # bps
shift_09_to_12 = (snapshots["2023-12"] - snapshots["2023-09"]) * 10000

tenor_labels = ["3M", "6M", "1Y", "2Y", "3Y", "5Y", "7Y", "10Y", "30Y"]
shift_matrix = pd.DataFrame(
    {"06→09": shift_06_to_09.values, "09→12": shift_09_to_12.values},
    index=tenor_labels,
).T

fig, ax = plt.subplots(figsize=(10, 2.5))
im = ax.imshow(shift_matrix.values, cmap="YlOrRd", aspect="auto")
ax.set_xticks(range(len(tenor_labels)))
ax.set_xticklabels(tenor_labels)
ax.set_yticks(range(len(shift_matrix.index)))
ax.set_yticklabels(shift_matrix.index)
ax.set_title("年限別シフト幅(bps)")

for i in range(shift_matrix.shape[0]):
    for j in range(shift_matrix.shape[1]):
        ax.text(j, i, f"{shift_matrix.iloc[i, j]:.0f}",
                ha="center", va="center", fontsize=9)

fig.colorbar(im, ax=ax, label="bps", shrink=0.8)
fig.tight_layout()
plt.show()

分析のヒント #

  • 短期金利が大きく上昇し長期が横ばいの場合は「ベアフラットニング」、逆に長期が上がるなら「ベアスティープニング」と呼ばれます。カーブの形で金融市場のセンチメントを把握できます。
  • 期間を対数スケールにしておくと30年債までの広いレンジでも視認性が保てます。
  • 実際のデータを使う場合は、各年限のリターンを計算してスプレッド(10年と2年の差など)を別グラフで描くと景気後退サインの検知に応用できます。
  • 日本国債の場合はYCC(イールドカーブ・コントロール)政策の影響で10年付近が固定されるため、カーブの形状が独特になる点にとくに注意が必要です。