OANDA API 過去データ(ヒストリカルデータ)の取得

スポンサーリンク
スポンサーリンク

前提

接続までの箇所は、接続ページとほぼ同じですが、過去データの取得には以下をインポートする必要があります。

import oandapyV20.endpoints.instruments as instruments

仕様

取得するためには以下の設定が必要です。

  • 通貨ペア:”USD_JPY”などとなります。
  • ローソク足の種類:”S5″,”M1″,”M5″,”M10″,”H1″,”D”,”W”,”M”などがあります。
  • 件数:最大5000件までです。それ以上必要な場合はループさせるしかありません。
  • 期間:いつから、いつまで、いつからいつまでと指定できます。期間を指定した場合は件数を外さないとエラーになります。
  • タイムゾーン:UTCやJapanなど。OandaやFXの世界は基本的にUTCです。

取得

指定日からN件

# APIのPythonラッパーをインポート
from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments

import pandas as pd
import settings

# OANDA API アクセストークンと口座ID
accountID       = settings.ACCOUNT_ID
access_token    = settings.ACCESS_TOKEN

# APIへ接続
api = API(environment="practice", access_token=access_token)

# -----------------------------------------------------------------------
# 取得情報
currency = "USD_JPY"
granularity = "M1" 
count = 10 

start_time = '2016-01-01T00:00:00.000000Z'
end_time = '2016-01-01T00:00:00.000000Z'

# -----------------------------------------------------------------------
# パラメーター設定
params = {
    'alignmentTimezone': 'UTC',
    'from': start_time,
#     "to": end_time,
    "count": count,                 # 最大値は5000
    "granularity": granularity
}

# APIへ過去データをリクエスト
req = instruments.InstrumentsCandles(instrument=currency, params=params)
api.request(req)

# リストに変換
data = []
for raw in req.response['candles']:
    data.append([raw['time'], float(raw['mid']['o']), float(raw['mid']['h']), float(raw['mid']['l']), float(raw['mid']['c']), raw['volume']])

# データフレームに変換
df = pd.DataFrame(data)
df.columns = ['Date Time', 'Open', 'High', 'Low', 'Close', 'Volume']

print(df)

#                         Date Time     Open     High      Low    Close  Volume
# 0  2016-01-03T22:00:00.000000000Z  120.195  120.218  120.194  120.216       4
# 1  2016-01-03T22:03:00.000000000Z  120.224  120.224  120.224  120.224       3
# 2  2016-01-03T22:04:00.000000000Z  120.224  120.225  120.211  120.211       6
# 3  2016-01-03T22:05:00.000000000Z  120.211  120.226  120.208  120.213      19
# 4  2016-01-03T22:06:00.000000000Z  120.212  120.231  120.212  120.222      17
# 5  2016-01-03T22:07:00.000000000Z  120.222  120.232  120.218  120.220      45
# 6  2016-01-03T22:08:00.000000000Z  120.222  120.235  120.222  120.225      33
# 7  2016-01-03T22:09:00.000000000Z  120.224  120.233  120.216  120.227      35
# 8  2016-01-03T22:10:00.000000000Z  120.226  120.229  120.216  120.229      13
# 9  2016-01-03T22:11:00.000000000Z  120.234  120.234  120.226  120.228       5

指定期間で5000件以上のデータを取得する場合

例えば以下のようになると思います。
ただし、毎回最後の行を削除しているの、実際の期間より1件少なくなります。

# APIのPythonラッパーをインポート
from oandapyV20 import API
import oandapyV20.endpoints.instruments as instruments

import pandas as pd
import settings

# OANDA API アクセストークンと口座ID
accountID       = settings.ACCOUNT_ID
access_token    = settings.ACCESS_TOKEN

# APIへ接続
api = API(environment="practice", access_token=access_token)

# -----------------------------------------------------------------------
# 取得情報
currency = "USD_JPY"
granularity = "M1" 
count = 5000 

start_time = '2016-01-01T00:00:00.000000Z'
end_time = '2016-02-01T00:00:00.000000Z'

data = []
# -----------------------------------------------------------------------
while start_time < end_time:
    # パラメーター設定
    params = {
        'alignmentTimezone': 'UTC',
        'from': start_time,
#         "to": end_time,
        "count": count,                 # 最大値は5000
        "granularity": granularity
    }

    # APIへ過去データをリクエスト
    req = instruments.InstrumentsCandles(instrument=currency, params=params)
    api.request(req)

    # リストに変換
    for raw in req.response['candles']:
        data.append([raw['time'], float(raw['mid']['o']), float(raw['mid']['h']), float(raw['mid']['l']), float(raw['mid']['c']), raw['volume']])

    # 最後の日時を取得
    start_time = raw['time']
    print(start_time)

    # 最後の行を削除
    data.pop()

# データフレームに変換
df = pd.DataFrame(data)
df.columns = ['DateTime', 'Open', 'High', 'Low', 'Close', 'Volume']

print(df)

# 2016-01-07T10:27:00.000000000Z
# 2016-01-12T22:21:00.000000000Z
# 2016-01-18T10:13:00.000000000Z
# 2016-01-21T23:44:00.000000000Z
# 2016-01-27T12:08:00.000000000Z
# 2016-02-02T00:23:00.000000000Z
#                              DateTime     Open     High      Low    Close  \
# 0      2016-01-03T22:00:00.000000000Z  120.195  120.218  120.194  120.216   
# 1      2016-01-03T22:03:00.000000000Z  120.224  120.224  120.224  120.224   
# 2      2016-01-03T22:04:00.000000000Z  120.224  120.225  120.211  120.211   
# 3      2016-01-03T22:05:00.000000000Z  120.211  120.226  120.208  120.213   
# 4      2016-01-03T22:06:00.000000000Z  120.212  120.231  120.212  120.222   
# ...                               ...      ...      ...      ...      ...   
# 29989  2016-02-02T00:18:00.000000000Z  120.914  120.914  120.902  120.914   
# 29990  2016-02-02T00:19:00.000000000Z  120.914  120.914  120.898  120.899   
# 29991  2016-02-02T00:20:00.000000000Z  120.896  120.907  120.896  120.900   
# 29992  2016-02-02T00:21:00.000000000Z  120.900  120.918  120.900  120.910   
# 29993  2016-02-02T00:22:00.000000000Z  120.914  120.926  120.914  120.924 

最後に(注意点

OANDA Japanの仕様で1点、注意事項があります。

1分足などで取得すると、足りない時間が発生します。
例えば、12:00:00の次のデータが12:02:00といったように歯抜けになります。

以下は実際にダウンロードしたデータの一部です。

Date TimeOpenHighLowCloseVolume
2019-01-01 22:00:00+00:00109.59109.59109.59109.591
2019-01-01 22:01:00+00:00109.673109.673109.673109.6731
2019-01-01 22:02:00+00:00109.673109.673109.673109.6731
2019-01-01 22:06:00+00:00109.669109.669109.669109.6691
2019-01-01 22:11:00+00:00109.666109.669109.666109.6692
2019-01-01 22:14:00+00:00109.664109.664109.65109.654
2019-01-01 22:15:00+00:00109.65109.674109.65109.6746
2019-01-01 22:18:00+00:00109.67109.67109.639109.6397
2019-01-01 22:19:00+00:00109.635109.635109.635109.6351

このように歯抜けになりますので、当然、インジゲーターなどもおかしくなりますので、足りない時間は前の時間の値を追加するようにしましょう。

 

コメント

タイトルとURLをコピーしました