问题描述
订单获取函数get_orders(),获取的是当天所有下单,有没有办法区分不同的subportfolio? 如果不能,平台能否完善这个功能?
麻烦看一下,谢谢。@薛定谔の喵-JoinQuant
解决方案
问题解答
在 JoinQuant(聚宽)目前的 API 设计中,get_orders() 函数返回的 Order 对象包含了订单的状态、标的、价格、数量等详细信息,但原生 Order 对象中确实没有直接包含 pindex(子账户索引)属性。因此,直接通过 get_orders() 的返回值是无法区分该订单属于哪个 subportfolio 的。
不过,在日常策略编写中,我们可以通过在全局变量中自行维护订单与子账户的映射关系来实现这一需求。
变通解决方案:自行维护映射字典
由于下单函数(如 order(), order_target() 等)在执行成功后会返回一个 Order 对象,该对象包含唯一的 order_id。我们可以在下单时,将 order_id 和对应的 pindex 记录到全局变量 g 中。
代码示例
def initialize(context):
# 初始化两个子账户,例如一个股票,一个期货
init_cash = context.portfolio.starting_cash / 2
set_subportfolios([
SubPortfolioConfig(cash=init_cash, type='stock'),
SubPortfolioConfig(cash=init_cash, type='futures')
])
# 初始化一个全局字典,用于记录 order_id 和 pindex 的映射
g.order_pindex_map = {}
run_daily(trade_logic, time='09:30')
run_daily(check_orders, time='14:50')
def trade_logic(context):
# 在子账户 0 (股票) 下单
order_obj_0 = order('000001.XSHE', 100, pindex=0)
if order_obj_0:
# 记录映射关系
g.order_pindex_map[order_obj_0.order_id] = 0
# 在子账户 1 (期货) 下单
order_obj_1 = order('IF9999.CCFX', 1, side='long', pindex=1)
if order_obj_1:
# 记录映射关系
g.order_pindex_map[order_obj_1.order_id] = 1
def check_orders(context):
# 获取当天所有订单
all_orders = get_orders()
for order_id, order_info in all_orders.items():
# 从我们维护的字典中获取该订单的 pindex
# 如果是系统自动产生的订单(如强平),可能不在字典中,使用 get 方法避免报错
pindex = g.order_pindex_map.get(order_id, '未知')
log.info(f"订单ID: {order_id}, 标的: {order_info.security}, 所属子账户: {pindex}, 状态: {order_info.status}")
方案优势与注意事项
- 灵活性高:通过字典映射,不仅可以记录
pindex,还可以记录下单时的自定义备注、策略信号来源等额外信息。 - 内存管理:如果策略运行周期极长且下单极其频繁,建议在
after_trading_end中定期清理g.order_pindex_map中已经完成(held,canceled,rejected)的订单,以防止字典过大占用过多内存。 - 平台建议:关于在
Order对象中原生增加pindex属性的建议非常合理,这能极大方便多策略/多仓位管理的开发者。建议您可以在聚宽社区的“产品建议”板块发帖,官方研发团队通常会收集此类高频需求并在后续 API 更新中进行迭代完善。