第二章 量化交易基础回顾:Python金融数据处理库快速复习

好,咱们直接进入正题。这一章我打算带大家快速过一遍量化交易里最基础、也最常用的几个工具——Pandas和NumPy。别担心,我不会讲成教科书式的语法大全。我会结合自己做碳排放权期货套利时的实际经验,告诉你哪些东西真正有用,哪些坑你最好提前避开。

核心观点:Pandas和NumPy不是用来背的,是用来用的。你只要掌握20%的核心功能,就能解决80%的金融数据处理问题。

2.1 NumPy:高性能数值计算的基础

NumPy,说白了就是Python里的数学引擎。我刚开始做量化的时候,总觉得用纯Python列表也能算,干嘛要学NumPy?直到有一次我处理10万条逐笔交易数据,用列表跑了快5分钟还没出结果……嗯,从那以后我再也不敢小看NumPy了。

2.1.1 ndarray:核心数据结构

NumPy的核心是ndarray,也就是N维数组。它比Python列表快几十倍,原因在于底层是用C语言实现的,而且数据在内存里是连续存储的。

import numpy as np

# 创建数组
prices = np.array([28.5, 28.7, 28.3, 29.0, 28.9])
print(prices.dtype)  # float64

# 向量化运算——这才是精髓
returns = np.diff(prices) / prices[:-1]
print(returns)
# 输出: [ 0.0070 -0.0140  0.0247 -0.0034]

我的习惯:只要涉及数值计算,我第一件事就是把数据转成ndarray。哪怕后面要用Pandas,中间的计算步骤我也会用NumPy完成,性能差距真的很大。

2.1.2 常用统计函数

做套利分析时,我们经常要算均值、标准差、相关系数。NumPy直接提供了这些函数:

# 假设这是某碳排放权期货的日收益率序列
daily_returns = np.array([0.002, -0.001, 0.003, -0.002, 0.001, 0.004, -0.003])

mean_return = np.mean(daily_returns)      # 平均收益率
std_return = np.std(daily_returns, ddof=1) # 样本标准差
max_drawdown = np.min(daily_returns)       # 最大回撤(简化版)

print(f"均值: {mean_return:.4f}, 标准差: {std_return:.4f}")

我曾经踩过的坑:计算标准差时,如果不加ddof=1,NumPy默认用总体标准差公式。但金融数据通常是样本数据,应该用样本标准差。这个细节会导致后续的Z-score计算偏差,直接影响套利信号的触发。

2.2 Pandas:金融数据分析的瑞士军刀

如果说NumPy是发动机,那Pandas就是整辆车。它把数据、索引、标签整合在一起,让你能像操作Excel一样操作数据,但功能强大得多。

2.2.1 DataFrame和Series

这两个概念必须搞明白。Series是一列带标签的数据,DataFrame是多列组成的表格。我个人习惯把DataFrame想象成一个带行索引和列索引的Excel表格。

import pandas as pd

# 创建时间序列数据
dates = pd.date_range('2024-01-01', periods=5, freq='D')
prices_cef = pd.Series([28.5, 28.7, 28.3, 29.0, 28.9], index=dates, name='CEF')

# 创建DataFrame,包含两个品种的数据
data = pd.DataFrame({
    'CEF': [28.5, 28.7, 28.3, 29.0, 28.9],
    'EUA': [32.1, 32.3, 31.9, 32.6, 32.4]
}, index=dates)

print(data.head())

2.2.2 数据清洗:真实世界的必修课

你想想看,交易所给的数据能是干干净净的吗?不可能。缺失值、异常值、重复数据,这些才是常态。我在做碳排放权期货数据清洗时,遇到过最头疼的问题是:某个合约在换月期间,新旧合约的数据同时存在,导致价差计算出现巨大偏差。

# 处理缺失值
data_clean = data.dropna()                    # 删除缺失行
data_filled = data.fillna(method='ffill')     # 前向填充

# 检测异常值(3倍标准差法)
z_scores = (data - data.mean()) / data.std()
outliers = (z_scores.abs() > 3).any(axis=1)
data_no_outliers = data[~outliers]

避坑指南:我曾经直接用dropna()删掉了所有含缺失值的行,结果发现删掉了将近30%的数据,因为多个品种的缺失时间点不一样。后来我改用前向填充,再结合插值法,才保住了大部分数据。记住:删除数据是最后的手段。

2.2.3 时间序列重采样

碳排放权期货的交易频率可能不一致,有的品种1分钟成交一次,有的可能5分钟才成交一次。重采样就是把这些数据对齐到统一的时间频率上。

# 假设有1分钟级别的数据
minute_data = pd.Series(...)  # 省略具体数据

# 重采样为5分钟数据
resampled_5min = minute_data.resample('5T').agg({
    'open': 'first',
    'high': 'max',
    'low': 'min',
    'close': 'last',
    'volume': 'sum'
})

2.3 时间序列分析基础

做套利,本质上就是在分析时间序列之间的关系。平稳性、自相关性、协整性,这三个概念你必须吃透。

2.3.1 平稳性检验

为什么平稳性重要?因为大多数统计模型都假设数据是平稳的。如果数据不平稳,你算出来的相关系数可能是假的——这叫伪回归。

from statsmodels.tsa.stattools import adfuller

# ADF检验
result = adfuller(data['CEF'].values)
print(f"ADF统计量: {result[0]:.4f}")
print(f"p值: {result[1]:.4f}")

if result[1] < 0.05:
    print("序列平稳,可以进行后续分析")
else:
    print("序列不平稳,需要差分处理")

我的经验:碳排放权期货的价格序列几乎都是非平稳的,但它们的价差(比如CEF和EUA的价差)往往表现出平稳性。这就是套利机会的来源——价差会围绕均值回归。

2.3.2 自相关与偏自相关

这两个概念用来判断时间序列的滞后结构。说白了,就是看今天的价格和昨天的价格有没有关系,和前天有没有关系。

from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

# 计算自相关函数
acf_values = plot_acf(data['CEF'].diff().dropna(), lags=20)
pacf_values = plot_pacf(data['CEF'].diff().dropna(), lags=20)

2.4 统计套利理论基础

统计套利的核心理念很简单:找到两个或多个价格走势相关的品种,当它们的价差偏离正常范围时,做多被低估的、做空被高估的,等待价差回归。

2.4.1 协整关系

协整是统计套利的数学基础。两个非平稳序列,如果它们的线性组合是平稳的,就说它们存在协整关系。这就像两个人喝醉了走路,虽然各自摇摇晃晃,但始终保持在一定的距离内。

from statsmodels.tsa.stattools import coint

# 检验CEF和EUA是否存在协整关系
score, pvalue, _ = coint(data['CEF'], data['EUA'])
print(f"协整检验p值: {pvalue:.4f}")

if pvalue < 0.05:
    print("存在协整关系,可以进行配对交易")
else:
    print("不存在协整关系,需要寻找其他配对")

我曾经犯过的错:只看相关系数就认为两个品种适合做套利。结果相关系数高达0.95,但协整检验没通过。后来才发现,那只是两个品种都在同步上涨,根本没有均值回归的特性。记住:相关系数高不等于协整。

2.4.2 价差与Z-score

一旦确认了协整关系,下一步就是计算价差,然后用Z-score来标准化。Z-score告诉你当前价差偏离均值多少个标准差,这是触发交易信号的关键指标。

# 计算价差
spread = data['CEF'] - data['EUA'] * hedge_ratio

# 计算Z-score
spread_mean = spread.mean()
spread_std = spread.std()
z_score = (spread - spread_mean) / spread_std

# 交易信号
entry_threshold = 2.0  # 入场阈值
exit_threshold = 0.5   # 出场阈值

long_signal = z_score < -entry_threshold
short_signal = z_score > entry_threshold
exit_signal = abs(z_score) < exit_threshold

我的习惯:Z-score的阈值不是固定的。我会用滚动窗口(比如60个交易日)动态计算均值和标准差,这样能适应市场环境的变化。固定阈值在趋势行情里会让你亏得很惨。

2.5 本章知识体系总览

下面这张图是我自己整理的,把本章的核心知识点串在了一起。你可以把它当作一个快速索引,以后忘了哪个部分,回来瞄一眼就行。

量化交易基础回顾:知识体系 NumPy基础 Pandas数据处理 统计套利理论 ndarray数组创建与运算 向量化计算(性能关键) 统计函数:mean/std/corr DataFrame/Series结构 数据清洗:缺失值/异常值 时间序列重采样 平稳性检验(ADF) 协整关系检验 价差与Z-score信号 碳排放权期货套利系统 三大模块相互支撑,共同构成套利系统的技术基础

好了,这一章的内容就到这里。NumPy和Pandas是基本功,花时间练熟它们,后面搭建套利系统时会顺手很多。下一章我们会正式进入碳排放权期货市场,看看这个市场的独特之处在哪里。


公众号:蓝海资料掘金营,微信deep3321