スポンサードリンク
FXヒストリカルデータを元にボリンジャーバンドを描写してみます。
前回の「FXのヒストリカルデータを元にPythonのpandasとmatplotlibを使用して移動平均線を描写する」で
移動平均線を描写していますので、ボリンジャーバンドの描写は簡単でした。
ボリンジャーバンドは、移動平均線を中心に上下に
+1σ(シグマ)、+2σ、-1σ、-2σ
の4本の線(移動平均線を含めると5本)の線を描写したものです。
移動平均線と同じくPandasのSeriesを使用します。
Pandasには、ボリンジャーバンドを描写するために必要な
σの値を算出する関数が用意されていますので、これを使用します。
ではさっそくプログラムソースです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 |
# -*- coding: utf-8 -*- """ Created on Tue Jan 10 16:44:16 2017 @author: ichizo """ import datetime import sqlite3 import pandas as pd import matplotlib.pyplot as plt from matplotlib.finance import candlestick_ohlc DB = 'usd_jpy_prices.db' FROMDATE = '20161201000000' TODATE = '20161201010000' DTYPE = '1min' def get_datas(): conn = sqlite3.connect(DB) sql = "SELECT datetime, open, high, low, close FROM onemin WHERE datetime >= '%s' AND datetime <= '%s';" % (FROMDATE, TODATE) datas = pd.io.sql.read_sql_query(sql, conn) conn.close() return datas def convert_datas(datas): datas['open'] = datas['open'].astype(float) datas['high'] = datas['high'].astype(float) datas['low'] = datas['low'].astype(float) datas['close'] = datas['close'].astype(float) if DTYPE == '1min': tmp = datas['datetime'].values.astype('datetime64[D]') datas['datetime'] = tmp.astype(float) return datas quotes_arr = [] tmp_open_price = 0 tmp_high_price = [] tmp_low_price = [] tmp_close_price = 0 count = 0 for loop, cDate in enumerate(datas['datetime']): isNext = False cDatetime = datetime.datetime.strptime(cDate, "%Y%m%d%H%M%S") if DTYPE == '5min' and cDatetime.minute % 5 == 0: isNext = True if DTYPE == '10min' and cDatetime.minute % 10 == 0: isNext = True if DTYPE == '30min' and cDatetime.minute % 30 == 0: isNext = True if DTYPE == '1hour' and cDatetime.minute == 0: isNext = True if DTYPE == '1day' and cDatetime.hour == 0: isNext = True if tmp_open_price == 0: tmp_open_price = datas['open'][loop] if isNext == True and loop != 0: data = [] data.append(cDate) data.append(tmp_open_price) data.append(max(tmp_high_price)) data.append(min(tmp_low_price)) data.append(tmp_close_price) pddata = pd.DataFrame([data]) pddata.columns = ["datetime", "open", "high", "low", "close"] pddata.index = [count] quotes_arr.append(pddata) tmp_open_price = datas['open'][loop] tmp_high_price = [] tmp_low_price = [] count += 1 tmp_high_price.append(datas['high'][loop]) tmp_low_price.append(datas['low'][loop]) tmp_close_price = datas['close'][loop] for idx, value in enumerate(quotes_arr): if idx == 0: quotes = quotes_arr[idx] else: quotes = pd.concat([quotes, value],axis=0) quotes['datetime'] = quotes['datetime'].astype(float) quotes['open'] = quotes['open'].astype(float) quotes['high'] = quotes['high'].astype(float) quotes['low'] = quotes['low'].astype(float) quotes['close'] = quotes['close'].astype(float) return quotes if __name__ == '__main__': datas = get_datas() datas = convert_datas(datas) plt.grid() ax = plt.subplot() candlestick_ohlc(ax, datas.values, width=200.0, colorup='#77d879', colordown='#db3f3f') #移動平均線 s = pd.Series(datas['close']) sma25 = s.rolling(window=25).mean() #sma5 = s.rolling(window=5).mean() #plt.plot(datas['datetime'], sma5) deviation = 2 sigma = s.rolling(window=25).std(ddof=0) #σの計算 upper_siguma = sma25 + sigma upper2_siguma = sma25 + sigma * deviation lower_siguma = sma25 - sigma lower2_siguma = sma25 - sigma * deviation plt.plot(datas['datetime'], sma25) plt.plot(datas['datetime'], upper_siguma) plt.plot(datas['datetime'], upper2_siguma) plt.plot(datas['datetime'], lower_siguma) plt.plot(datas['datetime'], lower2_siguma) plt.xlabel('Date') plt.ylabel('Price') plt.title('USD-JPY') plt.show() |
今回追加したのは以下の部分です。
1 2 3 4 5 6 7 8 9 10 11 12 |
deviation = 2 sigma = s.rolling(window=25).std(ddof=0) #σの計算 upper_siguma = sma25 + sigma upper2_siguma = sma25 + sigma * deviation lower_siguma = sma25 - sigma lower2_siguma = sma25 - sigma * deviation plt.plot(datas['datetime'], sma25) plt.plot(datas['datetime'], upper_siguma) plt.plot(datas['datetime'], upper2_siguma) plt.plot(datas['datetime'], lower_siguma) plt.plot(datas['datetime'], lower2_siguma) |
σの値は、
1 |
sigma = s.rolling(window=25).std(ddof=0) |
で計算できますので、この値を移動平均線の値にプラス(もしくはマイナス)するだけです。
出力した結果は以下になります。
それっぽいグラフになりました。
スポンサードリンク
スポンサードリンク