一、行情系统概述:实时数据流的概念、行情系统的业务价值、主流行情数据源介绍

各位同学,今天咱们聊聊行情系统。说实话,这个主题我讲了不下二十次,但每次讲都有新感悟。为什么?因为行情系统是量化交易的「眼睛」——眼睛要是瞎了,再厉害的策略也白搭。

我刚开始做量化那会儿,踩过一个坑。当时用了一个第三方数据源,延迟大概在500毫秒左右。嗯,你可能觉得500毫秒不算啥,但在高频交易里,这足够让对手盘把你的订单吃干抹净。那次教训让我明白:行情系统不是「有数据就行」,而是「又快又准又稳」。

1.1 实时数据流:到底是个啥?

先别急着看代码,咱们把概念捋清楚。

实时数据流,说白了就是「数据一边产生,一边被处理」。跟传统的数据处理不一样——传统做法是把数据存到数据库里,然后慢慢分析。实时流呢?数据来了,立刻处理,立刻输出结果。

举个例子你就明白了:

  • 传统方式:收盘后下载一天的行情数据,然后算均线、算波动率。这叫「离线分析」。
  • 实时流方式:每一笔成交数据过来,立刻更新最新价、计算瞬时波动率。这叫「实时处理」。

我个人习惯把实时数据流拆成三个核心要素:

要素 说明 我踩过的坑
低延迟 从数据产生到被消费,时间尽可能短 曾经用HTTP轮询,延迟飙到2秒,直接被老板骂
高吞吐 单位时间内能处理的数据量要大 某次行情爆发,每秒10万笔数据,系统直接挂了
有序性 数据到达的顺序必须跟产生顺序一致 乱序导致计算出的均线完全错误,亏了钱才发现的

你想想看,这三个要素缺一个,行情系统就废了。延迟高,你看到的永远是「历史」;吞吐不够,行情爆发时直接丢数据;顺序乱了,算出来的指标全是错的。

1.2 行情系统的业务价值:不只是「看价格」

很多人觉得行情系统就是「显示价格」的。太天真了。

我在项目中遇到过一家私募,他们的策略是「做市商策略」。说白了,就是同时挂买单和卖单,赚差价。这个策略对行情的要求极高——你必须在毫秒级别感知到价格变动,然后立刻调整挂单。

行情系统的业务价值,我总结为三点:

  1. 决策依据:没有实时行情,你的策略就是「盲人摸象」。我记得有个团队用延迟5秒的行情做高频策略,结果每次开仓都开在最高点,平仓平在最低点。
  2. 风险控制:实时行情能帮你发现异常。比如某只股票突然暴跌,你的风控系统必须立刻响应。我曾经见过一个案例,因为行情延迟,风控没及时触发,一天亏了300万。
  3. 成本优化:好的行情系统能帮你减少滑点。滑点是什么?就是你下单的价格和实际成交价格的差异。行情越快,滑点越小。

核心观点:行情系统不是「成本中心」,而是「利润中心」。你花在行情系统上的每一分钱,都会在交易中加倍赚回来。

1.3 主流行情数据源介绍

市面上行情数据源很多,但真正靠谱的就那么几个。我按自己的经验给你排个序:

数据源 特点 适用场景 我的评价
交易所直连 延迟最低(微秒级),成本最高 高频交易、做市商 最靠谱,但门槛高
券商API 延迟中等(毫秒级),免费或低价 中低频策略、个人交易 够用,但别太依赖
第三方数据商 延迟较高(百毫秒级),数据丰富 回测、研究、非实时场景 适合研究,不适合实盘
开源数据源 延迟最高,免费 学习、原型验证 玩玩可以,别当真

这里我要特别说一下交易所直连。很多人觉得「直连交易所」就是拉根网线就行了。其实不是。你需要申请交易席位、通过交易所的接口认证、还要搞定网络专线。我记得第一次做直连的时候,光申请流程就走了三个月。

我的建议:如果你是个人交易者或者小团队,先用券商API起步。等策略稳定了、资金量上来了,再考虑直连。别一上来就搞直连,成本太高,而且维护起来很麻烦。

1.4 实时数据流的典型架构

说了这么多概念,咱们来看看实际架构长什么样。下面这张图是我自己项目里用的架构,经过多次迭代,算是比较成熟了。

实时行情数据流架构 数据源层 交易所直连 | 券商API | 第三方数据商 数据接入层 协议解析 | 数据清洗 | 格式统一 数据处理层 行情计算 | 指标生成 | 事件触发 数据输出层

这个架构图看着简单,但每个层都有坑。我重点说两个:

  • 数据接入层:不同数据源的协议不一样。有的用FIX协议,有的用二进制协议,还有的用WebSocket。你得统一成内部格式。我曾经因为协议解析写错了一个字节,导致价格差了100倍,还好是测试环境。
  • 数据处理层:这里最容易出问题的是「数据对齐」。不同数据源的时间戳可能不一样,你得做时间同步。我建议用NTP服务器统一对时,不然算出来的指标全是错的。

注意:千万不要在数据处理层做「重计算」操作。比如实时计算复杂的机器学习模型,那会拖垮整个系统。把计算量大的任务放到离线层去做,实时层只做轻量级计算。

1.5 一个简单的行情接入示例

光说不练假把式。我给你看一段伪代码,演示行情接入的基本流程:

// 伪代码:行情接入示例
class MarketDataFeed {
    constructor(source) {
        this.source = source;  // 数据源类型
        this.buffer = [];      // 数据缓冲区
        this.callbacks = [];   // 回调函数列表
    }
    
    // 连接数据源
    connect() {
        if (this.source === 'exchange') {
            // 交易所直连,使用FIX协议
            this.socket = new FIXSocket('tcp://exchange:1234');
        } else if (this.source === 'broker') {
            // 券商API,使用WebSocket
            this.socket = new WebSocket('wss://broker:443/market');
        }
        
        this.socket.onMessage((data) => {
            this.process(data);
        });
    }
    
    // 处理原始数据
    process(rawData) {
        // 1. 协议解析
        let parsed = this.parseProtocol(rawData);
        
        // 2. 数据清洗
        let cleaned = this.cleanData(parsed);
        
        // 3. 格式统一
        let unified = this.unifyFormat(cleaned);
        
        // 4. 触发回调
        this.callbacks.forEach(cb => cb(unified));
    }
}

这段代码看着简单,但实际项目中要考虑的东西多得多。比如:

  • 断线重连怎么办?
  • 数据乱序怎么处理?
  • 缓冲区满了怎么丢弃?

这些问题咱们后面的章节会一个一个解决。今天先把概念搞清楚。

好了,行情系统的概述就讲到这里。记住一句话:行情系统是量化交易的基础设施,基础不牢,地动山摇

课后思考:如果你现在要设计一个行情系统,你会选择哪种数据源?为什么?

专注资料整理