導入
CCXTを使えば、大体のAPIはフォローされているのであまり困ることはない。
ただ、どうしてもBinanceのAPI仕様書に記載されているものをそのまま使いたい時がある。
仕様書では一部SHA256の認証を使えと書いてあるけど、具体的なコードが記載されていなくて、またグーグル先生に聞いても参考となるコードがあまり出てきませんでした。(Binance提供するモジュールのソースコードは存在したので参考にした)
そのため、誰かの参考になればと思い記載します。
参考プログラム(ステーキングのポジションを取得する)
main.py
import math
import time
from typing import Dict, Optional, List, Tuple
from binance.client import Client
from operator import itemgetter
import requests
import hmac
import hashlib
#色々パラメータ設定
api_key = "バイナンスで発行するAPIKEY"
api_secert = "バイナンスで発行する秘密鍵"
binance_api = "https://api.binance.com"
timestamp = time.time() * 1000
header = {"X-MBX-APIKEY" : api_key}
#サーバータイムを取りに行くまで先にやってしまう。特に先にやる意味はない。
#実際はここもAPIでとれるけど今回はパス
Client = Client(api_key,api_secert)
res = Client.get_server_time()
timestamp_offset = res['serverTime'] - int(timestamp)
ex_timestamp = timestamp + timestamp_offset
########################sha256のハッシュ生成(関数)############################
def _generate_signature(data: Dict) -> str:
assert api_secert, "API Secret required for private endpoints"
ordered_data = _order_params(data)
query_string = '&'.join([f"{d[0]}={d[1]}" for d in ordered_data])
m = hmac.new(api_secert.encode('utf-8'), query_string.encode('utf-8'), hashlib.sha256)
return m.hexdigest()
def _order_params(data: Dict) -> List[Tuple[str, str]]:
data = dict(filter(lambda el: el[1] is not None, data.items()))
has_signature = False
params = []
for key, value in data.items():
if key == 'signature':
has_signature = True
else:
params.append((key, str(value)))
# sort parameters by key
params.sort(key=itemgetter(0))
if has_signature:
params.append(('signature', data['signature']))
return params
##################ステーキングのポジションをゲットする(関数)######################
def Staking_get():
rtn = {}
#sha256で必要なパラメータを設定
q = {"product" : "STAKING" ,"recvWindow" : 5000 ,"timestamp" : int(ex_timestamp) }
#sha256のハッシュ生成
qq = _generate_signature(q)
#ハッシュを追加
q["signature"] = qq
#APIを投げる!
r = requests.get(binance_api+"/sapi/v1/staking/position",params = q ,headers = header )
print("Stakingのレスポンス :" , r)#200が返ってくるとOK
staking_asset = r.json()#返されたJSONを取り出す。
#結果を{"通貨:保有量"}という形にしてrtnに入れていく、重複がある場合は合計を求める。
for i in staking_asset:
if i["asset"] in rtn:
exit_postion = float(rtn[i["asset"]])
new_postion = float(i["amount"]) + exit_postion
rtn[i["asset"]] = new_postion
else:
rtn[i["asset"]] = float(i["amount"])
#DeFi Stakingのポジションをゲットする用
q2 = {"product" : "L_DEFI" ,"recvWindow" : 5000 ,"timestamp" : int(ex_timestamp) }
qq2 = _generate_signature(q2)
q2["signature"] = qq2
r2 = requests.get(binance_api+"/sapi/v1/staking/position",params = q2 ,headers = header )
asset2 = r2.json()
#DeFiの場合は基本的には重複はしないはずだから重複を考慮しない
for ii in asset2:
rtn[ii["asset"]] = float(ii["amount"])
print(rtn)
return (rtn)#戻り値必要な時
######################### Main #########################
Staking_get()
後はパラメータ変えると好きなように出来るはず!
参考
・BinanceのAPI仕様書
https://binance-docs.github.io/apidocs/#change-log