bot開発7.ccxtライブラリを利用してBitflyerで注文処理をやってみよう

前回、「bot開発6.仮想通貨トレードに便利なccxtを使ってみよう」ではccxtライブラリの基本的な部分にふれてみました。

各取引所のAPIでは、注文処理を行うのに長いコードを書く必要がありましたが、ccxtでは非常に短いコードで注文処理ができますので、その部分を一緒に取り組んでみて、実際に注文処理をしてみましょう。

Contents

事前準備

ccxtで注文処理を行うコードを書いていくわけですが、実際に、取引所に資金を入金しておく必要があります。資金がないと注文を通すことができないためです。

bitFlyer lightningの最低注文は0.01BTCからです。現在、(2022年9月時点)1BTCが約3,000,000円です。ですので、口座には3万円以上、5万円あれば安心して取引が可能です。

当ブログでは、注文処理の経験を積むテストですので、実際に約定しない状態で注文指示を出します。大体価格の15%ほど乖離がある価格で注文を出していればmんだいないでしょう。

おさらい

板情報の取得をしてみましょう。今回は、FXですので、コードにパラメータを追記する必要があります。

import ccxt
from pprint import pprint
 
bitflyer = ccxt.bitflyer()

#FX_BTC_JPY板情報の取得
ticker = bitflyer.fetch_ticker('BTC/JPY', params = { "product_code" : "FX_BTC_JPY" })
#出力
pprint(ticker)
{'ask': 3020059.0,
 'askVolume': None,
 'average': None,
 'baseVolume': 5742.67616643,
 'bid': 3020000.0,
 'bidVolume': None,
 'change': None,
 'close': 3020062.0,
 'datetime': '2022-09-10T16:04:35.020Z',
 'high': None,
 'info': {'best_ask': '3020059.0',
          'best_ask_size': '0.02',
          'best_bid': '3020000.0',
          'best_bid_size': '0.05',
          'ltp': '3020062.0',
          'market_ask_size': '0.0',
          'market_bid_size': '0.0',
          'product_code': 'FX_BTC_JPY',
          'state': 'RUNNING',
          'tick_id': '3843195',
          'timestamp': '2022-09-10T16:04:35.02',
          'total_ask_depth': '203.09293857',
          'total_bid_depth': '354.53293811',
          'volume': '5742.93716643',
          'volume_by_product': '5742.67616643'},
 'last': 3020062.0,
 'low': None,
 'open': None,
 'percentage': None,
 'previousClose': None,
 'quoteVolume': None,
 'symbol': 'BTC/JPY',
 'timestamp': 1662825875020,
 'vwap': None}

パブリックAPIを使い板情報を取得しました。’product_code’: ‘FX_BTC_JPY’を指定することで、FX_BTCの情報を取得できています。価格を知りたい場合はaskを確認すればOKです。

botでは、みなさんが作成するアルゴリズムを元に「買い」「売り」の注文が出されます。その時にの判断材料は「ask」「bid」となります。

パブリックAPIで注文処理をやってみよう

「買い」「売り」を行うにはパブリックAPIを利用します。誰の口座から買い注文をいれ、口座にお金があるのかを確認するには個別のAPI KeyとAPI Secret(キークレットキー)が必要です。

パブリックAPIを確認していきましょう。

ライブラリとAPIキー・シークレットkeyの入力

import ccxt
from pprint import pprint

#API Key&API Secret
apiKey  = "APIキー"
secret  = "API Secret"

base = ccxt.bitflyer({'apiKey':apiKey,'secret':secret})

bitflyerのAPI KeyとAPI Secretが必要になります。忘れてしまった人は「bot開発4.BitflyerのAPIキーとシークレットを取得」を参考に再取得してください。

ccxt.●●●●()の●●●●部分は取引所名を入力すれば他の取引所から情報を取得できます。

口座残高の取得

balance = base.fetch_balance()
v出力
pprint(balance)
{'BAT': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'BCH': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'BTC': {'free': 0.0002, 'total': 0.0002, 'used': 0.0},
 'DOT': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'ETC': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'ETH': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'JPY': {'free': 1530000.0, 'total': 1530000.0, 'used': 0.0},
 'LINK': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'LSK': {'free': 5.0, 'total': 5.0, 'used': 0.0},
 'LTC': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'MATIC': {'free': 0.0, 'total': 0.0, 'used': 0.0},
 'MKR': {'free': 0.0, 'total': 0.0, 'used': 0.0},
・
・
・

bitflyerに入金している口座情報を取得することができました。

JPYは日本円です。日本円で1530000円bitflyerにあることがわかります。その他、BTCを0.0002BTC保有しています。

FXの証拠金残高の確認

bitflyerでFXを行うには証拠金が必要になります。証拠金がいくらあるのか確認してみます。

collateral = base.private_get_getcollateral()
#出力
pprint( collateral )
{'collateral': '100000.0000000000000',
 'keep_rate': '0.0',
 'margin_call_amount': '0.0',
 'margin_call_due_date': None,
 'open_position_pnl': '0.0',
 'require_collateral': '0.0'}

証拠金「collateral」が100000あることが確認できました。
今回使っているprivate_get_getcollateral()はccxtにはありません。ですので、Bitflyerの提供している「v1/me/getcollateral」というAPIを利用しています。

どのように開発を行うのか、アルゴリズムを組むのかによっては、共通関数のみだけではなく、取引所のAPIも場合も一緒に使うことが可能です。

仮想通貨の取引(注文)

買いの注文を出してみましょう。1BTC約3,000,000円なので、即決済されない10%〜15%ほど乖離した価格で買い注文をいれます。

order = base.create_order(
	symbol = 'BTC/JPY',
	type='limit',
	side='buy',
	price='2700000',
	amount='0.01',
	params = { "product_code" : "FX_BTC_JPY" })
#出力
pprint(order)

プログラムを実行すると、サーバーから以下のような注文IDが返ってきます。この注文IDは、今後、注文状況を確認したりキャンセルするときに使います。

{'id': 'JRF20220910-165918-026890',
 'info': {'child_order_acceptance_id': 'JRF20220910-165918-026890'}}

bitflyerlightningの画面では以下のように買い注文が入っています。

ではこの処理の説明をします。
create_order()の各パラメータ説明は以下の通りです。このパラメータでいくらで買い注文をだすのか、何BTC購入するのかなどを設定できます。

引数名 概要 必須or任意
symbol 通貨レート 必須
type 注文方法:limit(指値),market(成行) 必須
price 指値価格 指値注文(limit)では必須
side 売買方法(buy or sell) 必須
amount(またはquantity) 仮想通貨取引数量 必須

買い注文の処理が走ると’id’: ‘JRF20220910-165918-026890’が発行され、処理完了の通知がきました。bitflyerlightningの画面にも同じ指値の注文が入っていることが確認できました。

注文状況の確認

未約定の注文をキャンセルするには、引数として通過コードと注文IDを渡し、キャンセル注文の処理を流すのですが、bitflyerlightningの画面では注文IDが表示されておりません。

注文価格の部分にカーソルを合わせてクリックすれば注文詳細情報が確認できます。が、一つ一つ確認し、IDをメモ帳にはりつけるという作業も面倒です。

以下は注文一覧を取得するプログラムです。

orders = base.private_get_getchildorders(params = {"product_code" : "FX_BTC_JPY", "count" : 10})

for i in range(len(orders)):
    if orders[i]["child_order_state"] == "ACTIVE":
        pprint(orders[i])

以前は、fetch_open_orders()関数で注文状況を取得できていたのですが、それが使えなくなったためprivate_get_getchildorders()関数を使っています。

{'average_price': '0.0',
 'cancel_size': '0.0',
 'child_order_acceptance_id': 'JRF20220911-023432-041976',
 'child_order_date': '2022-09-11T02:34:32',
 'child_order_id': 'JFX20220911-023432-175817F',
 'child_order_state': 'ACTIVE',
 'child_order_type': 'LIMIT',
 'executed_size': '0.0',
 'expire_date': '2022-10-11T02:34:32',
 'id': '0',
 'outstanding_size': '0.01',
 'price': '2680000.0',
 'product_code': 'FX_BTC_JPY',
 'side': 'BUY',
 'size': '0.01',
 'time_in_force': 'GTC',
 'total_commission': '0.0'}
・
・
・

ccxtのfetch_open_orders()であれば、未約定の注文状況のみ取得できたのですが、private_get_getchildordersは、約定済/未約定含めた注文一覧の情報を取得となります。

取得した情報からさらに欲しい情報を絞る必要があります。

例えば、約定の有無を判定するには、’child_order_state’を確認します。ここが”ACTIVE”であれば、未約定の注文となるわけです。注文キャンセルの場合、’child_order_acceptance_id’の情報が必要です。

ここでお気づきかもしれませんが、注文価格の部分にカーソルを合わせてクリックし確認した注文詳細情報とIDが違うのです。これ罠ですよね。私は開発している時散々ハマりました。(脱線してすいません。)

これで未約定注文に限定して情報を取得・表示が可能となりました。実際にbot動かした際は、countなどで数を指定した方がいいかもしれません。

注文内容をキャンセル(指定した注文ID)

注文をキャンセルする場合は、cancel_order()という共通の関数を使います。注文IDがすでにわかっている場合は、以下のように書くだけでOKです。

#注文した際の'child_order_acceptance_id'
order_id = 'JRF20220911-043441-046295'
cancel_order = base.cancel_order(order_id, 'FX_BTC_JPY')

#出力
pprint(cancel_order)
b''

キャンセルされた場合、特に返ってくる値はありません。

bitFlyer lightningの画面上、3つの注文。

cancel_order()後は、1つキャンセルされていることが確認できます。

注文内容をキャンセル(未約定の全注文)

注文IDを指定し、注文をキャンセルすることができました。では、未約定の全注文を一括キャンセルする方法を紹介します。

処理としては、未約定の注文状況を取得し、”child_order_acceptance_id”に対してキャンセル処理を行い、リスト化されたorders文実行するという流れを作ります。

  1. 未約定の注文状況を取得する
  2. キャンセルプログラムをfor文で実行する
orders = base.private_get_getchildorders(params = {"product_code" : "FX_BTC_JPY"})

for o in orders:
	bitflyer.cancel_order(
		symbol = "BTC/JPY",
		id = o["child_order_acceptance_id"],
		params = { "product_code" : "FX_BTC_JPY" })

未約定の全注文のキャンセルができました。bitFlyer lightningの画面でも確認してみてください。

※注意:本bot開発は「文系でもわかる!BitcoinのBOT自動売買トレードの始め方」をもとに開発・自分なりの解釈用備忘録としています。


Python勉強したいのであればこれ一択


AIの技術、データ分析を身につけるにはPythonが取り組みやすいです。専門コースもあるので、まずは、気軽に問い合わせしてみてください!
技術者も多くなってきていますが、世界と戦うにはまだまだ人材不足です。高い年収を狙うなら今がチャンス!


フリーランスエンジニアが登録して欲しいエージェント


長くお世話になっているengineer-route。
単価、稼働日数、稼働時間相談も親身にのってくれます。しっかりしたサポート・コミュニケーションを交わすことで「はいってみた違った」というエンジニアあるあるを極力回避できると思います。私は当たりしかないです。