def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" if not data: return # Get buffered position object key = f"{data['InstrumentID'], data['PosiDirection']}" position = self.positions.get(key, None) symbol = data["InstrumentID"] if "&" in symbol: exchange = Exchange.SSE else: exchange = symbol_exchange_map[data["InstrumentID"]] if not position: position = PositionData( symbol=symbol, exchange=exchange, direction=DIRECTION_SOPT2VT[data["PosiDirection"]], gateway_name=self.gateway_name) self.positions[key] = position # For SHFE position data update if position.exchange == Exchange.SHFE: if data["YdPosition"] and not data["TodayPosition"]: position.yd_volume = data["Position"] # For other exchange position data update else: position.yd_volume = data["Position"] - data["TodayPosition"] # Get contract size (spread contract has no size value) size = symbol_size_map.get(position.symbol, 0) # Calculate previous position cost cost = position.price * position.volume * size # Update new position volume position.volume += data["Position"] position.pnl += data["PositionProfit"] # Calculate average position price if position.volume and size: cost += data["PositionCost"] position.price = cost / (position.volume * size) # Get frozen volume if position.direction == Direction.LONG: position.frozen += data["ShortFrozen"] else: position.frozen += data["LongFrozen"] if last: for position in self.positions.values(): self.gateway.on_position(position) self.positions.clear()
def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool) -> None: """持仓查询回报""" if not data: return # 必须已经收到了合约信息后才能处理 symbol: str = data["InstrumentID"] contract: ContractData = symbol_contract_map.get(symbol, None) if contract: # 获取之前缓存的持仓数据缓存 key: str = f"{data['InstrumentID'], data['PosiDirection']}" position: PositionData = self.positions.get(key, None) if not position: position = PositionData( symbol=data["InstrumentID"], exchange=contract.exchange, direction=DIRECTION_CTP2VT[data["PosiDirection"]], gateway_name=self.gateway_name ) self.positions[key] = position # 对于上期所昨仓需要特殊处理 if position.exchange in [Exchange.SHFE, Exchange.INE]: if data["YdPosition"] and not data["TodayPosition"]: position.yd_volume = data["Position"] # 对于其他交易所昨仓的计算 else: position.yd_volume = data["Position"] - data["TodayPosition"] # 获取合约的乘数信息 size: int = contract.size # 计算之前已有仓位的持仓总成本 cost: float = position.price * position.volume * size # 累加更新持仓数量和盈亏 position.volume += data["Position"] position.pnl += data["PositionProfit"] # 计算更新后的持仓总成本和均价 if position.volume and size: cost += data["PositionCost"] position.price = cost / (position.volume * size) # 更新仓位冻结数量 if position.direction == Direction.LONG: position.frozen += data["ShortFrozen"] else: position.frozen += data["LongFrozen"] if last: for position in self.positions.values(): self.gateway.on_position(position) self.positions.clear()
def onRspQryPosition( self, data: dict, error: dict, reqid: int, last: bool ) -> None: """""" if not data and last: for position in self.positions.values(): self.gateway.on_position(position) self.positions.clear() return # Check if contract data received if data["InstrumentID"] in symbol_name_map: # Get buffered position object key = f"{data['InstrumentID'], data['Direction']}" position = self.positions.get(key, None) if not position: position = PositionData( symbol=data["InstrumentID"], exchange=EXCHANGE_UFT2VT[data["ExchangeID"]], direction=DIRECTION_UFT2VT[data["Direction"]], gateway_name=self.gateway_name ) self.positions[key] = position # For SHFE and INE position data update if position.exchange in [Exchange.SHFE, Exchange.INE]: if data["YdPositionVolume"] and not data["TodayPositionVolume"]: position.yd_volume = data["PositionVolume"] # For other exchange position data update else: position.yd_volume = data["PositionVolume"] - data["TodayPositionVolume"] # Get contract size (spread contract has no size value) size = symbol_size_map.get(position.symbol, 0) # Calculate previous position cost cost = position.price * position.volume * size # Update new position volume position.volume += data["PositionVolume"] position.pnl += data["PositionProfit"] # Calculate average position price if position.volume and size: cost += data["PositionCost"] position.price = cost / (position.volume * size) position.frozen += data["CloseFrozenVolume"]
def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" if not data: return # Get buffered position object key = f"{data['InstrumentID'], data['PosiDirection']}" position = self.positions.get(key, None) if not position: position = PositionData( symbol=data["InstrumentID"], exchange=symbol_exchange_map[data["InstrumentID"]], direction=DIRECTION_CTP2VT[data["PosiDirection"]], gateway_name=self.gateway_name ) self.positions[key] = position # Get contract size, return if size value not collected size = symbol_size_map.get(position.symbol, None) if not size: return # For SHFE position data update if position.exchange == Exchange.SHFE: if data["YdPosition"] and not data["TodayPosition"]: position.yd_volume = data["Position"] # For other exchange position data update else: position.yd_volume = data["Position"] - data["TodayPosition"] # Calculate previous position cost cost = position.price * position.volume * size # Update new position volume position.volume += data["Position"] position.pnl += data["PositionProfit"] # Calculate average position price if position.volume: cost += data["PositionCost"] position.price = cost / (position.volume * size) # Get frozen volume if position.direction == Direction.LONG: position.frozen += data["ShortFrozen"] else: position.frozen += data["LongFrozen"] if last: for position in self.positions.values(): self.gateway.on_position(position) self.positions.clear()
def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" if not data: return # Get buffered position object key = f"{data['InstrumentID'], data['Direction']}" position = self.positions.get(key, None) if not position: position = PositionData( symbol=data["InstrumentID"], exchange=symbol_exchange_map[data["InstrumentID"]], direction=DIRECTION_FEMAS2VT[data["Direction"]], gateway_name=self.gateway_name, ) self.positions[key] = position position.yd_volume = data["YdPosition"] # Calculate previous position cost cost = position.price * position.volume # Update new position volume position.volume += data["Position"] # Calculate average position price if position.volume: cost += data["PositionCost"] position.price = cost / position.volume # Get frozen volume position.frozen += data["FrozenPosition"] if last: for position in self.positions.values(): self.gateway.on_position(position) self.positions.clear()