在回测中使用api.get_position(code).pos时返回的值为目前的净持仓,但有一个问题是,如果在回测中同一根k线内分批次进行平仓操作时,使用如下语句会出现平仓手数不对的情况。
我看了一下回测结果,发现问题在于get_position().pos的返回值不是当天的持仓,而是上一交易日的净持仓。(我的回测用的是历史日k)
所以我想问一下,这个问题的原因是我回测中历史k线没有更新吗?还是说所有情况下,这个语句都只能返回上一交易日的净持仓数据?
如果我需要拿到实时的净仓数据,应该用什么语句呢?
set_target_volume((api.get_position(code).pos - vol)) # vol为分批次需要平仓的手数
我目前在回测的部分用代码绕过了这个问题,但是为了能上模拟和实盘,我还是想弄清楚get_position().pos究竟返回的是哪个时刻的净仓?这个语句的返回值会在什么机制下进行更新?
.pos 是当下的净持仓,不是前一天的,也就是说如果你下了单,这个.pos就会改变。
更新时机就像你说的是在wait_update()的时候更新,但要注意的是有可能下单并成交之后,下一次的 wait_update() 也有可能没有更新.pos
发生这个现象的主要原因是所有的数据都是基于事件的,所以推送不会说按照确定的一个顺序到达(部分事件应该是有顺序的),不是说先推送quote数据,再推送kline数据,再推送position数据,再推送trade,没有这样的严格顺序,所以有可能数据推送的时序是这样(up指代上行,down指代下行):
- up 新订单
- down 订单被交易所接受
- down 新订单部分成交(trade)
- down 新订单完全成交(trade)
- down quote信息
- down account的balance
- down position
那么你在调用wait_update()的时候,有可能刚好处于4和5之间,那么在这个时候的position就还没有更新(需要到7之后)
当然也有一种可能是
- up 新订单
- down 订单被交易所接受
- down 新订单部分成交(trade)
- down position
- down 新订单完全成交(trade)
- down position
- down account的balance
- …
在这种时序里,如果程序调用wait_update刚好在 4和5之间的话,是可以看到position有更新的,但这时的数据可能不是最终的数据(因为还有一部分成交在5)
而最好的办法是在你的分批次平仓逻辑里面先做一个判断
is_changing(position, ['pos_long_his', 'pos_long_today', 'pos_short_his','pos_short_today'])
之后再进行新的下单
补充问一下,get_position().pos这个语句是在什么时候更新返回值呢?
是wait_update()之后才会更新吗?还是说正常调用(模拟或实盘)时,只要我仓位有变化,下一次调用get_position().pos语句就能够拿到变化后的实时净仓数据呢?