多品种组合单品种剧烈波动:组合风控先平谁

前言

国内期货组合策略很常见:同一资金账户里同时持有螺纹钢、铁矿石、豆粕、股指等多个品种,各品种由子策略或同一策略的不同腿给出目标净仓。组合层面通常会设总风险度上限、总浮亏上限、单品种贡献度上限。平时各腿波动不大时,单合约止损就够;但当某一腿突然急涨急跌------政策消息、外盘联动、涨跌停封板------该腿浮亏和保证金占用会瞬间拉高,组合 risk_ratio 可能逼近 1,其他腿还没动就已经触及账户级风控。

这时不能只问"这个品种要不要止损",而要问"组合先减哪条腿、减多少、是否整体降杠杆"。天勤 TqSdk 可对每个 symbolget_positionget_quote,对账户读 get_account()。下面解释组合风控里常见英文字段含义、触发条件怎么写、某一腿剧烈波动时先平谁的优先级规则,以及如何用 TargetPosTask.set_target_volume 落地。

一、名词对照:组合风控读哪些天勤对象

代码/字段 是什么 组合风控里干什么
symbol 合约代码,如 SHFE.rb2510 多品种时逐个统计
get_position(symbol) 该合约持仓对象 读单腿净仓与浮亏
pos.pos 净持仓手数 减仓后是否归零
float_profit_long / float_profit_short 多头/空头浮动盈亏 单腿亏损排序
pos.margin 该合约占用保证金(若有) 单腿资金占用排序
get_account() 资金账户 组合总风险
risk_ratio 风险度,文档为保证金除以权益 接近 1 时组合危险
TargetPosTask 天勤调仓工具,把净仓推向目标 对 victim 品种 set 零或减量
set_target_volume(n) 把该合约目标净仓设为 n 减仓执行动作
wait_update() 推进行情与交易回报 触发判断前要更新

组合风控通常写在"上层主机":主循环里 wait_update 后先算组合指标,再决定是否覆盖各子策略给出的目标仓。

二、为什么要组合层,而不只靠单品种止损

单品种止损假设各腿独立;组合里两腿可能对冲(多螺纹空铁矿),单腿剧震时净敞口变向,只平剧震腿有时不够,有时平错腿会破坏对冲。组合层看的是:账户还能不能承受、哪条腿对组合伤害最大、哪条腿最容易平出去。

典型触发(团队可配置阈值):

  • account.risk_ratio > 0.90:账户级,可能所有腿都要减;
  • 某 symbol 浮亏之和低于 -per_sym_loss:单腿贡献过大;
  • 某 symbol 当日振幅或 ATR 突增:波动率异常,先禁开新仓或减该腿。
python 复制代码
def portfolio_risk_ok(api, symbols, limits):
    acc = api.get_account()
    if acc.risk_ratio > limits["max_risk"]:
        return False, "account_risk"
    for s in symbols:
        pos = api.get_position(s)
        pnl = pos.float_profit_long + pos.float_profit_short
        if pnl < -limits["per_sym_loss"]:
            return False, f"sym_loss:{s}"
    return True, ""

limits 是团队自定的字典,如 max_risk=0.85per_sym_loss=50000(元)。risk_ratio 刚启动时可能短暂为 nan,应 wait_update 若干帧后再判。

三、先平谁:四条常见优先级(可配置)

触发后不能对所有 symbol 同时 set_target_volume(0),有时只需减最危险的一腿。常见规则(选一或组合):

  1. 亏损最大腿先减:减小组合方向性暴露,适合趋势组合剧震腿已大幅浮亏。
  2. 流动性最好腿先减:看 quote.bid_volume1 + ask_volume1 或历史成交,先平容易成交的,避免封板腿平不掉、其他腿乱平。
  3. 非核心 beta 腿先减:保留对冲核心腿,例如套利里先减投机腿。
  4. 保证金占用最高腿先减:释放 available,防止后续拒单。

实现上生成 victim 列表,依次调仓:

python 复制代码
if not ok:
    victim = pick_victim(symbols, rule="worst_pnl")  # 按规则选 symbol
    new_target = reduce_target(victim)  # 归零或减 N 手
    tasks[victim].set_target_volume(new_target)
    log_portfolio_action(reason, victim, new_target)

tasks 是每个 symbol 的 TargetPosTask 实例;reduce_target 可以是 0 或 max(pos.pos - 1, 0) 等,由团队定。每次 set 后继续 wait_update,直到 pos.pos 接近目标或超时。

四、与单策略止损、涨跌停的关系

单品种止损在策略内(如均线破位平该 symbol);组合风控在上层。两层同时触发时,应合并为一次 set_target_volume,避免 A 层要平、B 层又要开,反复撤单占报单额度。

若剧震腿已涨跌停封板,set_target_volume(0) 可能长时间不成交,组合风控只能:平其他腿降总杠杆、或触发 emergency 告警人工介入。日志必须记录残留 poslast_msg,不能假设已平。

五、回测与极端日验证

组合风控规则应在 TqBacktest 或历史极端日回放里测:是否过度交易、是否在震荡日把组合砍光。回测里 risk_ratio 与实盘字段一致,但成交假设可能更乐观,应用快期模拟再观察一次减仓是否跟得上盘口。

六、多策略同账户时的边界

若一账户多策略共 symbol,组合层汇总后的目标才传给唯一 TargetPosTask(见多策略隔离专题)。组合风控触发时,应通知各子策略暂停新开仓,直到 portfolio_risk_ok 恢复。

总结

组合风控的难点从来不是'要不要减仓',而是'先减哪一腿才最符合组合目标、最能控制账户风险扩散'。当你提前把触发维度(account.risk_ratio、单腿浮亏/贡献、流动性指标)与优先级规则做成可执行的选择逻辑,极端行情下的决策就会从临场拍板变成流程化执行:先选 victim,再用 set_target_volume 把组合敞口降下来。这样写清楚之后,组合层就不会在单腿剧震时出现"忙着平但平错方向"的尴尬。更进一步,组合风控触发时要与子策略协同暂停新开仓,避免多层逻辑互相踩踏。把这套主线做厚做稳,组合系统才能在极端行情里保持可预期的行为。

FAQ

1)两腿相关性高,同时触发怎么办?

可定义成对减:例如多螺纹空铁矿同时减相同手数,保持价差敞口。

2)SP 组合合约怎么算?

按组合 symbol 一个 task,组合腿内部再拆规则。

3)risk_ratio 一直 nan?

刚连接时等几帧 wait_update;仍 nan 查账户是否回报异常。

4)人工在 APP 改仓?

见对账专题,组合层应以 get_position 为准同步。

风险提示

以上内容用于组合风控程序参考,不构成投资建议。

相关推荐
勇往直前plus1 小时前
Redis&Python 梳理
数据库·redis·python
战族狼魂1 小时前
AI 全栈开发实战训练路线(企业级)
人工智能·python·chatgpt·大模型
AC赳赳老秦1 小时前
用 OpenClaw 制定技术学习计划:根据目标岗位自动生成学习路线、推荐学习资源
开发语言·c++·人工智能·python·mysql·php·openclaw
长和信泰光伏储能2 小时前
探索绿色能源未来:光伏储能技术解析
python
李白的天不白2 小时前
config/WebMvcConfig.java
开发语言·python
Elaine3362 小时前
基于Django框架的静态个人名片网站设计
后端·python·django·mvt
henrylin99992 小时前
开源量化软件功能介绍
python·开源
C+-C资深大佬2 小时前
Python 新手学习指南
开发语言·python
嫂子的姐夫3 小时前
050-wx小程序合肥住房
爬虫·python·小程序·逆向