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)
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))
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)
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)
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)
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)
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()
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)
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) # 获取持仓
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.")
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)
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)
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)
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)
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()
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
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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)
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()
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()