【bitFlyer API】特殊注文まとめ

特殊注文とは?そのメリット

bitFlyerの特殊注文とは、「注文種別」・「執行条件」・「執行数量条件」というオプションを選択することができるタイプの注文です。下記、公式参考。
ビットコイン取引所【bitFlyer Lightning】

例えば、注文種別には以下の種類があります。(公式から引用)

IFD(If Done):一度に2つの注文を出して最初の注文が約定したら2つめの注文が自動的に発注される注文パターンです。
OCO( One-Cancels-the-Other order):2つの注文を同時に出して一方の注文が成立した際にもう一方の注文が自動的にキャンセルされる注文パターンです。
IFDOCO:IFDとOCOの組み合わせで、IFD注文が約定した後に自動的にOCO注文が発注される注文パターンです。

というように一度に複数の注文がだせます。

この特殊注文に目をつけた理由としては、
・遅延対策に有効なのでは?
スキャルピング等、利確・損切にスピードが求められるときに有効なのでは?
・ポジションとして管理したいときに便利では?
と思ったからですが、使いようはいろいろあるかと思います。

今回はAPIを使って特殊注文する際に、調査してわかったtipsを記事として残します。
なお、pybitFlyerを使用しています。
GitHub - yagays/pybitflyer: Python wrapper for bitFlyer's REST API.

特殊注文(親注文)を新規で送る

pybitFlyerで特殊注文を送ります。
APIでは特殊注文のことを親注文と言ったりしているようです。
「親」というのは、単体の注文を「子注文」とするとIFDやOCOなど複数の注文がセットになった注文を親注文とするからみたいです。
注文例としてIFDOCOを注文します。

IFD:指値で買い注文、約定したらOCO注文
OCO:①、②のいずれかの注文が約定したら片方の注文をキャンセルする。
 ①指値で売り注文(利確)
 ②ストップ注文、トリガー価格を下回ったら成行で注文(損切)

用いる関数は、sendparentorder()です。
ここでの引数は、

sendparentorder(
    order_method = 'IFDOCO' #注文種別
    minute_to_expire = '100' #親注文の有効期限(分)
    time_in_force = 'GTC' #執行数量条件
    parameters = [ 
        order1,
        order2,
        order3] #子注文の情報             
)

となります。

parametersには、子注文の情報をlist形式で渡します。今回のIFDOCO注文では、子注文が3つなので、[ {注文①},{注文②},{注文③}] というようになります。
また、ここで気をつけたいのが、minute_to_expireが親注文の有効期間であること。
最初の注文が約定したあとに、minute_to_expireで指定した時間をすぎると、2番目の注文がキャンセルされてしまいます。

さらに、子注文の情報は以下のようになります。若干sendchildorderの引数名と異なります。

order1 = { 
    "product_code": "FX_BTC_JPY",
    "condition_type": "LIMIT",
    "side": "BUY",
    "price": 1000000,
    "size": 0.1
}

最後に、注文する際のコードは以下のようになります。

sendparentorder(
    order_method = "IFDOCO",
    minute_to_expire = 10000,
    time_in_force =  "GTC",
    parameters = [
        {
            #IFD:指値で買い注文、約定したらOCO注文
            "product_code": "FX_BTC_JPY",
            "condition_type": "LIMIT",
            "side": "BUY",
            "price": 1000000,
            "size": 0.1
        },{
            #OCO①:指値で売り注文(利確)
            "product_code": "FX_BTC_JPY", 
            "condition_type": "LIMIT", 
            "side": "SELL",
            "price": 1001000,
            "size": 0.1
        },{
            #OCO②ストップ注文、トリガー価格を下回ったら成行で注文(損切)
            "product_code": "FX_BTC_JPY", 
            "condition_type": "STOP", 
            "side": "SELL",
            "trigger_price": 999000,
            "size": 0.1
        }
    ]
)

戻り値には
parent_order_acceptance_idが返ってきます。

注文状況を確認する

親注文の状況を確認したい場合は、getparentorders()を使います。

getparentorders(
    product_code='FX_BTC_JPY'
)
>>[{
    #(ログをとっていなかったので以下の注文結果は公式から拝借。)
    "id": 138398, 
    "parent_order_id": "JCO20150707-084555-022523",
    "product_code": "BTC_JPY",
    "side": "BUY",
    "parent_order_type": "STOP",
    "price": 30000,
    "average_price": 30000,
    "size": 0.1,
    "parent_order_state": "COMPLETED",
    "expire_date": "2015-07-14T07:25:52",
    "parent_order_date": "2015-07-07T08:45:53",
    "parent_order_acceptance_id": "JRF20150707-084552-031927",
    "outstanding_size": 0,
    "cancel_size": 0,
    "executed_size": 0.1,
    "total_commission": 0
} ......
]

parent_order_stateは、親注文自体の注文状況です。
例えば、注文種別がIFDやIFDOCOの場合、
最初の注文はCOMPLETEしているが、次の注文はACTIVE…といった状況があります。
この場合は、outstanding_sizeで見分ける必要があります。
outstanding_sizeが0より大きければ、未約定の注文がある=2番目の注文が未約定と判断します。

子注文ごとの取得価格、取引量を確認する

先程のgetparentorders()で注文状況がわかりました。
"price"という項目がありますが、これは公式によると「参考価格」だそうです。
IFDやIFDOCOのように2つの注文が約定する場合、各子注文の取得価格が知りたいわけですが、getparentorders()の結果からでは知ることができません。

各子注文のpriceとsizeは、getchildordersの引数にparent_order_idをいれることで該当する子注文の約定情報を取得することができます。

getchildorders(
    product_code = "FX_BTC_JPY",
    parent_order_id = xxxxxxxxx
)

>>[{
    "id" : 182386109, #エントリー時の注文
    "child_order_id" : "JFX20171219-175406-686140F",
    "product_code" : "FX_BTC_JPY",
    "side" : "BUY",
    "child_order_type" : "LIMIT",
    "price" : 2519026.0,
    "average_price" : 2519026.0,
    "size" : 0.03,
    "child_order_state" : "COMPLETED",
    "expire_date" : "2017-12-22T12:34:06",
    "child_order_date" : "2017-12-19T17:54:06",
    "child_order_acceptance_id" : "JRF20171219-175406-581421",
    "outstanding_size" : 0.0,
    "cancel_size" : 0.0,
    "executed_size" : 0.03,
    "total_commission" : 0.0
},{
    "id" : 182386274, #クローズ時の注文
    "child_order_id" : "JFX20171219-175409-686437F",
    "product_code" : "FX_BTC_JPY",
    "side" : "SELL",
    "child_order_type" : "LIMIT",
    "price" : 2521016.0,
    "average_price" : 2521016.0,
    "size" : 0.03,
    "child_order_state" : "COMPLETED",
    "expire_date" : "2017-12-22T12:34:06",
    "child_order_date" : "2017-12-19T17:54:10",
    "child_order_acceptance_id" : "JRF20171219-175406-581434",
    "outstanding_size" : 0.0,
    "cancel_size" : 0.0,
    "executed_size" : 0.03,
    "total_commission" : 0.0
}]


追記

注文種別がSIMPLEの場合、エラーがかえってきます。
パラメータは正しいと思うのですが…
子注文で注文しろということでしょうか…