日本国債金利の時系列データをPandasに取り込む

Japan's Treasury Interest Rates

方法

財務省の国債金利情報ページからヒストリカルデータのCSVをダウンロードできます。これをPandasのDataFrameに読み込みます。まずはデータを見てみましょう。
https://www.mof.go.jp/jgbs/reference/interest_rate/data/jgbcm_all.csv

国債金利情報,,,,,,,,,,,,,,,(単位 : %)  
基準日,1年,2年,3年,4年,5年,6年,7年,8年,9年,10年,15年,20年,25年,30年,40年 
S49.9.24,10.327,9.362,8.83,8.515,8.348,8.29,8.24,8.121,8.127,-,-,-,-,-,- S49.9.25,10.333,9.364,8.831,8.516,8.348,8.29,8.24,8.121,8.127,-,-,-,-,-,- S49.9.26,10.34,9.366,8.832,8.516,8.348,8.29,8.24,8.122,8.128,-,-,-,-,-,- S49.9.27,10.347,9.367,8.833,8.517,8.349,8.29,8.24,8.122,8.128,-,-,-,-,-,- S49.9.28,10.354,9.369,8.834,8.518,8.349,8.291,8.24,8.122,8.129,-,-,-,-,-,- S49.9.30,10.368,9.373,8.836,8.519,8.35,8.291,8.24,8.122,8.13,-,-,-,-,-,-

ひどい。政府サイトなのでわざわざ和暦を使いデータの2次利用を妨げています。利率がパーセント(←単位じゃないだろ)なのも使い勝手が悪そう。

ともあれ、DataFrameに読み込むため、和暦を西暦に変換する関数を定義します。ちなみに3行目の:=Python 3.8で導入されたセイウチ演算子

def convert_jp_calendar(jp_cal):
    year, month_day = jp_cal.split(".", maxsplit=1)
    if (era := year[0]) == "S":
        year0 = 1925
    elif era == "H":
        year0 = 1988
    elif era == "R":
        year0 = 2018
    else:
        raise ValueError
    return f"{year0 + int(year[1:])}.{month_day}"

この変換関数とPandasのread_csv関数だけで、データをあっさりDataFrameに取り込めます。2行目がヘッダー、欠損値 '-'、エンコーディングはShift-JIS。

import pandas as pd

url = "https://www.mof.go.jp/jgbs/reference/interest_rate/data/jgbcm_all.csv"
df = pd.read_csv(
    url,
    header=1,
    index_col="基準日",
    converters={"基準日": convert_jp_calendar},
    na_values="-",
    parse_dates=True,
    encoding="shift-jis"
)

こんな感じになります。短期金利の方が長期金利よりも高い、逆イールドです。石油ショックのせいかな。それにしても、約50年昔の金利が10%前後もあったとは。

df.head(4)
1年2年3年4年
基準日
1974-09-2410.3279.3628.8308.515
1974-09-2510.3339.3648.8318.516
1974-09-2610.3409.3668.8328.516
1974-09-2710.3479.3678.8338.517

追記

2022/2/18

英語ページから西暦のデータが入手できることに気づきました。上記の和暦→西暦変換は不要です。

import pandas as pd
import numpy as np

url = "https://www.mof.go.jp/english/policy/jgbs/reference/interest_rate/historical/jgbcme_all.csv"
df = pd.read_csv(
    url,
    header=1,
    dtype=np.float16,
    index_col="Date",
    na_values="-",
    parse_dates=True
)

文頭のグラフはこのコードで作成しました。

import matplotlib
from matplotlib import pyplot as plt
from matplotlib import rcParams

matplotlib.style.use("default")
rcParams["legend.frameon"] = False
rcParams["axes.spines.top"] = False
rcParams["axes.spines.right"] = False
rcParams["axes.labelsize"] = "large"
rcParams["font.sans-serif"] = ["Helvetica Neue"]
fig = plt.figure()
ax = fig.add_subplot()
df[["1Y", "3Y", "10Y", "30Y"]].plot(
    ax=ax, xlabel="Year", ylabel="Interest rate (%)", clip_on=False
)
ax.set_ylim(0, ax.get_ylim()[1])
ax.set_title("Japan's Treasury Bills and Bonds")

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です