第三章:数据基础设施——数据源选择、数据库选型与ETL设计

做量化策略研发,说白了就是跟数据打交道。我见过太多人策略逻辑写得天花乱坠,结果一上实盘就崩——十有八九是数据基础设施没搭好。这一章,咱们就把数据这块地基夯实了。

3.1 数据源选择:你的“米”从哪来?

量化交易里,数据就是米。没有米,再好的厨子也做不出饭。我个人习惯把数据源分成三类:金融终端类、开源Python库类、以及量化平台类。

3.1.1 Wind(万得)

Wind是机构标配。数据全、质量高、更新快。但贵,一年几万到几十万不等。我个人建议:如果你在机构工作,或者资金量上千万,直接上Wind。省心。

我的经验: Wind的API(WindPy)在Python里调用很方便。但注意,Wind客户端必须开着才能取数据。我曾经有一次服务器重启忘了开Wind,策略跑了一天空仓……嗯,从那以后我写了个开机自启脚本。

3.1.2 Tushare

Tushare是国内开源数据接口的鼻祖。免费版够用,但有限制(比如每分钟请求次数)。Pro版需要积分,其实也不贵。

我比较喜欢Tushare的地方:数据结构清晰,文档全。适合个人研究和小团队。

3.1.3 AkShare

AkShare是后起之秀,完全免费。它其实是个爬虫集合,从各大财经网站抓数据。好处是数据源广,连期货、期权、宏观经济数据都有。

注意: AkShare依赖第三方网站,如果对方改版或封IP,你的数据流就可能断。我建议把它当辅助数据源,别当主力。

3.1.4 聚宽(JoinQuant)

聚宽是个量化平台,也提供数据API。它的数据经过清洗,质量不错。如果你用聚宽的回测系统,直接用它的数据最方便。

怎么选?我列个表,你一看就明白:

数据源 费用 数据质量 适合场景
Wind 高(万元级) ★★★★★ 机构、大资金
Tushare 低(免费/积分) ★★★★ 个人研究、小团队
AkShare 免费 ★★★ 辅助数据、研究
聚宽 免费/付费 ★★★★ 平台内回测

3.2 数据库选型:你的“米缸”怎么选?

数据拿到手,得存起来。选数据库这事,我踩过不少坑。说白了,没有最好的数据库,只有最合适的。

3.2.1 MySQL / PostgreSQL

这两兄弟是关系型数据库的代表。适合存结构化数据,比如日线行情、财务数据。

我个人更倾向PostgreSQL。为什么?因为它支持数组、JSON等数据类型,做量化时很方便。比如存一个股票的5分钟K线,我可以直接把一天的数据存成一个数组,查询效率高很多。

3.2.2 ClickHouse

ClickHouse是列式存储数据库,专门为分析场景设计。如果你做高频策略,或者需要秒级查询上亿条数据,ClickHouse是首选。

核心优势: 查询速度极快。同样的硬件,ClickHouse比MySQL快10-100倍。我有个策略需要扫描全市场5000只股票3年的分钟数据,MySQL跑了2分钟,ClickHouse只用了3秒。

3.2.3 InfluxDB

InfluxDB是时序数据库,专门处理带时间戳的数据。如果你做Tick级别的高频交易,或者存传感器数据(比如服务器监控),用InfluxDB最合适。

怎么选?看你的数据量和查询频率:

  • 日线级别、数据量小(百万级):PostgreSQL就够了
  • 分钟级别、数据量大(亿级):ClickHouse
  • Tick级别、实时写入:InfluxDB

3.3 数据存储结构设计

结构设计这事,我刚开始做的时候也犯过傻。把所有数据塞一张表里,结果查询慢得要死。后来学乖了,按“频率+类型”分表。

举个例子,股票日线行情表:

CREATE TABLE stock_daily (
    ts_code VARCHAR(20),    -- 股票代码
    trade_date DATE,        -- 交易日期
    open DECIMAL(10,2),     -- 开盘价
    high DECIMAL(10,2),     -- 最高价
    low DECIMAL(10,2),      -- 最低价
    close DECIMAL(10,2),    -- 收盘价
    volume BIGINT,          -- 成交量
    amount DECIMAL(20,2),   -- 成交额
    PRIMARY KEY (ts_code, trade_date)
);

注意这里用了联合主键(股票代码+日期)。为什么?因为查询时最常用的条件就是“某只股票某段时间的数据”。这样设计,查询效率最高。

我的习惯: 我会再加一个索引字段,比如按月分区。这样查询某个月的数据时,数据库只扫描一个分区,速度更快。

3.4 数据ETL流程设计

ETL就是:抽取(Extract)、转换(Transform)、加载(Load)。说白了,就是把原始数据洗成你能用的样子。

3.4.1 抽取(Extract)

从数据源拉数据。我一般用Python写个定时任务,每天收盘后自动跑。

import tushare as ts
import pandas as pd

pro = ts.pro_api('your_token')
df = pro.daily(ts_code='000001.SZ', start_date='20240101', end_date='20240131')
df.to_csv('raw_data.csv', index=False)

3.4.2 转换(Transform)

这一步最花时间。原始数据可能有缺失值、异常值、复权问题等。

我举个例子:股票分红后,价格会跳空。如果你直接用原始价格算收益率,结果会失真。所以要做复权处理。

# 前复权处理示例
df['adj_close'] = df['close'] * (df['adj_factor'] / df['adj_factor'].iloc[-1])
避坑指南: 我曾经遇到过某数据源的复权因子算错了,导致策略回测收益虚高20%。后来我加了交叉验证——用两个不同数据源的数据对比,差异超过0.5%就报警。

3.4.3 加载(Load)

把清洗好的数据写入数据库。我建议用批量插入,别一条一条插,太慢了。

from sqlalchemy import create_engine
engine = create_engine('postgresql://user:pass@localhost:5432/quant')
df.to_sql('stock_daily', engine, if_exists='append', index=False, method='multi')

3.5 整体架构图

下面这张图,是我自己搭建数据流水线的标准架构。你照着搭,基本不会出大问题。

量化数据基础设施架构图 数据源层(Extract) Wind Tushare AkShare 聚宽 其他API ETL处理层(Transform) 数据清洗 复权处理 异常检测 格式统一 数据库层(Load) PostgreSQL ClickHouse InfluxDB Redis(缓存) 应用层:策略回测 / 实盘交易 / 数据分析

这张图从左到右,从上到下,就是数据从源头到应用的完整流程。你想想看,如果没有这一套基础设施,你的策略就像建在沙滩上的城堡——看着漂亮,一涨潮就没了。

总结一下: 数据源选1-2个主力(比如Wind+Tushare),数据库根据数据量选(小项目用PostgreSQL,大项目上ClickHouse),ETL流程一定要自动化、带监控。这样你的量化流水线才算真正跑起来了。

公众号:蓝海数据掘金营,微信deep3321