为什么隔夜持仓,第二天的持仓价格永远是错的,是柜台的问题吗?实盘帐号。
为什么隔夜持仓,第二天的持仓价格永远是错的,是柜台的问题吗?实盘帐号。
持仓价格是错的具体指的是什么呢?
比如第一天,开仓的价格是7301,第二天获取到的价格不是7301,貌似是昨日结算价。

只要是过夜的单子,持仓价格和实际不一致,但手机上查询的持仓价格没问题,不知道是不是CTP柜台的问题。
这是一个关于 VeighNa 持仓价格显示机制的问题。让我先查询相关文档和代码来了解具体情况。
让我进一步查询 CTP 接口和持仓数据相关的文档:
让我查看 CTP 接口模块的源代码,了解持仓价格是如何处理的:
我找到了问题的根源。让我再查询一下 PositionData 数据结构来确认:
根据我查询的 CTP 接口源代码,现在可以为您解答这个问题。
这不是柜台的问题,也不是 VeighNa 的 bug,而是期货市场的标准结算机制导致的。
在 CTP 接口的持仓查询回报处理代码中(ctp_gateway.py 第 317-342 行),持仓均价的计算逻辑如下:
# 计算之前已有仓位的持仓总成本
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)
这里的 data["PositionCost"] 是 CTP 柜台返回的持仓成本。
中国期货市场实行每日无负债结算制度(逐日盯市):
| 时间点 | 持仓成本的处理方式 |
|---|---|
| 开仓当天 | CTP 返回的成本基于开仓价格 |
| 每日结算后 | 交易所将持仓成本调整为当日结算价 |
具体流程:
PositionCost 已经是基于 7280 计算的如果您需要在策略中记录真实的开仓价格,有以下几种方式:
from vnpy.trader.object import TradeData
class MyStrategy(CtaTemplate):
def __init__(self, cta_engine, strategy_name, vt_symbol, setting):
super().__init__(cta_engine, strategy_name, vt_symbol, setting)
# 记录开仓价格的字典 {vt_symbol: open_price}
self.open_prices: dict[str, float] = {}
def on_trade(self, trade: TradeData) -> None:
"""成交回调"""
if trade.offset == Offset.OPEN:
# 记录开仓价格
self.open_prices[trade.vt_symbol] = trade.price
elif trade.offset in {Offset.CLOSE, Offset.CLOSETODAY, Offset.CLOSEYESTERDAY}:
# 平仓时清除记录
self.open_prices.pop(trade.vt_symbol, None)
def get_open_price(self, vt_symbol: str) -> float:
"""获取指定合约的开仓价格"""
return self.open_prices.get(vt_symbol, 0)
def calculate_avg_open_price(trades: list[TradeData]) -> float:
"""根据成交列表计算加权平均开仓价"""
total_cost: float = sum(t.price * t.volume for t in trades)
total_volume: float = sum(t.volume for t in trades)
if total_volume > 0:
return total_cost / total_volume
return 0
CTA 策略模板本身会维护 pos 变量和成交回调,您可以直接利用:
def on_trade(self, trade: TradeData) -> None:
"""成交回调"""
super().on_trade(trade) # 调用父类方法更新 pos
# 自定义逻辑记录开仓价
if trade.offset == Offset.OPEN:
# 保存到策略状态,会被持久化
self.set_variable("my_open_price", trade.price)
position.price参考资料:vnpy_ctp/gateway/ctp_gateway.py 中的 onRspQryInvestorPosition 函数