収益化へのステップ

仮想通貨の自動取引、bitFlyerでの特殊注文 – IFD、OCO、IFDOCO、ストップ、ストップリミット、トレール注文 等 –

仮想通貨の自動取引、bitFlyerでの特殊注文 - IFD、OCO、IFDOCO、ストップ、ストップリミット、トレール注文 等 -

本記事は、

  • bitFlyerの取引所で、Pythonにより、仮想通貨の自動取引システムを作りたい方

を対象にした記事です。

本記事は、下記記事に対する、追加記事になります。

基本的な、自動取引システムの作り方は、下記記事にてご紹介しています。

まだ読まれていない方は、先にこちらをどうぞ。

bitFlyerのAPIを使用して、Pythonにより自動取引システムを作る
bitFlyerのAPIを使用して、Pythonにより自動取引システムを作るbitFlyerのAPIを使用して、Pythonにより自動取引システムを作り方を、わかりやすく紹介した記事です。...

本記事で紹介する内容は、以下の通りです。

  • 特殊注文(親注文)を出す方法
    (具体的には、以下の項目になります。)
    • IFD、OCO、IFDOCO 注文
    • ストップ注文
    • ストップ・リミット注文
    • トレーリング・ストップ注文
  • 発注した特殊注文(親注文)を、キャンセルする方法

IFD注文? と思われた方、大丈夫です。

それぞれの、用語の解説も、併せてご紹介します。

冒頭に出てきた、用語(IFD注文 等々)の解説

ご存知の方は、この章をスキップして下さい。

IFD注文

イフダン注文と呼ばれます。由来は、イフダン(if – done)から、きています。

新規の注文と、その注文に対する、決済注文が同時に出せる注文方式です。

つまり、どういう事ですか?

  • つまり、〇〇円でになったら、新規発注をしたい
  • それが、△△円になったら、決済したい

というオーダーが、同時に発注できる注文方式です。

具体例を使って、解説します。

例えばですが、現在価格が100円とします。

IFD注文を使えば、

  • 新規買いを、98円なったら購入
  • 上記の買い注文が成立した場合で、105円になったら決済

という事ができます。

上記の例では、指値発注を例にしましたが、ストップ(逆指値)発注も可能です。

例えば、

  • 105円になったら、「売り」
  • それが、90円になったら、決済

といったパターンが、そちらに該当します。

OCO注文

名前は、「One side done then Cancel the other order」から、きています。

「オーシーオー」注文と呼ばれます。

2種類の注文を出し、どちらかが約定すれば、もう一方は、自動的キャンセル処理される、発注方式です。

こちらも、具体例を使って、解説します。

現在価格が、またまた、100円とします。

OCO注文を使えば、

  • 新規買い注文を、105円で「買い」で発注
  • 新規売り注文を、97円で「売り」で発注

という事が、同時に発注できます。

上記は、発注時を例にしましたが、

  • 既に発注していて、決済時の注文

にも使用可能です。

IFDOCO注文

IFD注文と、OCO注文を、組み合わせたものです。

IFDOCO注文を使えば、

  • 発注時を金額を設定する事ができ(指値 or 逆指値)、
  • もし発注されれば、
    • 利益確定の金額と
    • 損切りの金額

を設定する事が、できるようになります。

具体的なイメージは、以下になります。

ストップ注文

逆指値注文のことです。

「買い」で入る場合、

  • 指値注文は、「設定した金額」以下になれば、成行で発注

になりますが

  • ストップ(逆指値)注文は、「設定した金額」以上になれば、成行で発注

になります。

「売り」で入る場合は、逆の挙動になります。

  • 指値発注:「設定した価格」以上で成行発注
  • ストップ発注:「設定した価格」以下で成行発注

「設定した価格」は、トリガー価格 と呼ばれています。

ストップ・リミット発注

ストップ注文と似ています。

違いは、

  • ストップ注文が、設定価格になると、「成行注文」になりますが、
  • ストップ・リミット注文は、設定価格になると、「指値発注

になります。

トレーリング・ストップ注文

高値安値に合わせて、ストップ注文のトリガー価格を、リアルタイムに自動修正するものです。

価格が有利な方向に動いた場合、「設定した金額幅」に応じて、ストップ注文も、一定幅ずつ、スライドしていく注文方式です。

下図のようなイメージです。(「買い」の場合 )

価格が上がっていくと、

  • トレーリング価格も上昇

価格が下がり出すと、

  • トレーリング価格で決済

する方式になります。

特殊注文(親注文)の、Python コード紹介

ここまで紹介してきた注文方式は、bitFlyerさんでは、親注文という方式で実施します。

bitFlyerさんでは、

  • 成行注文
  • 指値注文

のみ、「子注文」という扱いになっています。

bitFlyerさんでは、「空売り」をするためには、

  • Lightning FX

を利用する必要があります。

本記事では取り扱いません。

ただし、本APIで「FXの自動取引」も可能です。

具体的には、bitFlyerさんのサイトで、「FXの使用許可」処理を実行した上で、コード中の変数

  • market_type
  • product_code

に、FX用の文字列を代入します。

詳細は、bitFlyerさんのAPI Documentationをご参照下さい。

紹介する順番

以下の順番で、ご紹介していきます。

  • 「IFD、OCO、IFDOCO 注文」全てで、共通するコード
  • IFD注文のコード
  • OCO注文のコード
  • IFDOCO注文のコード
  • ストップ注文
  • ストップ・リミット注文
  • トレーリング・ストップ注文 は、

IFD注文等を紹介している中で、具体的なコードという形で、ご紹介しています。

冒頭で紹介した「前回記事」でご紹介した、下記2点は、今回も使用します。

  • requestsパッケージ
  • 認証に関するコード(関数 header( ) で定義した部分

注文コードの雛形

IFD、OCO、IFDOCO 共通する、コードの雛形です。

def parent_order():
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/sendparentorder"

    body = {
        "order_method": "IFD", # 注文方式  IFD or OCO or IFDOCO  
        "minute_to_expire": 1000, # 期限切れまでの時間(分)  1000は仮です。
        "time_in_force": "GTC", # 執行数量条件 GTC or IOC or FOK
        "parameters": [
           {
             # 1つ目の発注条件を記載
           },
           {
             # 2つ目の発注条件を記載
           },
           {
             # 3つ目の発注条件を記載 (もしあれば)
           }
         ]
    }

    body = json.dumps(body)
    headers = header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.json()

コード中の「body」変数に代入されている、辞書型の各Keyを解説します。

  • order_method: 注文方式を設定します。(IFD or OCO or IFDOCO
  • minute_to_expire:期限切れまでの時間。省略すると、43200(30日)になります。
  • time_in_force:執行数量条件。省略すると、GTC になります。
  • parameters: 売買条件を記載していきます。次章で、具体的に記しています。

実行結果

上記の parent_order()を呼んだ結果です。

JSONで返ってきたものを、辞書型に変換しています。

下記の「API受付ID」は、キャンセル処理する際に、使用します。

{
  "parent_order_acceptance_id": "JRF20220508-020351-145960"  # 発注時の「API受付ID」
}

エラーが発生すると、下記のように、statsu=-200 が返ってきます。

{'status': -200, 'error_message': 'Insufficient funds', 'data': None}

上記は、日本円が足らずに、ビットコインを購入しようとしたケースです。

IFD注文のコード

前章で紹介した、注文コードの雛形をベースに、IFD発注の事例で具体的に記しました。

下記のコードは、

  • 「IFD注文」で、
  • 最初の発注は、「LIMIT」注文で買い
  • 損切りとして「STOP」注文で売り

で発注したケースです。

def parent_order():
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/sendparentorder"

    body = {
        "order_method": "IFD",
        "minute_to_expire": 10000,
        "time_in_force": "GTC",
        "parameters": [{
            "product_code": "btc_jpy", # ビットコインの場合
            "condition_type": "LIMIT", 
            "side": "BUY", 
            "price": 400000, 
            "size": 0.1 # 発注数量
          },
            {
             "product_code": "btc_jpy",
             "condition_type": "STOP",
             "side": "SELL", 
             "trigger_price": 390000, # STOP注文のトリガー価格
             "size": 0.1 # 売却数量
            }]
         }

    body = json.dumps(body)
    headers = header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.json()

OCO注文のコード

前章で紹介した、注文コードの雛形をベースに、OCO発注の事例で具体的に記しました。

下記のコードは、

  • 「OCO注文」で、
  • 新規買い注文を、「LIMIT」注文
  • 新規売り注文を、「STOP・LIMIT」注文

で発注したケースです。

def parent_order():
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/sendparentorder"

    body = {
        "order_method": "OCO",
        "minute_to_expire": 10000,
        "time_in_force": "GTC",
        "parameters": [{
            "product_code": "btc_jpy", # ビットコインの場合
            "condition_type": "LIMIT", 
            "side": "BUY",
            "price": 4100000, # 指値価格
            "size": 0.1 # 発注数量
            },
            {
             "product_code": "btc_jpy",
             "condition_type": "STOP_LIMIT",
             "side": "SELL", 
             "trigger_price": 3900000, # STOP・LIMIT注文のトリガー価格,
             "price": 3950000,  # STOP・LIMIT注文の指値価格
             "size": 0.1 # 売却数量
            }]
         }

    body = json.dumps(body)
    headers = header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.json()

IFDOCO注文のコード

前章で紹介した、注文コードの雛形をベースに、IFDOCO発注の事例で具体的に記しました。

下記のコードは、

  • 「IFDOCO注文」で、
  • 最初の発注は、「LIMIT」注文で買い
  • 利確として「LIMIT」注文で売り、
  • 損切りとして「TRAIL」注文で売り

で発注したケースです。

def parent_order():
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/sendparentorder"

    body = {
        "order_method": "IFDOCO",
        "minute_to_expire": 10000,
        "time_in_force": "GTC",
        "parameters": [{
            "product_code": "btc_jpy", # ビットコインの場合
            "condition_type": "LIMIT",
            "side": "BUY",
            "price": 4000000,
            "size": 0.1 # 発注数量
           },
           {
             "product_code": "btc_jpy",
             "condition_type": "LIMIT",
             "side": "SELL", 
             "price": 4100000, # 利確注文の価格
             "size": 0.1 # 売却数量
            },
            {
             "product_code": "btc_jpy",
             "condition_type": "TRAIL",
             "side": "SELL", 
             "offset": 1000, # トレーリング・ストップ注文のトレール幅
             "size": 0.1 # 売却数量
            }]
         }

    body = json.dumps(body)
    headers = header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.json()

注文結果の確認方法

約定された事を確認する

親注文の一覧を取得して、

  • 発注済みの、「parent_order_id」を確認の上、
  • 「parent_order_state」が、COMPLETED になっている事を確認します。

を確認します。

◆ 確認コード
    def list_parent_order(self):

        params = {
            "product_code": "btc_jpy", # BTCの場合
            "parent_order_state": "active" # オープンな注文一覧を取得する場合
        }
        endpoint_for_header = endpoint + '?'
        for k, v in params.items():
            endpoint_for_header += k + '=' + v
            endpoint_for_header += '&'
        endpoint_for_header = endpoint_for_header[:-1]

        headers = self.header('GET', endpoint=endpoint_for_header, body='')
        response = requests.get(self.base_url + endpoint, headers=headers, params=params)
        return response.json()

5行目の「parent_order_state」は、以下の項目が指定できます。

  • ACTIVE: オープンな注文の一覧を取得
  • COMPLETED: 全額が取引完了した注文の一覧を取得
  • CANCELED: ユーザーが、キャンセルした注文
  • EXPIRED: 有効期限に到達したため、取り消された注文の一覧を取得
  • REJECTED: 失敗した注文

省略した場合、全て返ってきます。

◆ 実行結果

下記結果の、「parent_order_state」が、COMPLETEDになっていれば、全取引が完了です。

[
  {
    "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
  },
  {
    "id": 138397,
    "parent_order_id": "JCO20150707-084549-022519",
    "product_code": "BTC_JPY",
    "side": "SELL",
    "parent_order_type": "IFD",
    "price": 30000,
    "average_price": 0,
    "size": 0.1,
    "parent_order_state": "CANCELED",  # ← ここに着目
    "expire_date": "2015-07-14T07:25:47",
    "parent_order_date": "2015-07-07T08:45:47",
    "parent_order_acceptance_id": "JRF20150707-084547-396699",
    "outstanding_size": 0,
    "cancel_size": 0.1,
    "executed_size": 0,
    "total_commission": 0
  }
]

発注した特殊注文(親注文)を、キャンセルする方法

特定の注文のみ、キャンセルする(未約定の場合のみ)

オーダー時に発行された、「API受付ID」が必要になります。

キャンセルに成功すれば、ステータスコードとして、200 が返ってきます。

import json

def order_cancel(self):
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/cancelparentorder"

    body = {
        "product_code": 'btc_jpy',
        "parent_order_acceptance_id": "JRF20150707-033333-099999"
    }

    body = json.dumps(body)
    headers = self.header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.status_code

全ての注文をキャンセルする

下記コードの、endpoint変数に、「/v1/me/cancelallchildorders」が代入されています。

親発注でも、全オーダーキャンセル時は、こちらのendpointをご使用下さい。

import json

def all_order_cancel():
    base_url = 'https://api.bitflyer.com'
    endpoint = "/v1/me/cancelallchildorders"

    body = {
        "product_code": 'btc_jpy'
    }

    body = json.dumps(body)
    headers = self.header('POST', endpoint=endpoint, body=body)

    response = requests.post(base_url + endpoint, data=body, headers=headers)
    return response.status_code

実行結果

正しく処理された場合は、ステータスコードの「200」が返ってきます。

最後に

最後に参考として、bitFlyerさんのAPI Documentationを、記載しておきます。

また冒頭の繰り返しになりますが、本記事は、下記記事の補足記事になります。

基本的な、bitFlyerさんの自動取引システムの作り方は、全てこちらで紹介しております。

本記事で、ご紹介した以外の機能を知りたい方は、下記までどうぞ。

bitFlyerのAPIを使用して、Pythonにより自動取引システムを作る
bitFlyerのAPIを使用して、Pythonにより自動取引システムを作るbitFlyerのAPIを使用して、Pythonにより自動取引システムを作り方を、わかりやすく紹介した記事です。...

最後まで読んで頂き、ありがとうございました。

また、お会いしましょう!