async def deal_trade_update(self, msg): """ Deal with trade message that updated. """ data = msg[1] symbol = msg[-1] if symbol not in self._symbols: return for item in data: price = "%.8f" % float(item[0]) quantity = "%.8f" % float(item[1]) timestamp = int(float(item[2]) * 1000) action = ORDER_ACTION_BUY if item[3] == "b" else ORDER_ACTION_SELL # Publish TradeEvent. trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
async def process_trade(self, data): """Deal with trade data, and publish trade message to EventCenter via TradeEvent.""" symbol = data["instrument_id"] if symbol not in self._symbols: return action = ORDER_ACTION_BUY if data[ "side"] == "buy" else ORDER_ACTION_SELL price = "%.5f" % float(data["price"]) if self._platform == const.OKEX_FUTURE: quantity = str(data["qty"]) else: quantity = str(data["size"]) timestamp = tools.utctime_str_to_mts(data["timestamp"]) # Publish EventTrade. trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.debug("symbol:", symbol, "trade:", trade, caller=self)
async def process(self, msg): """ 处理websocket上接收到的消息 """ # logger.debug("msg:", msg, caller=self) if not isinstance(msg, dict): return channel = msg.get("stream") if channel not in self._c_to_s: logger.warn("unkown channel, msg:", msg, caller=self) return symbol = self._c_to_s[channel] data = msg.get("data") e = data.get("e") # 事件名称 # 保存数据到数据库 if e == "kline": # K线 kline = { "platform": self._platform, "symbol": symbol, "open": data.get("k").get("o"), # 开盘价 "high": data.get("k").get("h"), # 最高价 "low": data.get("k").get("l"), # 最低价 "close": data.get("k").get("c"), # 收盘价 "volume": data.get("k").get("q"), # 交易量 "timestamp": data.get("k").get("t"), # 时间戳 "kline_type": const.MARKET_TYPE_KLINE } EventKline(**kline).publish() logger.info("symbol:", symbol, "kline:", kline, caller=self) elif channel.endswith("depth20"): # 订单薄 bids = [] asks = [] for bid in data.get("bids"): bids.append(bid[:2]) for ask in data.get("asks"): asks.append(ask[:2]) orderbook = { "platform": self._platform, "symbol": symbol, "asks": asks, "bids": bids, "timestamp": tools.get_cur_timestamp_ms() } EventOrderbook(**orderbook).publish() logger.info("symbol:", symbol, "orderbook:", orderbook, caller=self) elif e == "trade": # 实时成交信息 trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_SELL if data["m"] else ORDER_ACTION_BUY, "price": data.get("p"), "quantity": data.get("q"), "timestamp": data.get("T") } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self) else: logger.error("event error! msg:", msg, caller=self)
async def process_trade(self, msg): """Process trade data and publish TradeEvent.""" symbol = msg["product_id"].replace("-", "/") if symbol not in self._symbols: return if not msg.get( "trade_id" ): # The first ticker message received from Websocket maybe no this field, dropped. return action = ORDER_ACTION_BUY if msg.get( "side") == "buy" else ORDER_ACTION_SELL price = "%.8f" % float(msg["price"]) quantity = "%.8f" % float(msg["last_size"]) timestamp = tools.utctime_str_to_mts(msg["time"][:23] + "Z") trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
async def process(self, msg): """ 处理websocket上接收到的消息 """ logger.debug("msg:", msg, caller=self) if not isinstance(msg, dict): return table = msg.get("table") if table == "orderBook10": # 订单薄数据 for item in msg["data"]: symbol = item.get("symbol") orderbook = { "platform": self._platform, "symbol": symbol, "asks": item.get("asks"), "bids": item.get("bids"), "timestamp": tools.utctime_str_to_mts(item["timestamp"]) } EventOrderbook(**orderbook).publish() logger.info("symbol:", symbol, "orderbook:", orderbook, caller=self) elif table == "trade": # 成交数据 for item in msg["data"]: symbol = item["symbol"] trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_BUY if item["side"] else ORDER_ACTION_SELL, "price": "%.1f" % item["price"], "quantity": str(item["size"]), "timestamp": tools.utctime_str_to_mts(item["timestamp"]) } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self) elif table == "tradeBin1m": # 1分钟K线数据 for item in msg["data"]: symbol = item["symbol"] kline = { "platform": self._platform, "symbol": symbol, "open": "%.1f" % item["open"], # 开盘价 "high": "%.1f" % item["high"], # 最高价 "low": "%.1f" % item["low"], # 最低价 "close": "%.1f" % item["close"], # 收盘价 "volume": str(item["volume"]), # 交易量 "timestamp": tools.utctime_str_to_mts(item["timestamp"]), # 时间戳 "kline_type": MARKET_TYPE_KLINE } EventKline(**kline).publish() logger.info("symbol:", symbol, "kline:", kline, caller=self)
async def process_trade(self, symbol, data): """Process trade data and publish TradeEvent.""" trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_SELL if data["m"] else ORDER_ACTION_BUY, "price": data.get("p"), "quantity": data.get("q"), "timestamp": data.get("T") } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
async def on_trade_update_callback(self, trade: Trade): """ 市场最新成交更新 """ logger.info("trade:", trade, caller=self) kwargs = { "platform": trade.platform, "symbol": trade.symbol, "action": trade.action, "price": trade.price, "quantity": trade.quantity, "timestamp": trade.timestamp } EventTrade(**kwargs).publish()
async def process_trade(self, data): """Process trade data and publish TradeEvent.""" for item in data: symbol = item["symbol"] trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_BUY if item["side"] == "Buy" else ORDER_ACTION_SELL, "price": "%.8f" % item["price"], "quantity": str(item["size"]), "timestamp": tools.utctime_str_to_mts(item["timestamp"]) } EventTrade(**trade).publish() logger.debug("symbol:", symbol, "trade:", trade, caller=self)
def __init__(self, market_type, platform, symbol, callback): """ 初始化 @param market_type 行情类型 @param platform 交易平台 @param symbol 交易对 @param callback 行情更新回调函数,必须是async异步函数,回调参数为行情对象,比如k线回调函数: async def on_event_kline_update(kline: Kline): pass """ if market_type == const.MARKET_TYPE_ORDERBOOK: from quant.event import EventOrderbook EventOrderbook(platform, symbol).subscribe(callback) elif market_type == const.MARKET_TYPE_TRADE: from quant.event import EventTrade EventTrade(platform, symbol).subscribe(callback) elif market_type == const.MARKET_TYPE_KLINE: from quant.event import EventKline EventKline(platform, symbol).subscribe(callback)
def __init__(self, market_type, platform, symbol, callback): """ 初始化 @param market_type 行情类型 @param platform 交易平台 @param symbol 交易对 @param callback 更新回调函数 """ if market_type == const.MARKET_TYPE_ORDERBOOK: from quant.event import EventOrderbook EventOrderbook(platform, symbol).subscribe(callback) elif market_type == const.MARKET_TYPE_TRADE: from quant.event import EventTrade EventTrade(platform, symbol).subscribe(callback) elif market_type == const.MARKET_TYPE_KLINE: from quant.event import EventKline EventKline(platform, symbol).subscribe(callback)
async def process_trade(self, data): """Process trade data and publish TradeEvent.""" for item in data: symbol = item["instrument"] if symbol not in self._symbols: return trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_SELL if item["direction"] == "sell" else ORDER_ACTION_BUY, "price": item.get("price"), "quantity": item.get("quantity"), "timestamp": item["timeStamp"] } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
def __init__(self, market_type, platform, symbol, callback): """ Initialize. """ if platform == "#" or symbol == "#": multi = True else: multi = False if market_type == const.MARKET_TYPE_ORDERBOOK: from quant.event import EventOrderbook EventOrderbook(platform, symbol).subscribe(callback, multi) elif market_type == const.MARKET_TYPE_TRADE: from quant.event import EventTrade EventTrade(platform, symbol).subscribe(callback, multi) elif market_type in [const.MARKET_TYPE_KLINE, const.MARKET_TYPE_KLINE_5M, const.MARKET_TYPE_KLINE_15M]: from quant.event import EventKline EventKline(platform, symbol, kline_type=market_type).subscribe(callback, multi) else: logger.error("market_type error:", market_type, caller=self)
async def do_trade_update(self, *args, **kwargs): """ Fetch trade information.""" for symbol in self._symbols: result, error = await self._rest_api.get_ticker(symbol) if error: continue for data in result: trade = { "platform": self._platform, "symbol": symbol, "action": data["tradeType"], "price": data["price"], "quantity": data["volume"], "timestamp": data["timestamp"] } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self) # await 0.1 second before next request. await asyncio.sleep(0.1)
async def process_trade(self, data): """Process trade data and publish TradeEvent.""" symbol = data.get("instrument_id").replace("-", "/") if symbol not in self._symbols: return action = ORDER_ACTION_BUY if data["side"] == "buy" else ORDER_ACTION_SELL price = "%.8f" % float(data["price"]) quantity = "%.8f" % float(data["size"]) timestamp = tools.utctime_str_to_mts(data["timestamp"]) trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.debug("symbol:", symbol, "trade:", trade, caller=self)
async def on_trade_update_callback(self, trade: Trade): """ 市场最新成交更新 """ logger.info("trade:", trade, caller=self) #行情保存进数据库 kwargs = { "direction": trade.action, "tradeprice": trade.price, "volume": trade.quantity, "tradedt": trade.timestamp, "dt": tools.get_cur_timestamp_ms() } async def save(kwargs): #一秒内会有多次通知,将一秒内的通知都收集在一起,一次性写入数据库,约一秒写一次,提高数据库性能 dlist = self.d_trade_map[trade.symbol] dlist.append(kwargs) if dlist[len(dlist) - 1]["dt"] - dlist[0]["dt"] > 1000: #每秒写一次数据库 #因为是异步并发,所以先清空列表,重新收集新的一秒内的所有通知,而不是等待数据库IO完成再清空(python的变量只是对象的引用) #xxx = copy.deepcopy(dlist) #dlist.clear() #insert xxx self.d_trade_map[trade.symbol] = [] #写数据库 t_trade = self.t_trade_map[trade.symbol] if t_trade: s, e = await t_trade.insert(dlist) if e: logger.error("insert trade:", e, caller=self) SingleTask.run(save, kwargs) #发布行情到消息队列 kwargs = { "platform": trade.platform, "symbol": trade.symbol, "action": trade.action, "price": trade.price, "quantity": trade.quantity, "timestamp": trade.timestamp } EventTrade(**kwargs).publish()
async def do_trade_update(self, *args, **kwargs): """ 执行trade数据更新 """ for symbol in self._symbols: # 获取ticker数据 result, error = await self._rest_api.get_ticker(symbol) if error: continue for data in result: trade = { "platform": self._platform, "symbol": symbol, "action": data["tradeType"], "price": data["price"], "quantity": data["volume"], "timestamp": data["timestamp"] } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self) # 间隔0.1秒发起下一次请求 await asyncio.sleep(0.1)
async def process_trade_update(self, data): """ Deal with trade data, and publish trade message to EventCenter via TradeEvent. """ symbol = data["symbol"].replace("-", "/") if symbol not in self._symbols: return action = ORDER_ACTION_BUY if data[ "side"] == "buy" else ORDER_ACTION_SELL price = "%.8f" % float(data["price"]) quantity = "%.8f" % float(data["size"]) timestamp = int(int(data["time"]) / 1000000) # Publish EventTrade. trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
async def process_trade_update(self, data): """ Deal with trade data, and publish trade message to EventCenter via TradeEvent. Args: data: Newest trade data. """ symbol = data[0].replace("_", "/") for item in data[1]: action = ORDER_ACTION_BUY if item["type"] == "buy" else ORDER_ACTION_SELL price = "%.8f" % float(item["price"]) quantity = "%.8f" % float(item["amount"]) timestamp = int(item["time"] * 1000) # Publish EventTrade. trade = { "platform": self._platform, "symbol": symbol, "action": action, "price": price, "quantity": quantity, "timestamp": timestamp } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self)
async def process_binary(self, msg): """ 处理websocket上接收到的消息 """ data = json.loads(gzip.decompress(msg).decode()) # logger.debug("data:", json.dumps(data), caller=self) channel = data.get("ch") if not channel: if data.get("ping"): self.heartbeat_msg = data return symbol = self._c_to_s[channel] if channel.find("kline") != -1: # K线 d = data.get("tick") kline = { "platform": self._platform, "symbol": symbol, "open": "%.8f" % d["open"], # 开盘价 "high": "%.8f" % d["high"], # 最高价 "low": "%.8f" % d["low"], # 最低价 "close": "%.8f" % d["close"], # 收盘价 "volume": "%.8f" % d["amount"], # 成交量 "timestamp": int(data.get("ts")), # 时间戳 "kline_type": MARKET_TYPE_KLINE } EventKline(**kline).publish() logger.info("symbol:", symbol, "kline:", kline, caller=self) elif channel.find("depth") != -1: # 订单薄 d = data.get("tick") asks, bids = [], [] for item in d.get("asks")[:10]: price = "%.8f" % item[0] quantity = "%.8f" % item[1] asks.append([price, quantity]) for item in d.get("bids")[:10]: price = "%.8f" % item[0] quantity = "%.8f" % item[1] bids.append([price, quantity]) orderbook = { "platform": self._platform, "symbol": symbol, "asks": asks, "bids": bids, "timestamp": d.get("ts") } EventOrderbook(**orderbook).publish() logger.info("symbol:", symbol, "orderbook:", orderbook, caller=self) elif channel.find("trade") != -1: # 实时交易数据 tick = data.get("tick") direction = tick["data"][0].get("direction") price = tick["data"][0].get("price") quantity = tick["data"][0].get("amount") trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_BUY if direction == "buy" else ORDER_ACTION_SELL, "price": "%.8f" % price, "quantity": "%.8f" % quantity, "timestamp": tick.get("ts") } EventTrade(**trade).publish() logger.info("symbol:", symbol, "trade:", trade, caller=self) else: logger.error("event error! msg:", msg, caller=self)
async def process_binary(self, msg): """ Process binary message that received from Websocket connection. Args: msg: Binary message. """ data = json.loads(gzip.decompress(msg).decode()) # logger.debug("data:", json.dumps(data), caller=self) channel = data.get("ch") if not channel: if data.get("ping"): hb_msg = {"pong": data.get("ping")} await self._ws.send(hb_msg) return symbol = self._c_to_s[channel] if channel.find("kline") != -1: d = data.get("tick") kline = { "platform": self._platform, "symbol": symbol, "open": d["open"], "high": d["high"], "low": d["low"], "close": d["close"], "volume": d["amount"], "timestamp": data.get("ts"), "kline_type": MARKET_TYPE_KLINE } EventKline(**kline).publish() logger.debug("symbol:", symbol, "kline:", kline, caller=self) elif channel.find("depth") != -1: tick = data.get("tick") asks = tick.get("asks")[:self._orderbook_length] bids = tick.get("bids")[:self._orderbook_length] timestamp = tick.get("ts") orderbook = { "platform": self._platform, "symbol": symbol, "asks": asks, "bids": bids, "timestamp": timestamp } EventOrderbook(**orderbook).publish() logger.debug("symbol:", symbol, "orderbook:", orderbook, caller=self) elif channel.find("trade") != -1: tick = data.get("tick") direction = tick["data"][0].get("direction") price = tick["data"][0].get("price") quantity = tick["data"][0].get("amount") trade = { "platform": self._platform, "symbol": symbol, "action": ORDER_ACTION_BUY if direction == "buy" else ORDER_ACTION_SELL, "price": price, "quantity": quantity, "timestamp": tick.get("ts") } EventTrade(**trade).publish() logger.debug("symbol:", symbol, "trade:", trade, caller=self) else: logger.error("event error! msg:", msg, caller=self)