Ejemplo n.º 1
0
    async def _on_order_update_callback(self, order: Order):
        """ Order information update callback.

        Args:
            order: Order object.
        """
        o = {
            "platform": order.platform,
            "account": order.account,
            "strategy": order.strategy,
            "order_no": order.order_no,
            "action": order.action,
            "order_type": order.order_type,
            "symbol": order.symbol,
            "price": order.price,
            "quantity": order.quantity,
            "remain": order.remain,
            "status": order.status,
            "avg_price": order.avg_price,
            "trade_type": order.trade_type,
            "ctime": order.ctime,
            "utime": order.utime
        }
        EventOrder(**o).publish()
        if self._order_update_callback:
            SingleTask.run(self._order_update_callback, order)
Ejemplo n.º 2
0
    def _update_position(self, position_info):
        """ Position update.

        Args:
            position_info: Position information.

        Returns:
            None.
        """
        if len(
                position_info["holding"]
        ) == 0:  # When the length of `holding` is 0, specific all the position is closed
            self._position.update(0, 0, 0, 0, 0)
            return
        for item in position_info["holding"]:
            if item["side"] == "long":
                self._position.liquid_price = item["liquidation_price"]
                self._position.long_quantity = int(item["position"])
                self._position.long_avg_price = item["avg_cost"]
            elif item["side"] == "short":
                self._position.short_quantity = int(item["position"])
                self._position.short_avg_price = item["avg_cost"]
            else:
                continue
            self._position.utime = tools.utctime_str_to_mts(item["timestamp"])
        SingleTask.run(self._position_update_callback,
                       copy.copy(self.position))
Ejemplo n.º 3
0
def asset(resp, msg):
    token = msg["token"]
    trader = find_trader(token)
    if trader:

        async def _work(trader):
            success, error = await trader.get_assets()
            if error:
                r = {
                    "op": "asset",
                    "cid": msg.get("cid", ""),
                    "result": False,
                    "error_message": str(error)
                }
            else:
                r = {
                    "op": "asset",
                    "cid": msg.get("cid", ""),
                    "result": True,
                    "error_message": "",
                    "data": success.assets
                }
            await response(resp, r)

        SingleTask.run(_work, trader)
    else:
        r = {
            "op": "asset",
            "cid": msg.get("cid", ""),
            "result": False,
            "error_message": "Invalid token"
        }
        SingleTask.run(response, resp, r)
Ejemplo n.º 4
0
    def __init__(self):
        """ 初始化
        """
        super(CreateIndex, self).__init__()
        
        self.strategy = config.strategy
        self.platform = config.platforms[0]["platform"]
        self.symbols = config.platforms[0]["symbols"]

        #连接数据库
        self.t_depth_map = defaultdict(lambda:None)
        self.t_trade_map = defaultdict(lambda:None)
        self.t_kline_map = defaultdict(lambda:None)
        if config.mongodb:
            for sym in self.symbols:
                postfix = sym.replace('-','').replace('_','').replace('/','').lower() #将所有可能的情况转换为我们自定义的数据库表名规则
                #订单薄
                name = "t_orderbook_{}_{}".format(self.platform, postfix).lower()
                self.t_depth_map[sym] = MongoDB("db_market", name)
                #逐笔成交
                name = "t_trade_{}_{}".format(self.platform, postfix).lower()
                self.t_trade_map[sym] = MongoDB("db_market", name)
                #K线
                name = "t_kline_{}_{}".format(self.platform, postfix).lower()
                self.t_kline_map[sym] = MongoDB("db_custom_kline", name)
        #开始任务
        SingleTask.run(self._do_work)
Ejemplo n.º 5
0
 async def _auth_success_callback(self):
     """ 授权成功之后回调
     """
     # 获取当前未完成订单
     success, error = await self._rest_api.get_open_orders(self._raw_symbol)
     if error:
         e = Error("get open orders error: {}".format(error))
         if self._init_success_callback:
             SingleTask.run(self._init_success_callback, False, e)
         return
     for order_info in success:
         data = {
             "order-id": order_info["id"],
             "order-type": order_info["type"],
             "order-state": order_info["state"],
             "unfilled-amount": float(order_info["amount"]) - float(order_info["filled-amount"]),
             "order-price": float(order_info["price"]),
             "price": float(order_info["price"]),
             "order-amount": float(order_info["amount"]),
             "created-at": order_info["created-at"],
             "utime": order_info["created-at"],
         }
         self._update_order(data)
     # 订阅订单更新数据
     params = {
         "op": "sub",
         "topic": self._order_channel
     }
     await self.ws.send_json(params)
Ejemplo n.º 6
0
    def _update_position(self, position_info):
        """ Position update.

        Args:
            position_info: Position information.

        Returns:
            None.
        """
        self._position.leverage = position_info["leverage"]
        self._position.long_quantity = int(position_info["long_qty"])
        self._position.long_avg_price = position_info["long_avg_cost"]
        self._position.long_pnl_ratio = position_info["long_pnl_ratio"]
        self._position.long_pnl_unreal = position_info["long_unrealised_pnl"]
        self._position.long_pnl = position_info["long_settled_pnl"]
        self._position.short_quantity = int(position_info["short_qty"])
        self._position.short_avg_price = position_info["short_avg_cost"]
        self._position.short_pnl_ratio = position_info["short_pnl_ratio"]
        self._position.short_pnl_unreal = position_info["short_unrealised_pnl"]
        self._position.short_pnl = position_info["short_settled_pnl"]
        self._position.liquid_price = position_info["liquidation_price"]
        self._position.utime = tools.utctime_str_to_mts(position_info["updated_at"])
        self._position.long_pos_margin = position_info["long_margin"]
        self._position.short_pos_margin = position_info['short_margin']
        SingleTask.run(self._position_update_callback, copy.copy(self.position))

        # publish order
        EventPosition(**self.position.__dict__).publish()
        logger.info("position:", self.position, caller=self)
Ejemplo n.º 7
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)
            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 = OKEX_MARGIN
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

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

        url = self._wss + "/ws/v3"
        super(OKExMarginTrade, self).__init__(url, send_hb_interval=5)
        self.heartbeat_msg = "ping"

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

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

        # Subscribing AssetEvent.
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account,
                           self.on_event_asset_update)

        self.initialize()
Ejemplo n.º 8
0
def logout(resp, msg):
    token = msg["token"]
    trader = find_trader(token)
    if trader:
        trader.shutdown() #关闭接口
        k = app._my_trader_dict[token]["account"]
        if k:
            cb = app._my_callback
            del cb.ws_dict[k] #删除相应条目
        del app._my_trader_dict[token] #删除相应条目
        del resp._my_own_token_dict[token] #删除相应条目
        r = {
            "op": "logout",
            "cid": msg.get("cid", ""),
            "result": True,
            "error_message": ""
        }
        SingleTask.run(response, resp, r)
    else:
        r = {
            "op": "logout",
            "cid": msg.get("cid", ""),
            "result": False,
            "error_message": "Invalid token"
        }
        SingleTask.run(response, resp, r)
Ejemplo n.º 9
0
    def __init__(self, **kwargs):
        """ 初始化
        """
        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.gateio.ws"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://fx-ws.gateio.ws"
        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 = GATE_FUTURE
        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._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")
        self._contract_update_callback = kwargs.get('contract_update_callback')
        self._user_id = None

        url = self._wss + "/v4/ws"
        super(GateFutureTrade, self).__init__(url, send_hb_interval=5)
        self.heartbeat_msg = "ping"

        self._assets = {
        }  # 资产 {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # 订单 {"order_no": order, ... }
        self._position = Position(self._platform, self._account,
                                  self._strategy, self._symbol)

        # 初始化 REST API 对象
        self._rest_api = GateFutureRestAPI(self._host, self._access_key,
                                           self._secret_key)

        # 初始化资产订阅
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account,
                           self.on_event_asset_update)

        # 注册定时任务
        LoopRunTask.register(self._check_position_update, 1)  # 获取持仓
Ejemplo n.º 10
0
    def mongodb_init(cls,
                     host="127.0.0.1",
                     port=27017,
                     username="",
                     password="",
                     dbname="admin"):
        """ Initialize a connection pool for MongoDB.

        Args:
            host: Host for MongoDB server.
            port: Port for MongoDB server.
            username: Username for MongoDB server.
            password: Password for MongoDB server.
            dbname: DB name to connect for, default is `admin`.
        """
        if username and password:
            uri = "mongodb://{username}:{password}@{host}:{port}/{dbname}".format(
                username=quote_plus(username),
                password=quote_plus(password),
                host=quote_plus(host),
                port=port,
                dbname=dbname)
        else:
            uri = "mongodb://{host}:{port}/{dbname}".format(host=host,
                                                            port=port,
                                                            dbname=dbname)
        cls._mongo_client = motor.motor_asyncio.AsyncIOMotorClient(
            uri, connectTimeoutMS=5000, serverSelectionTimeoutMS=5000)
        #LoopRunTask.register(cls._check_connection, 2)
        SingleTask.call_later(cls._check_connection, 2)  #模拟串行定时器,避免并发
        logger.info("create mongodb connection pool.")
Ejemplo n.º 11
0
    def _update_kline(self, kline_info, symbol):
        """ kline update.

        Args:
            kline_info: kline information.

        Returns:
            None.
        """
        info = {
            "platform":
            self._platform,
            "symbol":
            symbol,
            "open":
            kline_info["open"],
            "high":
            kline_info["high"],
            "low":
            kline_info["low"],
            "close":
            kline_info["close"],
            "volume":
            kline_info["volume"],
            "timestamp":
            tools.utctime_str_to_mts(kline_info["startTime"],
                                     "%Y-%m-%dT%H:%M:%S+00:00"),
            "kline_type":
            MARKET_TYPE_KLINE
        }
        kline = Kline(**info)
        SingleTask.run(self.cb.on_kline_update_callback, kline)
Ejemplo n.º 12
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        """
        #new (accepted but not processed yet), open, or closed (filled or cancelled)

        #开仓
        #{"id": 742849571, "clientId": null, "market": "ETH-PERP", "type": "limit", "side": "buy", "price": 150.0, "size": 0.003, "status": "new", "filledSize": 0.0, "remainingSize": 0.003, "reduceOnly": false, "avgFillPrice": null, "postOnly": false, "ioc": false}

        #150->修改->151
        #{"id": 742849571, "clientId": null, "market": "ETH-PERP", "type": "limit", "side": "buy", "price": 150.0, "size": 0.003, "status": "closed", "filledSize": 0.0, "remainingSize": 0.0, "reduceOnly": false, "avgFillPrice": null, "postOnly": false, "ioc": false}
        #{"id": 742853455, "clientId": null, "market": "ETH-PERP", "type": "limit", "side": "buy", "price": 151.0, "size": 0.003, "status": "new", "filledSize": 0.0, "remainingSize": 0.003, "reduceOnly": false, "avgFillPrice": null, "postOnly": false, "ioc": false}

        #151->修改->187->成交
        #{"id": 742853455, "clientId": null, "market": "ETH-PERP", "type": "limit", "side": "buy", "price": 151.0, "size": 0.003, "status": "closed", "filledSize": 0.0, "remainingSize": 0.0, "reduceOnly": false, "avgFillPrice": null, "postOnly": false, "ioc": false}
        #{"id": 742862380, "clientId": null, "market": "ETH-PERP", "type": "limit", "side": "buy", "price": 187.0, "size": 0.003, "status": "closed", "filledSize": 0.003, "remainingSize": 0.0, "reduceOnly": false, "avgFillPrice": 186.96, "postOnly": false, "ioc": false}

        #市价全平仓位
        #{"id": 742875876, "clientId": null, "market": "ETH-PERP", "type": "market", "side": "sell", "price": null, "size": 0.003, "status": "closed", "filledSize": 0.003, "remainingSize": 0.0, "reduceOnly": true, "avgFillPrice": 186.79, "postOnly": false, "ioc": true}

        o = order_info["data"]

        order = self._convert_order_format(o)
        if order == None:
            return

        SingleTask.run(self.cb.on_order_update_callback, order)
Ejemplo n.º 13
0
    def _update_order(self, order_info):
        """ Order update.

        Args:
            order_info: Order information.

        Returns:
            None.
        """
        order_no = str(order_info["order_id"])
        state = order_info["state"]
        remain = float(order_info["size"]) - float(order_info["filled_size"])
        ctime = tools.utctime_str_to_mts(order_info["ctime"])
        utime = tools.utctime_str_to_mts(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)
            return None

        order = self._orders.get(order_no)
        if order:
            order.remain = remain
            order.status = status
            order.price = order_info["price"]
        else:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "action": ORDER_ACTION_BUY
                if order_info["side"] == "buy" else ORDER_ACTION_SELL,
                "symbol": self._symbol,
                "price": order_info["price"],
                "quantity": order_info["size"],
                "remain": remain,
                "status": status,
                "avg_price": order_info["price"]
            }
            order = Order(**info)
            self._orders[order_no] = order
        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_no)
Ejemplo n.º 14
0
    def _update_order(self, order_info):
        """ 更新订单信息
        @param order_info 订单信息
        * NOTE:
            order-state: 订单状态, submitting , submitted 已提交, partial-filled 部分成交, partial-canceled 部分成交撤销,
                filled 完全成交, canceled 已撤销
        """
        order_no = 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:
            logger.error("status error! order_info:", order_info, caller=self)
            return None

        order = self._orders.get(order_no)
        if not order:
            info = {
                "platform": self._platform,
                "account": self._account,
                "strategy": self._strategy,
                "order_no": order_no,
                "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_no] = 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_no)
Ejemplo n.º 15
0
    def __init__(self, **kwargs):
        """ 初始化
        """
        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.bitmex.com"
        if not kwargs.get("wss"):
            kwargs["wss"] = "wss://www.bitmex.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 = BITMEX
        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._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 + "/realtime"
        super(BitmexTrade, self).__init__(url, send_hb_interval=5)
        self.heartbeat_msg = "ping"

        self._order_channel = "order:{symbol}".format(symbol=self._symbol)  # 订单订阅频道
        self._position_channel = "position:{symbol}".format(symbol=self._symbol)  # 持仓订阅频道

        # 标记订阅订单、持仓是否成功
        self._subscribe_order_ok = False
        self._subscribe_position_ok = False

        self._assets = {}  # 资产 {"XBT": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}
        self._position = Position(self._platform, self._account, self._strategy, self._symbol)  # 仓位

        # 初始化REST API对象
        self._rest_api = BitmexAPI(self._host, self._access_key, self._secret_key)

        # 初始化资产订阅
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account, self.on_event_asset_update)

        self.initialize()
Ejemplo n.º 16
0
async def wshandler(request):
    resp = web.WebSocketResponse()
    available = resp.can_prepare(request)
    if not available:
        with open(WS_FILE, 'rb') as fp:
            return web.Response(body=fp.read(), content_type='text/html')

    await resp.prepare(request)
    
    resp._my_own_token_dict = {} #用于保存基于本套接字的所有交易通道
    
    resp._my_last_ts = tools.get_cur_timestamp_ms()
    request.app['sockets'].append(resp) #用于判断套接字是否还是活跃状态

    async for msg in resp: #开始接收消息
        if msg.type == web.WSMsgType.TEXT:
            try:
                data = json.loads(msg.data)
                await process(resp, data) #处理消息
                resp._my_last_ts = tools.get_cur_timestamp_ms() #保存最后活跃时间,用于判断套接字是否还是活跃状态
            except Exception as e:
                logger.error("process ERROR:", e)
                r = {
                    "op": "error",
                    "error_message": str(e)
                }
                SingleTask.run(response, resp, r) #产生错误,发送错误信息
    cleanup(resp) #清理此套接字下的所有交易通道
    return resp
Ejemplo n.º 17
0
async def process(resp, msg):
    """ 处理websocket上接收到的消息 text 类型
    """
    op = msg["op"]
    if op == "ping":
        r = {
            "op": "pong",
            "ts": msg["ts"]
        }
        SingleTask.run(response, resp, r)
    if op == "login":  #登录授权
        login(resp, msg)
    elif op == "place_order":  #下单
        place_order(resp, msg)
    elif op == "cancel_order":  #撤销订单
        cancel_order(resp, msg)
    elif op == "open_orders":  #查询当前未成交订单
        open_orders(resp, msg)
    elif op == "asset":   #查询账户资产
        asset(resp, msg)
    elif op == "position":   #查询当前持仓
        position(resp, msg)
    elif op == "symbol_info":   #查询符号信息
        symbol_info(resp, msg)
    elif op == "logout":   #退出登录
        logout(resp, msg)
Ejemplo n.º 18
0
    async def connected_callback(self):
        """ 建立连接之后,获取当前所有未完全成交的订单
        """
        order_infos, error = await self._rest_api.get_open_orders(
            self._raw_symbol)
        if error:
            return
        for order_info in order_infos:
            order_no = "{}_{}".format(order_info["orderId"],
                                      order_info["clientOrderId"])
            if order_info["status"] == "NEW":  # 部分成交
                status = ORDER_STATUS_SUBMITTED
            elif order_info["status"] == "PARTIALLY_FILLED":  # 部分成交
                status = ORDER_STATUS_PARTIAL_FILLED
            elif order_info["status"] == "FILLED":  # 完全成交
                status = ORDER_STATUS_FILLED
            elif order_info["status"] == "CANCELED":  # 取消
                status = ORDER_STATUS_CANCELED
            elif order_info["status"] == "REJECTED":  # 拒绝
                status = ORDER_STATUS_FAILED
            elif order_info["status"] == "EXPIRED":  # 过期
                status = ORDER_STATUS_FAILED
            else:
                logger.warn("unknown status:", order_info, caller=self)
                return

            info = {
                "platform":
                self._platform,
                "account":
                self._account,
                "strategy":
                self._strategy,
                "order_no":
                order_no,
                "action":
                order_info["side"],
                "order_type":
                order_info["type"],
                "symbol":
                self._symbol,
                "price":
                order_info["price"],
                "quantity":
                order_info["origQty"],
                "remain":
                float(order_info["origQty"]) -
                float(order_info["executedQty"]),
                "status":
                status,
                "ctime":
                order_info["time"],
                "utime":
                order_info["updateTime"]
            }
            order = Order(**info)
            self._orders[order_no] = order
            if self._order_update_callback:
                SingleTask.run(self._order_update_callback, order)
Ejemplo n.º 19
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)
            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 = BINANCE
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        super(BinanceTrade, self).__init__(self._wss)

        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_no: order, ... }

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

        # Subscribe our AssetEvent.
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account,
                           self.on_event_asset_update)

        # 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)
Ejemplo n.º 20
0
 def subscribe(self, callback, multi=False):
     """ 订阅此事件
     @param callback 回调函数
     @param multi 是否批量订阅消息,即routing_key为批量匹配
     """
     from quant.quant import quant
     self._callback = callback
     SingleTask.run(quant.event_center.subscribe, self, self.callback, multi)
Ejemplo n.º 21
0
 def enable_timer(self, interval=1):
     """使能定时器功能
     """
     if config.backtest or config.datamatrix:  #回测模式或者数据矩阵模式
         pass  #暂时不支持定时器的模拟
     else:  #实盘模式
         self._interval = interval
         SingleTask.call_later(self._later_call, self._interval)
Ejemplo n.º 22
0
    async def on_event_asset_update(self, asset: Asset):
        """ Asset data update callback.

        Args:
            asset: Asset object.
        """
        self._assets = asset
        SingleTask.run(self._asset_update_callback, asset)
Ejemplo n.º 23
0
    def _bind_and_consume(self):
        """ 绑定并开始消费事件消息
        """
        async def do_them():
            for event, callback, multi in self._subscribers:
                await self._initialize(event, callback, multi)

        SingleTask.run(do_them)
Ejemplo n.º 24
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)
Ejemplo n.º 25
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)
Ejemplo n.º 26
0
def position(resp, msg):
    token = msg["token"]
    trader = find_trader(token)
    if trader:
        kwargs = {}
        kwargs["symbol"] = msg["symbol"]

        async def _work(trader, kwargs):
            symbol = kwargs["symbol"]
            success, error = await trader.get_position(symbol)
            if error:
                r = {
                    "op": "position",
                    "cid": msg.get("cid", ""),
                    "result": False,
                    "error_message": str(error)
                }
            else:
                r = {
                    "op": "position",
                    "cid": msg.get("cid", ""),
                    "result": True,
                    "error_message": "",
                    "data": {
                        "margin_mode": success.margin_mode,
            
                        "long_quantity": success.long_quantity,
                        "long_avail_qty": success.long_avail_qty,
                        "long_open_price": success.long_open_price,
                        "long_hold_price": success.long_hold_price,
                        "long_liquid_price": success.long_liquid_price,
                        "long_unrealised_pnl": success.long_unrealised_pnl,
                        "long_leverage": success.long_leverage,
                        "long_margin": success.long_margin,
            
                        "short_quantity": success.short_quantity,
                        "short_avail_qty": success.short_avail_qty,
                        "short_open_price": success.short_open_price,
                        "short_hold_price": success.short_hold_price,
                        "short_liquid_price": success.short_liquid_price,
                        "short_unrealised_pnl": success.short_unrealised_pnl,
                        "short_leverage": success.short_leverage,
                        "short_margin": success.short_margin,

                        "utime": success.utime
                    }
                }
            await response(resp, r)

        SingleTask.run(_work, trader, kwargs)
    else:
        r = {
            "op": "position",
            "cid": msg.get("cid", ""),
            "result": False,
            "error_message": "Invalid token"
        }
        SingleTask.run(response, resp, r)
Ejemplo n.º 27
0
    def __init__(self, **kwargs):
        """ 初始化
        """
        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)
            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 = BINANCE
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        super(BinanceTrade, self).__init__(self._wss)

        self._raw_symbol = self._symbol.replace("/", "")  # 原始交易对

        self._listen_key = None  # websocket连接鉴权使用
        self._assets = {
        }  # 资产 {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # 订单

        # 初始化 REST API 对象
        self._rest_api = BinanceRestAPI(self._host, self._access_key,
                                        self._secret_key)

        # 初始化资产订阅
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account,
                           self.on_event_asset_update)

        # 30分钟重置一下listen key
        LoopRunTask.register(self._reset_listen_key, 60 * 30)
        # 获取listen key
        SingleTask.run(self._init_websocket)
Ejemplo n.º 28
0
    def __init__(self, strategy=None, platform=None, symbol=None, host=None, wss=None, account=None, access_key=None,
                 secret_key=None, passphrase=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["passphrase"] = passphrase
        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._order_update_callback = order_update_callback
        self._position_update_callback = position_update_callback
        self._init_success_callback = init_success_callback

        if platform == const.OKEX:
            from quant.platform.okex import OKExTrade as T
        elif platform == const.OKEX_MARGIN:
            from quant.platform.okex_margin import OKExMarginTrade as T
        elif platform == const.OKEX_FUTURE:
            from quant.platform.okex_future import OKExFutureTrade as T
        elif platform == const.OKEX_SWAP:
            from quant.platform.okex_swap import OKExSwapTrade as T
        elif platform == const.DERIBIT:
            from quant.platform.deribit import DeribitTrade as T
        elif platform == const.BITMEX:
            from quant.platform.bitmex import BitmexTrade as T
        elif platform == const.BINANCE:
            from quant.platform.binance import BinanceTrade as T
        elif platform == const.HUOBI:
            from quant.platform.huobi import HuobiTrade as T
        elif platform == const.COINSUPER:
            from quant.platform.coinsuper import CoinsuperTrade as T
        elif platform == const.COINSUPER_PRE:
            from quant.platform.coinsuper_pre import CoinsuperPreTrade as T
        elif platform == const.KRAKEN:
            from quant.platform.kraken import KrakenTrade as T
        elif platform == const.GATE:
            from quant.platform.gate import GateTrade as T
        elif platform == const.KUCOIN:
            from quant.platform.kucoin import KucoinTrade as T
        elif platform == const.HUOBI_FUTURE:
            from quant.platform.huobi_future import HuobiFutureTrade 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)
Ejemplo n.º 29
0
    def __init__(self, **kwargs):
        """ 初始化
        """
        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:10442"
        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)
            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 = OKEX
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        self._raw_symbol = self._symbol.replace("/", "-")  # 转换成交易所对应的交易对格式
        self._order_channel = "spot/order:{symbol}".format(symbol=self._raw_symbol)  # 订单订阅频道

        url = self._wss + "/ws/v3"
        super(OKExTrade, self).__init__(url, send_hb_interval=5)
        self.heartbeat_msg = "ping"

        self._assets = {}  # 资产 {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # 订单 {"order_no": order, ... }

        # 初始化 REST API 对象
        self._rest_api = OKExRestAPI(self._host, self._access_key, self._secret_key, self._passphrase)

        # 初始化资产订阅
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account, self.on_event_asset_update)

        self.initialize()
Ejemplo n.º 30
0
    def __init__(self, **kwargs):
        """ 初始化
        """
        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)
            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
        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._asset_update_callback = kwargs.get("asset_update_callback")
        self._order_update_callback = kwargs.get("order_update_callback")
        self._init_success_callback = kwargs.get("init_success_callback")

        self._raw_symbol = self._symbol.replace("/",
                                                "").lower()  # 转换成交易所对应的交易对格式
        self._order_channel = "orders.{}".format(self._raw_symbol)  # 订阅订单更新频道

        url = self._wss + "/ws/v1"
        super(HuobiTrade, self).__init__(url, send_hb_interval=0)

        self._assets = {
        }  # 资产 {"BTC": {"free": "1.1", "locked": "2.2", "total": "3.3"}, ... }
        self._orders = {}  # 订单

        # 初始化 REST API 对象
        self._rest_api = HuobiRestAPI(self._host, self._access_key,
                                      self._secret_key)

        # 初始化资产订阅
        if self._asset_update_callback:
            AssetSubscribe(self._platform, self._account,
                           self.on_event_asset_update)

        self.initialize()