こんにちは、野良エンジニアです。
ひさしぶりに Bot を作っています。複数取引所に対応している ccxt を使ってみたので、つまずいた事やその解決策について随時まとめていきたいと思います。
初心者向け・仮想通貨Lisk(LSK)を少しでも安く大量に買う方法
Lisk Vote 完全まとめ!やり方、確認方法、実績、効率、税金、etc... 最大効率の報酬で枚数を増やそう
仮想通貨ブログを書くなら、仮想通貨ウェブフォントを導入しよう
Amazon プライムは絶対入るべき!メリット・特典・会費・退会方法をまとめて簡単に紹介
内村さまぁ~ず 第1〜50回から選ぶオススメ神回10選【Amazonプライムビデオ】
キッチン作業が最高に捗る突っ張りキッチンラック【オススメグッズ・スペース倍増】
ccxt とは
ccxt について、簡単にまとめておきます。
複数の取引所に対応しているライブラリ
取引所ごとのライブラリを使って個別開発する必要がない
Coincheck、bitFlyer、binance、BITMEX など、主要取引所にはほぼ対応
JavaScript, Python, PHP に対応
CryptoCurrency eXchange Trading library の略
主な対応取引所
Coincheck
bitFlyer
bitbank
QUOINEX
Zaif
binance
Bitfinex
BITMEX
Bittrex
Huobi
Kucoin
ccxt の使い方メモ
ここでは、Python での ccxt の使い方についてメモしていきます。
インストール
# pip install ccxt
基本的な使い方
import ccxt exchange = ccxt.bitflyer() # Private API を利用する場合に設定 exchange.apiKey = "Key" exchange.secret = "Secret" # API 実行(スネークケース、キャメルケース、どちらの書き方でも良い) exchange.fetch_ticker("BTC/JPY") # Ticker(相場情報)の取得 exchange.fetchBalance() # 残高情報の取得 exchange.create_limit_sell_order ('BTC/JPY', 0.01, 200000) # 指値売り注文 ...
対応メソッドの確認
まだ開発中のため、取引所によっては使用できないメソッドがあります。
exchange.has
で使用できるメソッドを確認しましょう。
# encoding: utf-8 import ccxt bitbank = ccxt.bitbank() print(bitbank.has)
bitbank 対応メソッド ※2018/04/03 現在
見やすいように改行してます。
>>> import ccxt >>> ccxt.bitbank().has { 'publicAPI': True, 'privateAPI': True, 'CORS': False, 'cancelOrder': True, 'cancelOrders': False, 'createDepositAddress': False, 'createOrder': True, 'createMarketOrder': True, 'createLimitOrder': True, 'deposit': False, 'editOrder': 'emulated', 'fetchBalance': True, 'fetchClosedOrders': False, 'fetchCurrencies': False, 'fetchDepositAddress': False, 'fetchFees': False, 'fetchFundingFees': False, 'fetchL2OrderBook': True, 'fetchMarkets': True, 'fetchMyTrades': True, 'fetchOHLCV': True, 'fetchOpenOrders': True, 'fetchOrder': False, 'fetchOrderBook': True, 'fetchOrderBooks': False, 'fetchOrders': False, 'fetchTicker': True, 'fetchTickers': False, 'fetchTrades': True, 'fetchTradingFees': False, 'withdraw': False }
未対応メソッドを API から操作する
ccxt Manual の API Method Naming Conventions にやり方が記載されています。
簡単にまとめておきます、キャメルケース(PrivateApi
みたいに大文字で区切るやつ)、スネークケース(private_api
みたいに _
で区切るやつ)、どちらでも良いです。
1. API の種別(Public
or Private
)
2. HTTP の Method(GET
, POST
)
3. API の URL
4. パラメータは辞書(dict)型
もう少し詳しい例を、bitbank API を使って書いておきます。
ccxt Manual
bitbank API Doc
bitbank API エラーコード一覧
GET /user/spot/orders
取引所 API を直接叩いている(はず)ので、パラメータは各取引所の指定に従ってください。この例だと BTC/JPY
って書くとエラーになります。
bitbank.privateGetUserSpotOrders({"symbol": "btc_jpy", "id": 12345678}) bitbank.private_get_user_spot_orders({"symbol": "btc_jpy", "id": 12345678})
GET /user/spot/active_orders
URL に _
が含まれているケース。キャメルケースにしたい場合は _
を削って、次を大文字にすれば OK。
orders = bitbank.privateGetUserSpotActiveOrders({"pair": "btc_jpy"}) orders = bitbank.private_get_user_spot_active_orders({"pair": "btc_jpy"})
残高の確認
fetch_balance ()
で残高が取得できます。
balance = bitbank.fetchBalance() print(json.dumps(balance, indent: 2))
レスポンスはこんな感じ。
{ "info": { "success": 1, "data": { "assets": [ { "asset": "jpy", "amount_precision": 4, "onhand_amount": "0.0000", "locked_amount": "0.0000", "free_amount": "0.0000", "stop_deposit": false, "stop_withdrawal": false, "withdrawal_fee": { "threshold": "30000.0000", "under": "540.0000", "over": "756.0000" } }, ... ] } }, "jpy": { "free": 0.0, "used": 0.0, "total": 0.0 }, "btc": { "free": 0.0, "used": 0.0, "total": 0.0 }, ... "free": { "jpy": 0.0, "btc": 0.0, "ltc": 0.0, "xrp": 0.0, "eth": 0.0, "mona": 0.0, "bcc": 0.0 }, "used": { "jpy": 0.0, ... }, "total": { "jpy": 0.0, ... } }
相場情報(ticker) 取得
fetch_ticker (symbol)
で相場情報(ticker)が取得できます。
ticker = bitbank.fetch_ticker("BTC/JPY") print(json.dumps(ticker, indent: 2))
レスポンスはこんな感じ。
{ "symbol": "BTC/JPY", "timestamp": 1522762518935, "datetime": "2018-04-03T13:35:19.935Z", "high": 796405.0, "low": 736132.0, "bid": 790605.0, "bidVolume": null, "ask": 790773.0, "askVolume": null, "vwap": null, "open": null, "close": 790947.0, "last": 790947.0, "previousClose": null, "change": null, "percentage": null, "average": null, "baseVolume": 2163.0537, "quoteVolume": null, "info": { "sell": "790773", "buy": "790605", "high": "796405", "low": "736132", "last": "790947", "vol": "2163.0537", "timestamp": 1522762518935 } }
注文関連
指値注文
指値買い
create_limit_buy_order(symbol, amount, price[, params])
で指値買い、params
は取引所固有のパラメータがあれば設定可能です。
result = bitbank.create_limit_buy_order("MONA/JPY", 1, 2000) # 1MONA を 2000円で買い注文 print(json.dumps(result, indent: 2))
レスポンスはこんな感じ。
{ "id": "7378568", "datetime": "2018-04-03T12:55:37.805Z", "timestamp": 1522760136805, "status": "open", "symbol": "MONA/JPY", "type": "limit", "side": "buy", "price": 2000.0, "cost": 0.0, "amount": 1.0, "filled": 0.0, "remaining": 1.0, "trades": null, "fee": null, "info": { "order_id": 7378568, "pair": "mona_jpy", "side": "buy", "type": "limit", "start_amount": "1.00000000", "remaining_amount": "1.00000000", "executed_amount": "0.00000000", "price": "2000.0000", "average_price": "0.0000", "ordered_at": 1522760136805, "status": "UNFILLED" } }
指値売り
create_limit_sell_order (symbol, amount, price[, params])
で指値売り、params
は取引所固有のパラメータがあれば設定可能です。
result = bitbank.create_limit_sell_order("MONA/JPY", 1, 2000) # 1MONA を 2000円で売り注文 print(json.dumps(result, indent: 2))
レスポンスはこんな感じ。
{ "id": "7378568", "datetime": "2018-04-03T12:55:37.805Z", "timestamp": 1522760136805, "status": "open", "symbol": "MONA/JPY", "type": "limit", "side": "sell", "price": 2000.0, "cost": 0.0, "amount": 1.0, "filled": 0.0, "remaining": 1.0, "trades": null, "fee": null, "info": { "order_id": 7378568, "pair": "mona_jpy", "side": "sell", "type": "limit", "start_amount": "1.00000000", "remaining_amount": "1.00000000", "executed_amount": "0.00000000", "price": "2000.0000", "average_price": "0.0000", "ordered_at": 1522760136805, "status": "UNFILLED" } }
成行注文
create_market_buy_order (symbol, amount[, params])
、create_market_sell_order (symbol, amount[, params])
で成行注文。
成行注文といえど、メソッド実行した瞬間(= API 発行した瞬間)はまだ約定していないので注意。
{ "id": "379751834", "datetime": "2018-04-03T17:02:40.871Z", "timestamp": 1522774959871, "status": "open", "symbol": "BTC/JPY", "type": "market", "side": "buy", "price": 0.0, "cost": 0.0, "amount": 0.0001, "filled": 0.0, "remaining": 0.0001, "trades": null, "fee": null, "info": { "order_id": 379751834, "pair": "btc_jpy", "side": "buy", "type": "market", "start_amount": "0.00010000", "remaining_amount": "0.00010000", "executed_amount": "0.00000000", "average_price": "0.0000", "ordered_at": 1522774959871, "status": "UNFILLED" } }
注文の確認
fetch_order(id, symbol)
で注文の最新状況を取得
order = bitbank.fetch_order(7378542, "MONA/JPY") print(json.dumps(order, indent: 2))
レスポンスはこんな感じ。
{ "id": "7378542", "datetime": "2018-04-03T12:54:55.633Z", "timestamp": 1522760094633, "status": "open", "symbol": "MONA/JPY", "type": "limit", "side": "sell", "price": 2000.0, "cost": 0.0, "amount": 1.0, "filled": 0.0, "remaining": 1.0, "trades": null, "fee": null, "info": { "order_id": 7378542, "pair": "mona_jpy", "side": "sell", "type": "limit", "start_amount": "1.00000000", "remaining_amount": "1.00000000", "executed_amount": "0.00000000", "price": "2000.0000", "average_price": "0.0000", "ordered_at": 1522760094633, "status": "UNFILLED" } }
キャンセル
cancel_order(id, symbol)
でキャンセル、id
は文字列でも数値でも OK っぽい(bitbank はどっちでもいけました)
result = bitbank.cancel_order("7365919", "MONA/JPY") print(json.dumps(result, indent: 2))
レスポンスはこんな感じ。
{ "order_id": 7365912, "pair": "mona_jpy", "side": "sell", "type": "limit", "start_amount": "1.00000000", "remaining_amount": "1.00000000", "executed_amount": "0.00000000", "price": "1000.0000", "average_price": "0.0000", "ordered_at": 1522744451311, "canceled_at": 1522758207410, "status": "CANCELED_UNFILLED" }
注文を全部キャンセル
例外処理とか未考慮ですが一案です。
orders = exchange.fetch_open_orders("MONA/JPY") for order in orders: exchange.cancel_order(order["id"], order["symbol"])
JSON の整形
ccxt の戻り値は基本的に JSON 形式(のはず)。
json
モジュールを import して json.dump
メソッドで整形できます。
import json print(json.dumps(json_data, indent=2))
例:fetch_ticker の整形
fetch_ticker
はこうなります。
{ "symbol": "BTC/JPY", "timestamp": 1522756790945, "datetime": "2018-04-03T11:59:51.945Z", "high": 796405.0, "low": 736132.0, "bid": 781570.0, "bidVolume": null, "ask": 782190.0, "askVolume": null, "vwap": null, "open": null, "close": 781554.0, "last": 781554.0, "previousClose": null, "change": null, "percentage": null, "average": null, "baseVolume": 2153.4508, "quoteVolume": null, "info": { "sell": "782190", "buy": "781570", "high": "796405", "low": "736132", "last": "781554", "vol": "2153.4508", "timestamp": 1522756790945 } }
例:GET /user/spot/orders の整形
GET /user/spot/orders
はこうなります。
{ "success": 1, "data": { "order_id": 12345678, "pair": "btc_jpy", "side": "sell", "type": "limit", "start_amount": "1.00000000", "remaining_amount": "1.00000000", "executed_amount": "0.00000000", "price": "1200000.0000", "average_price": "0.0000", "ordered_at": 1522744456362, "status": "UNFILLED" } }
参考
他に ccxt について書かれているページをまとめておきます。
Python3とCCXTを使用して仮想通貨の自動売買プログラムを作る - エンジニアの頭の中
ccxtを使って裁定取引botを作ってみたらなぜか虚しくなった件 - Qiita
Python3とCCXTライブラリを用いたBitMEX自動売買bot作成Tips|AKAGAMI|note
[Python]CCXTを使ったBitMEXのオープンポジション取得方法(API) – Aoiue's memorandum
まとめ
少しずつ開発と記事更新を行っていきます。
初心者向け・仮想通貨Lisk(LSK)を少しでも安く大量に買う方法
Lisk Vote 完全まとめ!やり方、確認方法、実績、効率、税金、etc... 最大効率の報酬で枚数を増やそう
仮想通貨ブログを書くなら、仮想通貨ウェブフォントを導入しよう
Amazon プライムは絶対入るべき!メリット・特典・会費・退会方法をまとめて簡単に紹介
内村さまぁ~ず 第1〜50回から選ぶオススメ神回10選【Amazonプライムビデオ】
キッチン作業が最高に捗る突っ張りキッチンラック【オススメグッズ・スペース倍増】