本篇内容主要讲解“怎么解决VNPY的CTP平昨仓位不足问题”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么解决VNPY的CTP平昨仓位不足问题”吧!
其实我现在实盘还是用VNPY 1.92版本,这个“CTP:平昨仓位不足”出现在VNPY1.92版本,而且只发生在使用CtaTrading无人值守程序,而在使用vnTrader这个GUI版本没有这个问题。刚好借这个问题分析下VNPY平昨平今的操作。
然后就开始问题分析呢,这个是平仓问题,而且这个区分平今/平昨的品种就上期所和能源等几个交易所。那么开始debug了,这个debug还是挺麻烦,只有在交易天时候中午比较合适,交易所接收CTP请求还不会产生交易。
首先在CtaEngine.sendOrder函数中的设断点,这个convertOrderReq函数是把一般的交易请求进行转换。
# 委托转换
reqList = self.mainEngine.convertOrderReq(req)
2. 然后一路跟踪,最后发现最终是调用PositionDetail.convertOrderReq方法,PositionDetail这个类是针对单个持仓品种的,记录持仓信息。比如你账户持有3个品种,对应就有3个PositionDetail实例。
这个里面重要是self.mode这个属性,有三种值,如下所示。
MODE_NORMAL = 'normal' # 普通模式
MODE_SHFE = 'shfe' # 上期所今昨分别平仓
MODE_TDPENALTY = 'tdpenalty' # 平今惩罚
对应交易请求,包括品种类型,数量,金额,开平类型属性,平今平昨主要区别在开平类型
从下面代码可以看到,self.mode如果是普通模式,直接返回原来传入交易请求。
交易请求中的开平类型为默认的OFFSET_CLOSE;如果是MODE_SHFE,在平仓时候按照持仓情况进行拆分两个request,今天仓位平仓类型用OFFSET_CLOSETODAY,昨天仓位平仓类型用OFFSET_CLOSEYESTERDAY
def convertOrderReq(self, req):
"""转换委托请求"""
# 普通模式无需转换
if self.mode is self.MODE_NORMAL:
return [req]
# 上期所模式拆分今昨,优先平今
elif self.mode is self.MODE_SHFE:
# 开仓无需转换
if req.offset is OFFSET_OPEN:
return [req]
# 多头
if req.direction is DIRECTION_LONG:
posAvailable = self.shortPos - self.shortPosFrozen
tdAvailable = self.shortTd- self.shortTdFrozen
ydAvailable = self.shortYd - self.shortYdFrozen
# 空头
else:
posAvailable = self.longPos - self.longPosFrozen
tdAvailable = self.longTd - self.longTdFrozen
ydAvailable = self.longYd - self.longYdFrozen
# 平仓量超过总可用,拒绝,返回空列表
if req.volume > posAvailable:
return []
# 平仓量小于今可用,全部平今
elif req.volume <= tdAvailable:
req.offset = OFFSET_CLOSETODAY
return [req]
# 平仓量大于今可用,平今再平昨
else:
l = []
if tdAvailable > 0:
reqTd = copy(req)
reqTd.offset = OFFSET_CLOSETODAY
reqTd.volume = tdAvailable
l.append(reqTd)
reqYd = copy(req)
reqYd.offset = OFFSET_CLOSEYESTERDAY
reqYd.volume = req.volume - tdAvailable
l.append(reqYd)
return l
#......
3. debug发现,上期所品种PositionDetail.mode竟然是MODE_NORMAL,而不是MODE_SHFE。VNPY就调用了OFFSET_CLOSE,这个时候CTP接口就返回错误信息“CTP:平昨仓位不足”,应该是默认就变成平昨了。
4. 为什么不对了,继续debug,发现是虽然策略持仓信息实在数据库独立保存的,但是vnpy在启动时候还会去交易所查询账户持仓信息,这个持仓信息会在vnTrader中显示,也作为平今平昨时候用。
5.runCtaTrading.py中,有下面一段代码,去读账户持仓信息保存。但是这段被我不小心删除了,原因是之前没有夜盘时候我调整代码,不小心删除。这样的化,就没有初始账户持仓信息,这时候就会使用默认配置,认为是普通交易所。恢复后就OKay.....
sleep(10) # 等待CTP接口初始化
me.dataEngine.saveContracts() # 保存合约信息到文件
到此,相信大家对“怎么解决VNPY的CTP平昨仓位不足问题”有了更深的了解,不妨来实际操作一番吧!这里是天达云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!