前回の記事、「FX自動取引プログラムを開発する~準備編~ヒストリカルデータを登録する」
で登録したデータを元にローソク足を表示するプログラムを開発します。
データはFOREXITEからダウンロードした2001年以降の1分足のデータです。
では早速プログラムソースです。
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 |
# -*- 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 = '5min' 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') plt.xlabel('Date') plt.ylabel('Price') plt.title('USD-JPY') plt.show() |
まずは、Sqliteに保存したデータを取得し、pandasで読み込みます。
テーブル構成は、"datetime", "open", "high", "low", "close"という形になっています。
次に、取得したデータをconvert_datasメソッドに渡し、
プロット用に変換します。
データが1分足なので、そのまま出力する場合は単にfloatに変換するだけです。
5分足や10分足、1時間足等も表示できるようにプログラムしてみました。
全データでループを回して、5分足や10分足等、
表示する間隔ごとにリストに保存します。
high、lowはそのリスト中の最大値および最小値を使用します。
変換したデータでもって
1 |
candlestick_ohlc(ax, datas.values, width=200.0, colorup='#77d879', colordown='#db3f3f') |
で描画します。
1分足だとこんな感じです。
5分足だとこうなります。
ローソク足っぽい見た目ではありますが、
横軸の日時と縦軸の価格ラベルの表示がうまくいっていません。
もう少し改善する余地があります。
pandasを使っての描写は常に便利なのですが
pandasを始めて使うということで、若干試行錯誤しました。
最初、配列を生成してcandlestick_ohlcに渡すように実装していたのですが、
うまくいかずpandasを使用するようにするとうまくいきました。
ローソク足を描写できたので、移動平均線の表示等にチャレンジしてみます。