PythonでAPIを使ってBybitの現物取引(レバレッジあり・なし)をする方法

この記事では、Bybitの現物取引のAPIの使い方を、実際に動くPythonのコードを載せて説明します。デリバティブ取引はこの記事では扱いません。

Bybitの現物取引では、証拠金(マージン)取引ができます。
つまり、現物取引でレバレッジ取引が行えます。

この記事では、レバレッジあり・なしの現物取引のAPIの使い方を、Pythonのサンプルコードをお見せしながらご紹介します。

今はレバレッジ2倍から10倍まで可能です。

Bybitの証拠金取引(マージン取引)の説明を載せておきます。

Bybitの証拠金取引とは、現物取引でレバレッジ取引するための機能です。証拠金取引では、現物アカウントの資産を担保として利用することができます。Bybitから追加資金を借り入れることで、より大きな現物ポジションの保有、あるいは現物での空売り(ショート)ができるようになります。

Bybitマージン取引のご案内 (現物)

前提知識

APIで取引するので、前提となる情報を共有させてください。
すでにAPIを使ったことがある方はスルーしてください。

BybitのAPI仕様書

APIのパラメータはこの記事ではあまり触れないので、詳細はこちらをご覧ください。

Pythonのimportモジュール

モジュールは以下を使います。

import requests
import json
import time
from datetime import datetime
import hmac
import hashlib
import urllib.parse

Bybitの現物取引の手数料

手数料には3つの種類があります。
https://www.bybit.com/ja-JP/help-center/article/Spot-Margin-Trading-Fees-Explained

  • 現物取引手数料
    • レバレッジなし・ありのどちらでも現物取引を行った場合に発生する。
  • 利息
    • レバレッジありの現物取引を行った場合に発生する。
    • 資金の借入れが成功すると直ちに利息が発生する。注文が約定する・しないに関わらず利息が発生する。
    • 利息は手動返済したり、ポジションが強制決済されるとき、現物アカウントからのみ控除される。
    • 証拠金取引で負う利息は時間単位で発生する。短時間でも1時間とみなされる。
  • 強制決済手数料
    • 強制決済が行われた場合に発生する。

それぞれの手数料の計算方法は以下となります。

現物取引手数料

取引手数料 = 約定注文数量 × 現物取引手数料率

Bybitに口座開設したばかりのときは、非VIP会員になります。
非VIP会員は現物取引するときに0.1%の取引手数料を支払うことになります。
https://www.bybit.com/ja-JP/help-center/article/Trading-Fee-Structure

利息

利息 = 借入額 × 日次利息率/24 × 時間

それぞれのコインの利息は以下のサイトに載っています。
https://www.bybit.com/en/announcement-info/fullstock-leverage-uta/

1時間の利息はAPIで取得できます。
使用するAPIは”Get VIP Margin Data”になります。
https://bybit-exchange.github.io/docs/v5/spot-margin-uta/vip-margin

ご自身のVIPレベルと知りたいコインを設定して、APIを呼んでみてください。

endPoint = 'https://api.bybit.com'
path     = '/v5/spot-margin-trade/data'
url = endPoint + path

params = {
    'vipLevel': 'No VIP',
    'currency': 'USDT',
}

response = requests.get(url, params=params)
res = response.json()
print(json.dumps(res, indent=4))

VIP0(非VIP会員)のUSDTの1時間の利息率は0.0000071388540000でした。

{
    "retCode": 0,
    "retMsg": "success",
    "result": {
        "vipCoinList": [
            {
                "list": [
                    {
                        "borrowable": true,
                        "collateralRatio": "1",
                        "currency": "USDT",
                        "hourlyBorrowRate": "0.0000071388540000",
                        "liquidationOrder": "1",
                        "marginCollateral": true,
                        "maxBorrowingAmount": "5500000"
                    }
                ],
                "vipLevel": "No VIP"
            }
        ]
    }
}

VIP0(非VIP会員)のBTC(ビットコイン)の1時間の利息率は0.0000017278920000でした。

{
    "retCode": 0,
    "retMsg": "success",
    "result": {
        "vipCoinList": [
            {
                "list": [
                    {
                        "borrowable": true,
                        "collateralRatio": "0.98",
                        "currency": "BTC",
                        "hourlyBorrowRate": "0.0000017278920000",
                        "liquidationOrder": "2",
                        "marginCollateral": true,
                        "maxBorrowingAmount": "100"
                    }
                ],
                "vipLevel": "No VIP"
            }
        ]
    }
}

強制決済手数料

強制決済手数料 = 強制決済資産 × 強制決済手数料率 

Bybitでの前準備

APIを使う前にBybitで以下をやっておく必要があります。

Bybitの口座と入金

APIで注文を実行するためには、入金できていないとエラーになります。
口座開設と入金を先に済ませましょう。

口座を開設されていない方は以下の記事をご覧ください。

Bybitの口座開設と入金のやり方(口座開設前に見てください)

資金を統合取引アカウントに振替

「資産」のところで、「資金調達」から「統合取引アカウント」へ資産の振替をしましょう。

統合取引アカウントで担保を有効化

USDTやUSDCはデフォルトで担保になっていますが、他のコインの場合は許可が必要となります。現物取引で証拠金取引(マージン取引)を行う場合は、以下のように担保として利用したいコインを有効化してください。

APIの使い方

実際に動作するコードをお見せしながら、APIの使用方法を説明します。

現物取引のステータス確認

現物取引のステータス確認APIは”Get Status And Leverage”です。
https://bybit-exchange.github.io/docs/v5/spot-margin-uta/status

endPoint = 'https://api.bybit.com'
path     = '/v5/spot-margin-trade/state'
url = endPoint + path

timestamp = int(time.time() * 1000)
recv_window = '5000'
text = str(timestamp) + apiKey + recv_window
sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest()

headers = {
    'X-BAPI-API-KEY': apiKey,
    'X-BAPI-TIMESTAMP': str(timestamp),
    'X-BAPI-SIGN': sign,
    'X-BAPI-RECV-WINDOW': recv_window,
}

response = requests.get(url, headers=headers)
res = response.json()
print(json.dumps(res, indent=4))

変数apiKeyとsecretKeyはご自身のものに置き換えてください。

こんなレスポンスが返ります。
レバレッジの倍数はサイトで設定している値が返ってきて、レバレッジ10倍となっています。

{
    "retCode": 0,
    "retMsg": "OK",
    "result": {
        "spotLeverage": "10",
        "spotMarginMode": "1",
        "effectiveLeverage": "1"
    },
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

現物取引(レバレッジ1倍)

新規注文APIはPlace Order APIです。
レバレッジあり・なしの両方で使います。
https://bybit-exchange.github.io/docs/v5/order/create-order

レバレッジなしの売買のコードを見てみましょう。

買い注文

レバレッジなしの場合は、変数isLeverage=0にします。
BTCUSDTの買い注文をしてみます。

endPoint = 'https://api.bybit.com'
path     = '/v5/order/create'
url = endPoint + path

params = {
    'category': 'spot',
    'symbol': 'BTCUSDT',
    'isLeverage': 0,
    'side': 'Buy',
    'orderType': 'Limit',
    'qty': 0.00005,
    'price': 60000,
}

timestamp = int(time.time() * 1000)
recv_window = '5000'
text = str(timestamp) + apiKey + recv_window + urllib.parse.urlencode(params)
sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest()

headers = {
    'X-BAPI-API-KEY': apiKey,
    'X-BAPI-TIMESTAMP': str(timestamp),
    'X-BAPI-SIGN': sign,
    'X-BAPI-RECV-WINDOW': recv_window,
}

response = requests.post(url, headers=headers, data=params)
res = response.json()
print(json.dumps(res, indent=4))

変数apiKeyとsecretKeyはご自身のものに置き換えてください。

私の統合取引アカウントは、現物取引で使えるUSDTがゼロなので、以下のレスポンスになります。
残高不足エラーです。

{
    "retCode": 170131,
    "retMsg": "Insufficient balance.",
    "result": {},
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

売り注文

BTCUSDTの売り注文をしてみます。
レバレッジなしなので、変数isLeverage=0です。

endPoint = 'https://api.bybit.com'
path     = '/v5/order/create'
url = endPoint + path

params = {
    'category': 'spot',
    'symbol': 'BTCUSDT',
    'isLeverage': 0,
    'side': 'Sell',
    'orderType': 'Limit',
    'qty': 0.00005,
    'price': 72000,
}

timestamp = int(time.time() * 1000)
recv_window = '5000'
text = str(timestamp) + apiKey + recv_window + urllib.parse.urlencode(params)
sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest()

headers = {
    'X-BAPI-API-KEY': apiKey,
    'X-BAPI-TIMESTAMP': str(timestamp),
    'X-BAPI-SIGN': sign,
    'X-BAPI-RECV-WINDOW': recv_window,
}

response = requests.post(url, headers=headers, data=params)
res = response.json()
print(json.dumps(res, indent=4))

レスポンスです。
BTCはいくらか持っているので、売り注文に成功しました。

{
    "retCode": 0,
    "retMsg": "OK",
    "result": {
        "orderId": "nnnnnnnnnnnnnnnnnnn",
        "orderLinkId": "nnnnnnnnnnnnnnnnnnn"
    },
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

orderId, orderLinkId, time の”n”の部分は数字が入ります。

現物取引(証拠金取引、レバレッジ10倍)

買い注文

私の統合取引アカウントのUSDT残高はゼロなので、レバレッジありの買い注文のサンプルコードは省略させていただきます。約定に関わらず、注文するだけで利息が発生するとなっていたので。

売り注文

レバレッジの倍数は現在設定されるものが設定されます。
新規注文APIでレバレッジ倍数を変更することはできません。

レバレッジ倍数はSet Levarage APIで設定できます。
https://bybit-exchange.github.io/docs/v5/spot-margin-uta/set-leverage

レバレッジあり・なしの違いは変数isLeverageで判断されます。
レバレッジありなので、isLeverage=1を設定します。

endPoint = 'https://api.bybit.com'
path     = '/v5/order/create'
url = endPoint + path

params = {
    'category': 'spot',
    'symbol': 'BTCUSDT',
    'isLeverage': 1,
    'side': 'Sell',
    'orderType': 'Limit',
    'qty': 0.00005,
    'price': 72000,
}

timestamp = int(time.time() * 1000)
recv_window = '5000'
text = str(timestamp) + apiKey + recv_window + urllib.parse.urlencode(params)
sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest()

headers = {
    'X-BAPI-API-KEY': apiKey,
    'X-BAPI-TIMESTAMP': str(timestamp),
    'X-BAPI-SIGN': sign,
    'X-BAPI-RECV-WINDOW': recv_window,
}

response = requests.post(url, headers=headers, data=params)
res = response.json()
print(json.dumps(res, indent=4))

レスポンスは成功の場合、レバレッジあり・なしで変わりません。

{
    "retCode": 0,
    "retMsg": "OK",
    "result": {
        "orderId": "nnnnnnnnnnnnnnnnnnn",
        "orderLinkId": "nnnnnnnnnnnnnnnnnnn"
    },
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

取引画面上では、レバレッジあり・なしの違いは以下のように見えます。

下が先に注文したレバレッジなしの注文です。
上が後に注文したレバレッジありの注文です。
商品の表記が変わるだけでした。

借り入れ状況の確認

統合取引アカウントの右上Menuの「借入履歴」を見ると、借入明細と借入履歴を見ることができます。

エラー例

注文サイズが少なすぎるエラー

Bybitの現物取引の最小注文数量は以下で言及されています。

Bybitでは、注文ごとに最小・最大の注文数量及び価額を設定しています。たとえば、BTC/USDTの註文ごとの最小注文値は1USDTより小さくすることはできず、注文ごとの最大注文値は 2,000,000 USDT を超えることはできません。

Bybit 現物取引ルール

BTCUSDTの場合、注文価格 ✕ 注文数量の値が1USDT以上でないと以下のエラーになります。(※レバレッジなしの現物取引の場合)

{
    "retCode": 170136,
    "retMsg": "Order quantity exceeded lower limit.",
    "result": {},
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

コインの残高が不足しているエラー

例えば、USDTの資産がゼロの場合に、BTCUSDTのペアで買い注文すると以下のエラーになります。(※レバレッジなしの現物取引の場合)

{
    "retCode": 170131,
    "retMsg": "Insufficient balance.",
    "result": {},
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

コインの担保有効化ができていないエラー

取引で使うコインを担保として有効にできていない場合は、このエラーになります。

{
    "retCode": 170037,
    "retMsg": "BTC has not opened collateral settings.",
    "result": {},
    "retExtInfo": {},
    "time": nnnnnnnnnnnnn
}

統合取引アカウントの資産残高の画面で以下をお確かめください。