def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" if not data: return # Check if contract data received if data["InstrumentID"] in symbol_exchange_map: # 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_SGIT2VT[data["PosiDirection"]], 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["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"] * data["Position"] * size 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['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['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 # 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 # 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 # 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 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 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['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()
def on_position(self, d): """""" symbol = d["symbol"] position = self.positions.get(symbol, None) if not position: position = PositionData( symbol=d["symbol"], exchange=Exchange.BITMEX, direction=Direction.NET, gateway_name=self.gateway_name, ) self.positions[symbol] = position volume = d.get("currentQty", None) if volume is not None: position.volume = volume price = d.get("avgEntryPrice", None) if price is not None: position.price = price self.gateway.on_position(copy(position))
def on_position_info(self, packet: dict) -> None: """""" positions = {} data = packet.get("data", []) for d in data: position = PositionData( symbol=d["symbol"].replace('.', '-'), exchange=Exchange.OTC, direction=Direction.NET, gateway_name=self.gateway_name ) if d["type"] == POSITION_TYPE_BUY: position.volume = d["volume"] else: position.volume = -d["volume"] position.price = d["price"] position.pnl = d["current_profit"] positions[position.symbol] = position for symbol in self.position_symbols: if symbol not in positions: position = PositionData( symbol=symbol, exchange=Exchange.OTC, direction=Direction.NET, gateway_name=self.gateway_name ) positions[symbol] = position for position in positions.values(): self.position_symbols.add(position.symbol) self.on_position(position)
def update_order_info(self, packet: dict) -> None: """""" data = packet["data"] # Check Request Event if data["event_type"] == EVENT_REQUEST: if not data["magic"]: return local_id = str(data["magic"]) sys_id = data["order_"] self.sys_local_map[sys_id] = local_id self.local_sys_map[local_id] = sys_id if sys_id in self.temp_orders.keys(): order = self.orders[local_id] order.status = self.temp_orders[sys_id] self.on_order(order) del self.temp_orders[sys_id] # Check TradeTransaction Event else: order_status = STATUS_MT2VT.get(data["order_state"], None) sys_id = data["order"] local_id = self.sys_local_map.get(sys_id, None) if local_id: # cheque order status order = self.orders[local_id] order.status = order_status self.on_order(order) # cheque trade_status if data["event_type"] == EVENT_HISTORY_ADD: trade = TradeData(symbol=data["symbol"], exchange=Exchange.OTC, tradeid=data["deal"], orderid=order.orderid, price=data["price"], volume=data["volume"], gateway_name=self.gateway_name, direction=order.direction, datetime=datetime.now()) if order.volume == trade.volume: order.traded = trade.volume order.status = Status.ALLTRADED else: order.traded = trade.volume order.status = Status.PARTTRADED self.on_order(order) self.on_trade(trade) if trade.direction == Direction.LONG: otype = TYPE_BUY_LIMIT elif trade.direction == Direction.SHORT: otype = TYPE_SELL_LIMIT key = (trade.symbol, otype) position = self.positions.get(key, None) if not position: position = PositionData( symbol=trade.symbol, exchange=Exchange.OTC, direction=trade.direction, gateway_name=self.gateway_name, ) self.positions[key] = position cost = position.price * position.volume cost += data["volume"] * data["price"] position.volume += data["volume"] position.price = cost / position.volume self.on_position(position) self.positions[key] = position else: self.temp_orders[sys_id] = order_status