DSL 如何编译成规则:从规则树到执行引擎

很多量化平台的策略系统最终都会走到一个问题:

策略到底应该“写代码”,还是“可视化搭积木”?

写代码灵活,但不可治理、不可复用、难协作;
可视化好交付,但容易被质疑“能力不够”。

结论先行:EasyQuant 选择用 DSL 规则树 描述策略,用 编译(compile) 的方式把 DSL 映射到 Indicator/Rule/Strategy,从而同时获得:

  • 平台级的版本治理与可视化编辑
  • 接近代码级的表达能力(AND/OR/CROSS/比较/自定义扩展)
  • 可解释与可复现的输入口径(见 03、04)

一、为什么一定要“编译”,而不是“解释执行”?

平台常见两种做法:

  • 解释执行:每次评估直接走 DSL 树,边走边算

    • 优点:实现快,直观
    • 缺点:性能难控,复用难做,错误上下文难沉淀
  • 编译:把 DSL 编译成指标与规则对象图

    • 优点:可缓存复用,便于优化与治理;错误更可定位
    • 缺点:需要设计良好的中间结构与工厂体系

EasyQuant 更偏“平台交付”,因此选择编译路线:把策略变成可复用的可执行对象,并为未来优化(缓存、并行、增量计算)留空间。


二、DSL 规则树能表达什么?

从产品视角,关键不是 DSL 长什么样,而是它能覆盖什么常见策略表达:

  • 逻辑组合:AND / OR / NOT
  • 比较:GT / LT / EQ(价格 vs 指标、指标 vs 指标)
  • 交叉:CROSS_UP / CROSS_DOWN(均线金叉死叉、价格突破等)
  • 常量与参数引用:const / ref
  • 指标引用:ind(把指标当作一等公民)
  • 可扩展节点:自定义规则(例如 Groovy 扩展)

这套表达能力的意义在于:策略作者关注“逻辑”,平台负责“执行与治理”。


三、编译流水线:从 JSON 到可执行策略对象

用一句话描述编译流水线:

  1. 读取激活版本(或回退模板)得到 DSL + 参数(见 04 的 provenance)
  2. 构建指标图:把每个 indicator 节点编译成 系统 Indicator<Num>
  3. 构建规则图:把 entry/exit 的 rule 节点编译成 系统 Rule
  4. 组合成 Strategy,交给执行引擎在 bars 序列上评估

这里的关键是 “指标图”:同一个指标可能被多个规则引用,必须复用,否则会造成重复计算与不一致。


四、可解释性从哪里来?

很多系统做了 DSL,但仍然解释不清“为什么没信号”。
根因是:只做了“规则计算”,没做“运行证据”。

EasyQuant 的产品化方向是:

  • 规则评估结果(true/false)要能落到运行事件里
  • 阻塞原因要能归类(NO_BARS / NO_SYMBOLS / SIGNAL_NONE / ENGINE_ERROR 等)
  • 关键输入要能在 provenance 里对齐(版本/参数/数据窗口/成本口径)

最终,用户在 UI 上看到的不是“一个黑盒买卖点”,而是:
这次为什么触发/为什么没触发,属于哪一类问题,下一步查哪里。


五、可扩展点:如何在不破坏平台治理的情况下“更灵活”

平台的挑战是:既要给高级用户空间,又不能把系统变成“随便写脚本”。

推荐的扩展边界:

  • 指标扩展:新增 indicator 类型(参数有中文说明、可校验、可复用)
  • 规则扩展:新增 rule 节点(例如 N 日突破、分形、形态识别)
  • 自定义规则脚本:仅作为“受控扩展”,必须有沙箱与白名单(防止不可控 I/O 与安全风险)

原则是:扩展必须仍然能被版本化、可复现、可诊断,否则交付能力会被破坏。


六、一个验收:从“策略没生效”到“问题可定位”

你可以用一个常见坑来验收 DSL 编译体系是否真具备平台价值:

场景:你改了规则但回测行为没变。
验收步骤:

  1. 确认是否发布并激活版本(VERSION_NOT_ACTIVE)
  2. 查看 provenance 中记录的 versionId 与 params 是否符合预期
  3. 若 version 正确但仍无信号,检查 SIGNAL_NONE / NO_BARS / ENGINE_ERROR 的归类

如果这条路径能在 5–10 分钟内收敛问题,而不是“改完再试”,说明 DSL 编译体系不仅能跑策略,更能支撑交付。


结语:DSL 的价值不在“可视化”,在“可治理”

可视化只是入口。真正的价值是:策略变成可版本化、可复现、可诊断、可运维的可执行对象。
这也是 EasyQuant 与“纯回测框架”最本质的区别之一。

下一篇(08)我们回到产品化细节:指标库与前后端一致性(catalog、中文参数说明、DSL 最小化),它决定了可视化策略是否真的好用、好维护。