ダウンロード__1_

OANDA API を使って kuchart を生成

こんにちは。しんせいたろうです。

FX取引ブローカーとして有名なOANDAが公開しているAPIの Python ラッパーである oandapy を使ってデータ取得したいと思います。ただ、それだけではつまらないので、Kuchartと呼ばれる各通貨の強弱を可視化したチャートを作りたいと思います。

KuChart

kuchart とは、これです。

Kuchartは、「通過強弱」とも言われています。かんたんに作成方法を説明します。

1. 強弱を知りたい通貨を選ぶ(例:ドル、円、ユーロ)
2. 通貨ペアを作る(例:EURUSD, EURJPY, USDJPY)
3. ヒストリカルデータを取得
4. 基準になる時刻を決める
5. その時刻と各時刻の差を対数で取得
6. 通貨強弱を計算する。
  EUR:EURUSD の対数変化率 + EURJPY の対数変化率
  USD: EURUSD の対数変化率*-1 + USDJPY の対数変化率
  JPY: USDJPY の対数変化率-1 + EURJPY の対数変化率-1
7. 通貨毎に描画

-1を掛けているのは、基準通貨を逆にするためです。例えばEURUSDであれば、正の変化はEURがUSDに対して強まった事を、負の変化であればEURがUSDに対して弱まった事を指します。USDを基準にした場合は逆になりますので、-1を掛けています。

OANDA API 使用申請

1. https://www.oanda.jp/
2. 新規口座開設
3. デモ口座を作成

新規口座開設は平日のみ受け付けているような気がします。週末アクセスするとメンテ中ですというページが出続けます。

デモ口座申請してから2日ほどたって、メールでログイン情報のお知らせが来ました。その情報を使ってAPI Keyを取得します。

oandapy インストール

$ pip install git+https://github.com/oanda/oandapy.git

注意: pip install oandapy だと、下記のエラーが出ます。インストールは ↑のようにgithub から行ってください。

>>> import oandapy
>>> oandapy.API()
Traceback (most recent call last):
 File "<stdin>", line 1, in <module>
AttributeError: module 'oandapy' has no attribute 'API'

その他設定

個人的に、API Keyなどは、実行ファイルとは別に保存しておきたいので、実行ファイルと同じディレクトリに config.txt を作ってIDとKeyを記入しておきます。

[oanda]
account_id = mq123456789
api_key = 123456789123456789-123456789123456789

コード

import pandas as pd
import numpy as np
from datetime import datetime 
import matplotlib.pyplot as plt 
import matplotlib.dates as mdates
import oandapy
## 設定ファイル読み込み
import configparser
config = configparser.ConfigParser()
config.read('./config.txt')
account_id = config['oanda']['account_id']
api_key = config['oanda']['api_key']

## APIへ接続
oanda = oandapy.API(environment="practice",  # 本番の場合は "live"
                  access_token=api_key)

現在の値を1ペアだけ取得

oanda.get_prices(instruments="USD_JPY")
# {'prices': [{'instrument': 'USD_JPY',
#    'time': '2019-01-21T00:51:40.409491Z',
#    'bid': 109.681,
#    'ask': 109.685}]}

複数ペア取得

oanda.get_prices(instruments="USD_JPY,EUR_USD")
# {'prices': [{'instrument': 'USD_JPY',
#    'time': '2019-01-21T00:54:42.999370Z',
#    'bid': 109.648,
#    'ask': 109.652},
#   {'instrument': 'EUR_USD',
#    'time': '2019-01-21T00:54:42.977611Z',
#    'bid': 1.13749,
#    'ask': 1.13754}]}

ヒストリカルデータを取得

# historical data は 指定しないと5分足を500本返す
hist = oanda.get_history(instrument="USD_JPY")
hist
# {'instrument': 'USD_JPY',
#  'granularity': 'S5',
#  'candles': [{'time': '2019-01-20T23:27:20.000000Z',
#    'openBid': 109.686,
#    'openAsk': 109.703,
#    'highBid': 109.686,
#    'highAsk': 109.703,
#    'lowBid': 109.686,
#    'lowAsk': 109.703,
#    'closeBid': 109.686,
#    'closeAsk': 109.703,
#    'volume': 1,
#    'complete': True},
#   {'time': '2019-01-20T23:27:35.000000Z',
#    'openBid': 109.684,
#    'openAsk': 109.7,
#    'highBid': 109.684,
#    'highAsk': 109.7,
#    'lowBid': 109.684,
#    'lowAsk': 109.7,
#    'closeBid': 109.684,
#    'closeAsk': 109.7,
#    'volume': 1,
#    'complete': True},

candles というキーワードに時間と各データが辞書型で入っており、その辞書がリストとして古い順に入っていますので、これを pandas DataFrame に渡せば見通しがよくなります。

pd.DataFrame(hist['candles']).head()

画像1

何足を何本取るか、という指定は、キワード引数 granularity と count で行います。

# 時間足を24本取りたい
oanda.get_history(instrument="USD_JPY", granularity="H1", count=24)

その他の granularity は、こちらの granularityを参照してください。

Kuchart を作る

def get_data(pair_name, granularity="M1", count="300"):
    hist = oanda.get_history(instrument=pair_name, 
                             granularity=granularity, 
                             count=count)
    df_hist = pd.DataFrame(hist['candles'], )
    
    # time を datetime 型にして、日本時間に変換
    df_hist.time = pd.to_datetime(df_hist.time, utc=True) 
    df_hist = df_hist.set_index(keys="time")
    df_hist.index = df_hist.index.tz_convert('Asia/Tokyo')
    return df_hist

df_eurusd = get_data("EUR_USD")
df_eurjpy = get_data("EUR_JPY")
df_usdjpy = get_data("USD_JPY")

pan = pd.Panel({"eurusd": df_eurusd, "eurjpy": df_eurjpy, "usdjpy":df_usdjpy,})
df_closeask = pan.transpose(2,1,0)["closeAsk"]
df_closeask.tail()

画像2

x = df_closeask.fillna(method="ffill").dropna()
# 現時点で取得できた最初のデータからの変化率を見る
x = (x / x.iloc[0]).applymap(np.log)

eur = x["eurjpy"] + x["eurusd"]
jpy = -x["eurjpy"] - x["usdjpy"]
usd = x["usdjpy"] - x["eurusd"]

fig = plt.figure(figsize=(20,10))
ax1 = fig.add_subplot(111)

ax1.plot(eur, label="EUR")
ax1.plot(usd, label="USD")
ax1.plot(jpy, label="JPY")

plt.legend()
plt.grid()

画像3

ユーロ、ドル、円の強弱が描画できました。では、今度は通貨を一気に増やしてみたいと思います。

通貨を増やす

fxpairs = ["EUR_USD", "EUR_JPY","EUR_AUD", "EUR_CAD", "EUR_CHF", "EUR_GBP","EUR_NZD",
           "GBP_USD", "GBP_AUD", "GBP_CAD", "GBP_JPY", "GBP_NZD", "GBP_CHF",
           "AUD_CAD", "AUD_CHF", "AUD_JPY", "AUD_NZD", "AUD_USD",            
           "NZD_USD", "NZD_CHF", "NZD_JPY", "NZD_CAD", 
           "USD_CAD", "USD_CHF", "USD_JPY", 
           "CAD_CHF", "CAD_JPY",
           "CHF_JPY",
          ]
d = dict()
for p in fxpairs:
    df = get_data(p,  granularity="M15", count="96")
    d[p] = df 
pan = pd.Panel(d)

df_closeask = pan.transpose(2,1,0)["closeAsk"]

def get_kupower(df_data, base_time, currency,fxpairs):
    #必要なFXData取得
    #_きって、最初なら+後なら-を掛ける
    
    pairs = [p for p in fxpairs if currency in p.split("_") ]
    df = df_data[pairs]
    df = df.fillna(method="ffill")

    df_change = df / df.loc[base_time]
    df_change = df_change.applymap(np.log,)

    for p in pairs:
        if p.split("_")[1] == currency: 
            df_change[p] = df_change[p] * -1 
    
    return df_change.sum(axis=1) 

# 強弱を描画したい通貨リスト
currencies = ["EUR", "USD", "CAD", "JPY", "CHF", "AUD", "NZD", "GBP"]
d = dict()
base_time = df_closeask.index[0]

for currency in currencies:
    d[currency] = get_kupower(df_closeask, base_time, currency,fxpairs)
    
import matplotlib.dates as mdates
    
df = pd.DataFrame(d)
ax = df.loc[base_time:].plot(figsize=(20,10))
ax.xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m-%d %H:%M'))
ax.grid()

画像4

最後あたりで、米ドルと円が強くなり、カナダドル、豪ドル、NZドルが弱っていっています。資源国が弱まっているので中国関連で何かニュースがあったのでしょうか。


この記事が気に入ったらサポートをしてみませんか?