vn.py量化社区
By Traders, For Traders.
Member
avatar
加入于:
帖子: 143
声望: 3

实盘中的一个策略,跑了一星期没问题,开仓代码如下。

        #开仓
        if 时间=开仓时间:                       
            if self.pos == 0:
                if bar.close_price > Price[1]:
                    self.buy(bar.close_price, 1)
                    self.f1.write("开仓做多"+"\n")
                if bar.close_price < Price[0]:
                    self.short(bar.close_price, 1)
                    self.f1.write("开仓做空"+"\n")
            elif self.pos > 0:
                if 条件3:
                    self.sell(bar.close_price, 1)
                    self.short(bar.close_price, 1)
                    self.f1.write("平多仓,反手"+"\n")
            else:
                if 条件4:
                    self.cover(bar.close_price, 1)
                    self.buy(bar.close_price, 1)  
                    self.f1.write("平空仓,反手"+"\n")

按理来说,不会出现持仓大于一手的情况的,可是今天我发现竟然有两手持仓,下面是我自己保存的日志

记录开盘价,时间是2019-10-29 09:01:00,价格是.....
平多仓,反手
平空仓,反手
平空仓,反手
开仓做多

执行了两次平空仓,而且有“开仓做多”这个字眼,
这就奇怪了,按理来说只有pos == 0才会执行“开仓做多”这个代码呀。
请问应该从哪里找原因?谢谢。。

Administrator
avatar
加入于:
帖子: 3517
声望: 183

以上逻辑是写在on_bar还是on_tick里面的?

self.pos是在策略收到成交回报后才会更新,如果因为某种原因你的交易接口卡了或者断了,之前发出的委托回来的成交回报没收到,导致self.pos还是0,此时如果on_bar或者on_tick被触发,就会重复发单。

Member
avatar
加入于:
帖子: 143
声望: 3

用Python的交易员 wrote:

以上逻辑是写在on_bar还是on_tick里面的?

self.pos是在策略收到成交回报后才会更新,如果因为某种原因你的交易接口卡了或者断了,之前发出的委托回来的成交回报没收到,导致self.pos还是0,此时如果on_bar或者on_tick被触发,就会重复发单。

是写在on_bar里面的。
1分钟bar的话应该不会存在成交回报没收到的情况吧?

如果是的话,可以利用什么代码来判断吗?

Administrator
avatar
加入于:
帖子: 3517
声望: 183

用的是BitMEX吗?我们之前发现了一个BITMEX的原始TICK时间戳可能乱序的问题,会导致on_bar在短时间内被重复触发

Member
avatar
加入于:
帖子: 143
声望: 3

用Python的交易员 wrote:

用的是BitMEX吗?我们之前发现了一个BITMEX的原始TICK时间戳可能乱序的问题,会导致on_bar在短时间内被重复触发

不是,做的螺纹。
我检查了一下,on_bar开始忘记加cancal all order了,
如果平了仓,反手开仓未成功,的确会导致self.pos == 0重新开仓,但也不会开两手呀

不知是不是这个原因导致的。
我先改一下代码试试。

Member
avatar
加入于:
帖子: 143
声望: 3

看样子不是忘记加cancal all order的问题,这两周运行正常,不过今天发现又出问题了。下面我自己的日志(相关代码也是在on_bar里面的)。

----------------------------------------------------------------------------------------------------
记录开盘价,时间是2019-11-21
平多仓,反手, 时间是2019-11-21 09:32:00,价格是3639.0
**************************************************
----------------------------------------------------------------------------------------------------
记录开盘价,时间是2019-11-22 
平空仓,反手, 时间是2019-11-22 14:22:00,价格是3649.0
平空仓,反手, 时间是2019-11-22 14:23:00,价格是3653.0
开仓做多, 时间是2019-11-22 14:24:00,价格是3656.0
**************************************************

然后我查看今天的成交记录:
14:24:03 买开一手
14:25:01 买开一手
并没有平空仓的记录,

所以我的策略本来是始终持仓一手的,今天变成了持三手了(一手空仓+2手多仓)

所以我自己分析:
14:22:00,的“平空仓,反手”指令没有成功
14:23:00 的“平空仓,反手”指令中,平空仓没成功,但反手开仓成功了。
14:24:00的“开仓做多”指令也成功了。
所以,请问:
A.问题是不是出在了平空仓没成功,但反手开仓成功了,这样我持有了一手多仓和一手空仓,vnpy认为我的仓位为0,所以又触发了“开仓做多”的代码?

B. 像这样的情况,如何保证平多反手,平空反手时平掉原来仓位、开新仓都成交?因为即使我将开仓价+5,但是好像也不能解决这个问题吧?因为毕竟有先后,不知可不可以一条命令同时发过去?一平一开,这样就同时了。

谢谢。

Member
avatar
加入于:
帖子: 54
声望: 1

回测中也碰到了这个问题, 所以应该不是成交的问题 可能是写法上不对

Administrator
avatar
加入于:
帖子: 3517
声望: 183

A:是有可能的
B:对于BitMEX这种采用净仓位交易的交易所,你可以直接将开平合成为一条委托发出去

最后你遇到的这个问题,可能和BitMEX在波动大时候的拒单机制有关系,推荐试试Bybit这个新的交易所吧,我们2.0.8也加上BybitGateway了,之前测试了一个月的CTA策略,比BitMEX执行稳定很多

Member
avatar
加入于:
帖子: 143
声望: 3

我做的是螺纹,
我觉得实盘中这是一个bug,就是空翻多或多翻空的时候如何保证两个单都成交,至少不要出现这种平单没成交,反手单又成交了的情况,不知陈总有没有好的办法,谢谢。

Administrator
avatar
加入于:
帖子: 3517
声望: 183

细粒度挂撤单控制,调用委托函数buy/sell/short/cover后,会返回一个委托号列表。

然后基于on_order接收这些委托状态,只有收到撤单确认回报后,再发出新的平仓委托。

© 2015-2019 上海韦纳软件科技有限公司
备案服务号:沪ICP备18006526号-3