BitMEXの自動売買BOTコマンド集
CCXT(CryptoCurrency eXchange Trading Library)を用いてBitMEXで稼働する自動売買BOTを作る際に使用するコマンド集をご紹介します。
やりたいことに対するコマンドがわかれば、あとはそれを組み合わせることで自動売買BOTを作ることができます。
コマンドを見ていく前に、一つコマンドを紹介します。
「pprint」というコマンドです。
これは、辞書型の変数をきれいに整形して表示してくれるコマンドです。
例えば、単純にBalanceの情報を取得したものをprintすると、下のように1行にすべて表示され、コマンドプロンプト内で折り返してしまい、非常に見にくいですが、
>>> print(Balance)
[{'account': 51246, 'symbol': 'XBTUSD', 'currency': 'XBt', 'underlying': 'XBT', 'quoteCurrency': 'USD', 'commission': 0.00075, 'initMarginReq': 0.04, 'maintMarginReq': 0.005, 'riskLimit': 20000000000, 'leverage': 25, 'crossMargin': False, 'deleveragePercentile': 1, 'rebalancedPnl': 10997, 'prevRealisedPnl': -10997, 'prevUnrealisedPnl': 0, 'prevClosePrice': 9729.68, 'openingTimestamp': '2018-05-04T12:00:00.000Z', 'openingQty': 0, 'openingCost': 0, 'openingComm': 0, 'openOrderBuyQty': 0, 'openOrderBuyCost': 0, 'openOrderBuyPremium': 0, 'openOrderSellQty': 0, 'openOrderSellCost': 0, 'openOrderSellPremium': 0, 'execBuyQty': 965, 'execBuyCost': 9906690, 'execSellQty': 1915, 'execSellCost': 19710630, 'execQty': -950, 'execCost': 9803940, 'execComm': 22212, 'currentTimestamp': '2018-05-04T12:59:41.046Z', 'currentQty': -950, 'currentCost': 9803940, 'currentComm': 22212, 'realisedCost': -3860, 'unrealisedCost': 9807800, 'grossOpenCost': 0, 'grossOpenPremium': 0, 'grossExecCost': 9778120, 'isOpen': True, 'markPrice': 9698.49, 'markValue': 9795450, 'riskValue': 9795450, 'homeNotional': -0.0979545, 'foreignNotional': 950, 'posState': '', 'posCost': 9807800, 'posCost2': 9807800, 'posCross': 0, 'posInit': 392312, 'posComm': 7651, 'posLoss': 0, 'posMargin': 399963, 'posMaint': 56690, 'posAllowance': 0, 'taxableMargin': 0, 'initMargin': 0, 'maintMargin': 387613, 'sessionMargin': 0, 'targetExcessMargin': 0, 'varMargin': 0, 'realisedGrossPnl': 3860, 'realisedTax': 0, 'realisedPnl': -18352, 'unrealisedGrossPnl': -12350, 'longBankrupt': 0, 'shortBankrupt': 0, 'taxBase': 0, 'indicativeTaxRate': 0, 'indicativeTax': 0, 'unrealisedTax': 0, 'unrealisedPnl': -12350, 'unrealisedPnlPcnt': -0.0013, 'unrealisedRoePcnt': -0.0315, 'simpleQty': -0.0981, 'simpleCost': -950, 'simpleValue': -951, 'simplePnl': -1, 'simplePnlPcnt': -0.0011, 'avgCostPrice': 9686, 'avgEntryPrice': 9686, 'breakEvenPrice': 9678.5, 'marginCallPrice': 10037, 'liquidationPrice': 10037, 'bankruptPrice': 10088.5, 'timestamp': '2018-05-04T12:59:41.046Z', 'lastPrice': 9698.49, 'lastValue': 9795450}]
>>>
pprintであれば、索引と値を1行ごとに表示してくれるため、非常にみやすくなります。
>>> pprint(Balance)
[{'account': 51246,
'avgCostPrice': 9686,
'avgEntryPrice': 9686,
'bankruptPrice': 10088.5,
'breakEvenPrice': 9678.5,
'commission': 0.00075,
'crossMargin': False,
'currency': 'XBt',
'currentComm': 22212,
'currentCost': 9803940,
'currentQty': -950,
'currentTimestamp': '2018-05-04T12:59:41.046Z',
'deleveragePercentile': 1,
'execBuyCost': 9906690,
'execBuyQty': 965,
'execComm': 22212,
'execCost': 9803940,
'execQty': -950,
'execSellCost': 19710630,
'execSellQty': 1915,
'foreignNotional': 950,
'grossExecCost': 9778120,
'grossOpenCost': 0,
'grossOpenPremium': 0,
'homeNotional': -0.0979545,
'indicativeTax': 0,
'indicativeTaxRate': 0,
'initMargin': 0,
'initMarginReq': 0.04,
'isOpen': True,
'lastPrice': 9698.49,
'lastValue': 9795450,
'leverage': 25,
'liquidationPrice': 10037,
'longBankrupt': 0,
'maintMargin': 387613,
'maintMarginReq': 0.005,
'marginCallPrice': 10037,
'markPrice': 9698.49,
'markValue': 9795450,
'openOrderBuyCost': 0,
'openOrderBuyPremium': 0,
'openOrderBuyQty': 0,
'openOrderSellCost': 0,
'openOrderSellPremium': 0,
'openOrderSellQty': 0,
'openingComm': 0,
'openingCost': 0,
'openingQty': 0,
'openingTimestamp': '2018-05-04T12:00:00.000Z',
'posAllowance': 0,
'posComm': 7651,
'posCost': 9807800,
'posCost2': 9807800,
'posCross': 0,
'posInit': 392312,
'posLoss': 0,
'posMaint': 56690,
'posMargin': 399963,
'posState': '',
'prevClosePrice': 9729.68,
'prevRealisedPnl': -10997,
'prevUnrealisedPnl': 0,
'quoteCurrency': 'USD',
'realisedCost': -3860,
'realisedGrossPnl': 3860,
'realisedPnl': -18352,
'realisedTax': 0,
'rebalancedPnl': 10997,
'riskLimit': 20000000000,
'riskValue': 9795450,
'sessionMargin': 0,
'shortBankrupt': 0,
'simpleCost': -950,
'simplePnl': -1,
'simplePnlPcnt': -0.0011,
'simpleQty': -0.0981,
'simpleValue': -951,
'symbol': 'XBTUSD',
'targetExcessMargin': 0,
'taxBase': 0,
'taxableMargin': 0,
'timestamp': '2018-05-04T12:59:41.046Z',
'underlying': 'XBT',
'unrealisedCost': 9807800,
'unrealisedGrossPnl': -12350,
'unrealisedPnl': -12350,
'unrealisedPnlPcnt': -0.0013,
'unrealisedRoePcnt': -0.0315,
'unrealisedTax': 0,
'varMargin': 0}]
>>>
本書では、辞書型の中身を表示する際に、このpprintを使用していますので、ご自身で確認する際はぜひ同じようにpprintを使用してください。
pprintは以下のコマンドでインストールし、
pip install pprint
以下のようにimportすれば使用できます。
from pprint import pprint
【本書で取り扱うコマンド】
・BTCの現在値の取得
・資産情報の取得
・建玉情報の取得
・注文情報の取得
・過去の足データの取得
・注文(成行)
・注文(指値)
・注文(逆指値)
・トレーリングストップ
・APIコマンドの調べ方
各コマンドについて、主要な項目値や引数の意味を説明しています。
また、情報取得系のコマンドについては実際の返り値を載せ、主要な返り値の意味の説明を載せています。
では、一つずつコマンドを見ていきましょう。
・BTCの現在値の取得
>>> btc = bitmex.fetch_ticker('BTC/USD')
>>> pprint(btc)
{'ask': 9665.5,
'askVolume': None,
'average': 9703.5,
'baseVolume': 195466.67559770995,
'bid': 9665.0,
'bidVolume': None,
'change': -76.0,
'close': 9665.5,
'datetime': '2018-05-04T14:07:58.879Z',
'high': 9778.0,
'info': {'close': 9665.5,
'foreignNotional': 1886976669,
'high': 9778,
'homeNotional': 195466.67559770995,
'lastSize': 9000,
'low': 9351,
'open': 9741.5,
'symbol': 'XBTUSD',
'timestamp': '2018-05-05T00:00:00.000Z',
'trades': 286310,
'turnover': 19546667559771,
'volume': 1886976669,
'vwap': 9654.3734},
'last': 9665.5,
'low': 9351.0,
'open': 9741.5,
'percentage': -0.7801673253605708,
'previousClose': None,
'quoteVolume': 1886976669.0,
'symbol': 'BTC/USD',
'timestamp': 1525442877879,
'vwap': 9654.3734}
「直近の価格」という意味であれば、この「close」を使用するのがよいでしょう。btc['close']で取得できます。
・総資金、未実現損益などの資産情報
>>> Balance = bitmex.fetch_balance()
>>> pprint(Balance)
{'BTC': {'free': 0.0057353000000000005,
'total': 0.00992493,
'used': 0.00418963},
'free': {'BTC': 0.0057353000000000005},
'info': [{'account': 51246,
'action': '',
'amount': 991845,
'availableMargin': 573530,
'commission': None,
'confirmedDebit': 0,
'currency': 'XBt',
'excessMargin': 573530,
'excessMarginPcnt': 0.0584,
'grossComm': 22212,
'grossExecCost': 0,
'grossLastValue': 9826800,
'grossMarkValue': 9826800,
'grossOpenCost': 0,
'grossOpenPremium': 0,
'indicativeTax': 0,
'initMargin': 0,
'maintMargin': 418963,
'marginBalance': 992493,
'marginBalancePcnt': 0.101,
'marginLeverage': 9.901127766140416,
'marginUsedPcnt': 0.4221,
'pendingCredit': 0,
'pendingDebit': 0,
'prevRealisedPnl': -10997,
'prevState': '',
'prevUnrealisedPnl': 0,
'realisedPnl': -18352,
'riskLimit': 1000000000000,
'riskValue': 9826800,
'sessionMargin': 0,
'state': '',
'syntheticMargin': 0,
'targetExcessMargin': 0,
'taxableMargin': 0,
'timestamp': '2018-05-04T14:16:26.443Z',
'unrealisedPnl': 19000,
'unrealisedProfit': 0,
'varMargin': 0,
'walletBalance': 973493,
'withdrawableMargin': 573530}],
'total': {'BTC': 0.00992493},
'used': {'BTC': 0.00418963}}
主な項目値は以下の通り。
avgCostPrice:平均取得単価
realisedPnl:実現損益(satoshi)
unrealisedPnl:未実現損益(satoshi)
total:総資産(未実現損益込み)
free:余力(btc)
・建玉
>>> Position = bitmex.private_get_position({'filter':json.dumps({"symbol": Symbol})})
>>> pprint(Position)
[{'account': 51246,
'avgCostPrice': 9686,
'avgEntryPrice': 9686,
'bankruptPrice': 10088.5,
'breakEvenPrice': 9678.5,
'commission': 0.00075,
'crossMargin': False,
'currency': 'XBt',
'currentComm': 22212,
'currentCost': 9803940,
'currentQty': -950,
'currentTimestamp': '2018-05-04T14:21:21.108Z',
'deleveragePercentile': 1,
'execBuyCost': 0,
'execBuyQty': 0,
'execComm': 0,
'execCost': 0,
'execQty': 0,
'execSellCost': 0,
'execSellQty': 0,
'foreignNotional': 950,
'grossExecCost': 0,
'grossOpenCost': 0,
'grossOpenPremium': 0,
'homeNotional': -0.098325,
'indicativeTax': 0,
'indicativeTaxRate': 0,
'initMargin': 0,
'initMarginReq': 0.04,
'isOpen': True,
'lastPrice': 9661.67,
'lastValue': 9832500,
'leverage': 25,
'liquidationPrice': 10037,
'longBankrupt': 0,
'maintMargin': 424663,
'maintMarginReq': 0.005,
'marginCallPrice': 10037,
'markPrice': 9661.67,
'markValue': 9832500,
'openOrderBuyCost': 0,
'openOrderBuyPremium': 0,
'openOrderBuyQty': 0,
'openOrderSellCost': 0,
'openOrderSellPremium': 0,
'openOrderSellQty': 0,
'openingComm': 22212,
'openingCost': 9803940,
'openingQty': -950,
'openingTimestamp': '2018-05-04T14:00:00.000Z',
'posAllowance': 0,
'posComm': 7651,
'posCost': 9807800,
'posCost2': 9807800,
'posCross': 0,
'posInit': 392312,
'posLoss': 0,
'posMaint': 56690,
'posMargin': 399963,
'posState': '',
'prevClosePrice': 9653.95,
'prevRealisedPnl': -10997,
'prevUnrealisedPnl': 0,
'quoteCurrency': 'USD',
'realisedCost': -3860,
'realisedGrossPnl': 3860,
'realisedPnl': -18352,
'realisedTax': 0,
'rebalancedPnl': 10997,
'riskLimit': 20000000000,
'riskValue': 9832500,
'sessionMargin': 0,
'shortBankrupt': 0,
'simpleCost': -950,
'simplePnl': 2.5,
'simplePnlPcnt': 0.0026,
'simpleQty': -0.0981,
'simpleValue': -947.5,
'symbol': 'XBTUSD',
'targetExcessMargin': 0,
'taxBase': 28560,
'taxableMargin': 0,
'timestamp': '2018-05-04T14:21:21.108Z',
'underlying': 'XBT',
'unrealisedCost': 9807800,
'unrealisedGrossPnl': 24700,
'unrealisedPnl': 24700,
'unrealisedPnlPcnt': 0.0025,
'unrealisedRoePcnt': 0.063,
'unrealisedTax': 0,
'varMargin': 0}]
>>>
色々と情報がでていますが、現在建てている玉の合計は
・currentQty:建玉の合計(プラスはロング、マイナスはショート)
・注文
>>> Orders = bitmex.fetch_open_orders()
>>> pprint(Orders)
[{'amount': 1.0,
'cost': 0.0,
'datetime': '2018-05-04T14:24:20.648Z',
'fee': None,
'filled': 0.0,
'id': 'f906632a-3272-aa1b-8a5d-a3107d167692',
'info': {'account': 51246,
'avgPx': None,
'clOrdID': '',
'clOrdLinkID': '',
'contingencyType': '',
'cumQty': 0,
'currency': 'USD',
'displayQty': None,
'exDestination': 'XBME',
'execInst': '',
'leavesQty': 1,
'multiLegReportingType': 'SingleSecurity',
'ordRejReason': '',
'ordStatus': 'New',
'ordType': 'Limit',
'orderID': 'f906632a-3272-aa1b-8a5d-a3107d167692',
'orderQty': 1,
'pegOffsetValue': None,
'pegPriceType': '',
'price': 10000,
'settlCurrency': 'XBt',
'side': 'Sell',
'simpleCumQty': 0,
'simpleLeavesQty': 0.0001,
'simpleOrderQty': None,
'stopPx': None,
'symbol': 'XBTUSD',
'text': 'Submission from www.bitmex.com',
'timeInForce': 'GoodTillCancel',
'timestamp': '2018-05-04T14:24:19.648Z',
'transactTime': '2018-05-04T14:24:19.648Z',
'triggered': '',
'workingIndicator': True},
'lastTradeTimestamp': None,
'price': 10000.0,
'remaining': 1.0,
'side': 'sell',
'status': 'open',
'symbol': 'BTC/USD',
'timestamp': 1525443859648,
'type': 'limit'},
{'amount': 2.0,
'cost': 0.0,
'datetime': '2018-05-04T14:24:30.896Z',
'fee': None,
'filled': 0.0,
'id': '4465c9d7-224f-0ff7-7022-e03ebc783e55',
'info': {'account': 51246,
'avgPx': None,
'clOrdID': '',
'clOrdLinkID': '',
'contingencyType': '',
'cumQty': 0,
'currency': 'USD',
'displayQty': None,
'exDestination': 'XBME',
'execInst': '',
'leavesQty': 2,
'multiLegReportingType': 'SingleSecurity',
'ordRejReason': '',
'ordStatus': 'New',
'ordType': 'Limit',
'orderID': '4465c9d7-224f-0ff7-7022-e03ebc783e55',
'orderQty': 2,
'pegOffsetValue': None,
'pegPriceType': '',
'price': 10000,
'settlCurrency': 'XBt',
'side': 'Sell',
'simpleCumQty': 0,
'simpleLeavesQty': 0.0002,
'simpleOrderQty': None,
'stopPx': None,
'symbol': 'XBTUSD',
'text': 'Submission from www.bitmex.com',
'timeInForce': 'GoodTillCancel',
'timestamp': '2018-05-04T14:24:29.896Z',
'transactTime': '2018-05-04T14:24:29.896Z',
'triggered': '',
'workingIndicator': True},
'lastTradeTimestamp': None,
'price': 10000.0,
'remaining': 2.0,
'side': 'sell',
'status': 'open',
'symbol': 'BTC/USD',
'timestamp': 1525443869896,
'type': 'limit'}]
>>> len(Orders)
2
>>>
Ordersを取得した時に、このアカウントは二つの指値売り注文を出していました。
主な項目値は以下の通り。
・amount:ロットサイズ(USD)
・datetime:発注時刻
・id:注文ID
・ordType:オーダーの種類(Limit:指値)
・price:指値価格
・side:買いか売りか(Sellはショート)
len(Orders)で分かる通り、注文の数だけディクショナリーが入った配列が返ってきます。
・過去の足データの取得
>>> Now = int(datetime.datetime.now().timestamp())
>>> Ashi = requests.get('https://www.bitmex.com/api/udf/history?symbol=XBTUSD&resolution=5&from=' + str(int(Now) - 3600 * 2) + '&to=' + str(Now), timeout=20)
>>> Ohlcv = Ashi.json()
>>> pprint(Ohlcv)
{'c': [9718,
9722.5,
9722.5,
9705.5,
9689,
9702,
9718.5,
9717.5,
9699.5,
9680.5,
9699,
9709.5,
9693,
9685,
9671.5,
9658.5,
9635.5,
9653,
9654,
9661,
9673,
9672.5,
9649,
9660,
9668.5],
'h': [9738,
9730.5,
9723,
9726.5,
9705.5,
9704.5,
9721,
9719,
9718,
9710.5,
9700,
9711.5,
9710,
9701.5,
9685.5,
9672,
9659,
9658.5,
9692,
9675,
9673,
9680,
9672,
9660,
9669],
'l': [9716.5,
9718,
9712.5,
9680,
9678,
9687,
9701,
9706.5,
9695,
9671,
9680,
9698.5,
9692.5,
9685,
9670,
9652,
9632,
9633.5,
9610,
9645,
9657,
9660,
9636,
9641.5,
9659.5],
'o': [9737.5,
9718,
9722.5,
9722.5,
9705.5,
9689,
9702,
9718.5,
9717.5,
9699.5,
9680.5,
9699,
9709.5,
9693,
9685,
9671.5,
9658.5,
9635.5,
9653,
9654,
9661,
9673,
9672.5,
9649,
9660],
's': 'ok',
't': [1525437000,
1525437300,
1525437600,
1525437900,
1525438200,
1525438500,
1525438800,
1525439100,
1525439400,
1525439700,
1525440000,
1525440300,
1525440600,
1525440900,
1525441200,
1525441500,
1525441800,
1525442100,
1525442400,
1525442700,
1525443000,
1525443300,
1525443600,
1525443900,
1525444200],
'v': [9780598,
7791731,
9346305,
20205119,
16395350,
10685903,
9244297,
5650577,
6772285,
14137385,
8875695,
5585369,
3478156,
4601639,
12122954,
14910746,
21123434,
19177914,
34503364,
12040039,
7012030,
8878227,
8346269,
6243688,
5359487]}
>>>
取得元のアドレスを見ればわかるように、BitMEXのヒストリカルデータを取得しています。
resolution:何分足を取得するか(5分なら5、日足なら1440)
from-to:ヒストリカルデータの取得範囲
主な項目値は以下の通り。
c:終値
h:高値
l:安値
o:始値
t:時刻
v:出来高
また、tを見ればわかる通り、値は一番最後が一番新しい(現在に近い)です。
一番新しい終値は以下のコマンドで取得できます。
>>> Ohlcv['c'][-1]
9668.5
この情報があれば、pythonでテクニカル指標を組むことができます。
・注文(成行)
#ショート
Sell_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Sell", "orderQty":1, "ordType": "Market"})
#ロング
Buy_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Buy", "orderQty":1, "ordType": "Market"})
symbol:対象通貨ペア
orderQty:ロットサイズ(ドル)
ordType:オーダーの種類(Market:成行)
・注文(指値)
買いの場合は現在値よりも低いprice、売りの場合は現在値よりも高いpriceを設定する必要があります。
Sell_limit_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Sell", "orderQty": 1, "ordType": "Limit", "price":10000})
Buy_limit_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Buy", "orderQty": 1, "ordType": "Limit", "price":9000})
・ordType:オーダーの種類(Limit:指値)
・price:逆指値価格
・注文(逆指値)
買いの場合は現在値よりも高いstopPx、売りの場合は現在値よりも低いstopPxを設定する必要があります。
Sell_stop_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Sell", "orderQty": 1, "ordType": "Stop", "stopPx":9000 ,"execInst": "LastPrice"})
Buy_stop_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Buy", "orderQty": 1, "ordType": "Stop", "stopPx":10000 ,"execInst": "LastPrice"})
・ordType:オーダーの種類(stop:逆指値)
・stopPx:逆指値価格
・execInst:使用する価格(以下で説明)
【BitMEXで使用される価格】
BitMEXで使用される価格には3種類あります。
・直近価格(Last Price):BitMEXの現在の取引価格
・インデックス価格(Index Price):他の取引所を参照している価格(チャート上のBXBT)
・マーク価格(Mark Price):インデックス価格と手数料を使って算出される価格。含み損益の計算、レバレッジの計算、ロスカットの執行基準価格。
・トレーリングストップ
Sell_trail_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Sell", "orderQty": 1, "ordType": "Stop" ,"execInst": "LastPrice" , "pegPriceType":"TrailingStopPeg" , "pegOffsetValue":100})
Buy_trail_Order = bitmex.privatePostOrder({"symbol": "XBTUSD", "side": "Buy", "orderQty": 1, "ordType": "Stop", "execInst": "LastPrice" , "pegPriceType":"TrailingStopPeg" , "pegOffsetValue":100})
・pegPriceType:ここに「TrailingStopPeg」を指定するとトレーリングストップになります。
・pegOffsetValue:トレール幅(USD)
最後に、BitMEXのAPIの調べ方をご紹介します。
以下のAPI Explorerを見れば、すべて仕様が載っています。
英語しかないので、英語が苦手な方は努力が必要です。
例えば、オーダーの仕方を調べたいときは、以下のようにOrderの中のPOSTの中身を見ていきます。
このコマンドのすべての変数と初期値、それに各変数に入れるべき値が書いてあるので、だいたいここを見てコマンドを組み立て、あとはエラーメッセージを見ながらバグとりをすれば、正解にたどり着けます。
以上です。最後まで読んでいただきありがとうございました。
この記事が気に入ったらサポートをしてみませんか?