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