4.66K 浏览
0

log信息后反复确认,get_position后程序存在逻辑错误。该逻辑错误存在普遍性,几乎所有的类似编码结构都受影响。

日志信息如下(注:有一手隔夜持仓,晚间程序kill掉,9:01启动程序):
——————————————————————————-
2020-07-02 09:01:11 – DCE.jd2008 <INFO> 1)get serial…
2020-07-02 09:01:11 – DCE.jd2008 <INFO> 2)klines serial is ready…
2020-07-02 09:01:11 – DCE.jd2008 <INFO> 1)old position: position long 0, short 0 (记录当前持仓信息)
2020-07-02 09:01:12 – DCE.jd2008 <INFO> 2)new position: position long 0, short 0 (wait_update 等待1秒后在查看持仓信息)
——————————————————————————-
实现代码:
l.info(“1)old position:position long %d, short %d” % (position.pos_long, position.pos_short))
deadline = time.time() + 1
while api.wait_update(deadline=deadline):
pass
l.info(“2)new position long %d, short %d” % (position.pos_long, position.pos_short))
即等待一秒(希望更新position)后程序再往下走。
注意到,klines serial那么多数据都更新了,position依然是0。一手的隔夜持仓没有获取!

该问题影响:

klines = api.get_kline_serial(SYMBOL)
position = api.get_position(SYMBOL) 代码(1)

while True:
api.wait_update()
if tiaojian == True:
position.pos_long == 0:
target_pos.set_target_volume(1) 代码(2)
代码(1)与代码(2)是异步的,谁先执行不一定。所以,会造成很多怪异的错误。

影响结果1:
1. 程序启动;2. position信息在程序启动瞬间未获得持仓信息;3. 因为position.pos_long == 0 下单交易;4. 下单后又获得了position信息,发现已经是2了,所以撤单;5.撤单失败;6.position.pos_long == 2,平一手! (无缘无故多出一对“买-卖操作” + 滑点)
影响结果2:
1. 程序启动;2. position信息在程序启动瞬间未获得持仓信息;3. 因为position.pos_long == 0 下单交易,交易成功。
后续循环中获取了position.pos_long信息:因为position.pos_long == 0不再满足了,set_target_volume(1)也就永远不再执行。本来隔夜持仓1手,变为2手。

官方上次的回答:“在每次wait_update()之后调用is_changing()判断position中的相关字段是不是已经更新”是不行的,因为没有后续逻辑,position将 永远 不会改变,程序一直卡在那里等待。

上述两类影响我都遇到了,目前只有再加长wait_update等待时间,以缓解该问题。
等待一秒在一定程度上是有用的,好几天没有出现该问题了。今天等待1秒也出现了该问题。
等待的方式始终有隐患,应该加入:api.is_position_ready(position)函数。

xuansuokeji 发表新评论 2020年10月26日

我实盘用类似的方法开一单,结果给我连续开平了4次才完成,无故损失了不少手续费和价差,感觉就是这个问题导致的,

好像就是的呢,大神,这问题你解决了吗?[笑哭]

0

9点01分登录,异步的问题就是会有可能造成POSITION不对的问题。如果你早一点登录服务器呢,这个问题应该就没有了。

gerry 已回答的问题 2020年7月8日
0

可以写一份最小的复现代码,然后如果能够复现把代码和日志发到我的邮箱

xuyida@shinnytech.com

ringo 已回答的问题 2020年7月2日