Engineering Note

プログラミングなどの技術的なメモ

ボリンジャーバンド (Pythonによるファイナンス)

moving average

本記事は、PythonのPandasを用いてファイナンスの基本的な理論などについて学んでいきます。

今回は、標準偏差正規分布という統計学的な観点からトレンドを把握するボリンジャーバンド(Bollinger Bands)について学んでいきます。

 

 

Pandasとは

Pandasとは、データ分析や操作をまとめたPythonのライブラリです。

特にPanel、DataFrameおよびSeriesと呼ばれるデータ構造は使いやすく、また統計量を求めるための様々なメソッドが組み込まれています。

なお、Pandasの由来はPanel Dataから来ているそうです。

以下が公式のドキュメントになります。

 

 

ボリンジャーバンドとは

統計学で用いられる正規分布(Normal Distribution) では、データのばらつき具合を示す標準偏差(Standard Deviation:\sigma )を用いて、平均値 \mu\pm1\sigma では約0.6826( \fallingdotseq 70%)、平均値 \mu\pm2\sigma では約0.9544( \fallingdotseq 95%)の確率でデータが収まるということが証明されています。

これを応用したものがボリンジャーバンド(Bollinger Bands)と呼ばれるもので、1980年代にJohn Bollingerによって提唱されました。

つまり +2\sigma を超えた場合、株価が上昇しすぎであると判断し、反対に -2\sigma では株価が下落しすぎであると判断します。

 

Pythonボリンジャーバンドを描いてみる

それでは、Pythonボリンジャーバンドをチャートに描いてみます。

 

import pickle
import pandas as pd
import matplotlib.pyplot as plt

def show_bollinger_bands(df, days=25, start=False, end=False):
    c = df.close
    ma = c.rolling(window=days, min_periods=days-1).mean()
    vol = c.rolling(window=days, min_periods=days-1).std()
    bol1_p = pd.DataFrame(index=ma.index)
    bol1_p = ma + vol
    bol1_m = pd.DataFrame(index=ma.index)
    bol1_m = ma - vol

    bol2_p = pd.DataFrame(index=ma.index)
    bol2_p = ma + (vol * 2)
    bol2_m = pd.DataFrame(index=ma.index)
    bol2_m = ma - (vol * 2)


    plt.style.use('ggplot')
    fig = plt.figure(figsize=(15,5))
    ax = fig.add_subplot(111)
    xdate = df.index

    if start:
        xmin = start
    else:
        xmin = df.index[0]
    if end:
        xmax = end
    else:
        xmax = df.index[-1]
    ymin = c.loc[xmin:xmax].min() - 50
    ymax = c.loc[xmin:xmax].max() + 50

    ax.plot(xdate, ma, color='g', label='moving average {}'.format(days))
    ax.plot(xdate, c, color='b', label='close')
    ax.fill_between(xdate, bol1_p, bol1_m, color="red", alpha=0.7, label="$1\sigma$")
    ax.fill_between(xdate, bol2_p, bol2_m, color="red", alpha=0.3, label="$2\sigma$")
    ax.set_ylabel('price')
    ax.set_xlabel('year')
    ax.set_ylim(ymin, ymax)
    ax.set_xlim(xmin, xmax)
    ax.legend(loc=1)
    plt.show()

with open('n225.pkl', 'rb') as f:
    n225 = pickle.load(f)

show_bollinger_bands(n225)

 

動作確認

それでは、上記で作成したスクリプトを実行してみます。

事前に2017年1月~2019年2月までの日経平均株価のDataFrameをpickleとして保存しておき、それをロードして使用しています。

今回は25日移動平均を基準にボリンジャーバンドを描画しています。

fig1. ボリンジャーバンド

fig1. ボリンジャーバンド

 

ボラティリティが低ければバンド幅は縮み、高ければバンド幅は拡がります。

この拡張と収縮は交互に現れ、一般的にはバンド幅が異常に広がった場合は、トレンド転換のサインとなります。

 

参考書籍

Python3ではじめるシステムトレード ──環境構築と売買戦略 (Modern alchemists series)

完全独習 統計学入門

マーケットのテクニカル分析 ――トレード手法と売買指標の完全総合ガイド

PythonユーザのためのJupyter[実践]入門