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