Example #1
0
 async def _reset_listen_key(self, *args, **kwargs):
     """Reset listen key."""
     if not self._listen_key:
         logger.error("listen key not initialized!", caller=self)
         return
     await self._rest_api.put_listen_key(self._listen_key)
     logger.info("reset listen key success!", caller=self)
Example #2
0
    async def on_event_orderbook_update(self, orderbook: Orderbook):
        """ 订单薄更新
        """
        logger.debug("orderbook:", orderbook, caller=self)
        bid3_price = orderbook.bids[2][0]  # 买三价格
        bid4_price = orderbook.bids[3][0]  # 买四价格

        # 判断是否需要撤单
        if self.order_id:
            if float(self.create_order_price) < float(bid3_price) or float(
                    self.create_order_price) > float(bid4_price):
                return
            _, error = await self.trader.revoke_order(self.order_id)
            if error:
                logger.error("revoke order error! error:", error, caller=self)
                return
            self.order_id = None
            logger.info("revoke order:", self.order_id, caller=self)

        # 创建新订单
        price = (float(bid3_price) + float(bid4_price)) / 2
        quantity = "0.1"  # 假设委托数量为0.1
        action = ORDER_ACTION_BUY
        order_id, error = await self.trader.create_order(
            action, price, quantity)
        if error:
            logger.error("create order error! error:", error, caller=self)
            return
        self.order_id = order_id
        self.create_order_price = price
        logger.info("create new order:", order_id, caller=self)
Example #3
0
    def _update_order(self, order_info):
        """Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        """
        order_id = str(order_info["order_id"])
        state = order_info["state"]
        remain = float(order_info["size"]) - float(order_info["filled_size"])
        avg_price = order_info.get("last_fill_px")
        ctime = tools.utctime_str_to_ms(order_info["ctime"])
        utime = tools.utctime_str_to_ms(order_info["utime"])

        if state == "-2":
            status = ORDER_STATUS_FAILED
        elif state == "-1":
            status = ORDER_STATUS_CANCELED
        elif state == "0":
            status = ORDER_STATUS_SUBMITTED
        elif state == "1":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "2":
            status = ORDER_STATUS_FILLED
        else:
            logger.error("status error! order_info:", order_info, caller=self)
            SingleTask.run(self._error_callback, "order status error.")
            return None

        order = self._orders.get(order_id)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_id": order_id,
                "client_order_id": order_info["client_oid"],
                "action": ORDER_ACTION_BUY
                if order_info["side"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["size"]
            }
            order = Order(**info)
            self._orders[order_id] = order
        order.remain = remain
        order.status = status
        order.avg_price = avg_price if avg_price else 0
        order.ctime = ctime
        order.utime = utime

        SingleTask.run(self._order_update_callback, copy.copy(order))
        if status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_id)
Example #4
0
 async def _check_connection(self, *args, **kwargs):
     if self._connected and self._channel and self._channel.is_open:
         return
     logger.error("CONNECTION LOSE! START RECONNECT RIGHT NOW!", caller=self)
     self._connected = False
     self._protocol = None
     self._channel = None
     self._event_handler = {}
     SingleTask.run(self.connect, reconnect=True)
Example #5
0
    def __init__(self, **kwargs):
        """Initialize."""
        e = None
        if not kwargs.get("account"):
            e = Error("param account miss")
        if not kwargs.get("strategy"):
            e = Error("param strategy miss")
        if not kwargs.get("symbol"):
            e = Error("param symbol miss")
        if not kwargs.get("host"):
            kwargs["host"] = "https://www.okex.com"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://real.okex.com:8443"
        if not kwargs.get("access_key"):
            e = Error("param access_key miss")
        if not kwargs.get("secret_key"):
            e = Error("param secret_key miss")
        if not kwargs.get("passphrase"):
            e = Error("param passphrase miss")
        if e:
            logger.error(e, caller=self)
            SingleTask.run(kwargs["error_callback"], e)
            SingleTask.run(kwargs["init_callback"], False)
            return

        self._account = kwargs["account"]
        self._strategy = kwargs["strategy"]
        self._platform = kwargs["platform"]
        self._symbol = kwargs["symbol"]
        self._host = kwargs["host"]
        self._wss = kwargs["wss"]
        self._access_key = kwargs["access_key"]
        self._secret_key = kwargs["secret_key"]
        self._passphrase = kwargs["passphrase"]
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_callback = kwargs.get("init_callback")
        self._error_callback = kwargs.get("error_callback")

        self._raw_symbol = self._symbol.replace("/", "-")
        self._order_channel = "spot/order:{symbol}".format(
            symbol=self._raw_symbol)

        url = self._wss + "/ws/v3"
        self._ws = Websocket(url,
                             self.connected_callback,
                             process_binary_callback=self.process_binary)

        self._assets = {
        }  # Asset object. e.g. {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # Order objects. e.g. {"order_id": Order, ... }

        # Initializing our REST API client.
        self._rest_api = OKExRestAPI(self._access_key, self._secret_key,
                                     self._passphrase, self._host)

        # Create a loop run task to send ping message to server per 5 seconds.
        LoopRunTask.register(self._send_heartbeat_msg, 5)
Example #6
0
 async def _on_consume_event_msg(self, channel, body, envelope, properties):
     try:
         key = "{exchange}:{routing_key}".format(exchange=envelope.exchange_name, routing_key=envelope.routing_key)
         funcs = self._event_handler[key]
         for func in funcs:
             SingleTask.run(func, channel, body, envelope, properties)
     except:
         logger.error("event handle error! body:", body, caller=self)
         return
     finally:
         await self._channel.basic_client_ack(delivery_tag=envelope.delivery_tag)  # response ack
Example #7
0
    def __init__(self, **kwargs):
        """Initialize Trade module."""
        e = None
        if not kwargs.get("account"):
            e = Error("param account miss")
        if not kwargs.get("strategy"):
            e = Error("param strategy miss")
        if not kwargs.get("symbol"):
            e = Error("param symbol miss")
        if not kwargs.get("host"):
            kwargs["host"] = "https://api.binance.com"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://stream.binance.com:9443"
        if not kwargs.get("access_key"):
            e = Error("param access_key miss")
        if not kwargs.get("secret_key"):
            e = Error("param secret_key miss")
        if e:
            logger.error(e, caller=self)
            SingleTask.run(kwargs["error_callback"], e)
            SingleTask.run(kwargs["init_callback"], False)

        self._account = kwargs["account"]
        self._strategy = kwargs["strategy"]
        self._platform = kwargs["platform"]
        self._symbol = kwargs["symbol"]
        self._host = kwargs["host"]
        self._wss = kwargs["wss"]
        self._access_key = kwargs["access_key"]
        self._secret_key = kwargs["secret_key"]
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_callback = kwargs.get("init_callback")
        self._error_callback = kwargs.get("error_callback")

        self._raw_symbol = self._symbol.replace(
            "/", "")  # Row symbol name, same as Binance Exchange.
        self._listen_key = None  # Listen key for Websocket authentication.
        self._assets = {
        }  # Asset data. e.g. {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # Order data. e.g. {order_id: order, ... }

        # Initialize our REST API client.
        self._rest_api = BinanceRestAPI(self._access_key, self._secret_key,
                                        self._host)

        # Create a loop run task to reset listen key every 30 minutes.
        LoopRunTask.register(self._reset_listen_key, 60 * 30)

        # Create a coroutine to initialize Websocket connection.
        SingleTask.run(self._init_websocket)

        LoopRunTask.register(self._send_heartbeat_msg, 10)
Example #8
0
    def __init__(self, **kwargs):
        """Initialize Trade module."""
        e = None
        if not kwargs.get("account"):
            e = Error("param account miss")
        if not kwargs.get("strategy"):
            e = Error("param strategy miss")
        if not kwargs.get("symbol"):
            e = Error("param symbol miss")
        if not kwargs.get("host"):
            kwargs["host"] = "https://api.huobi.pro"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://api.huobi.pro"
        if not kwargs.get("access_key"):
            e = Error("param access_key miss")
        if not kwargs.get("secret_key"):
            e = Error("param secret_key miss")
        if e:
            logger.error(e, caller=self)
            SingleTask.run(self._error_callback, e)
            SingleTask.run(kwargs["init_callback"], False)
            return

        self._account = kwargs["account"]
        self._strategy = kwargs["strategy"]
        self._platform = kwargs["platform"]
        self._symbol = kwargs["symbol"]
        self._host = kwargs["host"]
        self._wss = kwargs["wss"]
        self._access_key = kwargs["access_key"]
        self._secret_key = kwargs["secret_key"]
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_callback = kwargs.get("init_callback")
        self._error_callback = kwargs.get("error_callback")

        self._raw_symbol = self._symbol.replace("/", "").lower()
        self._order_channel = "orders.{}".format(self._raw_symbol)
        self._assets = {}
        self._orders = {}

        # Initialize our REST API client.
        self._rest_api = HuobiRestAPI(
            self._access_key,
            self._secret_key,
            self._host,
        )

        url = self._wss + "/ws/v1"
        self._ws = Websocket(url,
                             self.connected_callback,
                             process_binary_callback=self.process_binary)
Example #9
0
 async def _init_websocket(self):
     """Initialize Websocket connection."""
     # Get listen key first.
     success, error = await self._rest_api.get_listen_key()
     if error:
         e = Error("get listen key failed: {}".format(error))
         logger.error(e, caller=self)
         SingleTask.run(self._error_callback, e)
         SingleTask.run(self._init_callback, False)
         return
     self._listen_key = success["listenKey"]
     uri = "/ws/" + self._listen_key
     url = urljoin(self._wss, uri)
     self._ws = Websocket(url, self.connected_callback, process_callback=self.process)
Example #10
0
 async def _connect(self) -> None:
     logger.info("url:", self._url, caller=self)
     proxy = config.proxy
     session = aiohttp.ClientSession()
     try:
         self._ws = await session.ws_connect(self._url, proxy=proxy)
     except aiohttp.ClientConnectorError:
         logger.error("connect to Websocket server error! url:",
                      self._url,
                      caller=self)
         return
     if self._connected_callback:
         SingleTask.run(self._connected_callback)
     SingleTask.run(self._receive)
Example #11
0
    def __init__(self,
                 strategy=None,
                 platform=None,
                 symbol=None,
                 host=None,
                 wss=None,
                 account=None,
                 access_key=None,
                 secret_key=None,
                 passphrase=None,
                 order_update_callback=None,
                 position_update_callback=None,
                 init_callback=None,
                 error_callback=None,
                 **kwargs):
        """Initialize trade object."""
        kwargs["strategy"] = strategy
        kwargs["platform"] = platform
        kwargs["symbol"] = symbol
        kwargs["host"] = host
        kwargs["wss"] = wss
        kwargs["account"] = account
        kwargs["access_key"] = access_key
        kwargs["secret_key"] = secret_key
        kwargs["passphrase"] = passphrase
        kwargs["order_update_callback"] = self._on_order_update_callback
        kwargs["position_update_callback"] = self._on_position_update_callback
        kwargs["init_callback"] = self._on_init_callback
        kwargs["error_callback"] = self._on_error_callback

        self._raw_params = copy.copy(kwargs)
        self._order_update_callback = order_update_callback
        self._position_update_callback = position_update_callback
        self._init_callback = init_callback
        self._error_callback = error_callback

        if platform == const.BINANCE:
            from aioquant.platform.binance import BinanceTrade as T
        elif platform == const.HUOBI:
            from aioquant.platform.huobi import HuobiTrade as T
        elif platform == const.OKEX:
            from aioquant.platform.okex import OKExTrade as T
        else:
            logger.error("platform error:", platform, caller=self)
            e = Error("platform error")
            SingleTask.run(self._on_error_callback, e)
            SingleTask.run(self._on_init_callback, False)
            return
        self._t = T(**kwargs)
Example #12
0
    async def create_order(self,
                           action,
                           symbol,
                           price,
                           quantity,
                           order_type=ORDER_TYPE_LIMIT,
                           client_oid=None):
        """Create an order.
        Args:
            action: Action type, `BUY` or `SELL`.
            symbol: Trading pair, e.g. `BTC-USDT`.
            price: Order price.
            quantity: Order quantity.
            order_type: Order type, `MARKET` or `LIMIT`.
            client_oid: Client order id, default is `None`.

        Returns:
            success: Success results, otherwise it's None.
            error: Error information, otherwise it's None.
        """
        uri = "/api/spot/v3/orders"
        data = {
            "side": "buy" if action == ORDER_ACTION_BUY else "sell",
            "instrument_id": symbol,
            "margin_trading": 1
        }
        if order_type == ORDER_TYPE_LIMIT:
            data["type"] = "limit"
            data["price"] = price
            data["size"] = quantity
        elif order_type == ORDER_TYPE_MARKET:
            data["type"] = "market"
            if action == ORDER_ACTION_BUY:
                data["notional"] = quantity  # buy price.
            else:
                data["size"] = quantity  # sell quantity.
        else:
            logger.error("order_type error! order_type:",
                         order_type,
                         caller=self)
            return None, "order type error!"
        if client_oid:
            data["client_oid"] = client_oid
        result, error = await self.request("POST", uri, body=data, auth=True)
        return result, error
Example #13
0
    async def process_binary(self, raw):
        """Process binary message that received from websocket.

        Args:
            raw: Binary message received from websocket.

        Returns:
            None.
        """
        msg = json.loads(gzip.decompress(raw).decode())
        logger.debug("msg:", msg, caller=self)

        op = msg.get("op")

        if op == "auth":
            if msg["err-code"] != 0:
                e = Error(
                    "Websocket connection authorized failed: {}".format(msg))
                logger.error(e, caller=self)
                SingleTask.run(self._error_callback, e)
                SingleTask.run(self._init_callback, False)
                return
            logger.info("Websocket connection authorized successfully.",
                        caller=self)
            await self._auth_success_callback()
        elif op == "ping":  # ping
            params = {"op": "pong", "ts": msg["ts"]}
            await self._ws.send(params)
        elif op == "sub":
            if msg["topic"] != self._order_channel:
                return
            if msg["err-code"] != 0:
                e = Error("subscribe order event error: {}".format(msg))
                SingleTask.run(self._error_callback, e)
                SingleTask.run(self._init_callback, False)
            else:
                SingleTask.run(self._init_callback, True)
        elif op == "notify":
            if msg["topic"] != self._order_channel:
                return
            data = msg["data"]
            data["utime"] = msg["ts"]
            self._update_order(data)
Example #14
0
 async def _receive(self):
     """Receive stream message from Websocket connection."""
     async for msg in self.ws:
         if msg.type == aiohttp.WSMsgType.TEXT:
             if self._process_callback:
                 try:
                     data = json.loads(msg.data)
                 except:
                     data = msg.data
                 SingleTask.run(self._process_callback, data)
         elif msg.type == aiohttp.WSMsgType.BINARY:
             if self._process_binary_callback:
                 SingleTask.run(self._process_binary_callback, msg.data)
         elif msg.type == aiohttp.WSMsgType.CLOSED:
             logger.warn("receive event CLOSED:", msg, caller=self)
             SingleTask.run(self.reconnect)
         elif msg.type == aiohttp.WSMsgType.ERROR:
             logger.error("receive event ERROR:", msg, caller=self)
         else:
             logger.warn("unhandled msg:", msg, caller=self)
Example #15
0
    async def create_order(self, action, price, quantity, *args, **kwargs):
        """Create an order.

        Args:
            action: Trade direction, `BUY` or `SELL`.
            price: Price of each order.
            quantity: The buying or selling quantity.
            kwargs:
                order_type: Order type, `LIMIT` / `MARKET`, default is `LIMIT`.

        Returns:
            order_id: Order id if created successfully, otherwise it's None.
            error: Error information, otherwise it's None.
        """
        order_type = kwargs.get("order_type", ORDER_TYPE_LIMIT)
        client_order_id = kwargs.get("client_order_id")
        if action == ORDER_ACTION_BUY:
            if order_type == ORDER_TYPE_LIMIT:
                t = "buy-limit"
            elif order_type == ORDER_TYPE_MARKET:
                t = "buy-market"
            else:
                e = Error(
                    "order_type error! order_type: {}".format(order_type))
                logger.error(e, caller=self)
                SingleTask.run(self._error_callback, e)
                return None, "order type error"
        elif action == ORDER_ACTION_SELL:
            if order_type == ORDER_TYPE_LIMIT:
                t = "sell-limit"
            elif order_type == ORDER_TYPE_MARKET:
                t = "sell-market"
            else:
                e = Error(
                    "order_type error! order_type:: {}".format(order_type))
                logger.error(e, caller=self)
                SingleTask.run(self._error_callback, e)
                return None, "order type error"
        else:
            logger.error("action error! action:", action, caller=self)
            e = Error("action error! action:: {}".format(action))
            logger.error(e, caller=self)
            SingleTask.run(self._error_callback, e)
            return None, "action error"
        result, error = await self._rest_api.create_order(
            self._raw_symbol, price, quantity, t, client_order_id)
        if error:
            SingleTask.run(self._error_callback, error)
            return None, error
        order_id = result["data"]
        return order_id, None
Example #16
0
    async def send(self, data) -> bool:
        """ Send message to Websocket server.

        Args:
            data: Message content, must be dict or string.

        Returns:
            If send successfully, return True, otherwise return False.
        """
        if not self.ws:
            logger.warn("Websocket connection not connected yet!", caller=self)
            return False
        if isinstance(data, dict):
            await self.ws.send_json(data)
        elif isinstance(data, str):
            await self.ws.send_str(data)
        else:
            logger.error("send message failed:", data, caller=self)
            return False
        logger.debug("send message:", data, caller=self)
        return True
    def __init__(self) -> None:
        """
        '吃盘口毛刺'的简化策略: 根据实时盘口变化取卖6和卖8的价格,并根据他们的平均价格来挂卖单
        即, average_price = (ask6_price + ask8_price) / 2 取指定位数的数据, EOS是4位;

        在策略启动的时候判断是否有挂单, 如果有挂单, 判断价格是否已经超过 ask6_price 和 ask8_price 的区间,
        如果超过那么撤单后再重新挂单.
        """
        self._symbol = "EOSUSDT"
        self._action = "SELL"
        self._quantity = "2.5"
        self._order_id = ""
        self._price = 0.0

        self._is_ok = False

        params = dict(
            strategy=config.strategy_name,
            platform=config.platform,
            symbol=config.symbol,
            account=config.account,  # 分布式...多个
            access_key=config.access_key,
            secret_key=config.secret_key,
            passphrase=config.passphrase,
            order_update_callback=self.on_order_update_callback,
            init_callback=self.on_init_callback,
            error_callback=self.on_error_callback,
        )

        self._trade = Trade(**params)

        if config.platform == BINANCE:
            LoopRunTask.register(self.dynamic_trade_with_binance, interval=2)
        elif config.platform == HUOBI:
            LoopRunTask.register(self.dynamic_trade_with_huobi, interval=2)
        elif config.platform == OKEX:
            LoopRunTask.register(self.dynamic_trade_with_okex, interval=2)
        else:
            logger.error("platform error:", config.platform, caller=self)
            quant.stop()
Example #18
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 aioquant.event import EventOrderbook
         EventOrderbook(Orderbook(platform, symbol)).subscribe(callback, multi)
     elif market_type == const.MARKET_TYPE_TRADE:
         from aioquant.event import EventTrade
         EventTrade(Trade(platform, symbol)).subscribe(callback, multi)
     elif market_type in [
         const.MARKET_TYPE_KLINE, const.MARKET_TYPE_KLINE_3M, const.MARKET_TYPE_KLINE_5M,
         const.MARKET_TYPE_KLINE_15M, const.MARKET_TYPE_KLINE_30M, const.MARKET_TYPE_KLINE_1H,
         const.MARKET_TYPE_KLINE_3H, const.MARKET_TYPE_KLINE_6H, const.MARKET_TYPE_KLINE_12H,
         const.MARKET_TYPE_KLINE_1D, const.MARKET_TYPE_KLINE_3D, const.MARKET_TYPE_KLINE_1W,
         const.MARKET_TYPE_KLINE_15D, const.MARKET_TYPE_KLINE_1MON, const.MARKET_TYPE_KLINE_1Y]:
         from aioquant.event import EventKline
         EventKline(Kline(platform, symbol, kline_type=market_type)).subscribe(callback, multi)
     else:
         logger.error("market_type error:", market_type, caller=self)
Example #19
0
    async def connect(self, reconnect=False):
        """Connect to RabbitMQ server and create default exchange.

        Args:
            reconnect: If this invoke is a re-connection ?
        """
        logger.info("host:", self._host, "port:", self._port, caller=self)
        if self._connected:
            return

        # Create a connection.
        try:
            transport, protocol = await aioamqp.connect(host=self._host, port=self._port, login=self._username,
                                                        password=self._password, login_method="PLAIN")
        except Exception as e:
            logger.error("connection error:", e, caller=self)
            return
        finally:
            if self._connected:
                return
        channel = await protocol.channel()
        self._protocol = protocol
        self._channel = channel
        self._connected = True
        logger.info("Rabbitmq initialize success!", caller=self)

        # Create default exchanges.
        exchanges = ["Orderbook", "Kline", "Trade"]
        for name in exchanges:
            await self._channel.exchange_declare(exchange_name=name, type_name="topic")
        logger.debug("create default exchanges success!", caller=self)

        if reconnect:
            self._bind_and_consume()
        else:
            # Maybe we should waiting for all modules to be initialized successfully.
            asyncio.get_event_loop().call_later(5, self._bind_and_consume)
Example #20
0
    async def process_binary(self, raw):
        """Process binary message that received from websocket.

        Args:
            raw: Binary message received from websocket.

        Returns:
            None.
        """
        decompress = zlib.decompressobj(-zlib.MAX_WBITS)
        msg = decompress.decompress(raw)
        msg += decompress.flush()
        msg = msg.decode()
        if msg == "pong":
            return
        logger.debug("msg:", msg, caller=self)
        msg = json.loads(msg)

        # Authorization message received.
        if msg.get("event") == "login":
            if not msg.get("success"):
                e = Error(
                    "Websocket connection authorized failed: {}".format(msg))
                logger.error(e, caller=self)
                SingleTask.run(self._error_callback, e)
                SingleTask.run(self._init_callback, False)
                return
            logger.info("Websocket connection authorized successfully.",
                        caller=self)

            # Fetch orders from server. (open + partially filled)
            order_infos, error = await self._rest_api.get_open_orders(
                self._raw_symbol)
            if error:
                e = Error("get open orders error: {}".format(msg))
                SingleTask.run(self._error_callback, e)
                SingleTask.run(self._init_callback, False)
                return
            if len(order_infos) > 100:
                logger.warn("order length too long! (more than 100)",
                            caller=self)
            for order_info in order_infos:
                order_info["ctime"] = order_info["created_at"]
                order_info["utime"] = order_info["timestamp"]
                self._update_order(order_info)

            # Subscribe order channel.
            data = {"op": "subscribe", "args": [self._order_channel]}
            await self._ws.send(data)
            return

        # Subscribe response message received.
        if msg.get("event") == "subscribe":
            if msg.get("channel") == self._order_channel:
                SingleTask.run(self._init_callback, True)
            else:
                e = Error("subscribe order event error: {}".format(msg))
                SingleTask.run(self._error_callback, e)
                SingleTask.run(self._init_callback, False)
            return

        # Order update message received.
        if msg.get("table") == "spot/order":
            for data in msg["data"]:
                data["ctime"] = data["timestamp"]
                data["utime"] = data["last_fill_time"]
                self._update_order(data)
Example #21
0
    async def fetch(cls,
                    method,
                    url,
                    params=None,
                    body=None,
                    data=None,
                    headers=None,
                    timeout=30,
                    **kwargs):
        """ Create a HTTP request.

        Args:
            method: HTTP request method. `GET` / `POST` / `PUT` / `DELETE`
            url: Request url.
            params: HTTP query params.
            body: HTTP request body, string or bytes format.
            data: HTTP request body, dict format.
            headers: HTTP request header.
            timeout: HTTP request timeout(seconds), default is 30s.

            kwargs:
                proxy: HTTP proxy.

        Return:
            code: HTTP response code.
            success: HTTP response data. If something wrong, this field is None.
            error: If something wrong, this field will holding a Error information, otherwise it's None.

        Raises:
            HTTP request exceptions or response data parse exceptions. All the exceptions will be captured and return
            Error information.
        """
        session = cls._get_session(url)
        if not kwargs.get("proxy"):
            kwargs[
                "proxy"] = config.proxy  # If there is a `HTTP PROXY` Configuration in config file?
        try:
            if method == "GET":
                response = await session.get(url,
                                             params=params,
                                             headers=headers,
                                             timeout=timeout,
                                             **kwargs)
            elif method == "POST":
                response = await session.post(url,
                                              params=params,
                                              data=body,
                                              json=data,
                                              headers=headers,
                                              timeout=timeout,
                                              **kwargs)
            elif method == "PUT":
                response = await session.put(url,
                                             params=params,
                                             data=body,
                                             json=data,
                                             headers=headers,
                                             timeout=timeout,
                                             **kwargs)
            elif method == "DELETE":
                response = await session.delete(url,
                                                params=params,
                                                data=body,
                                                json=data,
                                                headers=headers,
                                                timeout=timeout,
                                                **kwargs)
            else:
                error = "http method error!"
                return None, None, error
        except Exception as e:
            logger.error("method:",
                         method,
                         "url:",
                         url,
                         "headers:",
                         headers,
                         "params:",
                         params,
                         "body:",
                         body,
                         "data:",
                         data,
                         "Error:",
                         e,
                         caller=cls)
            return None, None, e
        code = response.status
        if code not in (200, 201, 202, 203, 204, 205, 206):
            text = await response.text()
            logger.error("method:",
                         method,
                         "url:",
                         url,
                         "headers:",
                         headers,
                         "params:",
                         params,
                         "body:",
                         body,
                         "data:",
                         data,
                         "code:",
                         code,
                         "result:",
                         text,
                         caller=cls)
            return code, None, text
        try:
            result = await response.json()
        except:
            result = await response.text()
            logger.debug("response data is not json format!",
                         "method:",
                         method,
                         "url:",
                         url,
                         "headers:",
                         headers,
                         "params:",
                         params,
                         "body:",
                         body,
                         "data:",
                         data,
                         "code:",
                         code,
                         "result:",
                         result,
                         caller=cls)
        logger.debug("method:",
                     method,
                     "url:",
                     url,
                     "headers:",
                     headers,
                     "params:",
                     params,
                     "body:",
                     body,
                     "data:",
                     data,
                     "code:",
                     code,
                     "result:",
                     json.dumps(result),
                     caller=cls)
        return code, result, None
Example #22
0
    def _update_order(self, order_info):
        """Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        Note:
            order-state: Order status, `submitting` / `submitted` / `partial-filled` / `partial-canceled` / `filled` / `canceled`
        """
        order_id = str(order_info["order-id"])
        action = ORDER_ACTION_BUY if order_info["order-type"] in [
            "buy-market", "buy-limit"
        ] else ORDER_ACTION_SELL
        state = order_info["order-state"]
        remain = "%.8f" % float(order_info["unfilled-amount"])
        avg_price = "%.8f" % float(order_info["price"])
        ctime = order_info["created-at"]
        utime = order_info["utime"]

        if state == "canceled":
            status = ORDER_STATUS_CANCELED
        elif state == "partial-canceled":
            status = ORDER_STATUS_CANCELED
        elif state == "submitting":
            status = ORDER_STATUS_SUBMITTED
        elif state == "submitted":
            status = ORDER_STATUS_SUBMITTED
        elif state == "partial-filled":
            status = ORDER_STATUS_PARTIAL_FILLED
        elif state == "filled":
            status = ORDER_STATUS_FILLED
        else:
            e = Error("status error! order_info: {}".format(order_info))
            logger.error(e, caller=self)
            SingleTask.run(self._error_callback, e)
            return None

        order = self._orders.get(order_id)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_id": order_id,
                "action": action,
                "symbol": self._symbol,
                "price": "%.8f" % float(order_info["order-price"]),
                "quantity": "%.8f" % float(order_info["order-amount"]),
                "remain": remain,
                "status": status
            }
            order = Order(**info)
            self._orders[order_id] = order
        order.remain = remain
        order.status = status
        order.avg_price = avg_price
        order.ctime = ctime
        order.utime = utime

        SingleTask.run(self._order_update_callback, copy.copy(order))
        if status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_id)