diff --git a/examples/vn_trader/run.py b/examples/vn_trader/run.py index 1c31e879..f7c23125 100644 --- a/examples/vn_trader/run.py +++ b/examples/vn_trader/run.py @@ -8,7 +8,7 @@ from vnpy.trader.ui import MainWindow, create_qapp from vnpy.gateway.bitmex import BitmexGateway # from vnpy.gateway.futu import FutuGateway # from vnpy.gateway.ib import IbGateway -# from vnpy.gateway.ctp import CtpGateway +from vnpy.gateway.ctp import CtpGateway # from vnpy.gateway.ctptest import CtptestGateway # from vnpy.gateway.mini import MiniGateway # from vnpy.gateway.sopt import SoptGateway @@ -50,7 +50,7 @@ def main(): main_engine = MainEngine(event_engine) # main_engine.add_gateway(BinanceGateway) - # main_engine.add_gateway(CtpGateway) + main_engine.add_gateway(CtpGateway) # main_engine.add_gateway(CtptestGateway) # main_engine.add_gateway(MiniGateway) # main_engine.add_gateway(SoptGateway) diff --git a/vnpy/gateway/ctp/ctp_gateway.py b/vnpy/gateway/ctp/ctp_gateway.py index a72f4598..ab7919bf 100644 --- a/vnpy/gateway/ctp/ctp_gateway.py +++ b/vnpy/gateway/ctp/ctp_gateway.py @@ -479,46 +479,48 @@ class CtpTdApi(TdApi): 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 + # 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_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"] + # 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) + # 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 + # Calculate previous position cost + cost = position.price * position.volume * size - # Update new position volume - position.volume += data["Position"] - position.pnl += data["PositionProfit"] + # 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) + # 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"] + # 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(): diff --git a/vnpy/gateway/ctptest/ctptest_gateway.py b/vnpy/gateway/ctptest/ctptest_gateway.py index a25f9dec..e22ef0a6 100644 --- a/vnpy/gateway/ctptest/ctptest_gateway.py +++ b/vnpy/gateway/ctptest/ctptest_gateway.py @@ -478,46 +478,48 @@ class CtpTdApi(TdApi): 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 + # 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_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"] + # 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) + # 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 + # Calculate previous position cost + cost = position.price * position.volume * size - # Update new position volume - position.volume += data["Position"] - position.pnl += data["PositionProfit"] + # 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) + # 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"] + # 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(): diff --git a/vnpy/gateway/mini/mini_gateway.py b/vnpy/gateway/mini/mini_gateway.py index 1811396f..ff41b911 100644 --- a/vnpy/gateway/mini/mini_gateway.py +++ b/vnpy/gateway/mini/mini_gateway.py @@ -491,7 +491,7 @@ class MiniTdApi(TdApi): def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" - if data: + if data and data["InstrumentID"] in symbol_exchange_map: # Get buffered position object key = f"{data['InstrumentID'], data['PosiDirection']}" position = self.positions.get(key, None) diff --git a/vnpy/gateway/minitest/minitest_gateway.py b/vnpy/gateway/minitest/minitest_gateway.py index cd315540..0a96ef87 100644 --- a/vnpy/gateway/minitest/minitest_gateway.py +++ b/vnpy/gateway/minitest/minitest_gateway.py @@ -491,7 +491,7 @@ class MiniTdApi(TdApi): def onRspQryInvestorPosition(self, data: dict, error: dict, reqid: int, last: bool): """""" - if data: + if data and data["InstrumentID"] in symbol_exchange_map: # Get buffered position object key = f"{data['InstrumentID'], data['PosiDirection']}" position = self.positions.get(key, None)