예제 #1
0
def _update_positions(current_positions, deal_positions, trans):
    """ 更新持仓 
        current_positions: 当前持仓
        deal_positions: 开平仓对
    """
    class PositionsDetail(object):
        """ 当前相同合约持仓集合(可能不同时间段下单)。

        :ivar cost: 持仓成本。
        :ivar total: 持仓总数。
        :ivar positions: 持仓集合。
        :vartype positions: list
        """
        def __init__(self):
            self.total = 0
            self.positions = []
            self.cost = 0

    assert trans.quantity > 0
    poskey = PositionKey(trans.contract, trans.direction)
    p = current_positions.setdefault(poskey, PositionsDetail())
    if trans.side == TradeSide.KAI:
        # 开仓
        p.positions.append(trans)
        p.total += trans.quantity

    elif trans.side == TradeSide.PING:
        # 平仓
        assert (len(p.positions) > 0 and '所平合约没有持仓')
        left_vol = trans.quantity
        last_index = 0
        p.total -= trans.quantity
        for position in reversed(p.positions):
            if position.quantity < left_vol:
                # 还需从之前的仓位中平。
                left_vol -= position.quantity
                last_index -= 1
                deal_positions.append(
                    OneDeal(position, trans, position.quantity))

            elif position.quantity == left_vol:
                left_vol -= position.quantity
                last_index -= 1
                deal_positions.append(
                    OneDeal(position, trans, position.quantity))
                break

            else:
                position.quantity -= left_vol
                left_vol = 0
                deal_positions.append(OneDeal(position, trans, left_vol))
                break
        if last_index != 0:
            p.positions = p.positions[0:last_index]
        assert (left_vol == 0)  # 会被catch捕获 AssertError
예제 #2
0
    def _update_positions(self, current_positions, deal_positions, trans):
        """ 根据交易明细计算开平仓对。 """
        class PositionsDetail(object):
            """ 当前相同合约持仓集合(可能不同时间段下单)。

            :ivar cost: 持仓成本。
            :ivar total: 持仓总数。
            :ivar positions: 持仓集合。
            :vartype positions: list
            """
            def __init__(self):
                self.total = 0
                self.positions = []
                self.cost = 0
        assert trans.quantity > 0
        poskey = PositionKey(trans.contract, trans.direction)
        p = current_positions.setdefault(poskey, PositionsDetail())
        if trans.side == TradeSide.KAI:
            # 开仓
            p.positions.append(trans)
            p.total += trans.quantity

        elif trans.side == TradeSide.PING:
            # 平仓
            assert(len(p.positions) > 0 and '所平合约没有持仓')
            left_vol = trans.quantity
            last_index = 0
            search_index = 0
            p.total -= trans.quantity
            if trans.contract.is_stock:
                for position in reversed(p.positions):
                    # 开仓日期小于平仓时间
                    if position.datetime.date() < trans.datetime.date():
                        break
                    search_index -= 1
            if search_index != 0:
                positions = p.positions[:search_index]
                left_positions = p.positions[search_index:]
            else:
                positions = p.positions
            for position in reversed(positions):
                if position.quantity < left_vol:
                    # 还需从之前的仓位中平。
                    left_vol -= position.quantity
                    last_index -= 1
                    deal_positions.append(
                        OneDeal(position, trans, position.quantity))
                elif position.quantity == left_vol:
                    left_vol -= position.quantity
                    last_index -= 1
                    deal_positions.append(
                        OneDeal(position, trans, position.quantity))
                    break
                else:
                    position.quantity -= left_vol
                    left_vol = 0
                    deal_positions.append(OneDeal(position, trans, left_vol))
                    break
            if last_index != 0 and search_index != 0:
                p.positions = positions[0:last_index] + left_positions
            elif last_index != 0:
                p.positions = positions[0:last_index]
            # last_index == 0, 表示没找到可平的的开仓对,最后一根强平
            # 可以被catch捕获 AssertError
            assert(left_vol == 0 or last_index == 0)