千家信息网

怎么解决VNPY的CTP平昨仓位不足问题

发表于:2025-01-20 作者:千家信息网编辑
千家信息网最后更新 2025年01月20日,本篇内容主要讲解"怎么解决VNPY的CTP平昨仓位不足问题",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么解决VNPY的CTP平昨仓位不足问题"吧!其实
千家信息网最后更新 2025年01月20日怎么解决VNPY的CTP平昨仓位不足问题

本篇内容主要讲解"怎么解决VNPY的CTP平昨仓位不足问题",感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习"怎么解决VNPY的CTP平昨仓位不足问题"吧!

其实我现在实盘还是用VNPY 1.92版本,这个"CTP:平昨仓位不足"出现在VNPY1.92版本,而且只发生在使用CtaTrading无人值守程序,而在使用vnTrader这个GUI版本没有这个问题。刚好借这个问题分析下VNPY平昨平今的操作。

然后就开始问题分析呢,这个是平仓问题,而且这个区分平今/平昨的品种就上期所和能源等几个交易所。那么开始debug了,这个debug还是挺麻烦,只有在交易天时候中午比较合适,交易所接收CTP请求还不会产生交易。

  1. 首先在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平昨仓位不足问题"有了更深的了解,不妨来实际操作一番吧!这里是网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

0