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 件のコメント:
コメントを投稿