為替データからローソク足チャートを画像保存する方法(訓練データ用)
こんばんは、新米データサイエンティスト(@algon_fx)です。お気付きの方も多いかと思いますが、実験的にGoogle Adsenseをサイトに掲載してみました。
私がブログをやっている理由は2つ。自分の考えを上手くアウトプットするための練習が一つ目。二つ目は機械学習FXトレード初心者の方の手助けができればと思っています。決して、せっかくブログ書いているのだから、毎月5万円近く掛かるモデリング用のGoogle Cloudの料金の足しにでもなれば…なんて下心は断じてありません。(あります。)
さて、今日は少し変わりネタの記事です。FXや株で機械学習モデリングをやっている方なら、「ローソク足チャートの画像を訓練データとしてCNNでモデリング!」は誰しもが一度は通る道かと思います。
そこで今日は為替データ(終値、始値、高値、安値)から、matplotlibを使いローソク足チャートをJPEG画像ファイルとして書き出す方法をまとめます。
毎度でしつこいようですが、本記事も初心者向けです。処理が理解しやすいように、少し冗長的なコードになっていますが・・ご了承ください。本記事の最後に中級者向けにヒントも載せています。
STEP1 データ前処理
まずは為替データをpandsaで読み込みましょう。為替データは下のリンクからCSVファイルとしてダウンロードが可能です。こちらはOANDAジャパンのAPIを使って、私が取得して整形したものです。(詳しくはOANDA APIの使い方をご参照ください)
使うデータ
usd_10min_api.csv
では必要なライブラリをインポートしましょう。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 |
# ライブラリのインポート import pandas as pd import numpy as np import matplotlib.pyplot as plt import datetime # ローソク足描写 import matplotlib.pyplot as plt import mpl_finance from mpl_finance import candlestick2_ohlc %matplotlib inline |
続いて為替データが含まれるCSVファイル(usd_10min_api.csv)をpandasのデータフレームとして読み込みます。
1 2 3 4 5 |
usecols = ['time','close','open','high','low'] df = pd.read_csv("usd_10min_api.csv", usecols=usecols) df.head() |
1 2 3 4 5 6 7 8 9 10 |
--出力 time close open high low 0 2018/03/01 15:40:00 106.792 106.817 106.817 106.777 1 2018/03/01 15:50:00 106.766 106.796 106.796 106.738 2 2018/03/01 16:00:00 106.774 106.769 106.822 106.762 3 2018/03/01 16:10:00 106.815 106.777 106.828 106.765 4 2018/03/01 16:20:00 106.844 106.813 106.864 106.809 |
こちらはドル円の実際のレートデータをAPIで取得したものです。
簡単な前処理としてtimeカラムを日付型へ変更して、データセットに含まれるユニークな日付の値を抽出して確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11 |
# ユニークなdaysを引っ張ろう df['time'] = pd.to_datetime(df['time']) days = df['time'].dt.date.value_counts() times = df['time'].dt.hour days.sort_index(ascending=True, inplace=True) # 確認 print(days.shape) days.head(5) |
1 2 3 4 5 6 7 8 9 10 11 12 |
--出力 (140,) 2018-03-01 50 2018-03-02 144 2018-03-03 42 2018-03-05 102 2018-03-06 144 Name: time, dtype: int64 |
全部で140日分のデータが含まれています。value_countsメソッドで各日付のデータ個数を出力してみました。10分足のデータですので、本来であれば24時間で144個のデータポイントがあるはずですが、土曜日や月曜日など取引所が休みのケースもあリますので全日付で144個のデータが揃っている訳ではありません。
時系列データとして扱いやすいよう、timeカラムをデータフレームのインデックスラベルとして付与しましょう。set_indexメソッドのinplace引数を使う事で、直接データフレームの変更が可能です。
1 2 3 4 |
df.set_index('time', inplace=True) df.index[0:2] |
1 2 3 4 5 6 7 8 |
-- 出力 DatetimeIndex(['2018-03-01 15:40:00', '2018-03-01 15:50:00'], dtype='datetime64[ns]', name='time', freq=None) |
これで簡単な前処理は完了です。
STEP2 為替データからローソク足チャート
続いて為替データを要素として持つデータフレームから、matplotlibを使ってローソク足チャートを生成する関数を作成します。
畳み込みニューラルネットワーク(CNN)の訓練データとしてチャート画像を使う場合、画像の生成の仕方は様々な方法があります。本記事巻末で軽く触れますが、この記事ではシンプルに特定の日付と時間を指定して、為替データのローソク足チャートを画像ファイルとして書き出す方法をやります。
引数は以下の通りです。処理的には難しいことはしていません。下の定義した関数のコードを紐解いてみてください。
第一引数:データフレーム(open、high、low、closeのカラムを持つ)
day:日付の文字列(例 2019-03-02)
start : 開始時間の文字列(例 15)
end:終了時間の文字列(例 23)
save:画像を保存するか否かのboolean(Trueは保存)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 |
def candle(df, day=None, start=None, end=None, save=False): s = day + ' ' + start e = day + ' ' + end temp = df[s:e] if temp.shape[0] > 5: temp = temp.reset_index() fig = plt.figure(figsize=(18,9)) ax = plt.subplot(1,1,1) ax.axis('off') candlestick2_ohlc( ax, temp['open'], temp['high'], temp['low'], temp['close'], width=0.9, colorup='r', colordown='b' ) if save == True: fig.savefig(s[:-3] + '.jpg', tranprent=True) plt.close(fig) else : pass |
少し工夫を加えていると言えばmatplotlibのax.axis(‘off’)とすることで、x軸y軸のメモリを意図的に非表示にしています。畳み込みニューラルネットワークの訓練データとして使うことを考えれば、各軸のメモリは大半のケースで不要だからです。
では、実際に関数を使ってみましょう。2018年3月2日の10時〜23時までのデータを使ってローソク足を生成してみます。save引数の初期値はFalseですので、保存はせずにチャートのみを吐きます。
1 2 3 |
candle(df, day='2018-03-02', start='10', end='23') |
綺麗なチャートの画像が出力されました。前述した通り各軸のメモリは表示されていませんので、純粋なレートのローソク足の画像のみを出力した形になっています。
STEP3 ローソク足チャートをJPEGファイルで保存
上のステップ2で定義したcandle関数は1日の所定の時間レンジのデータを使ってローソク足を生成します。
ステップ1の前処理でデータフレーム内のユニークな日付をシリーズdaysへ書き出しています。for文を使い、シリーズdaysのインデックスラベルを分解して、各日付のローソク足を出力してみましょう。
まずは試しに3日間の10時〜23時までのローソク足を出力してみましょう。save引数へFalseを渡すことで画像は保存されず、ローソク足チャートが出力されるのみです。
1 2 3 4 5 6 7 8 9 |
n = 3 cnt = 0 for idx in days.index: if cnt < n: print(idx) candle(df, day=str(idx), start='10', end='23', save=False) cnt += 1 |
1 2 3 4 5 6 |
-- 出力 2018-03-01 2018-03-02 2018-03-03 |
本来であれば3つのローソク足チャートが出力されるはずですが、ご覧の通り出力は2018-03-01と2018-03-02のみです。
candle関数をみてみると分かりますが、指定した期間内で該当するデータが5つより少ない場合はローソク足を描写しない分岐処理が入っています。表示されなかった2018-03-03は土曜日ですので、指定した時間(10時〜23時)に該当するデータが存在しません。よって、ローソク足も出力されてない訳です。
このように、為替レートから訓練データを作る場合は様々な細かい部分に気をつける必要があります。しっかり自分が意図した画像データを生成しなくては、CNNのモデリングが仮に上手くいったとしても実戦で使い物にはなりません。
では、いよいよ本題です。同じ要領でcandle関数を使ってローソク足チャートを20枚のJPEGファイルとして書き出してみましょう。candle関数のsave引数がTrueへ変更している部分に注目しましょう。
1 2 3 4 5 6 7 8 9 |
n = 20 cnt = 0 for idx in days.index: if cnt < n: print(idx) candle(df, day=str(idx), start='10', end='23', save=True) cnt += 1 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 |
--出力 2018-03-01 2018-03-02 2018-03-03 2018-03-05 2018-03-06 2018-03-07 2018-03-08 2018-03-09 2018-03-10 2018-03-12 2018-03-13 2018-03-14 2018-03-15 2018-03-16 2018-03-17 2018-03-19 2018-03-20 2018-03-21 2018-03-22 2018-03-23 |
Jupyter Notebookの起動ディレクトリを確認してみましょう。各日付をファイル名として持つJPEGファイルが新規で作成されているはずです。
まとめと課題
今回は畳み込みニューラルネットワーク(CNN)で使うためのローソク足画像データの生成方法をまとめました。冒頭でも書いた通り初心者向けですので、詳細は割愛しています。
CNNを使ったFX予測ですが、訓練データとしてどのような画像を使うかは非常に奥の深い分野です。今回のように特定の日付・時間でローソク足を使う以外に以下のような手段も考えられます。
・ローソク足ではなく終値などの線グラフ
・テクニカル指標を追加する(例えば移動平均線など)
・計算コストを加味してグレースケールへ変換
・レートを正規化する
あくまで一例ですが、他にも様々なデータを画像として出力することが可能です。またCNNでFX予測をする場合、ターゲットをどのように設定するのかも極めて重要な項目になります。
ローソク足関連は当ブログでも色々と取り上げていますので、他にも触ってみたい方は以下の記事がオススメです。
ブログ読んでいただきありがとうございます!Twitterでも色々と発信しているので、是非フォローお願いします!
ディスカッション
コメント一覧
まだ、コメントがありません