2025-03-21 公開 / 2025-03-31 更新
正規分布していないデータに対して標準偏差を当たり前のように使うのは、どうも気持ち悪いといつも感じています。そこで、データの分布形状を前提としないメジアン(中央値)を利用した統計量を使い始めています。
毎週末の日経平均株価のまとめで、ボリンジャーバンドのチャート作成に使用しているコードをベースにした JupyterLab 向けのサンプルを紹介します。
下記の OS 環境で動作確認をしています。
|
Fedora Linux 41 Workstation | x86_64 |
| Python | 3.13.2 | |
| jupyterlab | 4.3.5 | |
| matplotlib | 3.10.1 | |
| mplfinance | 0.12.10b0 | |
| pandas | 2.2.3 | |
| yfinance | 0.2.55 |
JupyterLab を起動して、最初に必要なサンプルをインポートします。
import datetime import matplotlib.pyplot as plt import mplfinance as mpf import pandas as pd import yfinance as yf
過去 3 年分の週足データを表示しますが、ボリンジャーバンドをプロットする全域で欠けることなく描画するためには、さらに(26 週分の)古いデータが必要になります。そこで、まず過去 5 年分のデータを df0 で取得してから、過去 3 年分の週足表示用のデータフレーム df に分けています。
code = 'N225' symbol = '^%s' % code ticker = yf.Ticker(symbol) # 週足で過去 5 年分のデータを取得 df0 = ticker.history(period='5y', interval='1wk') # ローソク足のチャートには、そのうち過去 3 年分のみ使用する dt_last = df0.index[len(df0) - 1] tdelta_3y = datetime.timedelta(days=365 * 3) df = df0[df0.index >= dt_last - tdelta_3y]
mplfinance でローソク足チャートをプロットしていますが、細かい修飾などを Matplotlib 側で調節したかったので、mplfinance にプロット全てを任せずに、わざわざ Matplotlib の管理下でプロットしています。
ロバスト統計を使ったボリンジャーバンドは過去 5 年分のデータフレーム df0 で算出して、ローソク足のデータスコープ、すなわちデータフレーム df の日付インデックス (df.index) に合う行のみを表示しています。
fig, ax = plt.subplots(figsize=(12, 8))
# メジアン統計を使ったボリンジャーバンドの算出
period = 26
mv_median = df0['Close'].rolling(period).median()
mv_q1 = df0['Close'].rolling(period).quantile(.25)
mv_q3 = df0['Close'].rolling(period).quantile(.75)
mv_iqr = mv_q3 - mv_q1
mv_lower = mv_q1 - mv_iqr * 1.5
mv_upper = mv_q3 + mv_iqr * 1.5
apds = [
mpf.make_addplot(mv_upper[df.index], width=1.25, color='C1', linestyle='dotted', label='Upper bound', ax=ax),
mpf.make_addplot(mv_q3[df.index], width=1, color='C2', linestyle='dashed', label='Q3 (75%)', ax=ax),
mpf.make_addplot(mv_median[df.index], width=0.75, color='C3', label='Median', ax=ax),
mpf.make_addplot(mv_q1[df.index], width=1, color='C4', linestyle='dashed', label='Q1 (25%)', ax=ax),
mpf.make_addplot(mv_lower[df.index], width=1.25, color='C5', linestyle='dotted', label='Lower bound', ax=ax),
]
mpf.plot(
df, type='candle', style='default',
addplot=apds,
datetime_format='%y-%m-%d',
xrotation=0,
ax=ax,
)
ax.grid()
ax.legend(loc='best', fontsize=9)
# 銘柄によっては銘柄名を取得できない場合があるので、その際には銘柄コードのみ表示
try:
ax.set_title('Weekly chart for %s (%s)\nwith robust Bollinger bands (period=%dweeks)' % (ticker.info['longName'], symbol, period))
except KeyError:
ax.set_title('Weekly chart for %s\nwith robust Bollinger bands (period=%sweeks)' % (symbol, period))
plt.tight_layout()
plt.show()
下記のようなプロットが表示されます。



0 件のコメント:
コメントを投稿