BitMEXでポジションを取得してみる。
BitMEXのAPIから現在のポジションを取得してみました。 自動で損切りしたりアラート通知ができたら便利だろうと思ったので、その第一歩としてポジションの取得をしてみました。
認証
BitMEXのAPIで作成したAPIとそのシグネチャをリクエストのヘッダに載せると認証したことになり、指定したAPIを実行できる。
以下のソースコードはgenerate_signature
とdo_get
の2つの関数を定義している。
generate_signature
は公式サイトAPIの使用例にあったものを流用したものです、do_get
は指定したAPIのエンドポイントにgenerate_signature
で認証を行いつつGETリクエストのを送る関数になる。
import time import os import hashlib import json import hmac from urllib.parse import urlparse from datetime import datetime, timedelta, timezone import requests os.environ['TZ'] = 'UTC' time.tzset() def generate_signature(secret, verb, url, expires, data): parsedURL = urlparse(url) path = parsedURL.path if parsedURL.query: path = path + '?' + parsedURL.query if isinstance(data, (bytes, bytearray)): data = data.decode('utf8') print("Computing HMAC: %s" % verb + path + str(expires) + data) message = verb + path + str(expires) + data signature = hmac.new(bytes(secret, 'utf8'), bytes(message, 'utf8'), digestmod=hashlib.sha256).hexdigest() return signature def do_get(endpoint): base = 'https://www.bitmex.com' expires = int(round(time.time()) + 5) with open('./secret.json', 'r') as fp: secret = json.load(fp) api_key = secret['apiKey'] sig = generate_signature(secret['secret'], 'GET', endpoint, expires, '') res = requests.get(f'{base}{endpoint}', headers={ 'api-expires': str(expires), 'api-key': api_key, 'api-signature': sig, }) return json.loads(res.text)
ハマりポイント
少しハマってところを紹介する。
API Request
認証方法をいまいち理解していなかった。
api-expires
には整数値、api-key
は生成したapiKey、api-signature
には公式サイトからに書いてあるgenerate_signature
の参考実装で生成した署名をヘッダに乗せる必要がある。
REST APIではたぶん、こういった認証情報をヘッダに乗せるのはよくあることだと思うが失念してた。
requests.get(f'{base}{endpoint}', headers={ 'api-expires': str(expires), 'api-key': api_key, 'api-signature': sig, })
TImezone
環境変数TZ
にUTC
を設定してタイムゾーンを変更する。
BitMEXのサーバのタイムゾーンをはUTCになっているっぽいのでAPIでデータを取得する期間(startTime
, endTime
)もUTCにしないといけない。
datetime.todayなどの返り値は自身のタイムゾーンに依存するため、環境変数TZ
を変更して期待通りの日付を出せるようする。
os.environ['TZ'] = 'UTC' time.tzset()
ポジションの取得
XBTUSD
に対するポジションを取得してみる。
実行結果は現在のポジションに関する情報で参入価格や注文したサイズなどの情報をが入っている。
関連したAPIやリクエストのパラメーター等の詳細はBitMEX API Explorerを読むとよい。
最初のスクリプトが読み込まれた状態で以下を実行するとポジションを取得することができる。
do_get('/api/v1/position?symbol=XBTUSD')
実行結果
[{'account': 114514, 'avgCostPrice': 11149.5, 'avgEntryPrice': 11149.5, 'bankruptPrice': 100000000, 'breakEvenPrice': 11152, 'commission': 0.00075, 'crossMargin': True, 'currency': 'XBt', 'currentComm': 2235, 'currentCost': 91583, 'currentQty': -10, 'currentTimestamp': '2019-07-14T09:27:11.085Z', 'deleveragePercentile': 1, 'execBuyCost': 0, 'execBuyQty': 0, 'execComm': 0, 'execCost': 0, 'execQty': 0, 'execSellCost': 0, 'execSellQty': 0, 'foreignNotional': 10, 'grossExecCost': 0, 'grossOpenCost': 0, 'grossOpenPremium': 0, 'homeNotional': -0.0009022, 'indicativeTax': 0, 'indicativeTaxRate': 0, 'initMargin': 0, 'initMarginReq': 0.01, 'isOpen': True, 'lastPrice': 11084.37, 'lastValue': 90220, 'leverage': 100, 'liquidationPrice': 100000000, 'longBankrupt': 0, 'maintMargin': 1495, 'maintMarginReq': 0.005, 'marginCallPrice': 100000000, 'markPrice': 11084.37, 'markValue': 90220, 'openOrderBuyCost': -91840, 'openOrderBuyPremium': 0, 'openOrderBuyQty': 10, 'openOrderSellCost': 0, 'openOrderSellPremium': 0, 'openOrderSellQty': 0, 'openingComm': 2235, 'openingCost': 91583, 'openingQty': -10, 'openingTimestamp': '2019-07-14T09:00:00.000Z', 'posAllowance': 0, 'posComm': 68, 'posCost': 89690, 'posCost2': 89690, 'posCross': 0, 'posInit': 897, 'posLoss': 0, 'posMaint': 517, 'posMargin': 965, 'posState': '', 'prevClosePrice': 11089.33, 'prevRealisedPnl': -622, 'prevUnrealisedPnl': 0, 'quoteCurrency': 'USD', 'realisedCost': 1893, 'realisedGrossPnl': -1893, 'realisedPnl': -4128, 'realisedTax': 0, 'rebalancedPnl': 4150, 'riskLimit': 20000000000, 'riskValue': 90220, 'sessionMargin': 0, 'shortBankrupt': 0, 'simpleCost': None, 'simplePnl': None, 'simplePnlPcnt': None, 'simpleQty': None, 'simpleValue': None, 'symbol': 'XBTUSD', 'targetExcessMargin': 0, 'taxBase': 0, 'taxableMargin': 0, 'timestamp': '2019-07-14T09:27:11.085Z', 'underlying': 'XBT', 'unrealisedCost': 89690, 'unrealisedGrossPnl': 530, 'unrealisedPnl': 530, 'unrealisedPnlPcnt': 0.0059, 'unrealisedRoePcnt': 0.5909, 'unrealisedTax': 0, 'varMargin': 0}]