Exemplo n.º 1
0
 async def cancel_orders(self):
     """  取消订单
     """
     order_nos = [orderno for orderno in self.trader.orders]
     if order_nos and self.last_ask_price != self.ask1_price:
         _, errors = await self.trader.revoke_order(*order_nos)
         if errors:
             logger.error(self.strategy,
                          "cancel future order error! error:",
                          errors,
                          caller=self)
         else:
             logger.info(self.strategy,
                         "cancel future order:",
                         order_nos,
                         caller=self)
Exemplo n.º 2
0
    def __init__(self,
                 strategy=None,
                 platform=None,
                 symbol=None,
                 host=None,
                 wss=None,
                 account=None,
                 access_key=None,
                 secret_key=None,
                 asset_update_callback=None,
                 order_update_callback=None,
                 position_update_callback=None,
                 init_success_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["asset_update_callback"] = asset_update_callback
        kwargs["order_update_callback"] = self._on_order_update_callback
        kwargs["position_update_callback"] = self._on_position_update_callback
        kwargs["init_success_callback"] = self._on_init_success_callback

        self._raw_params = copy.copy(kwargs)
        self._order_update_callback = order_update_callback
        self._position_update_callback = position_update_callback
        self._init_success_callback = init_success_callback

        if platform == const.HUOBI_SWAP:
            from alpha.platforms.huobi_swap_trade import HuobiSwapTrade as T
        elif platform == const.HUOBI_FUTURE:
            from alpha.platforms.huobi_future_trade import HuobiFutureTrade as T
        elif platform == const.HUOBI_OPTION:
            from alpha.platforms.huobi_option_trade import HuobiOptionTrade as T
        else:
            logger.error("platform error:", platform, caller=self)
            e = Error("platform error")
            SingleTask.run(self._init_success_callback, False, e)
            return
        kwargs.pop("platform")
        self._t = T(**kwargs)
Exemplo n.º 3
0
 async def cancel_orders(self):
     """  取消订单
     """
     order_nos = [ orderno for orderno in self.trader.orders ]
     #if order_nos and self.last_mark_price != self.mark_price:
     if order_nos:
         _, errors = await self.trader.revoke_order(*order_nos)
         if errors:
             logger.error(self.strategy,"cancel option order error! error:", errors, caller=self)
             # 出错则取消所有挂单
             _, errors = await self.trader.revoke_order()
             if errors:
                 logger.error(self.strategy,"cancel all option orders error! error:", errors, caller=self)
             else:
                 logger.info(self.strategy,"cancel all option orders success!", caller=self)
         else:
             logger.info(self.strategy,"cancel option order:", order_nos, caller=self)
Exemplo n.º 4
0
    def __init__(self, platform=None, symbol=None, contract_type=None, channels=None, orderbook_length=None,
                 orderbook_step=None, orderbooks_length=None, klines_length=None, klines_period=None,
                 trades_length=None, wss=None, orderbook_update_callback=None, kline_update_callback=None,
                 trade_update_callback=None, rest_api=None, **kwargs):
        """initialize trade object."""
        kwargs["platform"] = platform
        kwargs["symbol"] = symbol
        kwargs["channels"] = channels
        kwargs["orderbook_length"] = orderbook_length
        kwargs["orderbook_step"] = orderbook_step
        kwargs["orderbook_length"] = orderbook_length
        kwargs["orderbooks_length"] = orderbooks_length
        kwargs["klines_length"] = klines_length
        kwargs["klines_period"] = klines_period
        kwargs["trades_length"] = trades_length
        kwargs["wss"] = wss
        kwargs["orderbook_update_callback"] = orderbook_update_callback
        kwargs["kline_update_callback"] = kline_update_callback
        kwargs["trade_update_callback"] = trade_update_callback
        kwargs["rest_api"] = rest_api

        if contract_type == "this_week":
            kwargs["contract_type"] = symbol + "_CW"
        elif contract_type == "next_week":
            kwargs["contract_type"] = symbol + "_NW"
        elif contract_type == "quarter":
            kwargs["contract_type"] = symbol + "_CQ"
        else:
            logger.error("is deliverd. symbol:", symbol, "contract_type:", contract_type, caller=self)
            return

        self._raw_params = copy.copy(kwargs)
        self._on_orderbook_update_callback = orderbook_update_callback
        self._on_kline_update_callback = kline_update_callback
        self._on_trade_update_callback = trade_update_callback
        self._rest_api = rest_api

        if platform == const.HUOBI_SWAP:
            from alpha.platforms.swap.huobi_swap_market import HuobiSwapMarket as M
        if platform == const.HUOBI_DELIVERY:
            from alpha.platforms.delivery.huobi_delivery_market import HuobiDeliveryMarket as M
        else:
            logger.error("platform error:", platform, caller=self)
            return
        self._m = M(**kwargs)
Exemplo n.º 5
0
    def _symbol_to_channel(self, symbol, channel_type):
        """ Convert symbol to channel.

        Args:
            symbol: Trade pair name.such as BTC-USD
            channel_type: channel name, kline / ticker / depth.
        """
        if channel_type == "kline":
            channel = "market.{s}.kline.1min".format(s=symbol.upper())
        elif channel_type == "depth":
            channel = "market.{s}.depth.step6".format(s=symbol.upper())
        elif channel_type == "trade":
            channel = "market.{s}.trade.detail".format(s=symbol.upper())
        else:
            logger.error("channel type error! channel type:", channel_type, caller=self)
            return None
        self._c_to_s[channel] = symbol
        return channel
Exemplo n.º 6
0
def post(access_key: str,
         secret_key: str,
         host: str,
         path: str,
         data: dict = None) -> json:
    try:
        url = 'https://{}{}?{}'.format(
            host, path,
            get_url_suffix('post', access_key, secret_key, host, path))
        headers = {
            'Accept': 'application/json',
            'Content-type': 'application/json'
        }
        res = requests.post(url, json=data, headers=headers)
        data = res.json()
        return data
    except Exception as e:
        logger.error(e)
    return None
Exemplo n.º 7
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:
         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)
         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)
Exemplo n.º 8
0
 async def on_ticker(self, *args, **kwargs):
     if not self.trade_init_result:
         logger.error("trade not init.", caller=self)
         return
     if not self.market.init_data():
         logger.error("not init market data.", caller=self)
         return
     if not self.trader.init_data():
         logger.error("not init trader data.", caller=self)
         return
     klines = self.market.klines
     if klines[-1].id == self.last_open_order_time:
         logger.info("haved order. ordertime:",
                     self.last_open_order_time,
                     caller=self)
         return
     ma_point = interval_handler(values=klines,
                                 periods=self.periods,
                                 vtype="close")
     if ma_point[self.periods[0]][1] < ma_point[self.periods[1]][1]:
         if ma_point[self.periods[0]][0] >= ma_point[self.periods[1]][0]:
             print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                   "开多平空")
     elif ma_point[self.periods[0]][1] > ma_point[self.periods[1]][1]:
         if ma_point[self.periods[0]][0] <= ma_point[self.periods[1]][0]:
             print(time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()),
                   "开空平多")
Exemplo n.º 9
0
    async def process_binary(self, msg):
        """ Process binary message that received from Websocket connection.
        """
        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_json(hb_msg)
            return

        if channel.find("kline") != -1:
            await self.process_kline(data)

        elif channel.find("depth") != -1:
            await self.process_orderbook(data)
        
        elif channel.find("trade") != -1:
            await self.process_trade(data)
        else:
            logger.error("event error! msg:", msg, caller=self)
Exemplo n.º 10
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.get_event_loop().create_task(self._reconnect())
Exemplo n.º 11
0
 async def connected_callback(self):
     """ After create Websocket connection successfully, we will subscribing orderbook/trade events.
     """
     for ch in self._channels:
         if ch == "kline":
             channel = self._symbol_to_channel(self._symbol, "kline")
             if not channel:
                 continue
             kline = {"sub": channel}
             await self.ws.send_json(kline)
         elif ch == "orderbook":
             channel = self._symbol_to_channel(self._symbol, "depth")
             if not channel:
                 continue
             data = {"sub": channel}
             await self.ws.send_json(data)
         elif ch == "trade":
             channel = self._symbol_to_channel(self._symbol, "trade")
             if not channel:
                 continue
             data = {"sub": channel}
             await self.ws.send_json(data)
         else:
             logger.error("channel error! channel:", ch, caller=self)
Exemplo n.º 12
0
    def __init__(self, strategy=None, platform=None, symbol=None, contract_type=None, host=None, wss=None, account=None,
                 access_key=None, secret_key=None, asset_update_callback=None, order_update_callback=None,
                 position_update_callback=None, init_success_callback=None, rest_api=None, **kwargs):
        """initialize trade object."""
        kwargs["strategy"] = strategy
        kwargs["platform"] = platform
        kwargs["symbol"] = symbol
        kwargs["contract_type"] = contract_type
        kwargs["host"] = host
        kwargs["wss"] = wss
        kwargs["rest_api"] = rest_api
        kwargs["account"] = account
        kwargs["access_key"] = access_key
        kwargs["secret_key"] = secret_key
        kwargs["asset_update_callback"] = asset_update_callback
        kwargs["order_update_callback"] = self._on_order_update_callback
        kwargs["position_update_callback"] = self._on_position_update_callback
        kwargs["init_success_callback"] = self._on_init_success_callback

        self._raw_params = copy.copy(kwargs)
        self._order_update_callback = order_update_callback
        self._position_update_callback = position_update_callback
        self._init_success_callback = init_success_callback
        self._rest_api = rest_api

        if platform == const.HUOBI_SWAP:
            from alpha.platforms.swap.huobi_swap_trade import HuobiSwapTrade as T
        elif platform == const.HUOBI_DELIVERY:
            from alpha.platforms.delivery.huobi_delivery_trade import HuobiDeliveryTrade as T
        else:
            logger.error("platform error:", platform, caller=self)
            e = Error("platform error")
            SingleTask.run(self._init_success_callback, False, e)
            return
        kwargs.pop("platform")
        self._t = T(**kwargs)
Exemplo n.º 13
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("contract_type"):
            e = Error("param contract_type miss")
        if not kwargs.get("host"):
            kwargs["host"] = "https://api.hbdm.com"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://api.hbdm.com"
        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)
            if kwargs.get("init_success_callback"):
                SingleTask.run(kwargs["init_success_callback"], False, e)
            return

        self._account = kwargs["account"]
        self._strategy = kwargs["strategy"]
        self._platform = HUOBI_SWAP
        self._symbol = kwargs["symbol"]
        self._contract_type = kwargs["contract_type"]
        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._position_update_callback = kwargs.get("position_update_callback")
        self._asset_update_callback = kwargs.get("asset_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        url = self._wss + "/swap-notification"
        super(HuobiSwapTrade, self).__init__(url, send_hb_interval=5)

        self._assets = {
        }  # Asset detail, {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }.
        self._orders = {}  # Order objects, {"order_id": order, ...}.
        self._position = Position(self._platform, self._account,
                                  self._strategy,
                                  self._symbol + '/' + self._contract_type)

        self._order_channel = "orders.{symbol}".format(symbol=self._symbol)
        self._position_channel = "positions.{symbol}".format(
            symbol=self._symbol)
        self._asset_channel = "accounts.{symbol}".format(symbol=self._symbol)

        self._subscribe_order_ok = False
        self._subscribe_position_ok = False
        self._subscribe_asset_ok = False

        self._rest_api = HuobiSwapRestAPI(self._host, self._access_key,
                                          self._secret_key)

        self.initialize()
Exemplo n.º 14
0
 async def _send_heartbeat_msg(self, *args, **kwargs):
     data = {"op": "pong", "ts": str(int(time.time() * 1000))}
     if not self.ws:
         logger.error("Websocket connection not yeah!", caller=self)
         return
     await self.ws.send_json(data)
Exemplo n.º 15
0
    async def delta_hedging(self, *args, **kwargs):
        """ delta hedge
        """
        logger.debug("delta hedging", caller=self)
        option_delta = 0
        assets, error = await self.trader.rest_api.get_asset_info(
            self.raw_symbol)
        if error:
            logger.error(self.strategy,
                         "get option asset error! error:",
                         error,
                         caller=self)
        else:
            for item in assets["data"]:
                if item["symbol"] == self.raw_symbol:
                    o_margin_balance = item["margin_balance"]
                    o_delta = item["delta"]
                    o_gamma = item["gamma"]
                    o_theta = item["theta"]
                    o_vega = item["vega"]
                    option_delta = o_delta + o_margin_balance

            #增加delta对冲,使用期货对冲。
            accounts, error = await self.future_trader.rest_api.get_account_position(
                self.raw_symbol)
            if error:
                logger.error(self.strategy,
                             "get future account and position error! error:",
                             error,
                             caller=self)
            else:
                margin_balance = accounts["data"][0]["margin_balance"]
                long_position = 0
                short_position = 0
                delta_long = 0
                delta_short = 0
                long_last_price = 0
                short_last_price = 0
                for position in accounts["data"][0]["positions"]:
                    if position["direction"] == "buy":
                        long_position = position["volume"]
                        long_cost_open = position["cost_open"]
                        long_last_price = position["last_price"]
                    if position["direction"] == "sell":
                        short_position = position["volume"]
                        short_cost_open = position["cost_open"]
                        short_last_price = position["last_price"]
                if long_position:
                    delta_long = self.future_volume_usd * int(
                        long_position) / float(long_last_price)
                if short_position:
                    delta_short = self.future_volume_usd * int(
                        short_position) / float(short_last_price)
                future_delta = margin_balance - delta_short + delta_long
                t_delta = option_delta + future_delta
                orders_data = []
                # 对冲对应数量的币
                if abs(t_delta) >= self.delta_limit:
                    if t_delta > 0:
                        # 开空单
                        price = 0
                        volume = int(t_delta * long_last_price /
                                     self.future_volume_usd)
                        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_MARKET
                                })
                    else:
                        # 开多单
                        price = 0
                        volume = abs(
                            int(t_delta * long_last_price /
                                self.future_volume_usd))
                        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_MARKET
                                })

                if orders_data:
                    order_nos, error = await self.future_trader.create_orders(
                        orders_data)
                    if error:
                        logger.error(self.strategy,
                                     "create future order error! error:",
                                     error,
                                     caller=self)
                    else:
                        logger.info(self.strategy,
                                    "create future orders success:",
                                    order_nos,
                                    caller=self)
Exemplo n.º 16
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).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)
Exemplo n.º 17
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
        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("method:", method, "url:", url, "headers:", headers, "params:", params, "body:", body,
        #              "data:", data, "code:", code, "result:", json.dumps(result), caller=cls)
        return code, result, None