def update_realtime_quotes(self, order_book_ids, print_log=False): if print_log: user_system_log.info('update_realtime_quotes\n%s' % repr(order_book_ids)) if not order_book_ids: return codes = [ts_code(book_id) for book_id in order_book_ids] try: df = ts.get_realtime_quotes(codes) except Exception as e: user_system_log.warn(repr(e)) return columns = set(df.columns) - set(['name', 'time', 'date', 'code']) for label in columns: df[label] = df[label].map(lambda x: 0 if str(x).strip() == '' else x) df[label] = df[label].astype(float) df['chg'] = df['price'] / df['pre_close'] - 1 df['order_book_id'] = df['code'].apply(order_book_id) df = df.set_index('order_book_id').sort_index() df['order_book_id'] = df.index df['datetime'] = df['date'] + ' ' + df['time'] df['close'] = df['price'] df['last'] = df['price'] df = df.rename( columns={ 'pre_close': 'prev_close', 'amount': 'total_turnover', 'b1_p': 'b1', 'a1_p': 'a1', 'b2_p': 'b2', 'a2_p': 'a2', 'b3_p': 'b3', 'a3_p': 'a3', 'b4_p': 'b4', 'a4_p': 'a4', 'b5_p': 'b5', 'a5_p': 'a5', }) df['limit_up'] = df.apply(lambda row: row.prev_close * (1.1 if 'ST' not in row['name'] else 1.05), axis=1).round(2) df['limit_down'] = df.apply(lambda row: row.prev_close * (0.9 if 'ST' not in row['name'] else 0.95), axis=1).round(2) del df['code'] del df['date'] del df['time'] self._env.price_board.set_snapshot(df) if print_log: user_system_log.info(repr(df))
def _on_pre_bar(self, event): if self.open_oders: data = self._query_filled_orders() if data is not None: for item in data: trade_no = item[u'成交编号'] if trade_no in self._trade_no: continue entrust_no = item[u'合同编号'] order_id = self._order_id_map.get(entrust_no, None) if order_id: order = self._orders.get(order_id, None) if order: account = self._env.get_account( order.order_book_id) user_system_log.info(repr(item)) trade = Trade.__from_create__( order_id=order.order_id, price=float(item[u'成交均价']), amount=int(item[u'成交数量']), side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, ) order.fill(trade) self._env.event_bus.publish_event( Event(EVENT.TRADE, account=account, trade=trade, order=order)) self._trade_no.add(trade_no)
def _query_filled_orders(self): url = '%s%s' % (self._address, '/orders/filled') user_system_log.info('loading: %s' % url) try: with request.urlopen(url) as f: user_system_log.info('status: %d %s' % (f.status, f.reason)) if f.status == 200: data = f.read().decode('utf-8') return json.loads(data) except Exception as e: user_system_log.warn(repr(e)) return None
def sync_portfolio(self, portfolio, retry=10): retryed = 0 balance_data = self._query_balance() while balance_data is None and retryed < retry: time.sleep(min(5 + retryed, 20)) retryed += 1 user_system_log.info('retry %d' % retryed) balance_data = self._query_balance() retryed = 0 position_data = self._query_position() while position_data is None and retryed < retry: time.sleep(min(5 + retryed, 20)) retryed += 1 user_system_log.info('retry %d' % retryed) position_data = self._query_position() stock = DEFAULT_ACCOUNT_TYPE.STOCK.name account = portfolio.accounts[stock] if balance_data: account._frozen_cash = float(balance_data.get(u'冻结金额')) account._total_cash = float( balance_data.get(u'可用金额')) + account._frozen_cash order_book_ids = set() if position_data: user_system_log.info('sync_positions') position_model = self._env.get_position_model(stock) positions = Positions(position_model) for pos in position_data: order_book_id = get_order_book_id(pos[u'证券代码']) if not (order_book_id and self._env.get_instrument(order_book_id)): continue quantity = int(pos.get(u'持股数量') or pos.get(u'股票余额')) if quantity > 0: price = float(pos.get(u'成本价') or pos.get(u'参考成本')) trade = _fake_trade(order_book_id, quantity, price) position = position_model(order_book_id) positions[order_book_id] = position position.apply_trade(trade) last_price = float(pos.get(u'市价')) position._last_price = last_price frozen_quantity = pos.get(u'冻结数量') if frozen_quantity is None and pos.get( u'持股数量') and pos.get(u'可用余额'): frozen_quantity = int(pos[u'持股数量']) - int(pos[u'可用余额']) position.long._non_closable = int(frozen_quantity or 0) user_system_log.info( '%s %d %f %f' % (order_book_id, quantity, price, last_price)) order_book_ids.add(order_book_id) account._positions = positions
def cancel_order(self, order): if self._open_orders.get(order.order_id, None): url = '%s%s?%s' % (self._address, '/cancel', self._order_id_map[order.order_id]) user_system_log.info('loading: %s' % url) try: with request.urlopen(url) as f: user_system_log.info('status: %d %s' % (f.status, f.reason)) if f.status == 200: data = f.read().decode('utf-8') resp = json.loads(data) if resp.get('success', False): account = self._env.get_account(order.order_book_id) self._env.event_bus.publish_event(Event(EVENT.ORDER_PENDING_CANCEL, account=account, order=order)) order.mark_cancelled("%d order has been cancelled." % order.order_id) self._env.event_bus.publish_event(Event(EVENT.ORDER_CANCELLATION_PASS, account=account, order=order)) str_order_id = str(order.order_id) entrust_no = self._order_id_map[str_order_id] del self._open_orders[str_order_id] del self._order_id_map[entrust_no] del self._order_id_map[str_order_id] return else: user_system_log.warn(resp.get('msg', 'request failed')) except Exception as e: user_system_log.warn(repr(e)) return else: user_system_log.info('cancel order not fund: %s' % order.order_id)
def submit_order(self, order): route = '/sell' if order.side == SIDE.SELL else '/buy' price = order.price if order.type == ORDER_TYPE.MARKET: if order.side == SIDE.SELL: price = self._env.price_board.get_bids(order.order_book_id)[-1] else: price = self._env.price_board.get_asks(order.order_book_id)[-1] parmas = 'stock_no=%s&amount=%d&price=%f' % ( get_stock_no(order.order_book_id), order.quantity - order.quantity % 100, price, ) url = '%s%s?%s' % (self._address, route, parmas) user_system_log.info('loading: %s' % url) reason = 'request failed' try: account = self._env.get_account(order.order_book_id) self._env.event_bus.publish_event( Event(EVENT.ORDER_PENDING_NEW, account=account, order=order)) with request.urlopen(url) as f: user_system_log.info('status: %d %s' % (f.status, f.reason)) if f.status == 200: data = f.read().decode('utf-8') user_system_log.info(data) resp = json.loads(data) code = resp.get('code', 1) if code == 0: entrust_no = resp['entrust_no'] order.set_secondary_order_id(entrust_no) order.active() self._env.event_bus.publish_event( Event(EVENT.ORDER_CREATION_PASS, account=account, order=order)) str_order_id = str(order.order_id) self._orders[str_order_id] = order self._order_id_map[entrust_no] = str_order_id return elif code == 1: reason = resp.get('msg', reason) else: user_system_log.info(data) return except Exception as e: user_system_log.warn(repr(e)) order.mark_rejected(reason) self._env.event_bus.publish_event( Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=order))
def run(config, source_code=None, user_funcs=None): env = Environment(config) persist_helper = None init_succeed = False mod_handler = ModHandler() try: # avoid register handlers everytime # when running in ipython set_loggers(config) init_rqdatac(getattr(config.base, 'rqdatac_uri', None)) system_log.debug("\n" + pformat(config.convert_to_dict())) env.set_strategy_loader( init_strategy_loader(env, source_code, user_funcs, config)) mod_handler.set_env(env) mod_handler.start_up() if not env.data_source: env.set_data_source( BaseDataSource(config.base.data_bundle_path, getattr(config.base, "future_info", {}))) if env.price_board is None: from rqalpha.data.bar_dict_price_board import BarDictPriceBoard env.price_board = BarDictPriceBoard() env.set_data_proxy(DataProxy(env.data_source, env.price_board)) _adjust_start_date(env.config, env.data_proxy) ctx = ExecutionContext(const.EXECUTION_PHASE.GLOBAL) ctx._push() # FIXME start_dt = datetime.datetime.combine(config.base.start_date, datetime.datetime.min.time()) env.calendar_dt = start_dt env.trading_dt = start_dt assert env.broker is not None assert env.event_source is not None if env.portfolio is None: from rqalpha.portfolio import Portfolio env.set_portfolio( Portfolio(config.base.accounts, config.base.init_positions)) env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_INIT)) scope = create_base_scope() scope.update({"g": env.global_vars}) scope.update(get_strategy_apis()) scope = env.strategy_loader.load(scope) if config.extra.enable_profiler: enable_profiler(env, scope) ucontext = StrategyContext() executor = Executor(env) persist_helper = init_persist_helper(env, ucontext, executor, config) user_strategy = Strategy(env.event_bus, scope, ucontext) env.user_strategy = user_strategy env.event_bus.publish_event(Event(EVENT.BEFORE_STRATEGY_RUN)) if persist_helper: with LogCapture(user_log) as log_capture: user_strategy.init() else: user_strategy.init() if config.extra.context_vars: for k, v in config.extra.context_vars.items(): if isinstance(v, RqAttrDict): v = v.__dict__ setattr(ucontext, k, v) if persist_helper: env.event_bus.publish_event(Event(EVENT.BEFORE_SYSTEM_RESTORED)) restored_obj_state = persist_helper.restore(None) check_key = ["global_vars", "user_context", "executor", "universe"] kept_current_init_data = not any( v for k, v in restored_obj_state.items() if k in check_key) system_log.debug( "restored_obj_state: {}".format(restored_obj_state)) system_log.debug( "kept_current_init_data: {}".format(kept_current_init_data)) if kept_current_init_data: # 未能恢复init相关数据 保留当前策略初始化变量(展示当前策略初始化日志) log_capture.replay() else: user_system_log.info(_('system restored')) env.event_bus.publish_event(Event(EVENT.POST_SYSTEM_RESTORED)) init_succeed = True bar_dict = BarMap(env.data_proxy, config.base.frequency) executor.run(bar_dict) env.event_bus.publish_event(Event(EVENT.POST_STRATEGY_RUN)) if env.profile_deco: output_profile_result(env) release_print(scope) except CustomException as e: if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH: persist_helper.persist() code = _exception_handler(e) mod_handler.tear_down(code, e) except Exception as e: system_log.error(traceback.format_exc()) if init_succeed and persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_CRASH: persist_helper.persist() exc_type, exc_val, exc_tb = sys.exc_info() user_exc = create_custom_exception(exc_type, exc_val, exc_tb, config.base.strategy_file) code = _exception_handler(user_exc) mod_handler.tear_down(code, user_exc) else: if persist_helper and env.config.base.persist_mode == const.PERSIST_MODE.ON_NORMAL_EXIT: persist_helper.persist() result = mod_handler.tear_down(const.EXIT_CODE.EXIT_SUCCESS) system_log.debug(_(u"strategy run successfully, normal exit")) return result