温馨提示×

温馨提示×

您好,登录后才能下订单哦!

密码登录×
登录注册×
其他方式登录
点击 登录注册 即表示同意《亿速云用户服务条款》

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

发布时间:2021-11-02 11:06:50 来源:亿速云 阅读:371 作者:iii 栏目:编程语言

本篇内容主要讲解“怎么解决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平昨仓位不足问题”有了更深的了解,不妨来实际操作一番吧!这里是亿速云网站,更多相关内容可以进入相关频道进行查询,关注我们,继续学习!

向AI问一下细节

免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。

AI