Как извлечь отдельные и уникальные сделки в реальном времени из журнала Bitmex Websocket API ws.recent_trades()
Я пытаюсь передать данные о торговле в реальном времени с Bitmex, чтобы выполнить некоторые вычисления и автоматизировать свою торговлю. Я использовал следующий код, полученный с https://github.com/BitMEX/api-connectors/blob/master/official-ws/python/main.py, и мой код выглядит следующим образом:
from bitmex_websocket import BitMEXWebsocket
import logging
# Basic use of websocket.
def run():
logger = setup_logger()
# Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
api_key=api_key, api_secret=api_secret)
logger.info("Instrument data: %s" % ws.get_instrument())
# Run forever
while(ws.ws.sock.connected):
# CODE TO STREAM THE LIVE TRADE
logger.info("Recent Trades: %s\n\n" % ws.recent_trades())
def setup_logger():
# Prints logger info to terminal
logger = logging.getLogger()
logger.setLevel(logging.INFO) # Change this to DEBUG if you want a lot more info
ch = logging.StreamHandler()
# create formatter
formatter = logging.Formatter("%(asctime)s - %(name)s - %(levelname)s - %(message)s")
# add formatter to ch
ch.setFormatter(formatter)
logger.addHandler(ch)
return logger
if __name__ == "__main__":
run()
Вот результат, который я получил:
2019-09-08 02:35:35,220 - root - INFO - Recent Trades: [{'timestamp': '2019-09-07T18:35:21.333Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 100, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'b5f7a502-9d28-5139-19e3-b713f7d86426', 'grossValue': 953900, 'homeNotional': 0.009539, 'foreignNotional': 100}]
2019-09-08 02:35:35,221 - root - INFO - Recent Trades: [{'timestamp': '2019-09-07T18:35:21.333Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 100, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'b5f7a502-9d28-5139-19e3-b713f7d86426', 'grossValue': 953900, 'homeNotional': 0.009539, 'foreignNotional': 100}]
2019-09-08 02:35:35,222 - root - INFO - Recent Trades: [{'timestamp': '2019-09-07T18:35:21.333Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 100, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'b5f7a502-9d28-5139-19e3-b713f7d86426', 'grossValue': 953900, 'homeNotional': 0.009539, 'foreignNotional': 100}]
Как видите, все 3 вывода предназначены для одной и той же сделки, как я могу заставить код печатать только текущие уникальные сделки, которые происходят, но не постоянно одну и ту же сделку?
Иногда я получаю длинный кусок потока, который содержит несколько сделок на поток, например:
2019-09-08 02:36:03,539 - root - INFO - Recent Trades: [{'timestamp': '2019-09-07T18:35:21.333Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 100, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'b5f7a502-9d28-5139-19e3-b713f7d86426', 'grossValue': 953900, 'homeNotional': 0.009539, 'foreignNotional': 100}, {'timestamp': '2019-09-07T18:36:04.168Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 1485, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': '8edc4253-85fa-dc93-23e4-3394be2153cc', 'grossValue': 14165415, 'homeNotional': 0.14165415, 'foreignNotional': 1485}, {'timestamp': '2019-09-07T18:36:04.168Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 10, 'price': 10483, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': '09bea4d1-14e2-86af-7152-38d468e7fbed', 'grossValue': 95390, 'homeNotional': 0.0009539, 'foreignNotional': 10},
Как я могу разделить их на отдельные сделки? Результатом моего желания будет каждая отдельная сделка в списке:[timestamp, price, qty, side]
и запустите функцию для выполнения некоторых вычислений по каждой сделке. Спасибо!
1 ответ
Хороший вопрос - не похоже, что существует очевидный способ получения сообщений веб-сокета, управляемых событиями, с использованием этой библиотеки (даже если вы пытаетесь подписаться только на trade
канал!)
Это самое простое решение с учетом вашего текущего кода. Он записывает вашу последнюю сделку и регистрирует только изменения.
from bitmex_websocket import BitMEXWebsocket
import logging
import time
# Basic use of websocket.
def run():
logger = setup_logger()
# Instantiating the WS will make it connect. Be sure to add your api_key/api_secret.
ws = BitMEXWebsocket(endpoint="https://testnet.bitmex.com/api/v1", symbol="XBTUSD",
api_key=api_key, api_secret=api_secret)
logger.info("Instrument data: %s" % ws.get_instrument())
# Run forever
start_time = time.time()
trades = []
while(ws.ws.sock.connected):
recent = ws.recent_trades()[-1] # take only last (most recent) trade
if not len(trades) or trades[-1] != recent:
# only store first trade or changed ones
logger.info("Trade: %s" % recent)
trades.append(recent)
# you could call some other useful function here
else:
logger.info('Unchanged')
# below recommended to slow down your poll slightly
time.sleep(0.05)
# below is just to exit loop after 5 secs and print the trades
if time.time() > start_time + 5:
print(trades)
break
Выход:
2019-09-11 23:57:28,601 - bitmex_websocket - INFO - Connected to WS.
2019-09-11 23:57:30,139 - bitmex_websocket - INFO - Got all market data. Starting.
2019-09-11 23:57:30,140 - root - INFO - Instrument data: {'symbol': 'XBTUSD', ...
2019-09-11 23:57:30,142 - root - INFO - Trade: {'timestamp': '2019-09-11T22:57:29.880Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 159, 'price': 10147, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'cc39257d-dc11-5b90-a0cc-ebabe7b6d104', 'grossValue': 1566945, 'homeNotional': 0.01566945, 'foreignNotional': 159}
2019-09-11 23:57:30,196 - root - INFO - Unchanged
2019-09-11 23:57:30,248 - root - INFO - Unchanged
2019-09-11 23:57:30,299 - root - INFO - Unchanged
2019-09-11 23:57:34,614 - root - INFO - Unchanged
2019-09-11 23:57:34,683 - root - INFO - Trade: {'timestamp': '2019-09-11T22:57:33.298Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 145, 'price': 10147, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': '3f12ae9f-371e-6261-3380-456b3c0a3c06', 'grossValue': 1428975, 'homeNotional': 0.01428975, 'foreignNotional': 145}
2019-09-11 23:57:34,752 - root - INFO - Unchanged
[
{'timestamp': '2019-09-11T22:57:29.880Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 159, 'price': 10147, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': 'cc39257d-dc11-5b90-a0cc-ebabe7b6d104', 'grossValue': 1566945, 'homeNotional': 0.01566945, 'foreignNotional': 159},
{'timestamp': '2019-09-11T22:57:33.298Z', 'symbol': 'XBTUSD', 'side': 'Sell', 'size': 145, 'price': 10147, 'tickDirection': 'ZeroMinusTick', 'trdMatchID': '3f12ae9f-371e-6261-3380-456b3c0a3c06', 'grossValue': 1428975, 'homeNotional': 0.01428975, 'foreignNotional': 145}
]
Надеюсь это поможет!
Изменить: чтобы извлечь только нужную информацию, просто выполните:
# Run forever
start_time = time.time()
trades = []
while(ws.ws.sock.connected):
recent = ws.recent_trades()[-1] # take only last (most recent) trade
if not len(trades) or trades[-1] != recent:
# only store first trade or changed ones
useful = {
"time": recent["timestamp"],
"price": recent["price"],
"size": recent["size"],
}
logger.info("Trade: %s" % useful)
trades.append(useful)
my_processing_func(trades)
# below recommended to slow down your poll slightly
time.sleep(0.05)
def my_processing_func(trades):
# This gets called every new trade, and gives you all past trades
# You may want to write them all to a file or just pass the most recent trade
just_sizes = [t["size"] for t in trades]
Если вы хотите, чтобы он работал постоянно, удалите добавленный мной блок:
# below is just to exit loop after 5 secs and print the trades
if time.time() > start_time + 5:
print(trades)
break