本文目录
1. 设计目标
在策略图系统中,风险引擎不建议只设计成一个简单的配置对象。更合理的方式是按照交易生命周期和账户状态,将风险控制明确拆分为四类规则:
pre_trade:交易前风控in_flight:订单执行中风控post_trade:成交后校验state_events:状态事件风控
这种拆分方式可以让每类规则拥有清晰的触发时机、职责边界和处理动作,避免把下单限制、订单监控、成交校验和止损逻辑混在同一个配置对象中。
2. 总体配置结构
{
"risk": {
"pre_trade": {},
"in_flight": {},
"post_trade": {},
"state_events": {}
}
}
四类规则分别覆盖以下风险控制阶段:
| 规则类别 | 触发时机 | 核心问题 |
|---|---|---|
pre_trade |
订单提交前 | 这笔订单能不能提交、最多提交多少? |
in_flight |
订单尚未完全成交时 | 未成交订单如何占用额度,风险变化后是否撤单? |
post_trade |
订单成交后 | 实际持仓是否超限,本地状态是否与经纪商一致? |
state_events |
价格、账户或策略状态变化时 | 触发止损、回撤或冷却后应该采取什么动作? |
3. pre_trade:交易前风控
3.1 作用
pre_trade 负责在订单提交前进行风险检查和订单约束,决定:
- 订单是否允许提交;
- 订单最大允许规模;
- 是否需要裁剪订单数量;
- 是否需要直接拒绝订单;
- 下单后是否会突破仓位、杠杆或敞口限制。
3.2 示例配置
{
"pre_trade": {
"max_position_weight": 0.5,
"max_leverage": 1.0,
"max_order_weight": 0.1,
"max_gross_exposure": 1.0,
"max_net_exposure": 0.8,
"allow_short": false
}
}
3.3 字段说明
| 字段 | 含义 |
|---|---|
max_position_weight |
单个标的或单个策略节点允许占用的最大仓位权重 |
max_leverage |
最大允许杠杆倍数 |
max_order_weight |
单笔订单相对于账户权益或策略资金的最大权重 |
max_gross_exposure |
最大总敞口,通常按多头与空头绝对敞口之和计算 |
max_net_exposure |
最大净敞口,通常按多头敞口减去空头敞口计算 |
allow_short |
是否允许开立或增加空头仓位 |
3.4 建议处理流程
- 接收策略生成的目标订单;
- 读取当前账户、持仓、挂单和风险状态;
- 计算订单执行后的预期仓位、杠杆和敞口;
- 按风险规则判断订单是否合规;
- 根据结果执行以下动作之一:
- 允许提交:按原始数量下单;
- 裁剪后提交:将订单调整到允许的最大规模;
- 拒绝提交:不发送订单并记录原因。
pre_trade的核心是控制“订单进入市场之前的最大风险”。
4. in_flight:订单执行中风控
4.1 作用
in_flight 负责监控已经提交但尚未完全成交的订单,处理订单执行期间风险额度的占用和风险条件变化。
它主要回答以下问题:
- 未成交订单是否占用风险额度;
- 订单挂单时间过长是否应自动撤销;
- 风险条件变化后,是否停止或撤销剩余订单;
- 账户进入暂停或限制状态后,未成交订单如何处理。
4.2 示例配置
{
"in_flight": {
"reserve_pending_orders": true,
"cancel_on_limit_breach": true,
"max_order_age_seconds": 60,
"cancel_unfilled_on_halt": true
}
}
4.3 字段说明
| 字段 | 含义 |
|---|---|
reserve_pending_orders |
是否将未成交订单预留在风险额度中,避免多个挂单叠加后突破限制 |
cancel_on_limit_breach |
风险条件突破限制时,是否自动撤销相关挂单 |
max_order_age_seconds |
订单允许保持未成交状态的最长时间 |
cancel_unfilled_on_halt |
策略或账户进入暂停状态时,是否撤销未成交订单 |
4.4 建议处理流程
- 订单提交成功后登记订单状态;
- 根据配置预留订单可能占用的仓位和敞口;
- 持续监听订单成交、撤单、拒单和超时事件;
- 定期重新计算账户风险状态;
- 当订单超时或风险条件突破时,执行撤单、停止追加订单等动作;
- 订单完全成交或终止后,释放相应的预留额度。
in_flight的核心是控制“订单已经发出,但风险尚未完全落地期间的中间状态”。
5. post_trade:成交后校验
5.1 作用
post_trade 负责在订单成交后,对真实成交结果、持仓状态和风险限制进行再次校验。
它主要回答以下问题:
- 实际成交后是否突破仓位、杠杆或敞口限制;
- 本地记录的持仓是否与经纪商或交易所持仓一致;
- 成交回报是否及时到达;
- 发生超限或状态不一致时,应停止交易、告警还是自动减仓。
5.2 示例配置
{
"post_trade": {
"breach_action": "reduce_only",
"reconcile_position": true,
"max_reconciliation_delay_seconds": 5
}
}
5.3 字段说明
| 字段 | 含义 |
|---|---|
breach_action |
成交后发现超限时的处理动作,例如 stop、alert 或 reduce_only |
reconcile_position |
是否执行本地持仓与经纪商或交易所持仓的对账 |
max_reconciliation_delay_seconds |
允许持仓状态未完成对账的最长时间 |
5.4 建议处理流程
- 接收成交回报;
- 更新本地订单、成交和持仓状态;
- 重新计算账户仓位、杠杆和总敞口;
- 与经纪商或交易所返回的实际持仓进行对账;
- 若发现超限或状态不一致,根据
breach_action执行:- 停止交易:禁止继续提交新的风险订单;
- 告警:记录并通知人工处理;
- 只减仓:禁止增加风险,只允许降低现有仓位;
- 自动减仓:通过反向订单将风险恢复到限制以内。
post_trade的核心是校验“交易实际发生后,账户最终处于什么风险状态”。
6. state_events:状态事件风控
6.1 作用
state_events 用于处理由价格、账户净值、回撤或策略运行状态触发的事件型风控规则。
与前三类规则相比,state_events 不一定由某一笔订单直接触发,而可能由持续的市场数据和账户状态变化触发。
它主要覆盖:
- 价格触发的止损;
- 账户触发的最大回撤;
- 触发后减仓、平仓、暂停交易或进入冷却期;
- 风控事件解除后的恢复条件。
6.2 示例配置
{
"state_events": {
"stop_loss": {
"type": "percentage",
"value": 0.08,
"action": "close_position"
},
"max_drawdown": {
"value": 0.2,
"action": "reduce_all_positions"
},
"cooldown_after_stop": {
"bars": 10
}
}
}
6.3 字段说明
| 事件 | 含义 |
|---|---|
stop_loss |
标的价格或持仓亏损达到阈值时触发止损 |
max_drawdown |
账户或策略从历史峰值回撤达到阈值时触发保护动作 |
cooldown_after_stop |
止损或重大风控事件触发后,暂停交易若干根 K 线或时间周期 |
type |
阈值类型,例如百分比、金额、点数或波动率倍数 |
value |
风控阈值 |
action |
触发后执行的动作,例如平仓、减仓、暂停或只减仓 |
bars |
冷却期长度,以 K 线根数表示 |
6.4 常见动作
close_position:平掉触发事件的持仓;reduce_position:降低部分仓位;reduce_all_positions:降低全部策略或账户仓位;halt_strategy:暂停策略运行;halt_trading:暂停账户或交易通道下单;reduce_only:进入只减仓模式;cooldown:进入冷却期,冷却期内不允许重新开仓。
state_events的核心是控制“账户或策略状态发生重大变化后的保护动作”。
7. 四类风控的协同关系
四类风控不是相互替代,而是共同构成完整的风险闭环:
策略产生目标订单
|
v
[pre_trade] 交易前检查、裁剪或拒绝
|
v
订单提交与执行
|
v
[in_flight] 监控挂单、预留额度、超时撤单
|
v
订单成交
|
v
[post_trade] 成交后校验、持仓对账、超限处理
|
v
[state_events] 监听止损、回撤、暂停和冷却事件
|
+------------------------------+
| |
+--> 触发减仓、平仓、暂停或冷却 --+
建议将风险判断设计成多层保护:
- 提交前先拦截:避免明显违规的订单进入市场;
- 执行中持续约束:防止挂单累积、订单超时或风险变化造成失控;
- 成交后再次校验:以实际成交和真实持仓为准;
- 状态事件兜底:在止损、回撤等重大事件发生时执行保护动作。
8. 建议的规则返回结果
为了方便策略图系统统一处理,风险引擎可以让每类规则返回结构化结果,而不是只返回布尔值。
{
"allowed": false,
"action": "reduce_only",
"original_quantity": 100,
"approved_quantity": 0,
"reason_code": "MAX_NET_EXPOSURE_BREACH",
"message": "订单将导致净敞口超过限制",
"risk_snapshot": {
"current_net_exposure": 0.75,
"projected_net_exposure": 0.92,
"max_net_exposure": 0.8
}
}
建议至少包含以下信息:
| 字段 | 作用 |
|---|---|
allowed |
是否允许当前动作继续执行 |
action |
风控引擎建议执行的动作 |
original_quantity |
原始订单数量 |
approved_quantity |
风控检查后允许执行的数量 |
reason_code |
稳定、可程序化处理的原因码 |
message |
面向日志或人工排查的说明 |
risk_snapshot |
风控判断时使用的关键风险快照 |
这样可以同时满足策略执行、日志审计、监控告警和问题排查的需求。
9. 设计原则总结
- 按交易生命周期拆分规则:将提交前、执行中、成交后和状态事件分开管理;
- 风险判断与动作解耦:先计算是否违规,再决定拒绝、裁剪、撤单、减仓或暂停;
- 以实际持仓为最终依据:成交后必须支持与经纪商或交易所对账;
- 未成交订单也要纳入风险计算:避免多个挂单同时占用未来风险额度;
- 所有风控动作都应可审计:保留规则版本、风险快照、触发原因和执行结果;
- 重大事件需要状态机支持:止损、最大回撤和冷却期不应只作为一次性函数调用,而应有明确的进入、持续和退出状态;
- 默认采用保守失败策略:风险状态不可确认、持仓对账超时或数据源异常时,优先停止增加风险。
通过以上四类规则,风险引擎可以从简单的参数校验,升级为覆盖订单生命周期、真实持仓和策略状态的完整风险控制系统。