4.90K 浏览
0

在回测中使用api.get_position(code).pos时返回的值为目前的净持仓,但有一个问题是,如果在回测中同一根k线内分批次进行平仓操作时,使用如下语句会出现平仓手数不对的情况。

我看了一下回测结果,发现问题在于get_position().pos的返回值不是当天的持仓,而是上一交易日的净持仓。(我的回测用的是历史日k)

所以我想问一下,这个问题的原因是我回测中历史k线没有更新吗?还是说所有情况下,这个语句都只能返回上一交易日的净持仓数据?

如果我需要拿到实时的净仓数据,应该用什么语句呢?

set_target_volume((api.get_position(code).pos - vol))
# vol为分批次需要平仓的手数
lookis 已回答的问题 2020年7月28日

补充问一下,get_position().pos这个语句是在什么时候更新返回值呢?
是wait_update()之后才会更新吗?还是说正常调用(模拟或实盘)时,只要我仓位有变化,下一次调用get_position().pos语句就能够拿到变化后的实时净仓数据呢?

我目前在回测的部分用代码绕过了这个问题,但是为了能上模拟和实盘,我还是想弄清楚get_position().pos究竟返回的是哪个时刻的净仓?这个语句的返回值会在什么机制下进行更新?

1

.pos 是当下的净持仓,不是前一天的,也就是说如果你下了单,这个.pos就会改变。

更新时机就像你说的是在wait_update()的时候更新,但要注意的是有可能下单并成交之后,下一次的 wait_update() 也有可能没有更新.pos

发生这个现象的主要原因是所有的数据都是基于事件的,所以推送不会说按照确定的一个顺序到达(部分事件应该是有顺序的),不是说先推送quote数据,再推送kline数据,再推送position数据,再推送trade,没有这样的严格顺序,所以有可能数据推送的时序是这样(up指代上行,down指代下行):

  1. up 新订单
  2. down 订单被交易所接受
  3. down 新订单部分成交(trade)
  4. down 新订单完全成交(trade)
  5. down quote信息
  6. down account的balance
  7. down position

那么你在调用wait_update()的时候,有可能刚好处于4和5之间,那么在这个时候的position就还没有更新(需要到7之后)

当然也有一种可能是

  1. up 新订单
  2. down 订单被交易所接受
  3. down 新订单部分成交(trade)
  4. down position
  5. down 新订单完全成交(trade)
  6. down position
  7. down account的balance

在这种时序里,如果程序调用wait_update刚好在 4和5之间的话,是可以看到position有更新的,但这时的数据可能不是最终的数据(因为还有一部分成交在5)

而最好的办法是在你的分批次平仓逻辑里面先做一个判断

is_changing(position, ['pos_long_his', 'pos_long_today', 'pos_short_his','pos_short_today'])

之后再进行新的下单

lookis 编辑答案 2020年7月28日
0

PS. 如果要用 asyncio 异步编程的话也需要做上面的那个判断,因为回调的时候有可能只是因为position别的字段被更新了,pos相关的字段没有更新(比方说 float_profit 字段更新也会有回调)

muze123 发表新评论 2020年7月28日

知道了,谢谢~