Exemplo n.º 1
0
 def _on_post_bar(self, event):
     if self._open_orders:
         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._open_orders.get(order_id, None)
                     if order:
                         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,
                         )
                         account = self._env.get_account(order.order_book_id)
                         trade._commission = self._env.get_trade_commission(account_type_str2enum(account.type), trade)
                         trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade)
                         order.fill(trade)
                         self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=order))
                         self._trade_no.add(trade_no)
                         if order.is_final():
                             str_order_id = str(order.order_id)
                             del self._open_orders[str_order_id]
                             del self._order_id_map[entrust_no]
                             del self._order_id_map[str_order_id]
Exemplo n.º 2
0
    def match(self, open_orders):
        price_board = self._env.price_board
        for account, order in open_orders:
            order_book_id = order.order_book_id
            instrument = self._env.get_instrument(order_book_id)

            deal_price = self._deal_price_decider(order_book_id, order.side)
            if not is_valid_price(deal_price):
                listed_date = instrument.listed_date.date()
                if listed_date == self._trading_dt.date():
                    reason = _(
                        u"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)
                continue

            if order.type == ORDER_TYPE.LIMIT:
                if order.side == SIDE.BUY and order.price < deal_price:
                    continue
                if order.side == SIDE.SELL and order.price > deal_price:
                    continue
                # 是否限制涨跌停不成交
                if self._price_limit:
                    if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(
                            order_book_id):
                        continue
                    if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(
                            order_book_id):
                        continue
                if self._liquidity_limit:
                    if order.side == SIDE.BUY and price_board.get_a1(
                            order_book_id) == 0:
                        continue
                    if order.side == SIDE.SELL and price_board.get_b1(
                            order_book_id) == 0:
                        continue
            else:
                if self._price_limit:
                    if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(
                            order_book_id):
                        reason = _(
                            "Order Cancelled: current bar [{order_book_id}] reach the limit_up price."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                    if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(
                            order_book_id):
                        reason = _(
                            "Order Cancelled: current bar [{order_book_id}] reach the limit_down price."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                if self._liquidity_limit:
                    if order.side == SIDE.BUY and price_board.get_a1(
                            order_book_id) == 0:
                        reason = _(
                            "Order Cancelled: [{order_book_id}] has no liquidity."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                    if order.side == SIDE.SELL and price_board.get_b1(
                            order_book_id) == 0:
                        reason = _(
                            "Order Cancelled: [{order_book_id}] has no liquidity."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue

            if self._volume_limit:
                bar = self._env.bar_dict[order_book_id]
                volume_limit = round(
                    bar.volume *
                    self._volume_percent) - self._turnover[order.order_book_id]
                round_lot = instrument.round_lot
                volume_limit = (volume_limit // round_lot) * round_lot
                if volume_limit <= 0:
                    if order.type == ORDER_TYPE.MARKET:
                        reason = _(
                            u"Order Cancelled: market order {order_book_id} volume {order_volume}"
                            u" due to volume limit").format(
                                order_book_id=order.order_book_id,
                                order_volume=order.quantity)
                        order.mark_cancelled(reason)
                    continue

                unfilled = order.unfilled_quantity
                fill = min(unfilled, volume_limit)
            else:
                fill = order.unfilled_quantity

            ct_amount = account.positions.get_or_create(
                order.order_book_id).cal_close_today_amount(fill, order.side)
            price = self._slippage_decider.get_trade_price(order, deal_price)

            trade = Trade.__from_create__(
                order_id=order.order_id,
                price=price,
                amount=fill,
                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._env.get_trade_commission(
                account_type_str2enum(account.type), trade)
            trade._tax = self._env.get_trade_tax(
                account_type_str2enum(account.type), trade)
            order.fill(trade)
            self._turnover[order.order_book_id] += fill

            self._env.event_bus.publish_event(
                Event(EVENT.TRADE, account=account, trade=trade, order=order))

            if order.type == ORDER_TYPE.MARKET and order.unfilled_quantity != 0:
                reason = _(
                    u"Order Cancelled: market order {order_book_id} volume {order_volume} is"
                    u" larger than {volume_percent_limit} percent of current bar volume, fill {filled_volume} actually"
                ).format(order_book_id=order.order_book_id,
                         order_volume=order.quantity,
                         filled_volume=order.filled_quantity,
                         volume_percent_limit=self._volume_percent * 100.0)
                order.mark_cancelled(reason)
Exemplo n.º 3
0
    def match(self, open_orders):
        price_board = self._env.price_board
        for account, order in open_orders:
            order_book_id = order.order_book_id
            instrument = self._env.get_instrument(order_book_id)

            deal_price = self._deal_price_decider(order_book_id, order.side)
            if not is_valid_price(deal_price):
                listed_date = instrument.listed_date.date()
                if listed_date == self._trading_dt.date():
                    reason = _(
                        u"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)
                continue

            if order.type == ORDER_TYPE.LIMIT:
                if order.side == SIDE.BUY and order.price < deal_price:
                    continue
                if order.side == SIDE.SELL and order.price > deal_price:
                    continue
                # 是否限制涨跌停不成交
                if self._price_limit:
                    if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id):
                        continue
                    if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id):
                        continue
                if self._liquidity_limit:
                    if order.side == SIDE.BUY and price_board.get_a1(order_book_id) == 0:
                        continue
                    if order.side == SIDE.SELL and price_board.get_b1(order_book_id) == 0:
                        continue
            else:
                if self._price_limit:
                    if order.side == SIDE.BUY and deal_price >= price_board.get_limit_up(order_book_id):
                        reason = _(
                            "Order Cancelled: current bar [{order_book_id}] reach the limit_up price."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                    if order.side == SIDE.SELL and deal_price <= price_board.get_limit_down(order_book_id):
                        reason = _(
                            "Order Cancelled: current bar [{order_book_id}] reach the limit_down price."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                if self._liquidity_limit:
                    if order.side == SIDE.BUY and price_board.get_a1(order_book_id) == 0:
                        reason = _(
                            "Order Cancelled: [{order_book_id}] has no liquidity."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue
                    if order.side == SIDE.SELL and price_board.get_b1(order_book_id) == 0:
                        reason = _(
                            "Order Cancelled: [{order_book_id}] has no liquidity."
                        ).format(order_book_id=order.order_book_id)
                        order.mark_rejected(reason)
                        continue

            if self._volume_limit:
                bar = self._env.bar_dict[order_book_id]
                volume_limit = round(bar.volume * self._volume_percent) - self._turnover[order.order_book_id]
                round_lot = instrument.round_lot
                volume_limit = (volume_limit // round_lot) * round_lot
                if volume_limit <= 0:
                    if order.type == ORDER_TYPE.MARKET:
                        reason = _(u"Order Cancelled: market order {order_book_id} volume {order_volume}"
                                   u" due to volume limit").format(
                            order_book_id=order.order_book_id,
                            order_volume=order.quantity
                        )
                        order.mark_cancelled(reason)
                    continue

                unfilled = order.unfilled_quantity
                fill = min(unfilled, volume_limit)
            else:
                fill = order.unfilled_quantity

            ct_amount = account.positions.get_or_create(order.order_book_id).cal_close_today_amount(fill, order.side)
            price = self._slippage_decider.get_trade_price(order, deal_price)

            trade = Trade.__from_create__(
                order_id=order.order_id,
                price=price,
                amount=fill,
                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._env.get_trade_commission(account_type_str2enum(account.type), trade)
            trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade)
            order.fill(trade)
            self._turnover[order.order_book_id] += fill

            self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=order))

            if order.type == ORDER_TYPE.MARKET and order.unfilled_quantity != 0:
                reason = _(
                    u"Order Cancelled: market order {order_book_id} volume {order_volume} is"
                    u" larger than {volume_percent_limit} percent of current bar volume, fill {filled_volume} actually"
                ).format(
                    order_book_id=order.order_book_id,
                    order_volume=order.quantity,
                    filled_volume=order.filled_quantity,
                    volume_percent_limit=self._volume_percent * 100.0
                )
                order.mark_cancelled(reason)
Exemplo n.º 4
0
    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
                ))

            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
                ))

        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, 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._env.get_trade_commission(account_type_str2enum(account.type), trade)
        trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade)
        order.fill(trade)

        self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=copy(order)))
Exemplo n.º 5
0
    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, 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._env.get_trade_commission(account_type_str2enum(account.type), trade)
        trade._tax = self._env.get_trade_tax(account_type_str2enum(account.type), trade)
        order.fill(trade)

        self._env.event_bus.publish_event(Event(EVENT.TRADE, account=account, trade=trade, order=copy(order)))