バイナンス ジャパンのSimple EarnのAPIを使ってみる

Binanceでは仮想通貨の売買をAPIでできるように、Simple Earnへの参加もAPIでできます。

今後、Simple Earnでbotを組んでみよう思うので、まずは何ができるか調べてみます。

Simple Earnの前提知識

Binance Simple Earnとは

Simple Earnとは、自分が持っている暗号資産をバイナンスに貸して、報酬を得る仕組みです。

Simple Earnできる暗号資産は20種類以上あります。(※2024年9月時点)

Binance Japanのサイトにも書かれているので、ご覧ください。

Simple Earnは、デジタル資産をフレキシブル商品または定期商品に入金することで、毎日の報酬を獲得することができます。

フレキシブル商品は、いつでも登録や償還ができるため、毎日の報酬を獲得しながら、資産に対する柔軟性と流動性を保持することができます。

定期商品は、お客様の資産をあらかじめ定められた償還日まで一定期間コミットすることでより高い報酬を提供します。償還日の前であればいつでも残高全額を償還することを選択できますが、その時点までに獲得した、または受け取った報酬は放棄することになります。

出典:Binance Simple Earnの紹介

Simple EarnのAPI仕様書

BinanceのAPIドキュメントの「Simple Earn Endpoints」のところを見ましょう。

Simple EarnのAPIを使えば、一例ですが以下はできます。

  • Simple Earnへの参加・償還(Subscribe・Redeem)
  • 現在のポジションの取得
  • Simple Earnの商品内容の取得

あと、記事のタイトルはバイナンス ジャパンとなっていますが、APIはバイナンス グローバルでも共通です。

Binance JapanのSimple Earnは定期商品のみ

APIドキュメントを見ると、API名の中に「Flexible」と「Locked」とやたら入っています。
これは、Simple Earnの商品の種類を指していて「フレキシブル商品」と「定期商品」に対するAPIとなります。

私のアカウントはBinance Japanなので、この記事ではLockedのAPI(定期商品用API)しか使いません。

分かりづらいと思うので、実際にログインして見てみましょう。

バイナンス ジャパンのユーザーなら上部Menuの「Earn」をクリック。

すると、「暗号資産レンディング(定期」となっていると思います。説明が「(定期)」となっており、「定期商品」しか扱っていないことを意味してます。

グローバルサイトのSimple Earnを見てみると、「フレキシブル商品」、「定期商品」、「ETH Staking」を扱っていることがわかります。

Simple EarnのAPIを使う

私の口座のSimple Earn状況

APIの使い方の説明の前に、私の口座のSimple Earnの状況を説明します。

以下の記事で、ソラナの14日間Simple Earnを1SOLほどサブスクライブしています。
そのため、私の口座では2024年9月20日より14日間の1SOLのEarnが開始されています。
そのことを前提にAPIを使ってみますので、ご承知おきください。

バイナンスジャパンのSimple Earnにソラナを14日間預けてみた

現在の私のSimple Earnの保有資産は以下と表示されています。
現在のSOLのレートは21,000円くらいです。1SOLサブスクライブ中なので21,000円分のポジションとなっています。
表示はBTC換算なので、BTCのレートは9,100,000円くらいなので、9,100,000円 x 0.0023472BTC = 21,359円です。

前準備

PythonでAPIコールするので、以下のモジュールをimportしてください。

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

サンプルコード内に出てくる変数の apiKeysecretKey はご自身のものに置き換えてください。

Simple Earnの保有資産の取得

保有資産の取得は Simple Account API です。
https://binance-docs.github.io/apidocs/spot/en/#simple-account-user_data

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/account'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
}

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))

レスポンスです。
保有資産はBTC換算値とUSDT換算値が返ってきます。
0.002349BTC = 約21,000円 となっています。
定期商品のSimple Earnをサブスクしているので、totalLockedInBTCにも値が入っています。

{
    "totalAmountInBTC": "0.002349",
    "totalAmountInUSDT": "148.3",
    "totalFlexibleAmountInBTC": "0",
    "totalFlexibleAmountInUSDT": "0",
    "totalLockedInBTC": "0.002349",
    "totalLockedInUSDT": "148.3"
}

Simple Earnの定期商品リストの取得

Simple Earnにどんな定期商品があるかは Locked Product List API で取得できます。
https://binance-docs.github.io/apidocs/spot/en/#get-simple-earn-locked-product-list-user_data

上で説明したようにフレキシブル商品(Flexible)はバイナンス ジャパンでは扱っていないので、定期商品(Locked)のAPIのみ説明します。

ソラナに限定して、商品リストを取得してみます。

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/list'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
    'asset': 'SOL',
}

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))

商品が5つほどあることがわかりました。

{
    "total": 5,
    "rows": [
        {
            "projectId": "Sol*120",
            "detail": {
                "asset": "SOL",
                "rewardAsset": "SOL",
                "duration": 120,
                "renewable": true,
                "isSoldOut": false,
                "apr": "0.056",
                "status": "PURCHASING",
                "subscriptionStartTime": 1658910000000
            },
            "quota": {
                "totalPersonalQuota": "80",
                "minimum": "0.01"
            }
        },
        {
            "projectId": "Sol*90",
            "detail": {
                "asset": "SOL",
                "rewardAsset": "SOL",
                "duration": 90,
                "renewable": true,
                "isSoldOut": false,
                "apr": "0.045",
                "status": "PURCHASING",
                "subscriptionStartTime": 1614254400000
            },
            "quota": {
                "totalPersonalQuota": "200000",
                "minimum": "0.01"
            }
        },
        {
            "projectId": "Sol*60",
            "detail": {
                "asset": "SOL",
                "rewardAsset": "SOL",
                "duration": 60,
                "renewable": true,
                "isSoldOut": false,
                "apr": "0.039",
                "status": "PURCHASING",
                "subscriptionStartTime": 1614254400000
            },
            "quota": {
                "totalPersonalQuota": "200000",
                "minimum": "0.01"
            }
        },
        {
            "projectId": "Sol*30",
            "detail": {
                "asset": "SOL",
                "rewardAsset": "SOL",
                "duration": 30,
                "renewable": true,
                "isSoldOut": false,
                "apr": "0.0299",
                "status": "PURCHASING",
                "subscriptionStartTime": 1614254400000
            },
            "quota": {
                "totalPersonalQuota": "400000",
                "minimum": "0.01"
            }
        },
        {
            "projectId": "Sol*14",
            "detail": {
                "asset": "SOL",
                "rewardAsset": "SOL",
                "duration": 14,
                "renewable": true,
                "isSoldOut": false,
                "apr": "0.0159",
                "status": "PURCHASING",
                "subscriptionStartTime": 1699531200000
            },
            "quota": {
                "totalPersonalQuota": "500000",
                "minimum": "0.01"
            }
        }
    ]
}

定期商品のポジション取得

現在、定期商品をどのくらい持っているかは Locked Product Position API で確認します。
https://binance-docs.github.io/apidocs/spot/en/#get-locked-product-position-user_data

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/position'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
}

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))

1SOL分の定期商品を持っていることがわかります。
※一部の数字を”n”に置き換えています。

{
    "total": 1,
    "rows": [
        {
            "positionId": nnnnnnnnn,
            "projectId": "Sol*14",
            "asset": "SOL",
            "amount": "1",
            "purchaseTime": nnnnnnnnnnnnn,
            "duration": 14,
            "accrualDays": 2,
            "rewardAsset": "SOL",
            "rewardAmt": "0.00008712",
            "nextPay": "0.00004356",
            "nextPayDate": 1726963200000,
            "payPeriod": 1,
            "redeemAmountEarly": "0.99991288",
            "rewardsEndDate": 1727913600000,
            "deliverDate": 1727949600000,
            "redeemPeriod": 0,
            "canRedeemEarly": true,
            "autoSubscribe": true,
            "type": "NORMAL",
            "status": "HOLDING",
            "canReStake": false,
            "apy": "0.0159"
        }
    ]
}

定期商品のSubscription履歴

貸付のサブスク履歴は Locked Subscription Record API で確認できます。
https://binance-docs.github.io/apidocs/spot/en/#get-locked-subscription-record-user_data

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/history/subscriptionRecord'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
}

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))

すでに1回サブスクしているので、その情報が取得できました。
※一部の数字を”n”に置き換えています。

{
    "total": 1,
    "rows": [
        {
            "positionId": nnnnnnnnn,
            "purchaseId": nnnnnnnnn,
            "time": nnnnnnnnnnnnn,
            "asset": "SOL",
            "amount": "1",
            "lockPeriod": 14,
            "type": "NORMAL",
            "status": "SUCCESS",
            "sourceAccount": "SPOT",
            "projectId": "Sol*14"
        }
    ]
}

定期商品のRedemption履歴

定期商品の償還履歴は Locked Redemption Record API で取得できます。
https://binance-docs.github.io/apidocs/spot/en/#get-locked-redemption-record-user_data

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/history/redemptionRecord'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
}

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))

まだRedeemした履歴はありません。

{
    "total": 0,
    "rows": []
}

定期商品の報酬の履歴

定期商品の報酬履歴は Locked Rewards History API で取得します。
https://binance-docs.github.io/apidocs/spot/en/#get-locked-rewards-history-user_data

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/history/rewardsRecord'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
}

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))

UNIX時間を変換すると、これまでに9/20、9/21に報酬が出ていることがわかります。
報酬のamountは 1SOL x APR0.0156 / 356日 くらいで日利となっていそうです。
報酬の単位はassetにあるようにSOLみたいです。

現時点の報酬は以下のようになっていましたが、償還期限の14日間の前に解約するとたぶん報酬は無くなります。

{
    "total": 2,
    "rows": [
        {
            "positionId": 282658996,
            "time": 1726877928000,
            "asset": "SOL",
            "lockPeriod": 14,
            "amount": "0.00004356"
        },
        {
            "positionId": 282658996,
            "time": 1726791529000,
            "asset": "SOL",
            "lockPeriod": 14,
            "amount": "0.00004356"
        }
    ]
}

定期商品の貸付開始(Subscribe)

商品を決めたら貸付の開始を Subscribe Locked Product API で行います。
https://binance-docs.github.io/apidocs/spot/en/#subscribe-locked-product-trade

イーサリアムの60日間のSimple Earnをサブスクしてみたいと思います。
ETHは現物でいくらか持っているので、新規購入せずにそれを割り当てます。

注文内容は以下としました。

  • 定期商品: ETH 60日間
  • 数量:0.01 (最小注文数量は0.002)
  • 貸付の自動更新:ON (変数autoSubscribeです。デフォルトはTrue。)
  • 貸付する暗号資産の内容:現物(SPOT・FUND・ALLが選択できる。デフォルトはSPOT。)
endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/subscribe'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
    'projectId': 'Eth*60',
    'amount': 0.01,
    'autoSubscribe': True,
    'sourceAccount': 'SPOT',
}

text = urllib.parse.urlencode(parameters)
sign = hmac.new(secretKey.encode('utf-8'), text.encode('utf-8'), hashlib.sha256).hexdigest()
parameters.update({'signature': sign})
print(json.dumps(parameters, indent=4))
#sys.exit()

headers = {
    "X-MBX-APIKEY": apiKey,
}

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

レスポンスです。
Subscribeできました。

{
    "purchaseId": nnnnnnnnn,
    "positionId": nnnnnnnnn,
    "success": true,
    "amount": "0.01"
}

定期商品の貸付終了(Redeem)

貸付を停止するときは Redeem Locked Product API を使います。
https://binance-docs.github.io/apidocs/spot/en/#redeem-locked-product-trade

上でサブスクしたEth*60はまだ運用開始前なので、Redeemでキャンセルしてみます。

endPoint = 'https://api.binance.com'
path     = '/sapi/v1/simple-earn/locked/redeem'
url = endPoint + path

timestamp = int(time.time() * 1000)
parameters = {
    'timestamp': timestamp,
    'positionId': position_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.post(url, headers=headers, params=parameters)
res = response.json()
print(json.dumps(res, indent=4))

変数position_idには、Subscription APIの戻り値のpositionIdを文字列で入れています。

キャンセルできました。

{
    "redeemId": nnnnnnnnn,
    "success": true
}

Simple EarnのAPIの使い方は以上となります。

Binanceは売買以外のAPIも充実しているのでいいですね。
国内の取引所は貸暗号資産のためのAPIは提供していないので、APIの拡充をお願いしたいです。

バイナンス ジャパンには「お友達紹介プログラム」があります。

以下のURLよりEメールアドレスもしくは電話番号で登録を行ってください。アカウント設定の画面で必ず紹介コードを入力してください。

・URL: 招待URL

・紹介コード: 116836794

・達成条件:初めて口座を開設されるお客さまで、紹介者から受け取った紹介コードを被紹介者が入力し、本人確認手続きを完了させ、口座開設を完了してください。

・特典:被紹介者の口座開設が完了した後、紹介者と被紹介者の両方のBinance Japan口座にそれぞれ1800円相当のBNBが30営業日以内に付与されます。