バイナンス ジャパンのAPIを使って仮想通貨botを作りましょう。
この記事では、Pythonでバイナンス ジャパンのAPIを使う方法を説明します。
実際に動作するコードをお見せします。
前準備
Binance Japanに口座を開設する
まず、バイナンス ジャパンで口座開設をしましょう。
バイナンス ジャパンには「お友達紹介プログラム」があります。
ぜひ、1800円相当のBNBを受け取ってください。
以下のURLよりEメールアドレスもしくは電話番号で登録を行ってください。アカウント設定の画面で必ず紹介コードを入力してください。
・URL: 招待URL
・紹介コード: 116836794
・達成条件:初めて口座を開設されるお客さまで、紹介者から受け取った紹介コードを被紹介者が入力し、本人確認手続きを完了させ、口座開設を完了してください。
・特典:被紹介者の口座開設が完了した後、紹介者と被紹介者の両方のBinance Japan口座にそれぞれ1800円相当のBNBが30営業日以内に付与されます。
Binance JapanのAPI仕様書
requestsモジュールの仕様書
APIコールで使用するrequestsの仕様書です。
必要なPythonモジュール
サンプルコードでimportするモジュールです。
import requests import json import time from datetime import datetime import hmac import hashlib import urllib.parse
API使用時の補足事項
# 不正な文字列だと以下のエラーが返る。 { "code": -1100, "msg": "Illegal characters found in parameter 'symbols'; legal range is '^\\[(\"[A-Z0-9-_.]{1,20}\"(,\"[A-Z0-9-_.]{1,20}\"){0,}){0,1}\\]$'." }
Market Data Endpoints
24hr Ticker Price Change Statistics
24時間統計情報を取得してみます。
https://binance-docs.github.io/apidocs/spot/en/#24hr-ticker-price-change-statistics
endPoint = 'https://api.binance.com' path = '/api/v3/ticker/24hr' url = endPoint + path # symbolsは["BTCJPY","BNBJPY"]のような文字列にする。スペース禁止。 symbols = ['BTCJPY', 'BNBJPY'] symbols = '","'.join(symbols) symbols = '["' + symbols + '"]' parameters = { 'symbols': symbols, 'type': 'MINI', } response = requests.get(url, params=parameters) res = response.json() print(json.dumps(res, indent=4))
レスポンスはこうなります。
typeパラメータをFULLにすると、もっと多くの情報を取得できます。
[ { "symbol": "BNBJPY", "openPrice": "74198.00000000", "highPrice": "76230.00000000", "lowPrice": "71755.00000000", "lastPrice": "75537.00000000", "volume": "467.93380000", "quoteVolume": "34432964.20890000", "openTime": 1726002934743, "closeTime": 1726089334743, "firstId": 579058, "lastId": 580945, "count": 1888 }, { "symbol": "BTCJPY", "openPrice": "8205300.00000000", "highPrice": "8262873.00000000", "lowPrice": "7880000.00000000", "lastPrice": "8174929.00000000", "volume": "21.65736900", "quoteVolume": "174862160.11487200", "openTime": 1726004797097, "closeTime": 1726091197097, "firstId": 1940213, "lastId": 1949622, "count": 9410 } ]
BTCJPYのopenTimeのUNIX時間を実時間に変換してみます。
t = datetime.fromtimestamp(1726004797097/1000) print(t) # 2024-09-11 06:46:37.097000
Trading Day Ticker
その日のTicker情報を取得します。
https://binance-docs.github.io/apidocs/spot/en/#trading-day-ticker
endPoint = 'https://api.binance.com' path = '/api/v3/ticker/tradingDay' url = endPoint + path # symbolsは["BTCJPY","BNBJPY"]のような文字列にする。スペース禁止。 symbols = ['BTCJPY', 'BNBJPY'] symbols = '","'.join(symbols) symbols = '["' + symbols + '"]' parameters = { 'symbols': symbols, 'type': 'MINI', } response = requests.get(url, params=parameters) res = response.json() print(json.dumps(res, indent=4))
レスポンスはこうなります。
[ { "symbol": "BNBJPY", "openPrice": "73521.00000000", "highPrice": "76230.00000000", "lowPrice": "71755.00000000", "lastPrice": "75537.00000000", "volume": "395.20860000", "quoteVolume": "29043945.82830000", "openTime": 1726012800000, "closeTime": 1726099199999, "firstId": 579141, "lastId": 580945, "count": 1805 }, { "symbol": "BTCJPY", "openPrice": "8216247.00000000", "highPrice": "8262873.00000000", "lowPrice": "7880000.00000000", "lastPrice": "8174929.00000000", "volume": "21.04431200", "quoteVolume": "169819916.64230600", "openTime": 1726012800000, "closeTime": 1726099199999, "firstId": 1940496, "lastId": 1949622, "count": 9127 } ]
BTCJPYのopenTimeのUNIX時間を実時間に変換してみます。
APIのtimeZoneパラメータはデフォルトなのでUTCになるのですが、9:00になっている理由がよくわかりません。
UTCとJSTの時差が9時間で、私のアカウントがBinace Japanだからでしょうか。
でも、endPointはBinance Globalのものなんですよね。シンボルにJPYが含まれるからですかね。
API仕様書からは読み取れませんでした。
t = datetime.fromtimestamp(1726012800000/1000) print(t) # 2024-09-11 09:00:00
24hour ticker と Trading day ticker のAPIの違いはあまりわかりませんでしたが、使いやすい方を使ってください。
LTPは同じ価格が返っていると思います。
Order Book
板情報を取得します。
https://binance-docs.github.io/apidocs/spot/en/#order-book
# 板情報取得 endPoint = 'https://api.binance.com' path = '/api/v3/depth' url = endPoint + path symbol = 'BTCJPY' parameters = { 'symbol': symbol, 'limit': 2, } response = requests.get(url, params=parameters) res = response.json() print(json.dumps(res, indent=4))
このようなレスポンスが返ります。
板情報の数はlimitパラメータで決まります。
デフォルトは100で、最大値は5000です。
{ "lastUpdateId": 181868260, "bids": [ [ "8276608.00000000", "0.02843500" ], [ "8275774.00000000", "0.04176900" ] ], "asks": [ [ "8279483.00000000", "0.00834500" ], [ "8279568.00000000", "0.02364800" ] ] }
Kline
Kline情報を取得します。
https://binance-docs.github.io/apidocs/spot/en/#kline-candlestick-data
BTCJPYの日足データを2つ取得してみます。
# KLine取得 endPoint = 'https://api.binance.com' path = '/api/v3/klines' url = endPoint + path parameters = { 'symbol': 'BTCJPY', 'interval': '1d', # 日足 'limit': 2, } response = requests.get(url, params=parameters) res = response.json() print(json.dumps(res, indent=4))
レスポンスです。
[ [ 1725926400000, "8183871.00000000", "8269121.00000000", "8074739.00000000", "8214810.00000000", "17.95516700", 1726012799999, "146895069.95628100", 8009, "8.79789100", "71977998.49504800", "0" ], [ 1726012800000, "8216247.00000000", "8262873.00000000", "7880000.00000000", "8176200.00000000", "21.11211300", 1726099199999, "170373932.95085800", 9160, "10.14012400", "81761256.46578200", "0" ] ]
取得した2つのKline open timeをUNIX時間から実時間に変換してみます。
ローソク足の長さは日足指定で、タイムゾーンはデフォルトのUTCにしています。
Kline open timeは9:00となっていました。UTCとJSTの時差が考慮された時刻になっていそうです。
t = datetime.fromtimestamp(1725926400000/1000) print(t) t = datetime.fromtimestamp(1726012800000/1000) print(t) # 2024-09-10 09:00:00 # 2024-09-11 09:00:00
Symbol Price Ticker
LTP(Last Traded Price:最終取引価格)を取得できます。
https://binance-docs.github.io/apidocs/spot/en/#symbol-price-ticker
# LTP取得 endPoint = 'https://api.binance.com' path = '/api/v3/ticker/price' url = endPoint + path # symbolsは["BTCJPY","BNBJPY"]のような文字列にする。スペース禁止。 symbols = ['BTCJPY', 'BNBJPY'] symbols = '","'.join(symbols) symbols = '["' + symbols + '"]' parameters = { 'symbols': symbols, } response = requests.get(url, params=parameters) res = response.json() print(json.dumps(res, indent=4))
レスポンスです。
[ { "symbol": "BNBJPY", "price": "76719.00000000" }, { "symbol": "BTCJPY", "price": "8266926.00000000" } ]
Wallet Endpoints
システムのステータス取得
システムの稼働状態を取得します。
https://binance-docs.github.io/apidocs/spot/en/#system-status-system
# システムのステータス取得 endPoint = 'https://api.binance.com' path = '/sapi/v1/system/status' url = endPoint + path response = requests.get(url) res = response.json() print(json.dumps(res, indent=4))
レスポンスです。
{ "status": 0, "msg": "normal" }
User Asset
資産残高を取得します。
https://binance-docs.github.io/apidocs/spot/en/#user-asset-user_data
# 資産残高の取得 endPoint = 'https://api.binance.com' path = '/sapi/v3/asset/getUserAsset' url = endPoint + path timestamp = int(time.time() * 1000) parameters = { 'timestamp': timestamp, 'needBtcValuation': True, } text = urllib.parse.urlencode(parameters) sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest() parameters.update({'signature': sign}) headers = { "X-MBX-APIKEY": apiKey, } response = requests.post(url, headers=headers, data=parameters) res = response.json() print(json.dumps(res, indent=4))
サンプルコード中のapiKeyとsecretKeyはご自身のものに置き換えてください。
レスポンスです。
[ { "asset": "BNB", "free": "0", "locked": "0", "freeze": "0", "withdrawing": "0", "ipoable": "0", "btcValuation": "0" }, { "asset": "BTC", "free": "0", "locked": "0", "freeze": "0", "withdrawing": "0", "ipoable": "0", "btcValuation": "0" }, { "asset": "JPY", "free": "0", "locked": "0", "freeze": "0", "withdrawing": "0", "ipoable": "0", "btcValuation": "0" } ]
Spot Trading Endpoints
New Order
新規注文方法です。
https://binance-docs.github.io/apidocs/spot/en/#new-order-trade
現物取引でビットコインを800万円で0.001サイズほど指値で買い注文するサンプルコードです。
# 新規注文 endPoint = 'https://api.binance.com' path = '/api/v3/order' url = endPoint + path timestamp = int(time.time() * 1000) parameters = { 'timestamp': timestamp, 'symbol': 'BTCJPY', 'side': 'BUY', 'type': 'LIMIT', 'price': 8000000, 'quantity': 0.001, 'timeInForce': 'GTC', } text = urllib.parse.urlencode(parameters) sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest() parameters.update({'signature': sign}) headers = { "X-MBX-APIKEY": apiKey, } response = requests.post(url, headers=headers, data=parameters) res = response.json() print(json.dumps(res, indent=4))
いくつか省略しますが、以下のようなレスポンスが返ります。
数字9桁の注文ID(orderId)が発行され、注文キャンセルする場合はこれを使います。
{ "symbol": "BTCJPY", "orderId": nnnnnnnnn, "orderListId": -1, "price": "8000000.00000000", "origQty": "0.00100000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", }
必須パラメータが抜けていたら、以下のようなエラーが返ります。
{ "code": -1102, "msg": "Mandatory parameter 'timeInForce' was not sent, was empty/null, or malformed." }
All Orders
注文一覧を取得します。
https://binance-docs.github.io/apidocs/spot/en/#all-orders-user_data
現物取引の注文一覧を取得するサンプルコードです。
ビットコインの注文一覧を1つ取得しています。
一覧の数はlimitパラメータで設定でき、デフォルトは500で最大値は1000になっています。
# 注文一覧の取得 endPoint = 'https://api.binance.com' path = '/api/v3/allOrders' url = endPoint + path timestamp = int(time.time() * 1000) parameters = { 'timestamp': timestamp, 'symbol': 'BTCJPY', 'limit': 1, } text = urllib.parse.urlencode(parameters) sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest() parameters.update({'signature': sign}) headers = { "X-MBX-APIKEY": apiKey, } response = requests.get(url, headers=headers, params=parameters) res = response.json() print(json.dumps(res, indent=4))
いくつか省略しますが、以下のようなレスポンスが返ります。
[ { "symbol": "BTCJPY", "orderId": nnnnnnnnn, "orderListId": -1, "price": "8000000.00000000", "origQty": "0.00100000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "NEW", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "isWorking": true, } ]
Cancel Order
注文キャンセル方法です。
https://binance-docs.github.io/apidocs/spot/en/#cancel-order-trade
上の例の注文時に発行された注文IDはを使って、キャンセルしてみます。
# 注文キャンセル endPoint = 'https://api.binance.com' path = '/api/v3/order' url = endPoint + path timestamp = int(time.time() * 1000) parameters = { 'timestamp': timestamp, 'symbol': 'BTCJPY', 'orderId': order_id, } text = urllib.parse.urlencode(parameters) sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest() parameters.update({'signature': sign}) headers = { "X-MBX-APIKEY": apiKey, } response = requests.delete(url, headers=headers, params=parameters) res = response.json() print(json.dumps(res, indent=4))
変数order_idに数字9桁の注文IDを入れてください。
いくつか省略しますが、以下のようなレスポンスが返ります。
{ "symbol": "BTCJPY", "orderId": nnnnnnnnn, "orderListId": -1, "price": "8000000.00000000", "origQty": "0.00100000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", }
注文キャンセル後に注文一覧を見ると、status=CANCELEDになっています。
[ { "symbol": "BTCJPY", "orderId": nnnnnnnnn, "orderListId": -1, "price": "8000000.00000000", "origQty": "0.00100000", "executedQty": "0.00000000", "cummulativeQuoteQty": "0.00000000", "status": "CANCELED", "timeInForce": "GTC", "type": "LIMIT", "side": "BUY", "stopPrice": "0.00000000", "icebergQty": "0.00000000", "isWorking": true, } ]
Spot Account Endpoints
Account Trade List
取引履歴を取得します。
https://binance-docs.github.io/apidocs/spot/en/#account-trade-list-user_data
現物取引の取引履歴を取得するサンプルコードです。
ビットコインの取引履歴を1つ取得してみます。
履歴の数はlimitパラメータで指定でき、デフォルト500で最大1000です。
# 取引履歴の取得 endPoint = 'https://api.binance.com' path = '/api/v3/myTrades' url = endPoint + path timestamp = int(time.time() * 1000) parameters = { 'timestamp': timestamp, 'symbol': 'BTCJPY', 'limit': 1, } text = urllib.parse.urlencode(parameters) sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest() parameters.update({'signature': sign}) headers = { "X-MBX-APIKEY": apiKey, } response = requests.get(url, headers=headers, params=parameters) res = response.json() print(json.dumps(res, indent=4))
以下のようなレスポンスが返ります。
[ { "symbol": "BTCJPY", "id": nnnnnnn, "orderId": nnnnnnnnn, "orderListId": -1, "price": "8245000.00000000", "qty": "0.00013200", "quoteQty": "1088.34000000", "commission": "0.00001043", "commissionAsset": "BNB", "isBuyer": false, "isMaker": true, "isBestMatch": true } ]