26. 系统架构设计:实时数据流、计算引擎、风控模块
做跨品种套利,最怕什么?
不是策略失效,而是系统崩了。数据没到、计算超时、风控没拦住——任何一个环节出问题,都可能让你一夜回到解放前。
这一章,我聊聊实际生产环境里,这套系统该怎么搭。说白了,就是三个核心模块:实时数据流、计算引擎、风控模块。
26.1 实时数据流:别让数据成为瓶颈
我见过太多团队,策略模型很漂亮,结果数据延迟几百毫秒,套利机会早没了。
实时数据流的核心就一个字:快。但光快不够,还得稳。
26.1.1 数据源接入
跨品种套利,你至少需要两个品种的行情。比如螺纹钢和热卷,或者豆粕和菜粕。
我个人习惯用多路数据源。什么意思?同一品种,同时接入交易所直连和第三方数据商。主路断了,备路立刻顶上。
关键指标:数据延迟不超过 10 毫秒。超过这个数,套利窗口基本就关了。
26.1.2 数据清洗与对齐
原始行情进来,不能直接用。为什么?因为两个品种的 tick 时间戳可能不同步。
举个例子:螺纹钢的 tick 在 09:30:00.123 到达,热卷的 tick 在 09:30:00.456 到达。你直接拿这两个价格算价差,误差会很大。
我的做法是:时间戳对齐。把两个品种的 tick 按毫秒级对齐,取最近的一对。如果某个品种的 tick 超过 50 毫秒没更新,就标记为「数据缺失」,暂时不参与计算。
// 伪代码:数据对齐逻辑
function alignTicks(tickA, tickB) {
// 取时间差最小的两个 tick
let diff = Math.abs(tickA.timestamp - tickB.timestamp);
if (diff < 50) {
return { priceA: tickA.price, priceB: tickB.price };
} else {
return null; // 数据不同步,跳过
}
}
避坑指南:我曾经遇到过数据商突然断流,备路切换花了 2 秒。后来我加了心跳检测,每 100 毫秒检查一次数据流是否正常。一旦发现异常,立即切换。
26.2 计算引擎:核心逻辑要快
数据到了,接下来就是算。算波动率曲面、算价差、算套利信号。
计算引擎的设计,我总结了三句话:内存计算、并行处理、结果缓存。
26.2.1 波动率曲面实时计算
跨品种套利的核心,是波动率曲面的相对定价。你需要实时计算两个品种的波动率曲面,然后找偏差。
计算量不小。一个品种的波动率曲面,涉及多个行权价、多个到期日。两个品种一起算,CPU 压力很大。
我的方案是:分层计算。
- 第一层:快速估算。用简化模型(比如 BS 公式的近似解)算个大概,延迟控制在 1 毫秒以内。
- 第二层:精确计算。用完整模型(比如 SVI 参数化)算精确值,延迟 5-10 毫秒。
平时用第一层就够了。只有发现套利机会时,才触发第二层做精确验证。
核心原则:能算近似值,就别算精确值。时间就是金钱。
26.2.2 并行处理架构
我建议用流水线架构。数据流进来,分三路并行:
- 品种 A 的波动率计算
- 品种 B 的波动率计算
- 价差监控(简单逻辑,不依赖波动率)
三路结果汇总到「信号生成器」,判断是否触发套利。
// 伪代码:并行计算框架
async function computeArbitrage(tickA, tickB) {
// 并行计算两个品种的波动率
let [surfaceA, surfaceB] = await Promise.all([
computeVolSurface(tickA),
computeVolSurface(tickB)
]);
// 计算价差信号
let signal = detectArbitrage(surfaceA, surfaceB);
return signal;
}
个人经验:我用的是 C++ 写核心计算模块,Python 做上层调度。C++ 负责算力密集的部分,Python 负责灵活调度。这样既快又好改。
26.3 风控模块:别让亏损失控
套利听起来风险低,但实际做起来,黑天鹅事件一样能让你爆仓。
风控模块,我把它分成三层:事前、事中、事后。
26.3.1 事前风控:参数校验
下单之前,先检查参数。比如:
- 价差是否在合理范围内?
- 持仓是否超过限额?
- 当前市场是否异常(比如涨跌停)?
任何一项不通过,直接拒绝下单。
注意:事前风控不能只检查一次。市场变化快,参数校验必须实时更新。比如,价差合理范围会随着波动率变化而动态调整。
26.3.2 事中风控:实时监控
下单之后,风控不能停。我设计了一个心跳监控机制:
- 每 100 毫秒检查一次持仓盈亏
- 如果亏损超过阈值(比如总资金的 2%),自动平仓
- 如果网络延迟超过 500 毫秒,暂停所有交易
// 伪代码:事中风控逻辑
function riskMonitor(position) {
let pnl = calculatePnL(position);
if (pnl < -maxLoss) {
liquidate(position); // 自动平仓
alert("风控触发:亏损超限");
}
let latency = getNetworkLatency();
if (latency > 500) {
pauseTrading(); // 暂停交易
alert("风控触发:网络延迟过高");
}
}
26.3.3 事后风控:复盘与优化
每天收盘后,我会跑一遍复盘脚本。看看今天触发了多少次风控,每次触发的原因是什么。
比如,如果发现某次风控是因为数据延迟导致的误判,那就需要优化数据流模块。如果是因为策略参数太激进,那就调整阈值。
我的习惯:每周出一份风控报告。内容包括:触发次数、触发原因、损失金额、优化建议。这份报告是迭代策略的重要依据。
26.4 系统架构总览
说了这么多,画张图总结一下。
这张图展示了三个核心模块的协作关系。数据流进来,经过计算引擎处理,风控模块全程监控,最后交给执行层下单。同时,风控模块的反馈会优化计算引擎的参数,形成闭环。
最后说一句:架构设计没有标准答案。我见过有人用全 Python 搭系统,也见过全 C++ 的。关键是找到适合你团队技术栈和业务场景的方案。别盲目追求「高大上」,稳定可靠才是第一位的。