![ダウンロード__1_](https://assets.st-note.com/production/uploads/images/9568960/rectangle_large_type_2_6e657568ff224436b4981726d1c62a2f.png?width=1200)
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()
何足を何本取るか、という指定は、キワード引数 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()
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()
ユーロ、ドル、円の強弱が描画できました。では、今度は通貨を一気に増やしてみたいと思います。
通貨を増やす
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()
最後あたりで、米ドルと円が強くなり、カナダドル、豪ドル、NZドルが弱っていっています。資源国が弱まっているので中国関連で何かニュースがあったのでしょうか。
この記事が気に入ったらサポートをしてみませんか?