3、策略引擎层:策略注册与生命周期管理、策略沙箱隔离、策略执行上下文、策略热加载与卸载
好,咱们接着聊策略引擎层。
这一层,说白了就是整个交易系统的「大脑」。你写的策略代码,最终要在这里跑起来。我见过不少团队,策略写得挺漂亮,结果引擎层设计得稀烂,一上线就崩。嗯,这里面的坑,我踩过不少。
3.1 策略注册与生命周期管理
每个策略,从诞生到消亡,都得有个清晰的流程。我个人习惯把它分成五个阶段:
| 阶段 | 状态 | 说明 |
|---|---|---|
| 1 | REGISTERED | 策略刚注册进来,还没初始化 |
| 2 | INITIALIZED | 资源分配完毕,参数加载完成 |
| 3 | RUNNING | 正在接收行情,执行交易逻辑 |
| 4 | PAUSED | 暂停执行,但保留上下文 |
| 5 | TERMINATED | 彻底销毁,释放所有资源 |
为什么要这么细?
我曾经遇到过一个场景:某个策略在回测时表现完美,一上实盘就疯狂报错。后来发现是初始化阶段没做好,参数没加载全。从那以后,我强制要求每个策略必须显式声明自己的状态转换。
核心原则:状态转换必须是单向的,不能从 TERMINATED 跳回 RUNNING。这就像人死不能复生,策略销毁了就别想再活过来。
3.2 策略沙箱隔离
你想想看,如果两个策略共用一个内存空间,一个策略崩了,把另一个也带崩了,那得多冤?
沙箱隔离就是为了解决这个问题。我常用的方案有三种:
- 进程级隔离:每个策略跑在独立进程里,最安全,但资源开销大
- 线程级隔离:共享进程内存,但用线程锁保护关键资源
- 容器级隔离:用 Docker 之类的技术,兼顾安全和效率
我个人更倾向于进程级隔离。为什么?
因为交易策略一旦出问题,往往是内存泄漏或者死循环。如果是线程级隔离,整个进程都得跟着遭殃。我记得有一次,一个同事写的策略里有个 while(true) 没加 sleep,直接把 CPU 干到 100%,其他策略全部卡死。从那以后,我们团队就全面转向进程级隔离了。
避坑指南:我曾经见过有人用 Python 的 multiprocessing 做隔离,结果子进程崩溃了,父进程收不到信号,导致僵尸进程越来越多。一定要做好进程监控和清理机制。
3.3 策略执行上下文
每个策略在执行时,都需要知道「我在哪」、「现在是什么行情」、「我的仓位是多少」。这些信息,就是执行上下文。
我一般把上下文设计成三个层级:
- 全局上下文:系统级别的配置,比如交易对、手续费率
- 策略上下文:策略自身的参数,比如止损比例、持仓周期
- 运行时上下文:实时数据,比如当前价格、账户余额
这里有个细节要注意:运行时上下文必须是只读的。策略不能直接修改行情数据,只能读取。我曾经遇到过有人直接在策略里改了 tick 数据,导致整个系统的数据一致性崩了。嗯,那场面,相当惨烈。
// 伪代码示例:策略执行上下文
class StrategyContext {
GlobalContext global; // 全局配置
StrategyConfig config; // 策略参数
RuntimeData runtime; // 运行时数据(只读)
void execute() {
// 策略只能读 runtime,不能写
double price = runtime.getCurrentPrice();
// 策略可以写自己的状态
config.setStopLoss(price * 0.95);
}
}
3.4 策略热加载与卸载
这是最刺激的部分。想象一下,你的交易系统正在跑着,突然发现策略有个 bug,需要立刻修复。难道要停机重启?那损失可就大了。
热加载,就是让你在不重启系统的情况下,动态替换策略代码。
实现思路其实不复杂:
- 用自定义类加载器加载策略的 jar 包或 .py 文件
- 新版本策略注册后,先进入 PAUSED 状态
- 把旧策略的上下文迁移到新策略
- 新策略进入 RUNNING,旧策略进入 TERMINATED
个人经验:热加载最容易出问题的地方是「上下文迁移」。旧策略可能有一些中间状态,比如正在执行的订单。我建议在迁移时,先让旧策略完成当前订单,再切换。别急着强杀,容易出事故。
卸载相对简单一些。把策略状态设为 TERMINATED,释放所有资源,关闭网络连接,就完事了。但要注意,一定要等策略的所有异步任务都执行完毕再卸载。我曾经因为没等异步任务结束就直接卸载,结果数据库里多了一堆脏数据。
警告:热加载不是银弹。如果你的策略涉及大量状态管理,或者依赖外部资源(比如数据库连接池),热加载的复杂度会指数级上升。我建议只在紧急修复时使用热加载,日常更新还是走正常的发布流程。
本章知识体系
下面这张图,是我对策略引擎层核心逻辑的总结。你可以看到,从策略注册到执行,再到热加载,每个环节都环环相扣。
嗯,策略引擎层就聊到这儿。这一层设计好了,你的交易系统就有了一个稳固的「大脑」。下一章,咱们聊聊执行层,看看订单是怎么从策略走到交易所的。