Exemplo n.º 1
0
    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)
Exemplo n.º 2
0
    async def process(self, msg):
        """ 处理websocket上接收到的消息
        """
        # logger.debug("msg:", msg, caller=self)
        if tools.get_cur_timestamp() <= self._last_msg_ts:
            return
        if not isinstance(msg, dict):
            return
        notifications = msg.get("notifications")
        if not notifications:
            return
        message = notifications[0].get("message")
        if message != "order_book_event":
            return

        symbol = notifications[0].get("result").get("instrument")
        bids = []
        for item in notifications[0].get("result").get("bids")[:10]:
            b = [item.get("price"), item.get("quantity")]
            bids.append(b)
        asks = []
        for item in notifications[0].get("result").get("asks")[:10]:
            a = [item.get("price"), item.get("quantity")]
            asks.append(a)
        self._last_msg_ts = tools.get_cur_timestamp()
        orderbook = {
            "platform": self._platform,
            "symbol": symbol,
            "asks": asks,
            "bids": bids,
            "timestamp": self._last_msg_ts
        }
        EventOrderbook(**orderbook).publish()
        logger.info("symbol:", symbol, "orderbook:", orderbook, caller=self)
Exemplo n.º 3
0
    async def publish_orderbook(self, symbol):
        """Publish OrderbookEvent."""
        ob = copy.copy(self._orderbooks[symbol])
        if not ob["asks"] or not ob["bids"]:
            logger.warn("symbol:", symbol, "asks:", ob["asks"], "bids:", ob["bids"], caller=self)
            return

        ask_keys = sorted(list(ob["asks"].keys()))
        bid_keys = sorted(list(ob["bids"].keys()), reverse=True)
        if ask_keys[0] <= bid_keys[0]:
            logger.warn("symbol:", symbol, "ask1:", ask_keys[0], "bid1:", bid_keys[0], caller=self)
            return

        asks = []
        for k in ask_keys[:self._orderbook_length]:
            price = "%.8f" % k
            quantity = "%.8f" % ob["asks"].get(k)
            asks.append([price, quantity])

        bids = []
        for k in bid_keys[:self._orderbook_length]:
            price = "%.8f" % k
            quantity = "%.8f" % ob["bids"].get(k)
            bids.append([price, quantity])

        orderbook = {
            "platform": self._platform,
            "symbol": symbol,
            "asks": asks,
            "bids": bids,
            "timestamp": ob["timestamp"]
        }
        EventOrderbook(**orderbook).publish()
        logger.debug("symbol:", symbol, "orderbook:", orderbook, caller=self)
Exemplo n.º 4
0
    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)
Exemplo n.º 5
0
    async def publish_orderbook(self, *args, **kwargs):
        """ 推送orderbook数据
        """
        for symbol, data in self._orderbooks.items():
            ob = copy.copy(data)
            if not ob["asks"] or not ob["bids"]:
                logger.warn("symbol:",
                            symbol,
                            "asks:",
                            ob["asks"],
                            "bids:",
                            ob["bids"],
                            caller=self)
                continue

            ask_keys = sorted(list(ob["asks"].keys()))
            bid_keys = sorted(list(ob["bids"].keys()), reverse=True)
            if ask_keys[0] <= bid_keys[0]:
                logger.warn("symbol:",
                            symbol,
                            "ask1:",
                            ask_keys[0],
                            "bid1:",
                            bid_keys[0],
                            caller=self)
                continue

            # 卖
            asks = []
            for k in ask_keys[:self._length]:
                price = "%.8f" % k
                quantity = "%.8f" % ob["asks"].get(k)
                asks.append([price, quantity])

            # 买
            bids = []
            for k in bid_keys[:self._length]:
                price = "%.8f" % k
                quantity = "%.8f" % ob["bids"].get(k)
                bids.append([price, quantity])

            # 推送订单薄数据
            orderbook = {
                "platform": self._platform,
                "symbol": symbol,
                "asks": asks,
                "bids": bids,
                "timestamp": ob["timestamp"]
            }
            EventOrderbook(**orderbook).publish()
            logger.info("symbol:",
                        symbol,
                        "orderbook:",
                        orderbook,
                        caller=self)
Exemplo n.º 6
0
 async def on_orderbook_update_callback(self, orderbook: Orderbook):
     """ 订单薄更新
     """
     logger.info("orderbook:", orderbook, caller=self)
     kwargs = {
         "platform": orderbook.platform,
         "symbol": orderbook.symbol,
         "asks": orderbook.asks,
         "bids": orderbook.bids,
         "timestamp": orderbook.timestamp
     }
     EventOrderbook(**kwargs).publish()
Exemplo n.º 7
0
    def __init__(self, platform, symbol):
        self._platform = platform  # 平台
        self._symbol = symbol  # 交易对
        self._asks = []  # 买单
        self._bids = []  # 卖单
        self._ask1 = None  # 买一
        self._bid1 = None  # 卖一
        self._timestamp = None  # 更新时间戳(秒)
        self._callback_handlers = []  # 外盘行情有更新的时候,执行的回调函数

        # 订阅事件回调
        EventOrderbook(self._platform,
                       self._symbol).subscribe(self.on_event_orderbook)
Exemplo n.º 8
0
 async def process_orderbook(self, data):
     """Process orderbook data and publish OrderbookEvent."""
     for item in 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.debug("symbol:", symbol, "orderbook:", orderbook, caller=self)
Exemplo n.º 9
0
    async def do_orderbook_update(self, *args, **kwargs):
        """ 执行订单薄数据更新
        """
        for symbol in self._symbols:
            result, error = await self._rest_api.get_orderbook(
                symbol, self._orderbook_fetch_count)
            if error:
                continue
            bids = []
            asks = []
            for item in result["asks"]:
                a = [item["limitPrice"], item["quantity"]]
                asks.append(a)
            for item in result["bids"]:
                b = [item["limitPrice"], item["quantity"]]
                bids.append(b)

            if not bids and not asks:
                logger.warn("no orderbook data", caller=self)
                continue

            # 判断买一是否小于卖一,防止异常数据
            if len(bids) > 0 and len(asks) > 0 and float(bids[0][0]) >= float(
                    asks[0][0]):
                logger.warn("symbol:",
                            symbol,
                            "bids one is grate than asks one! asks:",
                            asks,
                            "bids:",
                            bids,
                            caller=self)
                continue

            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)

            # 间隔0.1秒发起下一次请求
            await asyncio.sleep(0.1)
Exemplo n.º 10
0
    async def on_orderbook_update_callback(self, orderbook: Orderbook):
        """ 订单薄更新
        """
        logger.info("orderbook:", orderbook, caller=self)
        #行情保存进数据库
        kwargs = {}
        i = 1
        for ask in orderbook.asks:
            kwargs[f'askprice{i}'] = ask[0]
            kwargs[f'asksize{i}'] = ask[1]
            i = i + 1
            if i > 20: break
        i = 1
        for bid in orderbook.bids:
            kwargs[f'bidprice{i}'] = bid[0]
            kwargs[f'bidsize{i}'] = bid[1]
            i = i + 1
            if i > 20: break
        kwargs["pubdt"] = orderbook.timestamp  #交易所发布行情的时间
        kwargs["dt"] = tools.get_cur_timestamp_ms()  #本地采集行情的时间

        async def save(kwargs):
            #一秒内会有多次通知,将一秒内的通知都收集在一起,一次性写入数据库,约一秒写一次,提高数据库性能
            dlist = self.d_orderbook_map[orderbook.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_orderbook_map[orderbook.symbol] = []
                #写数据库
                t_orderbook = self.t_orderbook_map[orderbook.symbol]
                if t_orderbook:
                    s, e = await t_orderbook.insert(dlist)
                    if e:
                        logger.error("insert orderbook:", e, caller=self)

        SingleTask.run(save, kwargs)
        #发布行情到消息队列
        kwargs = {
            "platform": orderbook.platform,
            "symbol": orderbook.symbol,
            "asks": orderbook.asks,
            "bids": orderbook.bids,
            "timestamp": orderbook.timestamp
        }
        EventOrderbook(**kwargs).publish()
Exemplo n.º 11
0
 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)
Exemplo n.º 12
0
 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)
Exemplo n.º 13
0
    async def publish_orderbook(self, symbol, data):
        """ Publish orderbook message to EventCenter via OrderbookEvent.
        """
        if not data["asks"] or not data["bids"]:
            logger.warn("symbol:",
                        symbol,
                        "asks:",
                        data["asks"],
                        "bids:",
                        data["bids"],
                        caller=self)
            return

        ask_keys = sorted(list(data["asks"].keys()))
        bid_keys = sorted(list(data["bids"].keys()), reverse=True)
        if ask_keys[0] <= bid_keys[0]:
            logger.warn("symbol:",
                        symbol,
                        "ask1:",
                        ask_keys[0],
                        "bid1:",
                        bid_keys[0],
                        caller=self)
            return

        asks = []
        for k in ask_keys[:self._orderbook_length]:
            price = "%.8f" % k
            quantity = str(data["asks"].get(k))
            asks.append([price, quantity])

        bids = []
        for k in bid_keys[:self._orderbook_length]:
            price = "%.8f" % k
            quantity = str(data["bids"].get(k))
            bids.append([price, quantity])

        orderbook = {
            "platform": self._platform,
            "symbol": symbol,
            "asks": asks,
            "bids": bids,
            "timestamp": data["timestamp"]
        }
        EventOrderbook(**orderbook).publish()
        logger.info("symbol:", symbol, "orderbook:", orderbook, caller=self)
Exemplo n.º 14
0
 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)
Exemplo n.º 15
0
    async def on_event_orderbook(self, event):
        """ 事件回调 行情信息
        """
        orderbook = EventOrderbook().duplicate(event)
        if orderbook.platform != self._platform or orderbook.symbol != self._symbol:
            return

        self._asks = orderbook.asks
        self._bids = orderbook.bids
        self._bid1 = self._bids[0] if self._bids else None
        self._ask1 = self._asks[0] if self._asks else None
        self._timestamp = orderbook.timestamp

        for func in self._callback_handlers:
            asyncio.get_event_loop().create_task(
                func(self.platform, self.symbol, self.asks, self.bids,
                     self.timestamp))
Exemplo n.º 16
0
 async def process_orderbook(self, symbol, data):
     """Process orderbook data and publish OrderbookEvent."""
     bids = []
     asks = []
     for bid in data.get("bids")[:self._orderbook_length]:
         bids.append(bid[:2])
     for ask in data.get("asks")[:self._orderbook_length]:
         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)
Exemplo n.º 17
0
    async def get_newest_orderbook(self, symbol):
        """ Get the newest orderbook information.
        """
        result, error = await self._rest_api.get_orderbook(
            symbol.replace("/", ""), self._orderbook_length)
        key = list(result.keys())[0]

        asks, bids = [], []
        for item in result.get(key)["asks"]:
            asks.append(item[:2])
        for item in result.get(key)["bids"]:
            bids.append(item[: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)
Exemplo n.º 18
0
    async def do_orderbook_update(self, *args, **kwargs):
        """ Fetch orderbook information."""
        for symbol in self._symbols:
            result, error = await self._rest_api.get_orderbook(
                symbol.replace("/", "-"), self._orderbook_length)
            if error:
                continue
            orderbook = {
                "platform": self._platform,
                "symbol": symbol,
                "asks": result["asks"],
                "bids": result["bids"],
                "timestamp": result["time"]
            }
            EventOrderbook(**orderbook).publish()
            logger.info("symbol:",
                        symbol,
                        "orderbook:",
                        orderbook,
                        caller=self)

            # await 0.1 second before next request.
            await asyncio.sleep(0.1)
Exemplo n.º 19
0
 async def process_orderbook(self, data):
     """Process orderbook data and publish OrderbookEvent."""
     symbol = data["instrument"]
     if symbol not in self._symbols:
         return
     bids = []
     for item in data["bids"][:self._orderbook_length]:
         b = [item.get("price"), item.get("quantity")]
         bids.append(b)
     asks = []
     for item in data["asks"][:self._orderbook_length]:
         a = [item.get("price"), item.get("quantity")]
         asks.append(a)
     self._last_msg_ts = tools.get_cur_timestamp_ms()
     orderbook = {
         "platform": self._platform,
         "symbol": symbol,
         "asks": asks,
         "bids": bids,
         "timestamp": self._last_msg_ts
     }
     EventOrderbook(**orderbook).publish()
     logger.debug("symbol:", symbol, "orderbook:", orderbook, caller=self)
Exemplo n.º 20
0
    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)
Exemplo n.º 21
0
    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)