def on_position(self, d): """""" pos = PositionData( symbol=d["instrument_id"], exchange=Exchange.OKEX, direction=Direction.LONG, volume=d["long_qty"], frozen=float(d["long_qty"]) - float(d["long_avail_qty"]), price=d["long_avg_cost"], pnl=d["realised_pnl"], gateway_name=self.gateway_name, ) self.gateway.on_position(pos) pos = PositionData( symbol=d["instrument_id"], exchange=Exchange.OKEX, direction=Direction.SHORT, volume=d["short_qty"], frozen=float(d["short_qty"]) - float(d["short_avail_qty"]), price=d["short_avg_cost"], pnl=d["realised_pnl"], gateway_name=self.gateway_name, ) self.gateway.on_position(pos)
def on_query_position(self, data, request): """""" if not data["holding"]: return for pos_data in data["holding"][0]: if float(pos_data["long_qty"]) > 0: pos = PositionData( symbol=pos_data["instrument_id"].upper(), exchange=Exchange.OKEX, direction=Direction.LONG, volume=pos_data["long_qty"], frozen=float(pos_data["long_qty"]) - float(pos_data["long_avail_qty"]), price=pos_data["long_avg_cost"], pnl=pos_data["realised_pnl"], gateway_name=self.gateway_name, ) self.gateway.on_position(pos) if float(pos_data["short_qty"]) > 0: pos = PositionData( symbol=pos_data["instrument_id"], exchange=Exchange.OKEX, direction=Direction.SHORT, volume=pos_data["short_qty"], frozen=float(pos_data["short_qty"]) - float(pos_data["short_avail_qty"]), price=pos_data["short_avg_cost"], pnl=pos_data["realised_pnl"], gateway_name=self.gateway_name, ) self.gateway.on_position(pos)
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"] # 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 on_position(self, d): """""" position = PositionData( symbol=d["symbol"], exchange=Exchange.BITMEX, direction=Direction.NET, volume=d["currentQty"], gateway_name=self.gateway_name, ) self.gateway.on_position(position)
def on_query_position(self, data, request): """""" if self.check_error(data, "查询持仓"): return # Clear all buf data for position in self.positions.values(): position.volume = 0 position.frozen = 0 position.price = 0 position.pnl = 0 for d in data["data"]: key = f"{d['contract_code']}_{d['direction']}" position = self.positions.get(key, None) if not position: position = PositionData( symbol=d["contract_code"], exchange=Exchange.HUOBI, direction=DIRECTION_HBDM2VT[d["direction"]], gateway_name=self.gateway_name) self.positions[key] = position position.volume = d["volume"] position.frozen = d["frozen"] position.price = d["cost_hold"] position.pnl = d["profit"] for position in self.positions.values(): self.gateway.on_position(position)
def OnQueryPosition(self, xtp_position: XTPQueryStkPositionRsp, error_info: XTPRspInfoStruct, request_id: int, is_last: bool, session_id: int) -> Any: """""" position = PositionData(symbol=xtp_position.ticker, exchange=MARKET_XTP2VT[xtp_position.market], direction=Direction.NET, volume=xtp_position.total_qty, frozen=xtp_position.locked_position, price=xtp_position.avg_price, pnl=xtp_position.unrealized_pnl, yd_volume=xtp_position.yesterday_position, gateway_name=self.gateway_name) self.gateway.on_position(position)
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 updatePortfolio( # pylint: disable=invalid-name self, contract: Contract, position: float, marketPrice: float, marketValue: float, averageCost: float, unrealizedPNL: float, realizedPNL: float, accountName: str, ): """ Callback of position update. """ super(IbApi, self).updatePortfolio( contract, position, marketPrice, marketValue, averageCost, unrealizedPNL, realizedPNL, accountName, ) ib_size = contract.multiplier if not ib_size: ib_size = 1 price = averageCost / ib_size pos = PositionData( symbol=contract.conId, exchange=EXCHANGE_IB2VT.get(contract.exchange, contract.exchange), direction=Direction.NET, volume=position, price=price, pnl=unrealizedPNL, gateway_name=self.gateway_name, ) self.gateway.on_position(pos)
def query_position(self): """""" code, data = self.trade_ctx.position_list_query(trd_env=self.env, acc_id=0) if code: self.write_log(f"查询持仓失败:{data}") return for ix, row in data.iterrows(): symbol, exchange = convert_symbol_futu2vt(row["code"]) pos = PositionData( symbol=symbol, exchange=exchange, direction=Direction.LONG, volume=row["qty"], frozen=(float(row["qty"]) - float(row["can_sell_qty"])), price=float(row["pl_val"]), pnl=float(row["cost_price"]), gateway_name=self.gateway_name, ) self.on_position(pos)