def __init__(self, instance_id, config): super().__init__(instance_id, config, DB_ORDERS_NAME) exchange = config["exchange"] if exchange == "binance": self.__exchange = BinanceExchange(debug=True) elif exchange == "okex": self.__exchange = OkexExchange(debug=True) else: print("Wrong exchange name: %s" % exchange) exit(1)
def get_kline_column_names(exchange_name): if exchange_name == BINANCE_SPOT_EXCHANGE_NAME: return BinanceExchange.get_kline_column_names() elif exchange_name == BINANCE_MARGIN_EXCHANGE_NAME: return BinanceMargin.get_kline_column_names() elif exchange_name == OKEX_SPOT_EXCHANGE_NAME: return OkexExchange.get_kline_column_names() else: return None
def create_exchange(exchange_name): if exchange_name == BINANCE_SPOT_EXCHANGE_NAME: return BinanceExchange(debug=True) elif exchange_name == BINANCE_MARGIN_EXCHANGE_NAME: return BinanceMargin(debug=True) elif exchange_name == OKEX_SPOT_EXCHANGE_NAME: return OkexExchange(debug=True) else: return None
def __init__(self, instance_id, config, db_orders_name): self.instance_id = instance_id self.config = config self.db_orders_name = db_orders_name self._db = md.MongoDB(mongo_user, mongo_pwd, db_name, db_url) self._db.ensure_index(db_orders_name, [("instance_id",1),("symbol",1)]) self.can_buy_time = None exchange = config["exchange"] if exchange == "binance": self.kline_column_names = BinanceExchange.get_kline_column_names() elif exchange == "okex": self.kline_column_names = OkexExchange.get_kline_column_names()
def __init__(self, instance_id, config, db_orders_name=None): self.instance_id = instance_id self.config = config exchange = config["exchange"] if exchange == "binance": self.kline_column_names = BinanceExchange.get_kline_column_names() elif exchange == "okex": self.kline_column_names = OkexExchange.get_kline_column_names() self.md_db = md.MongoDB(mongo_user, mongo_pwd, exchange, db_url) self.td_db = md.MongoDB(mongo_user, mongo_pwd, "xquant", db_url) self.value = 100 if db_orders_name: self.db_orders_name = db_orders_name self.td_db.ensure_index(db_orders_name, [("instance_id", 1), ("symbol", 1)]) self.can_open_time = None self.tp_cc = {"base_open": 0}
class RealEngine(Engine): """实盘引擎""" def __init__(self, instance_id, config): super().__init__(instance_id, config, DB_ORDERS_NAME) exchange = config["exchange"] if exchange == "binance": self.__exchange = BinanceExchange(debug=True) elif exchange == "okex": self.__exchange = OkexExchange(debug=True) else: print("Wrong exchange name: %s" % exchange) exit(1) def now(self): return datetime.datetime.now() def get_klines(self, symbol, interval, size): """ 获取日k线 """ return self.__exchange.get_klines(symbol, interval, size) def get_klines_1day(self, symbol, size): """ 获取日k线 """ return self.__exchange.get_klines_1day(symbol, size) def get_account(self): """ 获取账户信息 """ return self.__exchange.get_account() def get_balances(self, *coins): """ 获取余额 """ return self.__exchange.get_balances(*coins) def get_position(self, symbol, cur_price): """ 获取持仓信息 """ self.sync_orders(symbol) orders = self.td_db.find(self.db_orders_name, { "instance_id": self.instance_id, "symbol": symbol }) if len(orders) > 0: now_ts = self.now().timestamp() if orders[-1]["action"] == xq.OPEN_POSITION: if "high" not in orders[-1] or orders[-1]["high"] < cur_price: orders[-1]["high"] = cur_price orders[-1]["high_time"] = now_ts self.td_db.update_one( self.db_orders_name, orders[-1]["_id"], { "high": cur_price, "high_time": now_ts, }, ) if "low" not in orders[-1] or orders[-1]["low"] > cur_price: orders[-1]["low"] = cur_price orders[-1]["low_time"] = now_ts self.td_db.update_one( self.db_orders_name, orders[-1]["_id"], { "low": cur_price, "low_time": now_ts, }, ) return self._get_position(symbol, orders, cur_price) def get_open_orders(self, symbol): """ 是否有open状态的委托 """ return self.td_db.find( DB_ORDERS_NAME, { "instance_id": self.instance_id, "symbol": symbol, "status": xq.ORDER_STATUS_OPEN, }, ) def sync_orders(self, symbol): orders = self.get_open_orders(symbol) if not orders: return df_amount, df_value = self.__exchange.get_deals(symbol) for order in orders: self.log_debug("order: %r" % order) order_id = order["order_id"] order_amount = order["amount"] if order_id not in df_amount.index: """ 没有成交信息 """ continue deal_amount = df_amount[order_id] target_coin, base_coin = xq.get_symbol_coins(symbol) deal_amount = ts.reserve_float(deal_amount, self.config["digits"][target_coin]) deal_value = df_value[order_id] status = xq.ORDER_STATUS_OPEN if deal_amount > order_amount: self.log_error("最新成交数量(%f)大于委托数量(%f) %g" % (deal_amount, order_amount, (deal_amount - order_amount))) continue elif deal_amount == order_amount: status = xq.ORDER_STATUS_CLOSE else: if deal_amount < order["deal_amount"]: self.log_warning("最新成交数量小于委托里记载的旧成交数量") continue elif deal_amount == order["deal_amount"]: self.log_info("成交数量没有更新") else: pass if self.__exchange.order_status_is_close(symbol, order_id): status = xq.ORDER_STATUS_CLOSE self.log_debug( "deal_amount: %f, deal_value: %g, deal_price: %g" % (deal_amount, deal_value, deal_value / deal_amount)) self.td_db.update_one( DB_ORDERS_NAME, order["_id"], { "deal_amount": deal_amount, "deal_value": deal_value, "status": status, }, ) return def send_order_limit(self, direction, action, symbol, pst_rate, cur_price, limit_price, amount, rmk): """ 提交委托 """ """ _id = self._db.insert_one( DB_ORDERS_NAME, { "create_time": self.now().timestamp(), "instance_id": self.instance_id, "symbol": symbol, "side": side, "pst_rate": pst_rate, "type": xq.ORDER_TYPE_LIMIT, "price": limit_price, "amount": amount, "status": xq.ORDER_STATUS_WAIT, "order_id": "", "cancle_amount": 0, "deal_amount": 0, "deal_value": 0, }, ) order_id = self.__exchange.send_order( side, xq.ORDER_TYPE_LIMIT, symbol, limit_price, amount, _id ) self._db.update_one( DB_ORDERS_NAME, _id, {"order_id": order_id, "status": xq.ORDER_STATUS_OPEN} ) """ # 暂时简单处理 order_id = self.__exchange.send_order(direction, action, xq.ORDER_TYPE_LIMIT, symbol, limit_price, amount) _id = self.td_db.insert_one( DB_ORDERS_NAME, { "create_time": self.now().timestamp(), "instance_id": self.instance_id, "symbol": symbol, "direction": direction, "action": action, "pst_rate": pst_rate, "type": xq.ORDER_TYPE_LIMIT, "market_price": cur_price, "price": limit_price, "amount": amount, "status": xq.ORDER_STATUS_OPEN, "order_id": order_id, "cancle_amount": 0, "deal_amount": 0, "deal_value": 0, "rmk": rmk, }, ) return order_id def cancle_orders(self, symbol): """ 撤掉本策略的所有挂单委托 """ orders = self.get_open_orders(symbol) if not orders: return e_order_ids = self.__exchange.get_open_order_ids(symbol) for order in orders: order_id = order["order_id"] if order_id not in e_order_ids: continue self.__exchange.cancel_order(symbol, order_id) self.td_db.update_one(DB_ORDERS_NAME, order["_id"], {"status": xq.ORDER_STATUS_CANCELLING}) def run(self, strategy, debug): """ run """ while True: tick_start = datetime.datetime.now() self.log_info( "%s tick start......................................" % tick_start) if debug: strategy.on_tick() else: try: strategy.on_tick() except Exception as ept: self.log_critical(ept) tick_end = datetime.datetime.now() self.log_info( "%s tick end...; tick cost: %s -----------------------\n\n" % (tick_end, tick_end - tick_start)) time.sleep(strategy.config["sec"])
class RealEngine(Engine): """实盘引擎""" def __init__(self, instance_id, config): super().__init__(instance_id, config, DB_ORDERS_NAME) exchange = config["exchange"] if exchange == "binance": self.__exchange = BinanceExchange(debug=True) elif exchange == "okex": self.__exchange = OkexExchange(debug=True) else: print("Wrong exchange name: %s" % exchange) exit(1) def now(self): return datetime.datetime.now() def get_klines_1day(self, symbol, size): """ 获取日k线 """ return self.__exchange.get_klines_1day(symbol, size) def get_balances(self, *coins): """ 获取余额 """ return self.__exchange.get_balances(*coins) def get_position(self, symbol, cur_price): """ 获取持仓信息 """ self.sync_orders(symbol) orders = self._db.find(self.db_orders_name, { "instance_id": self.instance_id, "symbol": symbol }) return self._get_position(symbol, orders, cur_price) def has_open_orders(self, symbol): """ 是否有open状态的委托 """ db_orders = self._db.find( DB_ORDERS_NAME, { "instance_id": self.instance_id, "symbol": symbol, "status": xq.ORDER_STATUS_OPEN, }, ) if db_orders: return True return False def sync_orders(self, symbol): """ 同步委托。注意:触发是本策略有未完成的委托,但同步是account下所有委托,避免重复查询成交 """ if not self.has_open_orders(symbol): return orders = self._db.find(DB_ORDERS_NAME, { "symbol": symbol, "status": xq.ORDER_STATUS_OPEN }) if not orders: return df_amount, df_value = self.__exchange.get_deals(symbol) for order in orders: logging.debug("order: %r", order) order_id = order["order_id"] order_amount = order["amount"] if order_id not in df_amount.index: """ 没有成交信息 """ continue deal_amount = df_amount[order_id] deal_value = df_value[order_id] status = xq.ORDER_STATUS_OPEN if deal_amount > order_amount: logging.error("最新成交数量大于委托数量") continue elif deal_amount == order_amount: status = xq.ORDER_STATUS_CLOSE else: if deal_amount < order["deal_amount"]: logging.warning("最新成交数量小于委托里记载的旧成交数量") continue elif deal_amount == order["deal_amount"]: logging.info("成交数量没有更新") else: pass if self.__exchange.order_status_is_close(symbol, order_id): status = xq.ORDER_STATUS_CLOSE logging.debug("deal_amount: %s, deal_value: %s", deal_amount, deal_value) self._db.update_one( DB_ORDERS_NAME, order["_id"], { "deal_amount": deal_amount, "deal_value": deal_value, "status": status, }, ) return def send_order_limit(self, side, symbol, pst_rate, cur_price, limit_price, amount, rmk): """ 提交委托 """ """ _id = self._db.insert_one( DB_ORDERS_NAME, { "create_time": self.now().timestamp(), "instance_id": self.instance_id, "symbol": symbol, "side": side, "pst_rate": pst_rate, "type": xq.ORDER_TYPE_LIMIT, "pirce": limit_price, "amount": amount, "status": xq.ORDER_STATUS_WAIT, "order_id": "", "cancle_amount": 0, "deal_amount": 0, "deal_value": 0, }, ) order_id = self.__exchange.send_order( side, xq.ORDER_TYPE_LIMIT, symbol, limit_price, amount, _id ) self._db.update_one( DB_ORDERS_NAME, _id, {"order_id": order_id, "status": xq.ORDER_STATUS_OPEN} ) """ # 暂时简单处理 order_id = self.__exchange.send_order(side, xq.ORDER_TYPE_LIMIT, symbol, limit_price, amount) _id = self._db.insert_one( DB_ORDERS_NAME, { "create_time": self.now().timestamp(), "instance_id": self.instance_id, "symbol": symbol, "side": side, "pst_rate": pst_rate, "type": xq.ORDER_TYPE_LIMIT, "pirce": limit_price, "amount": amount, "status": xq.ORDER_STATUS_OPEN, "order_id": order_id, "cancle_amount": 0, "deal_amount": 0, "deal_value": 0, "rmk": rmk, }, ) return order_id def cancle_orders(self, symbol): """ 撤掉本策略的所有挂单委托 """ if not self.has_open_orders(symbol): return orders = self.__exchange.get_open_orders(symbol) for order in orders: if order["instance_id"] == self.instance_id: self._db.update_one(DB_ORDERS_NAME, order["_id"], {"status": xq.ORDER_STATUS_CANCELLING}) self.__exchange.cancel_order(symbol, order["order_id"]) def run(self, strategy): """ run """ while True: tick_start = datetime.datetime.now() logging.info("%s tick start......................................", tick_start) strategy.on_tick() tick_end = datetime.datetime.now() logging.info( "%s tick end...; tick cost: %s -----------------------\n\n", tick_end, tick_end - tick_start, ) time.sleep(strategy.config["sec"])