PythonでPER/PBRバンドを描いて「その銘柄の割安度」を可視化する(J-Quants)
「PER10倍だから割安」——絶対値だけの判断は危ういです。PERの“ちょうどいい水準”は銘柄ごとに違うので、**その銘柄の過去レンジの中の“位置”**で見るのが安全です。
この記事では、J-Quantsの株価・財務データを使って PER/PBRバンド(過去のPER/PBRの推移を帯にしたもの)をPythonで描く方法をまとめます。 ※J-Quantsの認証・データ取得の基本は割愛します(x-api-key ヘッダーでV2 APIを叩く前提)。
考え方
過去の株価の時系列を取る
各時点の**EPS(1株利益)**で割って、PERの時系列にする
その分布から「安い/高い」の帯(例:25%〜75%分位)を引く
今のPERが帯のどこにいるかを見る
PBRバンドも、EPSをBPS(1株純資産)に置き換えるだけで同じ手順です。
STEP1:株価とEPSを時系列でそろえる
EPSは決算でしか更新されないので、日次の株価に合わせて前方補完(ffill)します。
# price: 日次終値の Series(index=日付)
# eps: 決算で更新されるEPSの Series(同じくindex=日付、歯抜け)
eps = eps.reindex(price.index, method="ffill")
per = (price / eps).dropna()
per = per[per > 0] # 赤字でEPSが負の期間は除外
EPSが負(赤字)の期間はPERが意味を持たないので除外しておくのがポイントです。
STEP2:バンド(分位)と現在位置を計算
low = per.quantile(0.25) # 割安ゾーンの目安
mid = per.quantile(0.50) # 中央
high = per.quantile(0.75) # 割高ゾーンの目安
now = per.iloc[-1] # 現在のPER
# 過去レンジ内での相対位置(0=最安, 1=最高)
pos = (now - per.min()) / (per.max() - per.min())
# パーセンタイル順位(過去のうち何%より高いか)
pct = (per < now).mean()
print(f"現在PER={now:.1f} / レンジ内位置={pos*100:.0f}% / 過去比 上位{(1-pct)*100:.0f}%")
pos や pct が小さいほど「その銘柄の歴史の中では割安寄り」と読めます。
STEP3:matplotlibで可視化
import matplotlib.pyplot as plt
fig, ax = plt.subplots(figsize=(10, 4))
ax.plot(per.index, per, color="#1d9e75", lw=1.4, label="PER")
ax.axhline(high, color="#d85a30", ls="--", lw=1, label="割高目安(75%)")
ax.axhline(mid, color="#888888", ls=":", lw=1, label="中央(50%)")
ax.axhline(low, color="#378add", ls="--", lw=1, label="割安目安(25%)")
ax.fill_between(per.index, low, high, color="#1d9e75", alpha=0.08)
ax.scatter(per.index[-1], now, color="#d85a30", zorder=5) # 現在地
ax.set_title("PERバンド")
ax.legend(fontsize=9)
plt.tight_layout()
plt.show()
帯の下のほうに現在のPERがいれば「歴史的に割安ゾーン」、上のほうなら「割高ゾーン」と判断できます。 (PBRバンドにしたい場合は per を pbr = price / bps に差し替えるだけです)
注意:バンドは“過去の話”
業績が構造的に悪化すると、レンジそのものが下方向にシフトします。 「過去レンジの下限だから割安」と飛びついたら、実は中身が劣化していた——いわゆるバリュートラップに注意です。 バンド単独で判断せず、売上・利益トレンドや財務の健全性とセットで見るのが安全です。
まとめ
割安/割高は絶対値ではなく「その銘柄の過去レンジ内の位置」で見る
PER = 株価 ÷ EPS の時系列に、分位でバンドを引くだけで実装できる
赤字期間の除外・EPSのffillなど、前処理がポイント
レンジは動く点に注意(業績・財務とセットで判断)
以上です。
同じ要領でPBRバンドや、複数銘柄の一括可視化にも応用できます。参考になれば幸いです。