快疯了,用TargetPosTask来调仓,同样是set_target_volume(0),有时是直接清仓,有时是反向对冲,这到底是怎么回事啊,其他设置都是一样的啊。构造TargetPosTask的语句如下:
ctx.pos_tasks[mid] = TargetPosTask( api=api, symbol=mid, price=price, offset_priority="昨今,开", support_open_min_volume=True, min_volume=min_vol, max_volume=max_vol, )
其中的参数price是一个函数,定义如下:
def get_price_by_quote(quote: Quote): def get_price(direction: str) -> float: if direction == DIRECTION_LONG: if quote.upper_limit is not None and quote.upper_limit > 0: return quote.upper_limit else: return quote.ask_price1 else: if quote.lower_limit is not None and quote.lower_limit > 0: return quote.lower_limit else: return quote.bid_price1 return get_price
set_target_volume(0) 调整的是该合约的净持仓,不等同于“只平仓、绝不反向开仓”。
你设置的 offset_priority 为 昨今,开,其中包含“开”:程序会先尝试平昨仓和平今仓,如果根据当前持仓、冻结仓位及委托状态仍未达到目标净持仓,就允许通过反向开仓达到目标。因此需要先检查调仓时的实际持仓和委托状态。
如果目标为 0 时只允许平仓、绝不反向开仓,可以去掉“开”,将 offset_priority 改为 昨今,或者根据需要使用 今昨。
另外,自定义 price 函数收到的 direction 是报单方向 BUY 或 SELL,不是持仓方向 LONG 或 SHORT。请确认 DIRECTION_LONG 的值确实等于 BUY,否则买卖价格分支会走反。建议先临时使用 ACTIVE,排除自定义价格函数的影响。
还需要注意:同一账户、同一合约只保留一个 TargetPosTask;不要同时使用 TargetPosTask 和手工 insert_order 操作同一合约;调用 set_target_volume 后必须继续调用 wait_update。
建议记录调仓前的今昨、多空持仓,以及实际委托的 direction、offset、status 和 last_msg。如果去掉“开”后仍有异常,请提供 TqSdk 版本、合约、调仓前持仓和实际委托记录,以便继续定位。
有其他问题欢迎加入官方Q群748265037一起交流