Esempio n. 1
0
 def __init__(self, instrument_id_):
     self.instrument_id = instrument_id_
     self.longSnapshot = Snapshot()
     self.shortSnapshot = Snapshot()
     self.longOpenPosition = 0
     self.shortOpenPosition = 0
     self.bid_list = OrderList(is_bid=True)
     self.ask_list = OrderList(is_bid=False)
     self.OrderRef2OrderInfo = {}
     self.snapshot = self.longSnapshot  # point to longSnapshot/shortSnapshot based on direction/offset
     self.order_list = self.bid_list  # point to bid_list/ask_list based on direction
Esempio n. 2
0
class OrderManager(object):
    def __init__(self, instrument_id_):
        self.instrument_id = instrument_id_
        self.longSnapshot = Snapshot()
        self.shortSnapshot = Snapshot()
        self.longOpenPosition = 0
        self.shortOpenPosition = 0
        self.bid_list = OrderList(is_bid=True)
        self.ask_list = OrderList(is_bid=False)
        self.OrderRef2OrderInfo = {}
        self.snapshot = self.longSnapshot  # point to longSnapshot/shortSnapshot based on direction/offset
        self.order_list = self.bid_list  # point to bid_list/ask_list based on direction

    def place_limit_order(self, orderRef, direction, offset, price, volume):
        orderInfo = OrderInfo(orderRef=orderRef,
                              priceType=PHX_FTDC_OPT_LimitPrice,
                              direction=direction,
                              offset=offset,
                              price=price,
                              volume=volume,
                              InstrumentID=self.instrument_id)
        return self._place_order(orderInfo)

    def place_market_order(self, orderRef, direction, offset, volume):
        orderInfo = OrderInfo(orderRef=orderRef,
                              priceType=PHX_FTDC_OPT_AnyPrice,
                              direction=direction,
                              offset=offset,
                              volume=volume,
                              InstrumentID=self.instrument_id)
        return self._place_order(orderInfo)

    def place_cancel_order(self, orderRef):
        if orderRef not in self.OrderRef2OrderInfo:
            return
        orderInfo = self.OrderRef2OrderInfo[orderRef]

        if OrderManager.is_tradable_status(orderInfo.OrderStatus):
            pass

    def on_rsp_order_insert(self, orderRef):
        if orderRef not in self.OrderRef2OrderInfo:
            return
        orderInfo = self.OrderRef2OrderInfo[orderRef]

        self.set_snapshot(orderInfo.Direction, orderInfo.OffsetFlag)
        self.set_order_list(orderInfo.Direction)
        old_status = orderInfo.OrderStatus
        orderInfo.OrderStatus = PHX_FTDC_OST_Error
        self.snapshot.TotalErrorTimes += 1

        tmp = orderInfo.VolumeTotalOriginal - orderInfo.VolumeTraded
        if old_status == PHX_FTDC_OST_Unknown:
            if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
                self.snapshot.OpenUnknownVolume -= tmp
            else:
                self.snapshot.FrozenPosition -= tmp
                self.snapshot.CloseUnknownVolume -= tmp
        else:
            if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
                self.snapshot.OpenUntradedVolume -= tmp
            else:
                self.snapshot.FrozenPosition -= tmp
                self.snapshot.CloseUntradedVolume -= tmp

        self.order_list.remove_by_order_ref(orderInfo.OrderLocalID)

    def on_rtn_order(self, order: CPhxFtdcOrderField):
        if order.OrderLocalID not in self.OrderRef2OrderInfo:
            return
        orderInfo = self.OrderRef2OrderInfo[order.OrderLocalID]

        if orderInfo.OrderSysID is None:
            orderInfo.OrderSysID = order.OrderSysID

        self.set_snapshot(orderInfo.Direction, orderInfo.OffsetFlag)
        self.set_order_list(orderInfo.Direction)

        if orderInfo.OrderStatus == PHX_FTDC_OST_Unknown and order.OrderStatus != PHX_FTDC_OST_Unknown:
            if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
                self.snapshot.OpenUnknownVolume -= order.VolumeTotalOriginal
                self.snapshot.OpenUntradedVolume += order.VolumeTotalOriginal
            else:
                self.snapshot.CloseUnknownVolume -= order.VolumeTotalOriginal
                self.snapshot.CloseUntradedVolume += order.VolumeTotalOriginal

        if order.OrderStatus == PHX_FTDC_OST_Canceled:
            self.snapshot.TotalCanceledTimes += 1

        orderInfo.OrderStatus = order.OrderStatus
        orderInfo.VolumeTraded = order.VolumeTraded

        if OrderManager.is_final_status(orderInfo.OrderStatus):
            tmp = orderInfo.VolumeTotalOriginal - orderInfo.VolumeTraded
            if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
                self.snapshot.OpenUntradedVolume -= tmp
            else:
                self.snapshot.FrozenPosition -= tmp
                self.snapshot.CloseUntradedVolume -= tmp

            self.order_list.remove_by_order_ref(orderInfo.OrderLocalID)
        # print('OnRtnOrder, data=%s' % json.dumps(order.__dict__))

    def on_rtn_trade(self, trade: CPhxFtdcTradeField):
        if trade.OrderLocalID not in self.OrderRef2OrderInfo:
            return

        orderInfo = self.OrderRef2OrderInfo[trade.OrderLocalID]
        orderInfo.TradeVolume += trade.Volume

        self.set_snapshot(orderInfo.Direction, orderInfo.OffsetFlag)

        if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
            self.snapshot.Position += trade.Volume
            self.snapshot.OpenVolume += trade.Volume
            self.snapshot.OpenUntradedVolume -= trade.Volume
        else:
            self.snapshot.Position -= trade.Volume
            self.snapshot.CloseVolume += trade.Volume
            self.snapshot.CloseUntradedVolume -= trade.Volume
        # print('OnRtnTrade, data=%s' % json.dumps(trade.__dict__))

    def get_total_canceled_times(self):
        return self.longSnapshot.TotalCanceledTimes + self.shortSnapshot.TotalCanceledTimes

    def get_total_error_times(self):
        return self.longSnapshot.TotalErrorTimes + self.shortSnapshot.TotalErrorTimes

    def get_total_order_times(self):
        return self.longSnapshot.TotalOrderTimes + self.shortSnapshot.TotalOrderTimes

    def get_open_volume(self):
        return self.longSnapshot.OpenVolume + self.shortSnapshot.OpenVolume

    def get_close_volume(self):
        return self.longSnapshot.CloseVolume + self.shortSnapshot.CloseVolume

    def get_traded_volume(self):
        return self.get_open_volume() + self.get_close_volume()

    def get_effective_long_trading_volume(self):
        return self.longSnapshot.OpenUnknownVolume + self.longSnapshot.OpenUntradedVolume \
               + self.shortSnapshot.CloseUnknownVolume + self.shortSnapshot.CloseUntradedVolume

    def get_effective_short_trading_volume(self):
        return self.shortSnapshot.OpenUnknownVolume + self.shortSnapshot.OpenUntradedVolume \
               + self.longSnapshot.CloseUnknownVolume + self.longSnapshot.CloseUntradedVolume

    def get_long_position_closeable(self):
        return self.longSnapshot.Position - self.longSnapshot.CloseUntradedVolume \
               - self.longSnapshot.CloseUnknownVolume

    def get_short_position_closeable(self):
        return self.shortSnapshot.Position - self.shortSnapshot.CloseUntradedVolume \
               - self.shortSnapshot.CloseUnknownVolume

    def get_effective_long_position(self):
        return self.longSnapshot.Position + self.get_effective_long_trading_volume(
        )

    def get_effective_short_position(self):
        return self.shortSnapshot.Position + self.get_effective_short_trading_volume(
        )

    def get_current_net_position(self):
        return self.get_effective_long_position(
        ) - self.get_effective_short_position()

    def get_current_net_holding_position(self):
        return self.longSnapshot.Position - self.shortSnapshot.Position

    def has_unknown_order(self):
        return self.longSnapshot.OpenUnknownVolume > 0 or self.longSnapshot.CloseUnknownVolume > 0 \
               or self.shortSnapshot.OpenUnknownVolume > 0 or self.shortSnapshot.CloseUnknownVolume > 0

    def get_unknown_orders(self):
        return self._get_orders_by(PHX_FTDC_OST_Unknown)

    def get_untraded_orders(self):
        return self._get_orders_by(PHX_FTDC_OST_NoTradeQueueing)

    def get_live_orders(self):
        bids = self.bid_list.get_orders()
        asks = self.ask_list.get_orders()
        return bids, asks

    def get_live_order_num(self):
        return self.bid_list.size() + self.ask_list.size()

    @staticmethod
    def is_final_status(status):
        return status == PHX_FTDC_OST_AllTraded or status == PHX_FTDC_OST_Canceled or status == PHX_FTDC_OST_Error

    @staticmethod
    def is_tradable_status(status):
        return status == PHX_FTDC_OST_PartTradedQueueing or status == PHX_FTDC_OST_NoTradeQueueing

    def clear(self):
        self.longSnapshot.clear()
        self.shortSnapshot.clear()
        self.bid_list.clear()
        self.ask_list.clear()
        self.longOpenPosition = 0
        self.shortOpenPosition = 0
        self.OrderRef2OrderInfo = {}

    def _get_orders_by(self, order_status):
        bids = self.bid_list.get_order_by_status(order_status)
        asks = self.ask_list.get_order_by_status(order_status)
        return bids, asks

    def _remove_order_from_list(self, orderInfo: OrderInfo):
        if orderInfo.OrderPriceType != PHX_FTDC_OPT_LimitPrice:
            return

        if orderInfo.Direction == PHX_FTDC_D_Buy:
            self.bid_list.remove_by_order_ref(orderInfo.OrderLocalID)
        else:
            self.ask_list.remove_by_order_ref(orderInfo.OrderLocalID)

    def _place_order(self, orderInfo: OrderInfo):
        self.OrderRef2OrderInfo[orderInfo.OrderLocalID] = orderInfo

        if orderInfo.Direction == PHX_FTDC_D_Buy:
            if orderInfo.OrderPriceType == PHX_FTDC_OPT_LimitPrice:
                self.bid_list.insert(orderInfo)
            self.snapshot = self.longSnapshot
        else:
            if orderInfo.OrderPriceType == PHX_FTDC_OPT_LimitPrice:
                self.ask_list.insert(orderInfo)
            self.snapshot = self.shortSnapshot

        self.snapshot.TotalOrderTimes += 1
        self.snapshot.TotalOrderVolume += orderInfo.VolumeTotalOriginal
        if orderInfo.OffsetFlag == PHX_FTDC_OF_Open:
            self.snapshot.OpenUnknownVolume += orderInfo.VolumeTotalOriginal
        else:
            self.snapshot.FrozenPosition += orderInfo.VolumeTotalOriginal
            self.snapshot.CloseUnknownVolume += orderInfo.VolumeTotalOriginal
        return orderInfo

    def set_order_list(self, direction):
        if direction == PHX_FTDC_D_Buy:
            self.order_list = self.bid_list
        else:
            self.order_list = self.ask_list

    def set_snapshot(self, direction, offset):
        if direction == PHX_FTDC_D_Buy:
            if offset == PHX_FTDC_OF_Open:
                self.snapshot = self.longSnapshot
            else:
                self.snapshot = self.shortSnapshot
        else:
            if offset == PHX_FTDC_OF_Open:
                self.snapshot = self.shortSnapshot
            else:
                self.snapshot = self.longSnapshot

    def insert_init_order(self, order: CPhxFtdcOrderField):
        if order.OrderLocalID in self.OrderRef2OrderInfo:
            return
        offset = PHX_FTDC_OF_Open
        if order.CombOffsetFlag[0] != PHX_FTDC_OF_Open:
            offset = PHX_FTDC_OF_Close

        if order.OrderPriceType == PHX_FTDC_OPT_AnyPrice:
            self.place_market_order(order.OrderLocalID, order.Direction,
                                    offset, order.VolumeTotalOriginal)
        else:
            self.place_limit_order(order.OrderLocalID, order.Direction, offset,
                                   order.LimitPrice, order.VolumeTotalOriginal)