Пример #1
0
    def _update_asset(self, data):
        """ Asset update.

        Args:
            data: asset data.
        
        Returns:
            None.
        """
        assets = {}
        for item in data["data"]:
            symbol = item["symbol"].upper()
            total = float(item["margin_balance"])
            free = float(item["margin_available"])
            locked = float(item["margin_frozen"])
            premium_frozen = float(item.get("premium_frozen", 0))
            premium_in = float(item.get("premium_in", 0))
            premium_out = float(item.get("premium_out", 0))
            delta = float(item.get("delta", 0))
            gamma = float(item.get("gamma", 0))
            theta = float(item.get("theta", 0))
            vega = float(item.get("vega", 0))
            option_value = float(item["option_value"])
            if total > 0:
                assets[symbol] = {
                    "total": "%.8f" % total,
                    "free": "%.8f" % free,
                    "locked": "%.8f" % locked,
                    "premium_frozen": "%.8f" % premium_frozen,
                    "premium_in": "%.8f" % premium_in,
                    "premium_out": "%.8f" % premium_out,
                    "delta": "%.8f" % delta,
                    "gamma": "%.8f" % gamma,
                    "theta": "%.8f" % theta,
                    "vega": "%.8f" % vega,
                    "option_value": "%.8f" % option_value
                }
        if assets == self._assets:
            update = False
        else:
            update = True

        if hasattr(self._assets, "assets") is False:
            info = {
                "platform": self._platform,
                "account": self._account,
                "assets": assets,
                "timestamp": tools.get_cur_timestamp_ms(),
                "update": update
            }
            asset = Asset(**info)
            self._assets = asset
            SingleTask.run(self._asset_update_callback,
                           copy.copy(self._assets))
        else:
            for symbol in assets:
                self._assets.assets.update({symbol: assets[symbol]})
            self._assets.timestamp = tools.get_cur_timestamp_ms()
            SingleTask.run(self._asset_update_callback,
                           copy.copy(self._assets))
Пример #2
0
 async def process_kline(self, data):
     """ process kline data
     """
     if not self._klines_init:
         logger.info("klines not init. current:", len(self.klines), caller=self)
         return
     channel = data.get("ch")
     symbol = self._c_to_s[channel]
     d = data.get("tick")
     # print("process_kline", symbol)
     # print(d)
     info = {
         "platform": self._platform,
         "id": int(d["id"]),
         "symbol": symbol,
         "open": "%.8f" % d["open"],
         "high": "%.8f" % d["high"],
         "low": "%.8f" % d["low"],
         "close": "%.8f" % d["close"],
         "volume": int(d["vol"]),
         "amount": "%.8f" % d["amount"],
         "timestamp": int(data.get("ts")),
         "kline_type": MARKET_TYPE_KLINE
     }
     kline = Kline(**info)
     if kline.id == self._klines[-1].id:
         self._klines.pop()
     self._klines.append(kline)
     SingleTask.run(self._kline_update_callback, copy.copy(kline))
Пример #3
0
    async def auth_callback(self, data):
        if data["err-code"] != 0:
            e = Error(
                "Websocket connection authorized failed: {}".format(data))
            logger.error(e, caller=self)
            SingleTask.run(self._init_success_callback, False, e)
            return
        self._subscribe_order_ok = False
        self._subscribe_position_ok = False
        self._subscribe_asset_ok = False

        # subscribe order
        data = {
            "op": "sub",
            "cid": tools.get_uuid1(),
            "topic": self._order_channel
        }
        await self.ws.send_json(data)

        # subscribe position
        data = {
            "op": "sub",
            "cid": tools.get_uuid1(),
            "topic": self._position_channel
        }
        await self.ws.send_json(data)

        # subscribe asset
        data = {
            "op": "sub",
            "cid": tools.get_uuid1(),
            "topic": self._asset_channel
        }
        await self.ws.send_json(data)
Пример #4
0
 async def connected_callback(self):
     """
     链接成功初始数据和加监听
     :return:
     """
     self._init_data()
     SingleTask.run(self._add_sub)
Пример #5
0
 async def process_orderbook(self, data):
     """ process orderbook data
     """
     channel = data.get("ch")
     symbol = self._c_to_s[channel]
     d = data.get("tick")
     asks, bids = [], []
     if d.get("asks"):
         for item in d.get("asks")[:self._orderbook_length]:
             price = "%.8f" % item[0]
             quantity = "%.8f" % item[1]
             asks.append([price, quantity])
     if d.get("bids"):
         for item in d.get("bids")[:self._orderbook_length]:
             price = "%.8f" % item[0]
             quantity = "%.8f" % item[1]
             bids.append([price, quantity])
     info = {
         "platform": self._platform,
         "symbol": symbol,
         "asks": asks,
         "bids": bids,
         "timestamp": d.get("ts")
     }
     orderbook = Orderbook(**info)
     self._orderbooks.append(orderbook)
     SingleTask.run(self._orderbook_update_callback, copy.copy(orderbook))
     logger.debug("symbol:", symbol, "orderbook:", orderbook, caller=self)
Пример #6
0
    async def _on_position_update_callback(self, position: Position):
        """ Position information update callback.

        Args:
            position: Position object.
        """
        if self._position_update_callback:
            SingleTask.run(self._position_update_callback, position)
Пример #7
0
    async def _on_order_update_callback(self, order: Order):
        """ Order information update callback.

        Args:
            order: Order object.
        """
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, order)
Пример #8
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_FUTURE
        self._symbol = kwargs["symbol"].split('_')[0]
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._position_update_callback = kwargs.get("position_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        url = self._wss + "/notification"
        super(HuobiFutureTrade, 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.lower())
        self._position_channel = "positions.{symbol}".format(symbol=self._symbol.lower())
        self._asset_channel = "accounts.{symbol}".format(symbol=self._symbol.lower())

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

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

        self.initialize()
Пример #9
0
 def _init_data(self):
     """
     初始必要数据
     :return:
     """
     async def init_history_Klines():
         success, error = await self._rest_api.get_klines(contract_type=self._contract_type,
                                                          period=self._klines_period,
                                                          size=self._klines_length)
         self._init_history_kline_callback(success, error)
     SingleTask.run(init_history_Klines)
Пример #10
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)
Пример #11
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
        elif platform == const.HUOBI_USDT_SWAP:
            from alpha.platforms.huobi_usdt_swap_trade import HuobiUsdtSwapTrade as T
        elif platform == const.HUOBI_USDT_SWAP_CROSS:
            from alpha.platforms.huobi_usdt_swap_cross_trade import HuobiUsdtSwapCrossTrade 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)
Пример #12
0
 def _update_position(self, data):
     # print("_update_position", self._symbol)
     # print(data)
     for position_info in data["data"]:
         if position_info["symbol"] != self._symbol:
             continue
         if position_info["contract_type"] != self._contract_type:
             continue
         if position_info["direction"] == "buy":
             self._position.long_quantity = int(position_info["volume"])
             self._position.long_avg_price = position_info["cost_hold"]
         else:
             self._position.short_quantity = int(position_info["volume"])
             self._position.short_avg_price = position_info["cost_hold"]
         # self._position.liquid_price = None
         self._position.utime = data["ts"]
         SingleTask.run(self._position_update_callback, copy.copy(self._position))
Пример #13
0
    def _update_asset(self, data):
        """ Asset update.

        Args:
            data: asset data.
        
        Returns:
            None.
        """
        assets = {}
        for item in data["data"]:
            symbol = item["margin_account"].upper()
            total = float(item["margin_balance"])
            #free = float(item["margin_available"])
            locked = float(item["margin_frozen"]) + float(
                item["margin_position"])
            free = total - locked
            if total > 0:
                assets[symbol] = {
                    "total": "%.8f" % total,
                    "free": "%.8f" % free,
                    "locked": "%.8f" % locked
                }
        if assets == self._assets:
            update = False
        else:
            update = True
        if hasattr(self._assets, "assets") is False:
            info = {
                "platform": self._platform,
                "account": self._account,
                "assets": assets,
                "timestamp": tools.get_cur_timestamp_ms(),
                "update": update
            }
            asset = Asset(**info)
            self._assets = asset
            SingleTask.run(self._asset_update_callback,
                           copy.copy(self._assets))
        else:
            for symbol in assets:
                self._assets.assets.update({symbol: assets[symbol]})
            self._assets.timestamp = tools.get_cur_timestamp_ms()
            SingleTask.run(self._asset_update_callback,
                           copy.copy(self._assets))
Пример #14
0
    def _update_position(self, data):
        """ Position update.

        Args:
            position_info: Position information.

        Returns:
            None.
        """
        for position_info in data["data"]:
            if position_info["contract_type"] != self._contract_type or position_info["symbol"] != self._symbol:
                continue
            if position_info["direction"] == "buy":
                self._position.long_quantity = int(position_info["volume"])
                self._position.long_avg_price = position_info["cost_open"]
            else:
                self._position.short_quantity = int(position_info["volume"])
                self._position.short_avg_price = position_info["cost_open"]
            # self._position.liquid_price = None
            self._position.utime = data["ts"]
            SingleTask.run(self._position_update_callback, copy.copy(self._position))
Пример #15
0
 async def process_trade(self, data):
     """ process trade
     """
     channel = data.get("ch")
     symbol = self._c_to_s[channel]
     ticks = data.get("tick")
     for tick in ticks["data"]: 
         direction = tick.get("direction")
         price = tick.get("price")
         quantity = tick.get("amount")
         info = {
             "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")
         }
         trade = Trade(**info)
         self._trades.append(trade)
         SingleTask.run(self._trade_update_callback, copy.copy(trade))
         logger.debug("symbol:", symbol, "trade:", trade, caller=self)
Пример #16
0
    async def process_kline(self, data):
        """ process kline data
        """
        channel = data.get("ch")
        symbol = self._c_to_s[channel]
        d = data.get("tick")
        info = {
            "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
        }
        kline = Kline(**info)
        self._klines.append(kline)
        SingleTask.run(self._kline_update_callback, copy.copy(kline))

        logger.debug("symbol:", symbol, "kline:", kline, caller=self)
Пример #17
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)
Пример #18
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.
        """
        if order_info["contract_code"] != self._symbol:
            return
        order_no = str(order_info["order_id"])
        status = order_info["status"]

        order = self._orders.get(order_no)
        if not order:
            if order_info["direction"] == "buy":
                if order_info["offset"] == "open":
                    trade_type = TRADE_TYPE_BUY_OPEN
                else:
                    trade_type = TRADE_TYPE_BUY_CLOSE
            else:
                if order_info["offset"] == "close":
                    trade_type = TRADE_TYPE_SELL_CLOSE
                else:
                    trade_type = TRADE_TYPE_SELL_OPEN

            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "client_order_id":
                order_info.get("client_order_id"),
                "order_price_type":
                order_info.get("order_price_type"),
                "order_type":
                order_info["order_type"],
                "action":
                ORDER_ACTION_BUY
                if order_info["direction"] == "buy" else ORDER_ACTION_SELL,
                "symbol":
                self._symbol + '/' + self._contract_type,
                "price":
                order_info["price"],
                "quantity":
                order_info["volume"],
                "trade_type":
                trade_type
            }
            order = Order(**info)
            self._orders[order_no] = order

        order.trade_quantity = None
        order.trade_price = None
        if order_info.get("trade"):
            quantity = 0
            price = 0
            amount = 0
            count = len(order_info.get("trade"))
            for trade in order_info.get("trade"):
                order.role = trade.get("role")
                quantity += float(trade.get("trade_volume"))
                amount += float(
                    trade.get("trade_volume") * trade.get("trade_price"))
            price = amount / quantity
            order.trade_quantity = int(quantity)
            order.trade_price = price

        if status in [1, 2, 3]:
            order.status = ORDER_STATUS_SUBMITTED
        elif status == 4:
            order.status = ORDER_STATUS_PARTIAL_FILLED
            order.remain = int(order.quantity) - int(
                order_info["trade_volume"])
        elif status == 6:
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
        elif status in [5, 7]:
            order.status = ORDER_STATUS_CANCELED
            order.remain = int(order.quantity) - int(
                order_info["trade_volume"])
        else:
            return

        order.avg_price = order_info["trade_avg_price"]
        order.ctime = order_info["created_at"]
        order.utime = order_info["ts"]

        SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [
                ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED
        ]:
            self._orders.pop(order_no)

        # publish order
        logger.info("symbol:", order.symbol, "order:", order, caller=self)
Пример #19
0
    def _update_order(self, order_info):
        # print("_update_order")
        # print(order_info)
        if order_info["symbol"] != self._symbol:
            return
        if order_info["contract_type"] != self._contract_type:
            return
        order_no = str(order_info["order_id"])
        status = order_info["status"]

        order = self._orders.get(order_no)
        if not order:
            if order_info["direction"] == "buy":
                if order_info["offset"] == "open":
                    trade_type = TRADE_TYPE_BUY_OPEN
                else:
                    trade_type = TRADE_TYPE_BUY_CLOSE
            else:
                if order_info["offset"] == "close":
                    trade_type = TRADE_TYPE_SELL_CLOSE
                else:
                    trade_type = TRADE_TYPE_SELL_OPEN

            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY if order_info["direction"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol + '/' + self._contract_type,
                "price": order_info["price"],
                "quantity": order_info["volume"],
                "trade_type": trade_type
            }
            order = Order(**info)
            self._orders[order_no] = order

        if status in [1, 2, 3]:
            order.status = ORDER_STATUS_SUBMITTED
        elif status == 4:
            order.status = ORDER_STATUS_PARTIAL_FILLED
            order.remain = int(order.quantity) - int(order_info["trade_volume"])
        elif status == 6:
            order.status = ORDER_STATUS_FILLED
            order.remain = 0
        elif status in [5, 7]:
            order.status = ORDER_STATUS_CANCELED
            order.remain = int(order.quantity) - int(order_info["trade_volume"])
        else:
            return

        order.avg_price = order_info["trade_avg_price"]
        order.ctime = order_info["created_at"]
        order.utime = order_info["ts"]

        SingleTask.run(self._order_update_callback, copy.copy(order))

        # Delete order that already completed.
        if order.status in [ORDER_STATUS_FAILED, ORDER_STATUS_CANCELED, ORDER_STATUS_FILLED]:
            self._orders.pop(order_no)
        
        # publish order
        logger.info("symbol:", order.symbol, "order:", order, caller=self)