问题描述
现在的需求是下单动态同步异步,需要异步的话下单之前就 设置一下set_option('async_order', True)
run_daily(market_open, time='open', reference_security='000300.XSHG')
def market_open(context):
set_option('async_order', True)
解决方案
在 JoinQuant (聚宽) 平台上,不建议且通常不支持在 run_daily 调用的盘中函数里动态使用 set_option 来切换同步/异步下单模式。
具体原因和解决方案如下:
1. set_option 的作用域
根据 JoinQuant 官方 API 文档,set_option 主要用于配置全局的回测和模拟交易环境(例如 set_option('use_real_price', True)、set_option('order_volume_ratio', 0.25) 等)。官方明确指出,这类环境设定函数必须或建议在 initialize(context) 初始化函数中调用。在盘中动态修改全局配置可能会导致底层撮合引擎状态混乱或直接被忽略。
2. 聚宽的订单处理机制(不支持 async_order)
聚宽的 API 文档中明确说明:
"回测模式整个过程是同步进行,order_*函数执行成功后会创建一个order对象,市价单的order对象撮合后(交易时间下单立即撮合)会立即获得交易的结果..."
目前 JoinQuant 官方 API 并没有提供 set_option('async_order', True) 这个参数。聚宽的下单函数(如 order, order_target 等)默认都是同步阻塞执行的。此外,平台出于安全和资源分配的考虑,明确限制了多线程/多进程的使用(日志中会出现 joblib will operate in serial mode 的警告)。
3. 替代方案:如何提高下单效率?
如果您希望实现“异步下单”的初衷是为了加快多只标的的下单速度,避免在 for 循环中单笔同步下单造成的耗时,聚宽提供了专门的篮子下单(批量委托)API:batch_submit_orders。
您可以在 run_daily 中构建好所有订单,然后一次性提交,底层会批量处理,效率远高于循环单笔下单。
示例代码:
def initialize(context):
# 全局设置放在 initialize 中
set_option('use_real_price', True)
run_daily(market_open, time='open', reference_security='000300.XSHG')
def market_open(context):
# 不要在这里使用 set_option 动态切换底层机制
# 如果需要快速批量下单,使用 batch_submit_orders
orders_list = [
{
"security": "000001.XSHE",
"amount": 100,
"pindex": 0
},
{
"security": "600000.XSHG",
"amount": 200,
"pindex": 0
}
]
# 批量提交委托,底层统一验资验券并报单
batch_submit_orders(orders_list)
总结:
请将 set_option 统一放在 initialize 中。聚宽不支持动态切换异步下单,若需提升下单效率,请改用 batch_submit_orders 批量下单接口。