【Python】Oanda FXで数百万データ取得(78種/15年分)

2021年4月29日

時系列データのビッグデータを構築したい人向けの記事になります。78種のFXデータを15年分取得します。機械学習をする上で、データ量が欲しくなりますよね。数十万〜数百万のデータが欲しい方はこの記事が参考になります。OandaのAPIを利用します。

Oandaのデモ口座開設

API利用のためデモ口座を開設します。デモ口座は5分程度で簡単に作れます。

  1. oandaにアクセス
  2. デモ口座を開設
  3. APIキーの発行

画面の赤線のところを押して、ページを移動したら分かると思います。ここで取得した APIキーは使用しますのでメモしておきましょう。

コード全体

# coding:utf-8
# oandapyのインストール
!pip install git+https://github.com/oanda/oandapy.git

# 必要なライブラリをインポート
import time
import oandapy
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
import pytz

# oanda APIキー情報
api_key = '' # 取得したAPIキーを入力
oanda = oandapy.API(environment = "practice", access_token = api_key)#practiceをliveに変更することで本番環境

# FXデータを15年分取得してファイルを出力する関数(期間と間隔の指定要)
def get_histry_data(file_path, kind,duration,year_start,year_end,month_start,month_end):
    file_name =  kind + '_' + duration +'.txt'
    ys = year_start
    ye = year_start
    ms = month_start
    me = month_start + 1
    res = pd.DataFrame(None)
    first_stock = 1
    while ye < year_end or (ye == year_end and me <= month_end) :
        fmt = '%Y-%m-%dT%H:%M:00.000000Z'
        # 取得する年、月のデータをoandapyのapiで利用できる文字列に変換
        start1 = datetime(year=ys, month=ms, day=10,hour=12, minute=5, second=0).strftime(fmt)
        end1   = datetime(year=ys, month=ms, day=25,hour=12, minute=0, second=0).strftime(fmt)
        start2 = datetime(year=ys, month=ms, day=25,hour=12, minute=5, second=0).strftime(fmt)
        end2   = datetime(year=ye, month=me, day=10,hour=12, minute=0, second=0).strftime(fmt)

        # oandapyを利用してデータ取得
        res1 = oanda.get_history(instrument = kind,start = start1,end = end1,granularity = duration)
        res2 = oanda.get_history(instrument = kind,start = start2,end = end2,granularity = duration)

        # データの取得対象時間をプリント
         #print(start1 + " " + end1)
         #print(start2 + " " + end2)

        # ローソク足1つ分のデータをDataFrameに変換
        res1 = pd.DataFrame(res1['candles'])
        res2 = pd.DataFrame(res2['candles'])

        # データの形式フォーマット変換および日本時間への変更
        res1['time'] = res1['time'].apply(lambda date: datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ'))
        res2['time'] = res2['time'].apply(lambda date: datetime.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ'))
        res1['time'] = res1['time'].apply(lambda date: pytz.utc.localize(date).astimezone(pytz.timezone("Asia/Tokyo")))
        res2['time'] = res2['time'].apply(lambda date: pytz.utc.localize(date).astimezone(pytz.timezone("Asia/Tokyo")))
        res1['time'] = res1['time'].apply(lambda date: date.strftime('%Y/%m/%d %H:%M:%S'))
        res2['time'] = res2['time'].apply(lambda date: date.strftime('%Y/%m/%d %H:%M:%S'))

        # 次の月に対して繰り返し処理を行う
        # 13月となるとき、次の年の1月になるよう値を修正する。
        ms += 1
        me += 1
        if ys == 13:
            ys = 1
        if ye == 13:
            ye = 1
        if ms == 13:
            ms = 1
            ys += 1
        if me == 13:
            me = 1
            ye += 1

        # 2つの取得データを結合
        res = res.append(res1)
        res = res.append(res2)

        # ファイルに書き出すが、初回のみheader情報を付与
        if first_stock == 1 :
            res.to_csv(file_path)
            first_stock = 0 
        else :
            res.to_csv(file_path, mode='a', header=None)
        res = pd.DataFrame(None)

#main ---------------------------------------------------------------------------------------------------------------
# ファイルの保存先 GoogleDriveに保存も可能
path = './'

# 取得可能な通貨一覧
kind = 'USD_JPY'

# 取得間隔一覧
duration = 'M5'

# 保存ファイルのパスをプリント
file_path =  path + kind + '_' + duration +'.txt'
print(file_path)

# get_data(通貨の種類,時間幅,開始年,終了年,開始月,終了月) (10日までのデータを取得)
get_histry_data(file_path,kind,duration,2005,2020,1,1)

# 保存データを読み込みプリント
data = pd.read_csv(file_path)
print(data)

コードの使い方

get_histry_data関数は、通貨の種類や時間足の種類を指定して利用できます。

get_histry_data(file_path, kind,duration,year_start,year_end,month_start,month_end)

  • file_path: ファイルパス
  • kind: 通貨の種類
  • duration: 取得通貨の間隔
  • year_start: 開始年
  • year_end: 終了年
  • month_start: 開始月
  • month_end: 終了月

これらのパラメータを変更して、get_histry_data関数を呼び出すことで、15年分のデータを取得できます。oanda.get_historyで実際に価格を取得していますが、最大5000件までのデータのみ取得可能ですので、1ヶ月のデータを2回に分て取得しています。そのため、今回作成したプログラムでは最短間隔は5分足までのみを取得可能としています。つまり、1分足のデータは取得できません。また、get_historyを使用する際には、使用時間を出力することをできるコードを残しています。48行目、49行目のコメントアウトを外すと、取得期間を出力できますので試してくださいね。

各種データ取得

oandaのAPIで取得可能な通貨一覧は公開されています。取得可能通貨の一覧は以下になります。

通貨の種類一覧

一覧は以下になりますが、詳細はoandaのHPを確認してください。

'USD_JPY’,’EUR_JPY’,’AUD_JPY’,’GBP_JPY’,’NZD_JPY’,’CAD_JPY’,’CHF_JPY’,’ZAR_JPY’,        

'EUR_USD’,’GBP_USD’,’NZD_USD’,’AUD_USD’,’USD_CHF’,’EUR_CHF’,’GBP_CHF’,’EUR_CHF’,       

'EUR_GBP’,’AUD_NZD’,’AUD_CAD’,’AUD_CHF’,’CAD_CHF’,’EUR_AUD’,’EUR_CAD’,’EUR_DKK’,       

'EUR_NOK’,’EUR_NZD’,’EUR_SEK’,’GBP_AUD’,’GBP_CAD’,’GBP_NZD’,’NZD_CAD’,’NZD_CHF’,      

'USD_CAD’,’USD_DKK’,’USD_NOK’,’USD_SEK’,’AUD_HKD’,’AUD_SGD’,’CAD_HKD’,’CAD_SGD’,      

'CHF_HKD’,’CHF_ZAR’,’EUR_CZK’,’EUR_CZK’,’EUR_HKD’,’EUR_HUF’,’EUR_HUF’,’EUR_PLN’,       

'EUR_SGD’,’EUR_TRY’,’EUR_ZAR’,’GBP_HKD’,’GBP_PLN’,’GBP_SGD’,’GBP_ZAR’,’HKD_JPY’,       

 'NZD_HKD’,’NZD_SGD’,’SGD_CHF’,’SGD_HKD’,’SGD_JPY’,’TRY_JPY’,’USD_CNH’,’USD_CZK’,       

 'USD_HKD’,’USD_HUF’,’USD_INR’,’USD_MXN’,’USD_PLN’,’USD_SAR’,’USD_SGD’,’USD_THB’,        

'USD_TRY’,’USD_ZAR’

取得間隔の一覧

取得間隔の一覧になります。

  • M:月足の情報
  • W:週足の情報
  • D:日足の情報
  • H2:2時間足の情報
  • H1:1時間足の情報
  • M30:30分足の情報
  • M10:10分足の情報
  • M5:5分足の情報

78種の為替レートを8種の時間足で全情報取得

少し強欲かもしれませんが、全てのデータを15年分取得するコードになります。実行にはかなり時間がかかりますし、oanda社のサーバへの負荷も大きいと思います。GoogleColabで実行する場合は、一度の実行のみで良いように、Google Driveにデータを保存しましょう。

# path = '/content/drive/My Drive/
# 取得可能な通貨一覧
kind = ['USD_JPY','EUR_JPY','AUD_JPY','GBP_JPY','NZD_JPY','CAD_JPY','CHF_JPY','ZAR_JPY',
        'EUR_USD','GBP_USD','NZD_USD','AUD_USD','USD_CHF','EUR_CHF','GBP_CHF','EUR_CHF',
        'EUR_GBP','AUD_NZD','AUD_CAD','AUD_CHF','CAD_CHF','EUR_AUD','EUR_CAD','EUR_DKK',
        'EUR_NOK','EUR_NZD','EUR_SEK','GBP_AUD','GBP_CAD','GBP_NZD','NZD_CAD','NZD_CHF',
        'USD_CAD','USD_DKK','USD_NOK','USD_SEK','AUD_HKD','AUD_SGD','CAD_HKD','CAD_SGD',
        'CHF_HKD','CHF_ZAR','EUR_CZK','EUR_CZK','EUR_HKD','EUR_HUF','EUR_HUF','EUR_PLN',
        'EUR_SGD','EUR_TRY','EUR_ZAR','GBP_HKD','GBP_PLN','GBP_SGD','GBP_ZAR','HKD_JPY',
        'NZD_HKD','NZD_SGD','SGD_CHF','SGD_HKD','SGD_JPY','TRY_JPY','USD_CNH','USD_CZK',
        'USD_HKD','USD_HUF','USD_INR','USD_MXN','USD_PLN','USD_SAR','USD_SGD','USD_THB',
        'USD_TRY','USD_ZAR']

# 取得間隔一覧
duration = ['M','W','D','H2','H1','M30','M10','M5']

# 通貨一覧毎に繰り返す
for k in kind:
 # 取得感覚一覧毎に繰り返す
 for d in duration:

  # get_data(通貨の種類,時間幅,開始年,終了年,開始月,終了月) (10日までのデータを取得)
  file_path =  path + k + '_' + d +'.txt'
  print(file_path)

  # get_data
  get_histry_data(file_path,k,d,2005,2020,1,1)

  # 保存データを読み込みプリント
  data = pd.read_csv(file_path)
  print(data

仮想通貨のデータ取得

仮想通過のデータ取得は別記事にて掲載していますので、もし興味がある方はこちらも読んでいただければと思います。

終わりに

これでFXのレートを数百万件取得してビッグデータを構築できます。このデータを利用して、バックテストや機械学習に活かしていきましょう。

興味がある方は是非OANDAにも登録してみてくださいね。