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))
Exemple #7
0
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