為替の予測をやってみた(その1〜データ取得編〜)

この記事の概要

目的: 為替予測のためのデータ取得についての備忘録

内容:

  • 為替データの入手
    • OANDA API v20を利用した
  • グラフ描画
    • plotlyを利用した
  • 予測の方針
    • 30分後の価格帯を予測することとした

為替データの入手

OANDA APIの呼び出し

まず、OANDA APIを使用に必要なライブラリーとインポートし、APIキーを設定します。

from oandapyV20.contrib.factories import InstrumentsCandlesFactory
from oandapyV20 import API

client = API(access_token=access_token)

※OANDA APIを利用した為替データの入手には、OANDA Japan(https://www.oanda.jp/)での口座開設が必要です。 私はデモ口座を開設しています。

次に、APIに接続して過去レートを取得し、保存します。

def cnv(r, h):
    for candle in r.get('candles'):
        ctime = candle.get('time')[0:19]
        try:
            rec = "{time},{complete},{o},{h},{l},{c},{v}".format(
                time=ctime,
                complete=candle['complete'],
                o=candle['mid']['o'],
                h=candle['mid']['h'],
                l=candle['mid']['l'],
                c=candle['mid']['c'],
                v=candle['volume'],
            )
        except Exception as e:
            print(e, r)
        else:
            h.write(rec+"\n")
_from = '2018-05-01T00:00:00Z' 
_to = '2018-07-31T00:00:00Z'
gran = 'M5'
instr = 'EUR_USD'  

params = {
    "granularity": gran,
    "from": _from,
    "to": _to
}

with open("/tmp/{}.{}.csv".format(instr, gran), "w") as O:
    for r in InstrumentsCandlesFactory(instrument=instr, params=params):
        print("REQUEST: {} {} {}".format(r, r.__class__.__name__, r.params))
        rv = client.request(r)
        cnv(r.response, O)

今回は、上記の様に以下の様なデータを取得しました。

  • 銘柄:EUR/USD
  • 単位:5分足
  • 期間:2018-05-01〜2019-07-31

また、上記のコードは、以下を参照しました。

参考: github.com

しばらくして、データの取得・保存が終わったら、データを読み出します。

df = pd.read_csv("/tmp/EUR_USD.M5.csv" ,header=None,usecols=[0,2,3,4,5,6])
df.columns = ['time','open', 'high', 'low', 'close','volume']
#df.index = 'time'
df = df.set_index('time')
df.head()

f:id:MorinoKuma3:20190407223238p:plain

上記の様に、'open', 'high', 'low', 'close','volume'を読み込むことができました。

また、グラフで見てるとこんな感じです。

f:id:MorinoKuma3:20190407224040p:plain

グラフ描画には以下を参照にして、plotlyにて描画しました。
個人的な趣味で、移動平均線(EMA)とchannelが好きなので併せて表示しています。

参考: Pythonでローソク足チャートの表示(Plotly編) - Qiita
Python&Colab:TA-Lib でテクニカル分析、Plotly でローソク足の描画 - Investment Tech Hack

以下の記事の様に、値を予測するモデルを作成するのは面白そうです。

LSTMでFX予測をやってみよう(機械学習初心者向けチュートリアル)

しかし、ドンピシャで値を予測するのは難しそうですし、かつ、この手の予測は、結局予測する時点と同じ価格を予測値とするのが最も誤差が小さくなるという結果になるのではないか、と思っています。

そのため、今回は値をドンピシャで予測をするのではなく、ある程度の領域で区切り、その区分内に入るかどうかを予測するモデルを構築しようと考えました。

区分の分け方:

  • 1区分の幅:ChannelのUpperとLowerを10分割した値
  • EMAを中心にした-10〜+11区分の計21分類f:id:MorinoKuma3:20190407235846p:plain
    • 最大・最小の区分はそれ以上・以下の領域を含む
  • 対象:Closeの値

上記の分け方で、とある時間(t=0)で、Closeの値がどの区分に含まれるかをヒストグラムで表すと以下の様になりました。

f:id:MorinoKuma3:20190407234757p:plain

当然ですが、移動平均値付近(e0,e-1)をピークにきれいに分布しているのがわかります。
※このグラフは-10〜+11区分(e-10〜e10)としています。

では、次にt=0から30分後(t=30)の値は、この区分に入るかをグラフ化してみます。

f:id:MorinoKuma3:20190407234802p:plain

※このグラフは-10〜+11区分(e-10〜e10)としています。
値がドリフトしているためか、両端の区分が多くなっています。 両端が増加してるので、ほどほど値動きがあり、かつ、単調なトレンドがないとも読み取れると思います。

また、上記のt=0とt=30をマトリックスにすると以下の様な感じです。

f:id:MorinoKuma3:20190407235846p:plain

やはり、あまり値が変化しないケースが多々あることが見て取れます。 ただ、思ったより値動きがありそうで期待できます。

今回は、t=0からt=30にかけて、3区分以上変化する場合に買い(Long)もしくは、売り(Short)をトレードのルールとして仮決めします。 このルールに沿って分類を総計した結果が以下です。

f:id:MorinoKuma3:20190408000655p:plain

図らずとも、程よくよい比率になりました!

次回は、上記の動作買い(Long)/売買しない(NA)/売り(Short)を正解データ(期待する動作)とし、 為替データから予測できるか試していきたいと思います。