Takehana Lab

System Trading : MultiCharts, TradingView, Python, R

RからOANDA-V20APIを叩く

概要

個人的にOANDAのAPI仕様には前から興味があったのですが、PythonのライブラリはあるもののRで簡単にAPIを叩けるサンプルがネットになかったので、自分で書きました。

Gitにクラス定義のフルコードを上げておきました。 クラスの使用サンプルもアップロードしましたのでご活用ください github.com

上記のクラスを使用するとRからOADA-V20APIを使用することができます。以下に使用例を掲載します。

まずGitからコードをDLしてください。

git <- "https://raw.githubusercontent.com/Takehana13/"
path <- paste0(git, "oanda_v20/master/API.R")
downloader::source_url(path, prompt = FALSE, quiet = TRUE)

OANDAJAPANにデモ口座を開設してください。するとtokenの取得が可能になりますのでその情報を以下のようにして入力します。

access_token <- "your access token"
account_id <- "your account i’d" 
account_type <- "practice"

今回はR6とreticulateパッケージを使ってクラスを定義したので、コードについて分からない点があれば、それぞれのリファレンスを参照してください。

reticulateはRからPythonを呼ぶパッケージで、使用するにはpythonがPCにインストールされている必要があります。PC内のpythonのpathを確認するには以下のコマンドを使用します。

py_path <- reticulate::py_discover_config()
py_path$python

これで準備が整いました。クラスはR6を使用しているので$new()メソッドを使用してインスタンスを生成してください。

oanda <- OANDA_V20$new(
  symbol_name = "USD_JPY",
  account_type = account_type,
  account_id = account_id,
  access_token = access_token,
  python_path = py_path$python
)

これでインスタンスが生成できました。次にデータを読み込んで可視化してみます。

データ操作

oanda$get_data(n = "5000",  tf = "D")

$get_data()はデータを取得して$price_dataスロットに格納します。 パラメータnデータの観測数を入力し(max = 5000)、tfにはデータのタイムフレームを入力します。

oanda$price_data %>% mutate(dttm = as_date(dttm)) %>% tail(50) %>% 
  ggplot(aes(x = dttm, y = close)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  theme_tq()

f:id:takehana13:20191018152721p:plain

ローソク足を描画できています。次に複数銘柄の価格データ取得をテストします。

まず$get_instrument()を使って、OANDA_APIで取得可能な銘柄データ一覧を取得します。

get_ticker <- function(env_obj, sym){
  env_obj$get_instrument()
  ins <- env_obj$instrument_lst$instruments %>%
    map(list.flatten) %>%
    map(flatten_df)
  
  ins <- ins %>% bind_rows()
  ins_nam <- env_obj$instrument_lst$instruments %>%
    list.select(name) %>%
    map_chr(as.character)
  
  sym_nam <- ins_nam %>% str_subset(sym)
  syms <- ins %>% filter(name %in% sym_nam) %>% pull(name)
}

syms <- get_ticker(oanda, "GBP")

今回はポンド関連銘柄のデータを取り出します。

get_dataset <- function(env_obj, sym){
  env_obj$symbol_name <- sym
  env_obj$get_data(n = "5000", tf = "D")
  env_obj$price_data
}

sym_dat <- syms %>%
  map(get_dataset, env_obj = oanda) %>%
  set_names(syms) %>% 
  bind_rows(.id = "symbol")

得られたデータを可視化してみましょう。

sym_dat %>% 
  mutate(dttm = as_date(dttm)) %>% 
  group_by(symbol) %>% 
  do(tail(., 20)) %>% 
  ungroup() %>% 
  ggplot(aes(x = dttm, y = close)) +
  geom_candlestick(aes(open = open, high = high, low = low, close = close)) +
  theme_tq() +
  facet_wrap(.~symbol, scale = "free")

f:id:takehana13:20191018154203p:plain

ポンド系銘柄のデータを簡単に可視化できました。

同様の手順でスプレッドデータを取得することも可能です。

get_sp <- function(env_obj, sym){
  env_obj$symbol_name <- sym
  env_obj$get_instrument()
  env_obj$get_data(n = "5000", tf = "M1")
  env_obj$chk_sp(mode = "hist")
  env_obj$hist_sp
}

sym_sp <- syms %>%
  map(get_sp, env_obj = oanda) %>% 
  set_names(syms) %>% 
  bind_rows(.id = "symbol")

sym_sp %>% 
  group_by(symbol) %>% 
  mutate(id = row_number()) %>% 
  ggplot(aes(id, sp)) +
  geom_line() +
  theme_tq() +
  facet_wrap(.~symbol, scale = "free")

f:id:takehana13:20191018194655p:plain

$chk_sp()は現在または過去のスプレットデータを取得することができます。

mode = “hist”では現在読み込んでいる$price_data分の長さのヒストリカルスプレッドを取り出し、mode = “current”では現在のスプレッドを取り出します。

アカウント情報の取り出し

口座情報を取り出してみます。$get_account_detail()は現在の口座情報の詳細を取り出します。

  • $account_detailには口座情報全般
  • $account_ordersには保有中のオーダー情報
  • $account_tradesには保有中のトレード情報
  • $account_positionsにはこれまでの取引履歴

がそれぞれのスロットに格納されます。

oanda$get_account_detail()
oanda$account_detail
oanda$account_orders
oanda$account_trades
oanda$account_positions

$get_account_summary()は口座情報の概要を取得します。

oanda$get_account_summary()
oanda$account_summary

発注関連

発注を行うにはまず引数として渡したいトレードの情報を作成してください。magic=は俗に言うマジックナンバー、つまりストラテジーごとの固有識別値です。tp_dis, sl_disはpipsベースでのTPSLの範囲指定です。

mkt_param <- list(
  units = "+10000",
  type = "MARKET",
  pos_fill = "DEFAULT",
  magic = oanda$strat_magic,
  use_tpsl = FALSE,
  tp_dis = NULL,
  sl_dis = NULL
)

この情報を$new_order()に渡すとトレードが実行されます。

がそれぞれ格納されます。

lift_dl(oanda$new_order)(mkt_param)
oanda$trans_lst
oanda$magic_lst
oanda$last_tiket_id
oanda$last_tiket_unit

$close_order()を使用するとデフォルトでは直前のポジションを決済します。

oanda$close_order()
oanda$trans_lst
oanda$magic_lst

次に指値注文のテスト実行します。基本的な仕様は$new_order()と同じですが、$pending_order()では価格を指定した指値・逆指値をオーダーを送信することができます。

pend_param <- list(
  price = "111.000",
  units = "-10000",
  magic = oanda$strat_magic,
  type = "LIMIT",
  pos_fill = "DEFAULT"
)
oanda$pending_order()
oanda$trans_lst
oanda$last_order_id

同様に$cancel_order()はデフォルトで直前のオーダーをカットします。

oanda$cancel_order()

最後にポジションの全決済を方法を確認します。

現在保有中の全ポジションを決済したい場合は$close_all()を使用してください。この関数を使用するには$get_pos_info()で現在保有中のチケット情報を取得しておくことが必要です。

oanda$get_pos_info()
oanda$close_all()

この関数はデフォルトでは現在のMagicNumberに対応するポジションのみを全決済します。完全に全てのポジションを決済したい場合には以下のようにします。

oanda$get_pos_info(all = T)
oanda$close_all()

同様に全ての指値・逆指値注文をキャンセルする場合、以下のようにします。

oanda$get_order_info()
oanda$cancel_all()

これで一通りの機能紹介を終わります。トレードAPIのプログラムは非常に重要なので、もし実際に試してみて不具合などありましたらご連絡ください。