예제 #1
0
 async def sub_callback(self, data):
     if data["err-code"] != 0:
         e = Error("subscribe {} failed!".format(data["topic"]))
         logger.error(e, caller=self)
         SingleTask.run(self._init_success_callback, False, e)
         return
     if data["topic"] == self._order_channel:
         self._subscribe_order_ok = True
     elif data["topic"] == self._position_channel:
         self._subscribe_position_ok = True
     elif data["topic"] == self._asset_channel:
         self._subscribe_asset_ok = True
     if self._subscribe_order_ok and self._subscribe_position_ok \
         and self._subscribe_asset_ok:
         success, error = await self._rest_api.get_open_orders(self._symbol)
         if error:
             e = Error("get open orders failed!")
             SingleTask.run(self._init_success_callback, False, e)
         elif "data" in success and "orders" in success["data"]:
             for order_info in success["data"]["orders"]:
                 order_info["ts"] = order_info["created_at"]
                 self._update_order(order_info)
             SingleTask.run(self._init_success_callback, True, None)
         else:
             logger.warn("get open orders:", success, caller=self)
             e = Error("Get Open Orders Unknown error")
             SingleTask.run(self._init_success_callback, False, e)
예제 #2
0
    async def on_ticker(self, *args, **kwargs):
        """ 定时执行任务
        """
        if self.trader.assets is None:
            return

        if self.trader.position is None:
            return

        ts_diff = int(time.time() * 1000) - self.last_orderbook_timestamp
        if ts_diff > self.orderbook_invalid_seconds * 1000:
            logger.warn("received orderbook timestamp exceed:",
                        self.strategy,
                        self.symbol,
                        ts_diff,
                        caller=self)
            return

        # 获取标记价格,每次的挂单价格与指数价格进行比较。
        success, error = await self.trader.rest_api.get_market_index(
            contract_code=self.symbol)
        if error:
            logger.error("Get swap market index faild:", error, caller=self)
        else:
            for item in success["data"]:
                if item["contract_code"] == self.symbol:
                    self.mark_price = item["mark_price"]

        await self.cancel_orders()
        await self.place_orders()
예제 #3
0
 async def on_ticker(self, *args, **kwargs):
     """ 定时执行任务
     """
     ts_diff = int(time.time()*1000) - self.last_orderbook_timestamp
     if ts_diff > self.orderbook_invalid_seconds * 1000:
         logger.warn("received orderbook timestamp exceed:", self.strategy, self.symbol, ts_diff, caller=self)
         return
     await self.cancel_orders()
     await self.place_orders()
예제 #4
0
    async def _reconnect(self):
        """ 重新建立websocket连接
        """
        if self.closed:
            logger.info("websocket closed, not reconnecting", caller=self)
            return

        logger.warn("reconnecting websocket right now!", caller=self)
        await self._connect()
예제 #5
0
 async def _check_connection(self, *args, **kwargs):
     """ 检查连接是否正常
     """
     # 检查websocket连接是否关闭,如果关闭,那么立即重连
     if not self.ws or self.closed:
         logger.warn("websocket connection not connected yet!", caller=self)
         return
     if self.ws.closed:
         await asyncio.create_task(self._reconnect())
         return
예제 #6
0
 async def _send_heartbeat_msg(self, *args, **kwargs):
     """ 发送心跳给服务器
     """
     if not self.ws:
         logger.warn("websocket connection not connected yet!", caller=self)
         return
     data = {"pong": int(time.time() * 1000)}
     try:
         await self.ws.send_json(data)
     except ConnectionResetError:
         await asyncio.create_task(self._reconnect())
예제 #7
0
 async def receive(self):
     """ 接收消息
     """
     async for msg in self.ws:
         if msg.type == aiohttp.WSMsgType.TEXT:
             try:
                 data = json.loads(msg.data)
             except:
                 data = msg.data
             await asyncio().create_task(self.process(data))
         elif msg.type == aiohttp.WSMsgType.BINARY:
             await asyncio.create_task(self.process_binary(msg.data))
         elif msg.type == aiohttp.WSMsgType.CLOSED:
             logger.warn("receive event CLOSED:", msg, caller=self)
             await asyncio.create_task(self._reconnect())
         elif msg.type == aiohttp.WSMsgType.CLOSE:
             logger.warn("receive event CLOSE:", msg, caller=self)
             await asyncio.create_task(self._reconnect())
         elif msg.type == aiohttp.WSMsgType.CLOSING:
             logger.warn("receive event CLOSING:", msg, caller=self)
             await asyncio.create_task(self._reconnect())
         elif msg.type == aiohttp.WSMsgType.ERROR:
             logger.error("receive event ERROR:", msg, caller=self)
             await asyncio.create_task(self._reconnect())
         else:
             logger.warn("unhandled msg:", msg, caller=self)
예제 #8
0
 async def _send_heartbeat_msg(self, *args, **kwargs):
     """ 发送心跳给服务器
     """
     if not self.ws:
         logger.warn("websocket connection not connected yet!", caller=self)
         return
     if self.heartbeat_msg:
         try:
             if isinstance(self.heartbeat_msg, dict):
                 await self.ws.send_json(self.heartbeat_msg)
             elif isinstance(self.heartbeat_msg, str):
                 await self.ws.send_str(self.heartbeat_msg)
             else:
                 logger.error("send heartbeat msg failed! heartbeat msg:",
                              self.heartbeat_msg,
                              caller=self)
                 return
             logger.debug("send ping message:",
                          self.heartbeat_msg,
                          caller=self)
         except ConnectionResetError:
             traceback.print_exc()
             await asyncio.create_task(self._reconnect())
예제 #9
0
    async def place_orders(self):
        """ 下单
        """
        orders_data = []
        if self.trader.position and self.trader.position.short_quantity:
            # 平空单
            price = round(self.mark_price - self.spread, 1)
            quantity = -self.trader.position.short_quantity
            action = ORDER_ACTION_BUY
            new_price = str(price)  # 将价格转换为字符串,保持精度
            if quantity:
                orders_data.append({
                    "price": new_price,
                    "quantity": quantity,
                    "action": action,
                    "order_type": ORDER_TYPE_LIMIT
                })
                self.last_mark_price = self.mark_price
        if self.trader.position and self.trader.position.long_quantity:
            # 平多单
            price = round(self.mark_price + self.spread, 1)
            quantity = self.trader.position.long_quantity
            action = ORDER_ACTION_SELL
            new_price = str(price)  # 将价格转换为字符串,保持精度
            if quantity:
                orders_data.append({
                    "price": new_price,
                    "quantity": quantity,
                    "action": action,
                    "order_type": ORDER_TYPE_LIMIT
                })
                self.last_mark_price = self.mark_price
        if self.trader.assets and self.trader.assets.assets.get(
                self.raw_symbol).get("free"):
            # 开空单
            if self.trader.position and self.trader.position.short_quantity and self.trader.position.short_quantity >= self.max_quantity:
                logger.warn("option short position exceeds the max quantity: ",
                            self.symbol,
                            self.trader.position.short_quantity,
                            self.max_quantity,
                            caller=self)
            else:
                price = round(self.mark_price + self.spread, 1)
                volume = self.volume
                if volume:
                    quantity = -volume  #  空张
                    action = ORDER_ACTION_SELL
                    new_price = str(price)  # 将价格转换为字符串,保持精度
                    if quantity:
                        orders_data.append({
                            "price": new_price,
                            "quantity": quantity,
                            "action": action,
                            "order_type": ORDER_TYPE_LIMIT
                        })
                        self.last_mark_price = self.mark_price
        if self.trader.assets and self.trader.assets.assets.get(
                self.partition_symbol) and self.trader.assets.assets.get(
                    self.partition_symbol).get("free"):
            # 开多单
            if self.trader.position and self.trader.position.long_quantity and self.trader.position.long_quantity >= self.max_quantity:
                logger.warn("option long position exceeds the max quantity: ",
                            self.symbol,
                            self.trader.position.long_quantity,
                            self.max_quantity,
                            caller=self)
            else:
                price = round(self.mark_price - self.spread, 1)
                volume = self.volume
                if volume:
                    quantity = volume  #  多张
                    action = ORDER_ACTION_BUY
                    new_price = str(price)  # 将价格转换为字符串,保持精度
                    if quantity:
                        orders_data.append({
                            "price": new_price,
                            "quantity": quantity,
                            "action": action,
                            "order_type": ORDER_TYPE_LIMIT
                        })
                        self.last_mark_price = self.mark_price

        if orders_data:
            order_nos, error = await self.trader.create_orders(orders_data)
            if error:
                logger.error(self.strategy,
                             "create future order error! error:",
                             error,
                             caller=self)
            logger.info(self.strategy,
                        "create future orders success:",
                        order_nos,
                        caller=self)