🐍 Python 量化栈:NumPy、Pandas 与向量化思维

收益率计算的两种写法差 400 倍速度;Pandas 对齐陷阱如何虚增回测收益;可视化与研究复现的工程纪律——全部用交易场景演示。

Python 成为量化第一语言不是因为它快(它很慢),而是因为它把「想法到验证」的距离压到最短。本篇不讲语法,讲三件真正影响研究质量的事:向量化思维、Pandas 的对齐陷阱、以及复现纪律。所有例子都来自交易场景。

NumPy:向量化是思维方式的转变

新手写双均线策略:

1
2
3
4
# 逐日循环:慢、啰嗦、容易在边界犯错
for i in range(1, len(close)):
    if ma5[i-1] > ma20[i-1] and ma5[i] < ma20[i]:
        signals.append(-1)

向量化写法把「逐日判断」变成「整列运算」:

1
2
ma5, ma20 = close.rolling(5).mean(), close.rolling(20).mean()
death_cross = (ma5.shift(1) > ma20.shift(1)) & (ma5 <= ma20)  # 整列布尔

三重收益:速度(底层 C 循环,百万行毫秒级,因子批量计算的前提)、正确性(shift(1) 强制你显式处理「用昨天信号交易今天」——逐日循环里这恰恰是最容易写错的地方)、可读性(公式与代码同构)。性能优化路线:纯 Python → NumPy 向量化 → NumPy 广播/einsum → Numba/Cython(只在 profile 证明瓶颈后用,见向量化的边界 )。

Pandas:强大之处与三大陷阱

Pandas 的 DataFrame 是量化数据的默认形态(T 行 × N 列,见线性代数 的收益矩阵)。但它有三个让回测悄悄变错的陷阱:

陷阱一:索引对齐的静默 NaN。 两只股票停牌日不同,df1 + df2 会按索引对齐,缺失处产生 NaN;随后 fillna(0) 把「没交易」填成「收益 0」——把停牌处理成免费平仓,回测收益虚高。守则:算完先看 df.isna().sum();明确每列的业务含义(停牌是「沿用昨日价」还是「不可交易」)再决定填充策略。

陷阱二:ffill 与前视。 用财报数据 ffill() 向前填充本身没错,错的是对齐错了时间戳:Q1 财报(4 月 30 日公布)的数据从 3 月 31 日就开始用,就是前视偏差。守则:财报数据一律以公告日重新索引后再 ffill(见PIT 数据库 )。

陷阱三:inplace 与链式赋值。 df[df.a>0]['b'] = 1 静默失败;inplace=True 在新版本已被弃用。守则:显式赋值 df.loc[mask, 'b'] = 1,研究代码避免 inplace。

SciPy 的日常角色:scipy.stats(t 检验、正态性检验)、scipy.optimize(组合优化的 SLSQP、GARCH 的 MLE)、scipy.linalg(Cholesky 分解做相关采样)。它们是统计推断 与优化 两章的工程对应物。

可视化:为判断服务,不为好看服务

量化图表的四条纪律:

  1. 累计净值永远配对数轴 + 画基准——线性轴让 2015 年的 3 倍吞掉后面所有细节;无基准的净值曲线没有信息量;
  2. 回撤曲线与净值同框——收益的样子骗人,回撤的形状诚实(水下曲线);
  3. 因子检验画分组净值而不是只报 IC——单调性是肉眼可见的(见因子检验 );
  4. 分布图画对数收益并标注 ±3σ 与极值点——肥尾一眼可见(见概率论基础 )。

工具选择:研究期 Matplotlib(快、可控、出报告图),交互探索 Plotly(缩放排查单日异常)。Matplotlib 的中文字体(plt.rcParams['font.sans-serif'] = ['Microsoft YaHei'])与负号显示(axes.unicode_minus = False)是 Windows 环境必配的两行。

Jupyter 与研究复现

Notebook 适合探索(分步验证数据、即时画图),但「cell 乱序执行」会制造不可复现的研究:df 在第 3 格被改、第 7 格重跑时结果全变而你不自知。复现纪律四条:

  1. 探索用 Notebook,成形即落盘:任何通过初检的因子,立刻把逻辑重写成 .py 模块 + 单元测试(见代码质量 ),Notebook 只留调用;
  2. 顶部固定环境:%load_ext autoreload、随机种子、数据版本号写在第一个 cell;
  3. Restart & Run All 是提交标准:一个 notebook 若不能一键从头跑通,就等于没写完;
  4. 数据快照:因子计算前记录数据表的行数、日期范围、来源版本——三个月后复现不出的「夏普 2.3」等于不存在(见因子存储与版本管理 )。

关联阅读:Git 与协作 管住代码版本;回测框架概览 评测现成轮子;任务调度 把 Notebook 研究变成每日自动运行的流水线。