シストレどうですか

  Algorithmic Trading for Dummies

OANDA API解説編 第1回 最新のレートを取得してみよう(1)

初めに

最近REST-APIを使ったサービスを仕事上でも使うことが多く、さらに新しい言語を学習しようとPythonの勉強も始めました。 ただ勉強していてもすぐに飽きる性格なのでなにか題材をと考えた時に、以前MT4の勉強をした時にお世話になったOANDAさんのデモ口座を思い出し、儲かる?シストレでも作ってみようと調べ始めましたが、日本語のマニュアルは古いバージョンのものしかないし、英語版もよく読んでみると難解なので理解するのにとても苦労しました。 ラッパーを使ったAPIの解説をしたブログは多くあったのでこれを参考にしながらとも思ったのですが、あくまでもRESTとPythoの勉強がメインであり、あえてラッパーを使用せずネイティブのものを使う事によって仮想通貨など他の事にも応用できる知識を得られたらいいな的なことをめざしていきます。

さっそくですが、まずはOANDA API(正確にはOANDA REST-v20)の使い方から解説して行きたいと思います。 参照しているOANDAの開発ガイド(英語版)はこちら。 具体的なAPIの解説は左サイドバーのEndpointsのところになります。 developer.oanda.com


最新のレートを取得する

GET /v3/accounts/{accountID}/pricing

保有口座内で指定された銘柄の価格情報を得る

OANDAの開発ガイドはこちらhttps://developer.oanda.com/rest-live-v20/pricing-ep/

APIのバージョンがv20なのになぜURLがv3なのか?というのはさておき、最新のレートを取得するための命令に必要な引数は以下になります。

名前 場所 必須 説明 内容
Authorization header string Y 署名なしトークンID  
Accept-Datetime-Format header AcceptDatetimeFormat 時刻フォーマット指定 初期値:RFC3339 (yyyy-mm-ddThh:mm:ss.nnnnnnnnnZ形式)
その他:UNIX (12345678.000000123形式)
accountID path AccountID Y 口座番号
instruments query List of
InstrumentName(csv)
Y 出力したい通貨ペア 例:USD_JPY 複数指定の場合はカンマ区切りUSD_JPY,EUR_USD
since query DateTime 指定時刻以降に更新されたプライスを取得 RFC3339またはUnix形式
includeUnitsAvailable*1 query boolean 初期値:True
includeHomeConversion query boolean 口座保有通貨への換算レートを含めるかどうか 初期値:False

場所コラムの値は

  • header : requestを呼び出す時のheader引数

  • path : URL内で指定が必要な必須の引数

  • query: URL内でデータを取得する条件を指定 (?で始まり&で複数条件を接続)

の3種類あります。

引数はいろいろありますが、まずは一銘柄(ここではUSD_JPY)のみの最新レートの取得を行います。

# 必要なモジュールの読み込み
import requests
import json

# 口座情報の設定 (口座の解説の仕方はググってね)
API_Token = '********************************-********************************'
API_AccountID = '999-999-99999999-999'

# URLの設定 (デモ口座用非ストリーミングURL)
API_URL =  "https://api-fxpractice.oanda.com"

# 通貨ペア
INSTRUMENT = "USD_JPY"

# <現在レートの取得用URLの変数の設定>
# /v3/accounts/{Account ID}/pricing 

url = API_URL + "/v3/accounts/%s/pricing?instruments=%s" % (str(API_AccountID), INSTRUMENT)

# ヘッダー情報の変数の設定
headers = {
                "Authorization" : "Bearer " + API_Token
         }

# サーバーへの要求
response = requests.get(url, headers=headers)

# 処理結果の編集
Response_Body = json.loads(response.text)
print(json.dumps(Response_Body, indent=2))

エラーがなく要求が通るとresponse.text内に結果が戻ってきますので、json.dumpsで編集すると以下のようなデータを受け取れます。 ("response.text"の代わりに"response.json()"から戻り値を取得すれば、すでにJSON型式のデータが格納されていますので"json.loads"は必要ありません。)

{
  "time": "2020-07-05T23:49:11.939615160Z",
  "prices": [
    {
      "type": "PRICE",
      "time": "2020-07-05T23:48:47.417429418Z",
      "bids": [
        {
          "price": "107.560",
          "liquidity": 10000000
        }
      ],
      "asks": [
        {
          "price": "107.574",
          "liquidity": 10000000
        }
      ],
      "closeoutBid": "107.560",
      "closeoutAsk": "107.574",
      "status": "tradeable",
      "tradeable": true,
      "unitsAvailable": {
        "default": {
          "long": "2472293",
          "short": "2472293"
        },
        "openOnly": {
          "long": "2472293",
          "short": "2472293"
        },
        "reduceFirst": {
          "long": "2472293",
          "short": "2472293"
        },
        "reduceOnly": {
          "long": "0",
          "short": "0"
        }
      },
      "quoteHomeConversionFactors": {
        "positiveUnits": "0.00929593",
        "negativeUnits": "0.00929714"
      },
      "instrument": "USD_JPY"
    }
  ]
}

後は他のJSON型式のデータを扱うのと同様にキーを指定すれば欲しい項目を取得できます。 今回は一銘柄だけの取得なので配列([])の部分は0番目を指定すればよいという事になります。

print(Response_Body["prices"][0]["instrument"]) 
print(Response_Body["prices"][0]["time"])
print(Response_Body["prices"][0]["bids"][0]["price"])
print(Response_Body["prices"][0]["asks"][0]["price"])
print(Response_Body["prices"][0]["tradeable"])
USD_JPY
2020-07-06T00:09:37.062593083Z
107.595
107.610
True

指定した通貨ペア、時刻・ビッド・アスクの値や現在取引可能な状態かどうかもわかります。


まとめ

例外処理を考えずにレートを取得するだけなら結構簡単ですね。
次回は今回触れなかった引数についても解説したいと思います。
なにか間違いを見つけた方ご指摘お願いいたします!

ストリーミングでのレートの取得方法については、こちらを参照してください。

jantzen.hatenablog.com


*1:廃止予定とあるので説明しません