初速1PV

プログラミングにまつわることの記録

BitMEXでポジションを取得してみる。

BitMEXのAPIから現在のポジションを取得してみました。 自動で損切りしたりアラート通知ができたら便利だろうと思ったので、その第一歩としてポジションの取得をしてみました。

認証

BitMEXのAPIで作成したAPIとそのシグネチャをリクエストのヘッダに載せると認証したことになり、指定したAPIを実行できる。 以下のソースコードgenerate_signaturedo_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

環境変数TZUTCを設定してタイムゾーンを変更する。 BitMEXのサーバのタイムゾーンをはUTCになっているっぽいのでAPIでデータを取得する期間(startTime, endTime)もUTCにしないといけない。 datetime.todayなどの返り値は自身のタイムゾーンに依存するため、環境変数TZを変更して期待通りの日付を出せるようする。

os.environ['TZ'] = 'UTC'
time.tzset()

ポジションの取得

XBTUSDに対するポジションを取得してみる。 実行結果は現在のポジションに関する情報で参入価格や注文したサイズなどの情報をが入っている。 関連したAPIやリクエストのパラメーター等の詳細はBitMEX API Explorerを読むとよい。

www.bitmex.com

最初のスクリプトが読み込まれた状態で以下を実行するとポジションを取得することができる。

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}]