DEV Community

ghostsworm
ghostsworm

Posted on

# 网格交易的风控困局与复合风控引擎的解法-2026最新最全版

网格交易的风控困局与复合风控引擎的解法

做量化交易做久了,你会发现一个规律:真正让你亏大钱的,往往不是某一个明确的坏信号,而是好几个"看起来还行"的信号同时出了问题。

这就好比开车。下雨天你会减速,转弯时你会减速,路面有坑你也会减速——每种情况单独处理都没问题。但如果下雨、转弯、路面有坑同时发生呢?三个"减速"叠在一起,可能就得停车了。你的大脑很自然地做了这种复合判断,但交易系统的风控模块并不一定能做到。

这篇文章聊聊我们在 QuantMesh 网格交易系统里遇到的风控困局,以及最终怎么用一套复合风控引擎(Composite Risk Controller)来解决它。

老系统的风控长什么样

先说现状。QuantMesh 的风控一直都有,而且看起来还挺全面——K线异常检测、市场深度监控、资金费率监控、AI 新闻分析、均线趋势过滤,该有的都有。

问题是它们各干各的。

具体来说:

  • K线异常检测(RiskMonitor)深度监控(DepthMonitor)symbol_manager.go 里做一个 OR 判断——只要有一个触发就拉响警报。
  • 资金费率监控(FundingRateMonitor)super_position_manager.go 里独立调整买入偏置系数 buyBias
  • 趋势检测(TrendDetector) 也在 super_position_manager.go 里独立决定是否过滤买入。
  • AI 新闻分析(NewsMonitor)risk_monitor.go 里做二元触发——要么触发要么不触发,非黑即白。

每个模块都在自己的世界里运转,彼此不知道对方在想什么。

这带来一个非常现实的问题:没法表达"多个因子同时偏空但都没达到单独触发阈值"的复合风险。

举个例子。某天晚上,AI 新闻模块检测到几条偏负面的消息,评分 55 分(触发线是 70),没触发。同一时间,均线出现死叉迹象,趋势检测的信号还不够强。资金费率连续两期为负,但还没到"连续三期"的阈值。市场深度比平时薄了一些,但没薄到触发线。

每个模块都觉得"嗯,还行,继续"。系统继续正常买入。然后价格一个小时跌了 8%。

这不是假设,这类场景在运行过程中出现过不止一次。

核心问题:独立判断 vs 联合判断

把上面的问题抽象一下,本质上就是"OR 判断"和"加权判断"的区别。

老系统用的是 OR 判断——每个模块独立看自己的数据,达到阈值就触发,没达到就放行。模块之间没有信息交换。

但风险这个东西不是这么运作的。一个 55 分的新闻风险加上一个 40 分的趋势风险加上一个 35 分的资金费率风险,三者叠加起来,整体风险远比任何单一因子看起来都高。可在老架构下,这三个信号加起来约等于零——因为没有一个达到各自的触发线。

这就是为什么需要一个能做"联合判断"的东西。

复合风控引擎的设计

解法其实不复杂。思路是这样的:把所有风控因子的输出统一归一化到 0-100 的分数,然后加权求和得到一个复合分数,再根据这个复合分数映射到不同的风控级别,执行不同的动作。

三层结构:

风控因子层 → 复合风控引擎 → 风控动作层
Enter fullscreen mode Exit fullscreen mode

风控因子层:每个因子独立评估当前市场状况,输出一个 0-100 的风险分数。0 表示安全,100 表示极度危险。

复合风控引擎:收集所有因子的分数,按权重加权求和,得到一个 compositeScore。

风控动作层:根据 compositeScore 的区间,映射到五个风控级别,执行对应的动作。

风控级别

compositeScore 区间 风控级别 对应动作
< 25 Normal 正常交易
25 - 45 Caution 减少买入量 20%
45 - 65 ReducePosition 减少买入量 50%
65 - 80 PauseBuying 暂停开新仓
> 80 StopTrading 停止交易并撤销所有挂单

这里有个设计上的考量:阈值不是线性分布的。低风险区间(Normal)给了 25 分的宽度,而高风险区间(StopTrading)只需要超过 80 就触发。这是因为在低风险区间容忍度应该高一些,避免频繁切换状态;而高风险时,宁可过度反应也不能反应不足。

核心数据结构

每个风控因子都实现同一个接口:

type RiskFactor interface {
    Name() string
    Evaluate(ctx context.Context) FactorResult
    Weight() float64
}
Enter fullscreen mode Exit fullscreen mode

因子评估的结果除了分数之外,还带着一个置信度(Confidence)字段:

type FactorResult struct {
    Score       float64   // 0-100, 0=安全, 100=极度危险
    Confidence  float64   // 0-1, 数据可信度
    Reason      string    // 人类可读的原因
    Details     map[string]interface{}
}
Enter fullscreen mode Exit fullscreen mode

为什么要有置信度?因为不是所有因子在所有时候都同样可靠。比如 AI 新闻分析在突发事件时很有用,但在没有新闻的时候它的输出意义不大。资金费率在某些交易所数据缺失的时候是不可用的。置信度低的因子在加权时影响会被削弱,避免"垃圾数据进、垃圾决策出"。

加权聚合的实际公式:

compositeScore = Σ(wi × si × ci) / Σ(wi × ci)
Enter fullscreen mode Exit fullscreen mode

其中 wi 是权重,si 是分数,ci 是置信度。分母做了归一化,确保最终分数仍然在 0-100 范围内。

五个风控因子

1. AI 新闻因子(NewsRiskFactor)

权重:0.30(默认最高)

这个因子权重最大,因为新闻对加密货币短期价格的冲击最直接。一条监管利空、一个交易所暴雷,价格反应比任何技术指标都快。

数据来源是已有的 NewsMonitor 模块,它会调用大语言模型对最新新闻做风险评估,输出一个 OverallRiskScore。新闻因子直接复用这个分数,再叠加一层逻辑:如果 CrashProbability(崩盘概率)超过 0.5,额外加分。

说实话,AI 分析新闻这件事准确率没法做到 100%,但它的价值在于提供了一个"技术指标看不到"的维度。K线还没反应的时候,新闻可能已经出来了。

2. 均线趋势因子(TrendRiskFactor)

权重:0.25

这个因子负责看"大方向"。它综合了好几个经典技术指标:

  • 均线偏离度:短期均线相对长期均线的位置。死叉程度越深,分数越高。
  • RSI:超买超卖区间。RSI 低于 30 进入超卖区,说明市场恐慌情绪浓厚。
  • MACD:柱状图的方向和强度。MACD 持续向下发散,趋势恶化的信号。
  • 价格与均线的关系:当前价格跌破了几根均线。跌破一根扣分不多,跌破三根以上就值得警觉了。

这些指标单独看都有噪音,但综合在一起能给出一个比较稳定的趋势判断。趋势因子的特点是反应偏慢(均线天然滞后),但一旦给出信号,通常持续时间较长。它和新闻因子的快反应形成互补。

3. 资金费率因子(FundingRateFactor)

权重:0.20

资金费率是永续合约市场独有的指标,反映多空力量对比。这个因子的评分规则:

  • 单次负费率:中等风险,30 分。说明空头力量暂时占优。
  • 连续 N 期负费率:每多一期加 10 分,上限 80 分。连续负费率是比较明确的空头信号。
  • 极端负费率(< -0.1%):直接 70 分。这种级别的负费率通常意味着市场正在剧烈下跌。
  • 正费率过高(> 0.15%):同样高风险,70 分。这意味着多头过度拥挤,随时可能出现多杀多的踩踏。

配置里有个 consecutive_negative_periods 参数,默认是 3,意思是连续 3 期负费率就开始升级风险等级。这个参数可以根据不同交易对的特性调整。

4. 市场深度因子(DepthRiskFactor)

权重:0.10

市场深度指的是挂单簿上买卖双方的挂单量。深度突然变薄,意味着大资金在撤单观望,市场可能即将出现大幅波动。

这个因子直接复用了现有的 DepthMonitor,把深度下降的百分比映射到 0-100 分。实现简单,但在极端行情前往往能提供有价值的预警。

权重设为 0.10,是因为深度数据波动比较大,单独看容易产生误判。但作为复合判断中的一个维度,它的边际贡献是正的。

5. K线异常因子(KlineAnomalyFactor)

权重:0.15

K线异常检测关注的是短期内的价格行为异常——比如突然出现的巨幅波动、成交量异常放大、连续的长上影线或长下影线等。

这个因子复用现有的 RiskMonitor,把它的异常检测结果映射到 0-100。它和深度因子类似,单独作为触发条件不够稳定,但在复合评分里提供了额外的信息量。

为什么是这个权重分配

权重分配不是拍脑袋的结果。背后的逻辑是:

  1. 新闻因子 0.30:唯一能提供"场外信息"的因子,在黑天鹅事件中几乎是唯一的预警源。
  2. 趋势因子 0.25:技术面的"骨干",稳定性最好,但有滞后性。
  3. 资金费率 0.20:衍生品市场的情绪指标,有独立的信息价值。
  4. K线异常 0.15:短期波动检测,对闪崩等事件有快速反应。
  5. 市场深度 0.10:辅助指标,波动大但边际信息有用。

当然,这些权重是可配置的。不同的交易对、不同的市场环境,最优权重可能不同。配置文件里可以灵活调整。

集成方式:覆盖而非叠加

复合风控引擎的输出是覆盖原有的独立判断,而不是在原有判断的基础上再加一层。

这是一个很重要的设计决策。如果是叠加模式,原来的独立风控判断可能把买入量砍了 30%,复合风控又砍了 50%,加起来实际买入量只剩 35%——这就过度风控了。

覆盖模式下,当复合风控引擎启用后,它的 CompositeRiskResult 直接决定 buyBias(买入偏置系数)和是否暂停交易。原来分散在各处的独立判断逻辑不再生效。

SuperPositionManager.AdjustOrders() 方法中,复合风控检查被插入到网格风控逻辑之后:

if spm.compositeRisk != nil {
    result := spm.compositeRisk.GetCurrentResult()
    switch result.Level {
    case safety.RiskStopTrading:
        spm.CancelAllBuyOrders()
        return nil
    case safety.RiskPauseBuying:
        skipBuying = true
    case safety.RiskReducePosition:
        buyBias *= 0.5
    case safety.RiskCaution:
        buyBias *= 0.8
    }
}
Enter fullscreen mode Exit fullscreen mode

干净利落。没有冗余,没有"先判断一次再判断一次"的浪费。

评估频率和性能

复合风控引擎的评估默认每 30 秒执行一次,不是每笔交易都跑一遍。

为什么?因为多数因子的数据源本身更新就没那么快。新闻不会每秒都来,均线的计算至少要有 K线级别的时间粒度,资金费率通常每 8 小时结算一次。每 30 秒评估一次已经足够覆盖大部分场景了。

每次评估的计算量也很小——五个因子各算一个分数,加权求和,查表映射。整个过程在毫秒级完成。不会对交易引擎的主循环造成任何可感知的延迟。

评估结果通过 GetCurrentResult() 方法缓存,交易引擎读取的是最近一次评估的快照,而不是实时计算。这保证了交易路径上没有额外的计算开销。

一个完整的场景推演

假设现在是凌晨 3 点,BTC 报价 98,000 USDT。各因子的状态:

  • AI 新闻因子:检测到某大型交易所传出"暂停提币"的消息,评分 62 分,置信度 0.8。
  • 均线趋势因子:4 小时级别 MA7 刚刚下穿 MA25,RSI 在 38,MACD 柱状图开始向下。评分 48 分,置信度 0.9。
  • 资金费率因子:连续两期负费率,分别是 -0.03% 和 -0.05%。评分 40 分,置信度 1.0。
  • 市场深度因子:买盘深度比 24 小时平均薄了 22%。评分 35 分,置信度 0.7。
  • K线异常因子:最近一根 15 分钟 K线出现了 2.3% 的长上影线。评分 30 分,置信度 0.85。

在老系统下,没有一个因子达到各自的触发线。系统会继续正常买入。

复合风控引擎的计算:

加权分数 = (0.30×62×0.8 + 0.25×48×0.9 + 0.20×40×1.0 + 0.15×30×0.85 + 0.10×35×0.7)
         / (0.30×0.8 + 0.25×0.9 + 0.20×1.0 + 0.15×0.85 + 0.10×0.7)

= (14.88 + 10.8 + 8.0 + 3.825 + 2.45) / (0.24 + 0.225 + 0.20 + 0.1275 + 0.07)

= 39.955 / 0.8625

≈ 46.3
Enter fullscreen mode Exit fullscreen mode

compositeScore 46.3,落在 45-65 的区间,对应 ReducePosition 级别。系统将买入量减半。

如果之后新闻进一步恶化,或者资金费率第三期仍为负,compositeScore 会继续上升,可能触发 PauseBuying 甚至 StopTrading。

这就是复合判断的价值——任何单个因子都没有说"危险",但综合起来,系统已经开始自我保护了

配置示例

composite_risk:
  enabled: true
  evaluate_interval: 30   # 评估间隔,秒
  thresholds:
    caution: 25
    reduce_position: 45
    pause_buying: 65
    stop_trading: 80
  factors:
    news:
      enabled: true
      weight: 0.30
    trend:
      enabled: true
      weight: 0.25
      use_rsi: true
      use_macd: true
    funding_rate:
      enabled: true
      weight: 0.20
      consecutive_negative_periods: 3
    depth:
      enabled: true
      weight: 0.10
    kline:
      enabled: true
      weight: 0.15
Enter fullscreen mode Exit fullscreen mode

每个因子都可以单独启用或禁用。权重在禁用某个因子后会自动重新归一化——你不需要手动调整其他因子的权重来凑 1.0。

阈值也是可配置的。如果你的交易策略比较激进,可以把 caution 调高一些,让系统在更高的风险水平下才开始减仓。反过来,保守型策略可以把阈值调低。

API 暴露

系统提供了一个 /api/composite-risk 端点,返回当前的复合风控状态:

{
  "composite_score": 46.3,
  "level": "reduce_position",
  "buy_bias": 0.5,
  "timestamp": "2026-02-06T03:00:30Z",
  "factors": {
    "news": { "score": 62, "confidence": 0.8, "reason": "交易所暂停提币传闻" },
    "trend": { "score": 48, "confidence": 0.9, "reason": "MA7 下穿 MA25, RSI 38" },
    "funding_rate": { "score": 40, "confidence": 1.0, "reason": "连续 2 期负费率" },
    "depth": { "score": 35, "confidence": 0.7, "reason": "买盘深度下降 22%" },
    "kline": { "score": 30, "confidence": 0.85, "reason": "15m K线 2.3% 长上影线" }
  },
  "reasons": [
    "AI 新闻因子评分较高 (62)",
    "趋势因子出现死叉信号 (48)",
    "资金费率连续负值 (40)"
  ]
}
Enter fullscreen mode Exit fullscreen mode

这个接口在 WebUI 仪表盘上也有对应的可视化展示。你可以随时看到每个因子的评分和整体风控状态,不用去翻日志。

写在最后

复合风控引擎不是什么花哨的概念,核心就一句话:把分散的信号聚合起来做联合判断

回到开头的开车比喻——下雨 + 转弯 + 路面有坑,你的大脑会综合评估然后决定是减速、刹车还是停车,而不是分三个独立的"如果下雨就减速 10%"、"如果转弯就减速 10%"、"如果有坑就减速 10%"叠在一起。复合风控引擎做的事情本质上就是这个。

对于网格交易来说,这类引擎特别有意义。网格策略的核心逻辑是在区间内反复买卖赚取波动差价,天然就需要一个可靠的"什么时候该收手"的判断机制。独立的风控模块在信号明确时能工作,但在"阴天"——多个信号都有点不对但又不够明确时——就力不从心了。复合引擎填补的正是这个盲区。


相关文章

Top comments (0)