def get_bars(self, instrument, frequency, trade_date=None, start_time=None, end_time=None): symbol = instrument_to_tushare(instrument) kwargs = {} if start_time is not None: kwargs["start_time"] = start_time elif end_time is not None: kwargs["end_time"] = end_time retry = 0 while retry < self.MAX_RETRY: retry += 1 try: freq = frequency[:-1] + frequency[-1].upper() params = dict(symbol=symbol, freq=freq, trade_date=0, **kwargs) bars, msg = self._api.bar(**params) code = msg.split(",")[0] if not isinstance(bars, pd.DataFrame) or code != "0": raise QuantOsQueryError(msg) else: break except QuantOsQueryError as e: if retry <= self.MAX_RETRY: user_system_log.warning( "[japs] Exception occurs when call api.bar with param [%s]: %s" % (params, e)) time.sleep(retry) else: raise e return QuantOsConverter.df2np(bars)
def _match(self, account, order): # TODO support tick cal env = Environment.get_instance() bar = env.get_bar(order.order_book_id) bar_status = bar._bar_status if bar_status == BAR_STATUS.ERROR: listed_date = bar.instrument.listed_date.date() if listed_date == self._trading_dt.date(): reason = _( "Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]").format( order_book_id=order.order_book_id, listed_date=listed_date, ) else: reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format( order_book_id=order.order_book_id) order.mark_rejected(reason) self._env.event_bus.publish_event(Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=order)) return if isinstance(order.style, LimitOrder): deal_price = order.style.get_limit_price() else: deal_price = bar.close deal_price = min(deal_price, bar.high) deal_price = max(deal_price, bar.low) deal_price = self._slippage_decider.get_trade_price(order.side, deal_price) if (order.side == SIDE.BUY and bar_status == BAR_STATUS.LIMIT_UP) or ( order.side == SIDE.SELL and bar_status == BAR_STATUS.LIMIT_DOWN): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order.order_book_id, quantity=order.quantity, bar_status=bar_status )) ct_amount = account.portfolio.positions.get_or_create(order.order_book_id).cal_close_today_amount(order.quantity, order.side) trade = Trade.__from_create__( order_id=order.order_id, calendar_dt=self._calendar_dt, trading_dt=self._trading_dt, price=deal_price, amount=order.quantity, side=order.side, position_effect=order.position_effect, order_book_id=order.order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount ) trade._commission = self._commission_decider.get_commission(account.type, trade) trade._tax = self._tax_decider.get_tax(account.type, trade) order.fill(trade) env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade))
def start_up(self, env, mod_config): self._env = env self._mod_config = mod_config self._enabled = ( mod_config.record or mod_config.plot or mod_config.output_file or mod_config.plot_save_file or mod_config.report_save_path or mod_config.bechmark ) if self._enabled: env.event_bus.add_listener(EVENT.POST_SYSTEM_INIT, self._subscribe_events) if not mod_config.benchmark: if getattr(env.config.base, "benchmark", None): user_system_log.warning( _("config 'base.benchmark' is deprecated, use 'mod.sys_analyser.benchmark' instead") ) mod_config.benchmark = getattr(env.config.base, "benchmark") if mod_config.benchmark: self._benchmark = mod_config.benchmark
def _match(self, account, order): order_book_id = order.order_book_id price_board = self._env.price_board last_price = price_board.get_last_price(order_book_id) if not is_valid_price(last_price): instrument = self._env.get_instrument(order_book_id) listed_date = instrument.listed_date.date() if listed_date == self._env.trading_dt.date(): reason = _( "Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]").format( order_book_id=order_book_id, listed_date=listed_date, ) else: reason = _(u"Order Cancelled: current bar [{order_book_id}] miss market data.").format( order_book_id=order_book_id) order.mark_rejected(reason) self._env.event_bus.publish_event(Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=copy(order))) return if order.type == ORDER_TYPE.LIMIT: deal_price = order.frozen_price else: deal_price = last_price if self._price_limit: """ 在 Signal 模式下,不再阻止涨跌停是否买进,price_limit 参数表示是否给出警告提示。 """ if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_UP )) return if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id): user_system_log.warning(_(u"You have traded {order_book_id} with {quantity} lots in {bar_status}").format( order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_DOWN )) return ct_amount = account.positions.get_or_create(order_book_id).cal_close_today_amount(order.quantity, order.side) trade_price = self._slippage_decider.get_trade_price(order.side, deal_price) trade = Trade.__from_create__( order_id=order.order_id, price=trade_price, amount=order.quantity, side=order.side, position_effect=order.position_effect, order_book_id=order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount ) trade._commission = self._commission_decider.get_commission(account.type, trade) trade._tax = self._tax_decider.get_tax(account.type, trade) order.fill(trade) self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=copy(order)))
def _match(self, account, order): order_book_id = order.order_book_id price_board = self._env.price_board last_price = price_board.get_last_price(order_book_id) if np.isnan(last_price): instrument = self._env.get_instrument(order_book_id) listed_date = instrument.listed_date.date() if listed_date == self._env.trading_dt.date(): reason = _( "Order Cancelled: current security [{order_book_id}] can not be traded in listed date [{listed_date}]" ).format( order_book_id=order_book_id, listed_date=listed_date, ) else: reason = _( u"Order Cancelled: current bar [{order_book_id}] miss market data." ).format(order_book_id=order_book_id) order.mark_rejected(reason) self._env.event_bus.publish_event( Event(EVENT.ORDER_UNSOLICITED_UPDATE, account=account, order=order)) return if order.type == ORDER_TYPE.LIMIT: deal_price = order.frozen_price else: deal_price = last_price if self._price_limit: """ 在 Signal 模式下,不再阻止涨跌停是否买进,price_limit 参数表示是否给出警告提示。 """ if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up( order_book_id): user_system_log.warning( _(u"You have traded {order_book_id} with {quantity} lots in {bar_status}" ).format(order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_UP)) return if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down( order_book_id): user_system_log.warning( _(u"You have traded {order_book_id} with {quantity} lots in {bar_status}" ).format(order_book_id=order_book_id, quantity=order.quantity, bar_status=BAR_STATUS.LIMIT_DOWN)) return ct_amount = account.positions.get_or_create( order_book_id).cal_close_today_amount(order.quantity, order.side) trade_price = self._slippage_decider.get_trade_price( order.side, deal_price) trade = Trade.__from_create__(order_id=order.order_id, calendar_dt=self._env.calendar_dt, trading_dt=self._env.trading_dt, price=trade_price, amount=order.quantity, side=order.side, position_effect=order.position_effect, order_book_id=order_book_id, frozen_price=order.frozen_price, close_today_amount=ct_amount) trade._commission = self._commission_decider.get_commission( account.type, trade) trade._tax = self._tax_decider.get_tax(account.type, trade) order.fill(trade) self._env.event_bus.publish_event( Event(EVENT.TRADE, account=account, trade=trade))
def _submit_order(id_or_ins, amount, side, position_effect, style): amount = int(amount) if amount == 0: user_system_log.warn(_(u"Order Creation Failed: Order amount is 0.")) return None if isinstance(style, LimitOrder) and style.get_limit_price() <= 0: raise RQInvalidArgument(_(u"Limit order price should be positive")) instrument = assure_instrument(id_or_ins) order_book_id = instrument.order_book_id env = Environment.get_instance() if env.config.base.run_type != RUN_TYPE.BACKTEST and instrument.type == INSTRUMENT_TYPE.FUTURE: if "88" in order_book_id: raise RQInvalidArgument( _(u"Main Future contracts[88] are not supported in paper trading." )) if "99" in order_book_id: raise RQInvalidArgument( _(u"Index Future contracts[99] are not supported in paper trading." )) price = env.get_last_price(order_book_id) if not is_valid_price(price): user_system_log.warn( _(u"Order Creation Failed: [{order_book_id}] No market data"). format(order_book_id=order_book_id)) return env = Environment.get_instance() orders = [] if position_effect in (POSITION_EFFECT.CLOSE_TODAY, POSITION_EFFECT.CLOSE): direction = POSITION_DIRECTION.LONG if side == SIDE.SELL else POSITION_DIRECTION.SHORT position = env.portfolio.get_position(order_book_id, direction) # type: Position if position_effect == POSITION_EFFECT.CLOSE_TODAY: if amount > position.today_closable: user_system_log.warning( _("Order Creation Failed: " "close today amount {amount} is larger than today closable quantity {quantity}" ).format(amount=amount, quantity=position.today_closable)) return [] orders.append( Order.__from_create__(order_book_id, amount, side, style, POSITION_EFFECT.CLOSE_TODAY)) else: quantity, old_quantity = position.quantity, position.old_quantity if amount > quantity: user_system_log.warn( _(u"Order Creation Failed: close amount {amount} is larger than position quantity {quantity}" ).format(amount=amount, quantity=quantity)) return [] if amount > old_quantity: if old_quantity != 0: # 如果有昨仓,则创建一个 POSITION_EFFECT.CLOSE 的平仓单 orders.append( Order.__from_create__(order_book_id, old_quantity, side, style, POSITION_EFFECT.CLOSE)) # 剩下还有仓位,则创建一个 POSITION_EFFECT.CLOSE_TODAY 的平今单 orders.append( Order.__from_create__(order_book_id, amount - old_quantity, side, style, POSITION_EFFECT.CLOSE_TODAY)) else: # 创建 POSITION_EFFECT.CLOSE 的平仓单 orders.append( Order.__from_create__(order_book_id, amount, side, style, POSITION_EFFECT.CLOSE)) elif position_effect == POSITION_EFFECT.OPEN: orders.append( Order.__from_create__(order_book_id, amount, side, style, position_effect)) else: raise NotImplementedError() if len(orders) > 1: user_system_log.warn( _("Order was separated, original order: {original_order_repr}, new orders: [{new_orders_repr}]" ). format( original_order_repr= "Order(order_book_id={}, quantity={}, side={}, position_effect={})" .format(order_book_id, amount, side, position_effect), new_orders_repr=", ".join([ "Order({}, {}, {}, {})".format(o.order_book_id, o.quantity, o.side, o.position_effect) for o in orders ]))) for o in orders: if o.type == ORDER_TYPE.MARKET: o.set_frozen_price(price) if env.can_submit_order(o): env.broker.submit_order(o) else: orders.remove(o) # 向前兼容,如果创建的order_list 只包含一个订单的话,直接返回对应的订单,否则返回列表 if len(orders) == 1: return orders[0] else: return orders