pythonで為替データを分析したり可視化してみたいと考えた。
今回は、リアルタイムでドル円相場を取ってきてローソク足をプロットし、その上に移動平均,ボラティリティ,ゴールデンクロス,デッドクロスを可視化してみるというところまでやってみる。
データを取ってくる
まずはデータを取ってこないといけない。
以前はCSVファイルを取ってこれるサイトを紹介したけれど、やっぱりリアルタイムでもデータを取ってきたい。(為替の分足CSVデータが無料でダウンロードできるサイト - 技術メモ)
そこで今回はOANDAのAPIを使うことにした。
調べた限りOANDAだけが無料でリアルタイムのデータを取れるAPIを出してくれているらしいからだ。
OANDAの登録からキーの取得までは色々なサイトで確認してほしい。
pythonでは、oandapyV20というラッパーを使えばうまく取ってこられるらしい。
The oandapyV20 REST-V20 API wrapper documentation — OANDA REST V20 API Wrapper 0.6.3 documentation
ひとまずサンプルコードを動かしてみる。
コードは下の参考サイトにも載せた ここ を参考にした。
必要なライブラリがなければインストールしておく
pip install pandas pip install matplotlib pip install seaborn pip install oandapyV20
今回はデータの取得と可視化を別のプログラムで書いたのでいったん”candle.csv”としてCSV形式で保存することにした。
account_tokenには自分で取得したアクセストークンを入れてほしい。
import datetime import pandas from oandapyV20 import API import oandapyV20.endpoints.instruments as oandapy start = datetime.datetime(year=2018,month=5,day=1) minutes = 150 # 150分取得 start = start.strftime("%Y-%m-%dT%H:%M:00.000000Z") access_token = "XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX" api = API(access_token = access_token, environment="practice") request = oandapy.InstrumentsCandles(instrument = "USD_JPY", params = { "alignmentTimezone": "Japan", "from": start, "count": minutes, "granularity": "M1" }) api.request(request) filename = "candle.csv" candle = pandas.DataFrame.from_dict([ row['mid'] for row in request.response['candles'] ]) candle['time'] = [ row['time'] for row in request.response['candles'] ] candle.to_csv(filename)
土日に動かしていたので日付は固定してしまっているが、スタート時刻を変えればリアルタイムでも動かせる。
(*土日は為替相場が閉まってるからデータが取れない!!!)
移動平均線、ボリバンを可視化する
import pandas import seaborn import matplotlib.pyplot as plt from matplotlib.finance import candlestick2_ohlc as plt_candle seaborn.set_style("whitegrid") # csvを読み込む candle = pandas.read_csv('candle.csv') # 移動平均とボラティリティを求める window_size = 5 #5分移動平均を求める avg_move = pandas.Series.rolling(candle.c, window = window_size).mean().dropna().reset_index(drop = True) sigma = pandas.Series.rolling(candle.c, window = window_size).std(ddof = 0).dropna().reset_index(drop = True) sigma_plus1 = avg_move + sigma sigma_plus2 = avg_move + sigma * 2 sigma_plus3 = avg_move + sigma * 3 sigma_minus1 = avg_move - sigma sigma_minus2 = avg_move - sigma * 2 sigma_minus3 = avg_move - sigma * 3 candle = candle[window_size:].reset_index(drop = True) # X軸の見た目を整える # 時間だけを切り出すために先頭からの12文字目から取るようにしている xticks_number = 15 #15分刻みに目盛りを書く xticks_index = range(0,len(candle), xticks_number) xticks_date = [candle.time.values[i][11:16] for i in xticks_index] figure, ax = plt.subplots() plt_candle( ax, opens = candle.o.values, highs = candle.h.values, lows = candle.l.values, closes = candle.c.values, width=0.6, colorup='#DC143C', colordown='#4169E1') plt.plot(avg_move, color='#006400') plt.plot(sigma_plus1, color='#3CB371') plt.plot(sigma_plus2, color='#9ACD32') plt.plot(sigma_plus3, color='#ADFF2F') plt.plot(sigma_minus1, color='#3CB371') plt.plot(sigma_minus2, color='#9ACD32') plt.plot(sigma_minus3, color='#ADFF2F') plt.xticks(xticks_index, xticks_date, rotation=80) plt.show()
5分の移動平均を求めている。
移動平均線やボリンジャーバンドをアルゴリズム的に簡単に言うと
それぞれ「過去N本分のローソク足の終値の平均、標準偏差」のこと。
標準偏差は1σ、2σ、3σまで求めるのが普通だ。
ここがよくわからないかもしれない
candle = candle[window_size:].reset_index(drop = True)
これは、移動平均と実際のローソク足を合わせることをしている。
移動平均線は過去5分の平均を求めている事を意味するので、最初の4分は意味がないことになる。
5分の移動平均線に対しては4分ずらさないとローソク足が一致しないので、そもそもデータから取り除いてしまえということだ。
意外と手間取ったのが見た目に関してだった。
良い感じで15分毎くらいにX軸を出したかったがあんまり簡単にできる方法が見つからなかった。
xticksという関数を見つけて無理やり良い感じになるようにしたけれどもっといい方法があるかもしれない。
あと、seabornは素晴らしいのでとりあえず使っとけって感じはある。
ゴールデンクロス、デッドクロスを可視化
import pandas as pd import seaborn import matplotlib.pyplot as plt from matplotlib.finance import candlestick2_ohlc as plt_candle seaborn.set_style("whitegrid") # csvを読み込む candle = pd.read_csv('candle.csv') #移動平均を求める small_window = 5 # 5分平均線を求める big_window = 20 # 20分平均線求める sma5 = pd.Series.rolling(candle.c, window = small_window).mean() sma20 = pd.Series.rolling(candle.c, window = big_window).mean() candle = candle[ big_window: ].reset_index(drop=True) sma5 = sma5[ big_window: ].reset_index(drop=True) sma20 = sma20[ big_window: ].reset_index(drop=True) #ゴールデンクロス、デッドクロスを見つける cross = sma5 > sma20 golden = (cross != cross.shift(1)) & (cross == True) dead = (cross != cross.shift(1)) & (cross == False) #ゴールデンクロス、デッドクロスの位置をリスト化する index_g = [i-1 for i, x in enumerate(golden) if x == True] index_d = [i-1 for i, x in enumerate(dead) if x == True] # X軸の見た目を整える # 時間だけを切り出すために先頭からの12文字目から取るようにしている xticks_number = 15 #15分刻みに目盛りを書く xticks_index = range(0,len(candle), xticks_number) xticks_date = [candle.time.values[i][11:16] for i in xticks_index] figure, ax = plt.subplots() plt_candle( ax, opens = candle.o.values, highs = candle.h.values, lows = candle.l.values, closes = candle.c.values, width=0.6, colorup='#DC143C', colordown='#4169E1') plt.plot(sma5, color='greenyellow', label='sma5') plt.plot(sma20, color='darkgreen', label='sma20') plt.scatter(index_g, sma20[index_g], color='red', s=500, label="golden cross") plt.scatter(index_d, sma20[index_d], color='blue', s=500, label="dead cross") plt.xticks(xticks_index, xticks_date, rotation=80) plt.legend() plt.show()
ゴールデンクロスとデッドクロスは5分と20分の移動平均に関するクロスを計算するようにした。
ここでは20分移動平均線を5分移動平均線が下から交差すればゴールデンクロス、上から交差すればデッドクロス、ということにしている。
注意しないといけないことは、こちらは20分の移動平均を使っていることだ。
つまりローソク足に関しては最初の19分、5分の移動平均線に関しては最初の14分が不要ということになる。
それがこの部分にあたる。
candle = candle[ big_window: ].reset_index(drop=True) sma5 = sma5[ big_window: ].reset_index(drop=True) sma20 = sma20[ big_window: ].reset_index(drop=True)
長期移動平均線が上向きで短期移動平均が長期移動平均を下から上へクロスする場合、買い。(ゴールデンクロス)
長期移動平均線が下向きで短期移動平均が長期移動平均を上から下へクロスする場合、売り。(デッドクロス)
引用: http://fx.kakaku.com/fx/articleview/?no=21
と書かれてるところもあり、これに従うならもうすこし手を加える必要があるかもしれない。
改良版 ⇒ pythonでゴールデンクロスデッドクロスを可視化(2) - 技術メモ
OANDAのAPIは結構便利そうだ。
課金(口座に25万円以上入金)さえすればトレードに関するリクエストなんかも送れるらしく、リアルタイムで分析しながらシステムトレードなんかもできるかもしれない。
完全自動売買のプログラムによる不労所得生活もきっと夢じゃない。
参考サイト
- 基本的なところはここから拝借してる(ありがとうございます)
Pythonで為替のテクニカル指標を可視化 - AdwaysEngineersBlog - Adwaysエンジニアブログ
【Pandas】株価のゴールデンクロス・デッドクロスを求める | アルゴリズム雑記
- OANDA API 開発ガイド