PythonでOanda REST APIから取得した為替レートをMongoDBに入れる

メモ。
両方ともJSON形式を使っているので非常に相性がよい。


#環境構築
一応ここから。pythonの環境構築については流石に省略
##WindowsにMongoDBをインストール
binにPATHを通すことを忘れずに。（忘れてた）
http://qiita.com/yoh-nak/items/f0c429f10347ae7ec98b
http://qiita.com/t-koyama/items/9b8804cbec59b3c93eb0
##pymongoをインストール
    pip install pymongo
##oandapyをインストール(oanda REST APIのpython wrapper)
    pip install oandapy

#説明書
##MongoDB入門書
http://qiita.com/saba1024/items/f2ad56f2a3ba7aaf8521
http://www.cuspy.org/diary/2012-04-17/the-little-mongodb-book-ja.pdf
##OandaAPIの使い方
http://developer.oanda.com/docs/jp/
ちなみにsandbox環境は使えた試しがないので、最初からfxTrade Practice環境を使うことをお勧めします。

##pymongoの使い方
http://api.mongodb.com/python/
##oandapyの使い方
https://github.com/oanda/oandapy

#コード例
##oandapyを使ってAPIを叩く
    import oandapy
    
    oanda = oandapy.API(environment="practice", access_token="your_token")
    response = oanda.get_history(instrument="EUR_USD",granularity="D",count=500)
    EUR_USD_D = response.get("candles")
これだけで過去のユーロ対ドルの日足データ(500ステップ)が取得できる。start,endも指定可能。

##MongoDBにデータを入れる
    from pymongo import MongoClient

    client = MongoClient('localhost',27017)
    db = client.ex_rate
    collection = db.eur_usd_d
    collection.insert_many(d for d in EUR_USD_D)
これだけでMongoDBのデータベース[ex_rate]のコレクション(テーブル)[eur_usd_d]にJSON形式で上で取得した日足データ(500ステップ)が入れられる。MongoDBの中身が空でもデータベース、コレクションを勝手に作ってくれてる。

#取得可能な銘柄のリストを取得する
    import oandapy
    import pandas as pd

    oanda = oandapy.API(environment="practice", access_token="your_token")
    #account_idには口座idを入力する(ログイン時のidではない)
    response = oanda.get_instruments(account_id="xxxxxxx")
    insts = response.get("instruments")
    #見やすいようにpandasで
    df = pd.DataFrame(list(insts))
    df.head()

↓出力

	displayName	instrument	maxTradeUnits	pip
    0	AUD/CAD	AUD_CAD	10000000	0.0001
    1	AUD/CHF	AUD_CHF	10000000	0.0001
    2	AUD/HKD	AUD_HKD	10000000	0.0001
    3	AUD/JPY	AUD_JPY	10000000	0.01
    4	AUD/NZD	AUD_NZD	10000000	0.0001

#5000ステップ以上のデータを取得したい場合
以下の要領で、取得したい数が上限5000を超えるようでも連続で取得できます。
もうちょっとスマートなやり方があるかもしれません。
・直近のデータ群を取得して、トップ(一番古い)の"time"を取得
・"time"のデータをフォーマットしなおしたものを、"end"として再度リクエストを出す

    import oandapy
    import datetime as dt

    oanda = oandapy.API(environment="practice", 
    access_token="your_token")

    response1 = oanda.get_history(instrument="EUR_USD",granularity="D",count=2)
    EUR_USD_H1 = response1.get("candles")

    #先頭のデータのtimeを取得して、RFC3339フォーマットをpythonのdatetimeフォーマットに変換
    dtime = dt.datetime.strptime(EUR_USD_H1[0]['time'],'%Y-%m-%dT%H:%M:%S.%fZ')
    #もう一度RFC3339フォーマットに変換
    rfc_endtime = dtime.isoformat('T')

    response2 = oanda.get_history(instrument="EUR_USD",granularity="D",end=rfc_endtime,count=2)
    EUR_USD_H2 = response2.get("candles")

    for d in EUR_USD_H2:
        print(d)
    for d in EUR_USD_H1:
        print(d)

↓出力

    {'time': '2017-08-28T21:00:00.000000Z', 'openBid': 1.19762, 'openAsk': 1.19787, 'highBid': 1.20698, 'highAsk': 1.20712, 'lowBid': 1.19451, 'lowAsk': 1.19471, 'closeBid': 1.19709, 'closeAsk': 1.19728, 'volume': 73642, 'complete': True}
    {'time': '2017-08-29T21:00:00.000000Z', 'openBid': 1.19697, 'openAsk': 1.19731, 'highBid': 1.19839, 'highAsk': 1.19853, 'lowBid': 1.18803, 'lowAsk': 1.18821, 'closeBid': 1.18828, 'closeAsk': 1.18856, 'volume': 56980, 'complete': True}
    {'time': '2017-08-30T21:00:00.000000Z', 'openBid': 1.18827, 'openAsk': 1.18857, 'highBid': 1.19119, 'highAsk': 1.19139, 'lowBid': 1.18225, 'lowAsk': 1.18238, 'closeBid': 1.19079, 'closeAsk': 1.19102, 'volume': 59987, 'complete': True}
    {'time': '2017-08-31T21:00:00.000000Z', 'openBid': 1.19078, 'openAsk': 1.19103, 'highBid': 1.19794, 'highAsk': 1.19807, 'lowBid': 1.18485, 'lowAsk': 1.18508, 'closeBid': 1.18572, 'closeAsk': 1.18625, 'volume': 76954, 'complete': True}