4.63K 浏览
0

我目前函数需要用到一个类似于分批平仓的功能,但是目前我用的是set_target_volume()这个方法,所以会出现一个问题:当报单速度过快时,下一次的set_target_volume(target_pos)报出去可能上一次的还没有成交,这样就会导致报单实际上会出错。

所以我考虑加入一个成交检测机制,只有检测到上一次的成交后,下一次的报单才会发出去,那么请问怎么样才能获取到成交回报呢?我看了一下TargetPosTask里面的那个trade_chan,但是没搞懂具体怎么用,求指导~谢谢

Shoe X 已回答的问题 2020年8月18日

粒度那么细 就用insert_order自己写吧

0

trade_chan (TqChan): [可选]成交通知channel, 当有成交发生时会将成交手数(多头为正数,空头为负数)发到该channel上

详见官方文档https://doc.shinnytech.com/pysdk/latest/reference/tqsdk.lib.html#tqsdk.lib.TargetPosTask

经过一番摸索,可以使用target_pos._trade_chan取得channel及返回的成交手数。但请注意:在9手多的情况下,set_target_volume(0)返回-9;而set_target_volume(-9)返回[-9, -9]

要检测上一次是否成交,请参见下面示例:

from tqsdk import TqApi, TargetPosTask
api = TqApi()
SYMBOL = "SHFE.ru2101"
quote = api.get_quote(SYMBOL)
position = api.get_position(SYMBOL)
target_pos_value = position.pos  # 目标净持仓数
target_pos = TargetPosTask(api, SYMBOL)
x = target_pos._trade_chan._queue
#通常,此时x为deque([])
#可以给x一个初始值,以便之后计算仓位的变化
#当前target_pos_value持仓为0
x.append(target_pos_value)
#开多9手
target_pos_value = 9
while True:
    target_pos.set_target_volume(target_pos_value)
    api.wait_update()
    print("最新价", quote.last_price)
    #判断是否已经成交,如果是再开9手,净持仓共18手
    if x:
        if x[-1]>0:
            print("[多头]已成交%i手" % x[-1])
        elif x[-1]<0:
            print("[空头]已成交%i手" % x[-1])
        else:
            print("下单中……")
    if target_pos_value == sum(x):
        print("第一次9手已经成交,再下单9手")
        target_pos_value = 18
    if sum(x)==18:
        print("当前净持仓:", position.pos)
        break
api.close()

但请注意:if target_pos_value == sum(x)仅仅能检测最后一次下单是否成交,而不能检测下单队列中的某个指定订单。

所以,如果仅仅是要求“上一次的成交后,下一次的报单才会发出去”,那么,请将下单的代码块写在if 中,例如这样:

#......省略
while True:
    target_pos.set_target_volume(target_pos_value)
    api.wait_update()
    if target_pos_value == sum(x):
        #等待成交,只有下单被成交后才开始新的计算,判断,下单
        print("最新价", quote.last_price)
        #......省略

NULL NULL 发表新评论 2020年8月18日

谢谢,我改用insert order了

0

下一次的set_target_volume(target_pos)报出去时会自动等上一次targetpostask执行完才会执行最新的一次命令

NULL NULL 编辑评论 2020年8月17日

target_pos.set_target_volume(real_vol_applied)
api.wait_update()

我的报单部分是这样写的,每次set_target_volume()之后wait_update()一次发出报单。但是今天遇到了如下情况,可以看到策略本意是先交易9手,然后再交易9手,但是实际情况是第一个9手延迟成交之后,第二个9手不知为什么被撤单了,在此期间我没有用软件登录账号或做其他操作。所以如果我需要通过获取成交报单信息来避免这种情况的话,是否只有通过get_order()方法才能获取到报单情况?
2020-08-17 09:12:45 – WARNING – 交易警告: SHFE.ru2101C14000实际在场手数9
2020-08-17 09:12:45 – WARNING – 交易警告:SHFE.ru2101C14000入场
**:这里相当于target_pos.set_target_volume(9)
api.wait_update()
2020-08-17 09:12:46 – WARNING – 交易警告: SHFE.ru2101C14000实际在场手数18
2020-08-17 09:12:46 – WARNING – 交易警告:SHFE.ru2101C14000入场
**:这里相当于target_pos.set_target_volume(18)
api.wait_update()
2020-08-17 09:12:46,270 – INFO – 通知: 下单成功
2020-08-17 09:12:46,270 – INFO – 通知: 成交通知,合约:SHFE.ru2101C14000,手数:9
2020-08-17 09:21:29,719 – WARNING – 通知: 要撤销的单不存在

如果我改用insert_order(),传参order_id有什么限制吗?还是任意的字符串都可以?