
用 Python 揭秘均值回归策略:你的收益从何而来?
2026年重磅升级已全面落地!欢迎加入专注财经数据与量化投研的【数据科学实战】知识星球!您将获取持续更新的《财经数据宝典》与《量化投研宝典》,双典协同提供系统化指引;星球内含 500 篇以上独有高质量文章,深度覆盖策略开发、因子分析、风险管理等核心领域,内容基本每日更新;同步推出的「量化因子专题教程」系列(含完整可运行代码与实战案例),系统详解因子构建、回测与优化全流程,并实现日更迭代。我们持续扩充独家内容资源,全方位赋能您的投研效率与专业成长。无论您是量化新手还是资深研究者,这里都是助您少走弯路、事半功倍的理想伙伴,携手共探数据驱动的投资未来!
做量化的朋友都知道,高频行情数据里藏着金矿 —— 订单簿动态、成交冲击、知情订单流、日内流动性变化……这些信息是日频 OHLC 数据根本无法提供的。
但问题也来了:直接基于 tick 级数据做策略,基础设施贵、信噪比低、换手成本高、扩展困难。对大多数 Python 量化学习者来说,这几乎是一道无法逾越的高墙。
有没有一种折中方案?有。这就是近期在系统化交易圈越来越流行的思路 —— 中低频因子:从分钟 Bar 或 tick 级数据中提取统计显著的信号,压缩成稳定的日频特征,然后直接接入中低频策略管线。
今天这篇文章,就带大家看看 DolphinDB 团队是如何搭建这样一套生产级框架的,以及我们 Python 用户可以从中学到哪些思路。
做过高频数据处理的同学都有体会:用 Pandas 搭个原型很简单,但一旦跑到“多年全市场分钟数据”这个量级,问题立刻暴露:
说白了,缺少一套标准化、可扩展、覆盖全生命周期的框架。
框架中每个因子都遵循同一个接口:输入数据表,输出包含 SecurityID、TradeDate、Value、FactorName、UpdateTime 的标准表。
下面是 DolphinDB 原生脚本示例 —— 基于快照数据计算成交量占比偏度因子:
def skewVolProp(snapshot){
// 从快照中计算成交量增量占比
snap =
select
TradeDate, TradeTime, SecurityID,
deltas(TotalVolumeTrade)\last(TotalVolumeTrade) as volProp
from snapshot
context by TradeDate, SecurityID csort TradeTime
having TradeTime >= 09:30:00.000
// 按股票和日期聚合,计算偏度作为因子值
res =
select
SecurityID,
TradeDate,
skew(volProp) as Value,
"skewVolProp" as FactorName,
now() as UpdateTime
from snap
group by TradeDate, SecurityID
return res
}对于 Python 用户来说,同样的思路可以用 Pandas 实现(示意):
import pandas as pd
def skew_vol_prop(snapshot: pd.DataFrame) -> pd.DataFrame:
"""
基于快照数据计算成交量占比偏度因子
输入:包含 TradeDate, TradeTime, SecurityID, TotalVolumeTrade 的数据帧
输出:标准格式的日频因子表
"""
# 仅保留连续竞价时段数据
df = snapshot[snapshot["TradeTime"] >= "09:30:00"].copy()
# 按股票和日期分组,计算成交量增量占比
df = df.sort_values(["TradeDate", "SecurityID", "TradeTime"])
df["volProp"] = (
df.groupby(["TradeDate", "SecurityID"])["TotalVolumeTrade"]
.transform(lambda x: x.diff() / x.iloc[-1])
)
# 聚合计算偏度
res = (
df.groupby(["TradeDate", "SecurityID"])["volProp"]
.skew()
.reset_index(name="Value")
)
res["FactorName"] = "skewVolProp"
res["UpdateTime"] = pd.Timestamp.now()
return res关键点:统一的输出 schema 意味着任何因子都可以被存储、查询、对比,无需格式转换。新增自定义因子只要遵守同一套约定,就能自动接入现有管理层。
框架覆盖 4 类数据源,按照不同维度做统计压缩:
分钟 Bar 因子,聚焦日内价量行为:
Level-2 快照因子,挖掘订单簿和高频波动结构:
订单级因子,捕捉订单意图:
逐笔成交因子,衡量主动成交和大单冲击:
高频数据量大,顺序处理完全不现实。框架在两个层面做了优化:
submitJob 把任务提交到后台,客户端会话立即释放mr(map-reduce) 在数据分区上并行执行Python 用户可以用 multiprocessing、joblib 或 Dask 实现类似效果:
from joblib import Parallel, delayed
import pandas as pd
def compute_factor_by_day(day: str, func) -> pd.DataFrame:
"""按天加载数据并计算因子"""
# 读取当天的分钟数据(示意)
df = pd.read_parquet(f"./minute_data/{day}.parquet")
return func(df)
def run_parallel(days: list, func, n_jobs: int = 8) -> pd.DataFrame:
"""并行计算多天因子,并合并结果"""
results = Parallel(n_jobs=n_jobs)(
delayed(compute_factor_by_day)(d, func) for d in days
)
return pd.concat(results, ignore_index=True)
# 使用示例:并行计算 1 月份所有交易日的因子
days = pd.bdate_range("2021-01-01", "2021-01-31").strftime("%Y-%m-%d").tolist()
factor_df = run_parallel(days, skew_vol_prop, n_jobs=8)框架使用分布式存储,按交易日和因子名分区。使用 TSDB 引擎配合 keepDuplicates=LAST,对相同日期与股票的因子值重写时自动保留最新值,无需手动去重。
// 创建日频因子数据库
create database "dfs://factor_day"
partitioned by RANGE(date(datetimeAdd(1980.01M, 0..80*12, 'M'))), VALUE(...)
engine='TSDB',
atomic='CHUNK'
// 创建因子表,采用窄表格式
create table "dfs://factor_day"."factor_day"(
SecurityID SYMBOL,
TradeDate DATE[comment="time column", compress="delta"],
Value DOUBLE,
FactorName SYMBOL,
UpdateTime TIMESTAMP,
)
partitioned by TradeDate, FactorName
sortColumns=[`SecurityID, `TradeDate],
keepDuplicates=LAST一句话总结:算一次扔掉是研究,算一次存下来、可更新、可追溯,才叫因子库。
窄表(长格式)适合更新和维护,宽表适合做横截面分析。DolphinDB 用 pivot by 一条语句就能切换:
dailyFactor = loadTable("dfs://factor_day", "factor_day")
// 把多个因子透视成宽表,便于横截面分析
factorTB1 = select Value
from dailyFactor
where FactorName in `skewVolProp`netBuyIntenOpen
pivot by SecurityID, TradeDate, FactorNamePython 中的等价写法非常熟悉:
# 加载窄表因子数据
daily_factor = pd.read_parquet("factor_day.parquet")
# 筛选目标因子,并透视成宽表
wide_df = (
daily_factor[daily_factor["FactorName"].isin(["skewVolProp", "netBuyIntenOpen"])]
.pivot_table(
index=["SecurityID", "TradeDate"],
columns="FactorName",
values="Value",
)
.reset_index()
)对 Python 量化学习者来说,这篇文章的核心启发有 3 点:
joblib、Dask、Ray 或分布式引擎来支撑。高频数据本身不会直接变成 alpha,只有当你能可靠地、规模化地把它压缩成稳定信号时,它才真正有用。希望这套思路能给正在学 Python 量化的你一些启发 —— 先从统一因子模板开始,然后再逐步加上并行、存储和版本化。
2026年全面升级已落地!【数据科学实战】知识星球核心权益如下:
星球已沉淀丰富内容生态——涵盖量化文章专题教程库、因子日更系列、高频数据集、PyBroker实战课程、专家深度分享与实时答疑服务。无论您是初探量化的学习者,还是深耕领域的从业者,这里都是助您少走弯路、高效成长的理想平台。诚邀加入,共探数据驱动的投资未来!
好文推荐
1. 用 Python 打造股票预测系统:Transformer 模型教程(一)
2. 用 Python 打造股票预测系统:Transformer 模型教程(二)
3. 用 Python 打造股票预测系统:Transformer 模型教程(三)
4. 用 Python 打造股票预测系统:Transformer 模型教程(完结)
6. YOLO 也能预测股市涨跌?计算机视觉在股票市场预测中的应用
9. Python 量化投资利器:Ridge、Lasso 和 Elastic Net 回归详解
好书推荐