第三章 Python环境搭建:NumPy基础、Pandas基础、Matplotlib基础、SciPy优化器介绍
说实话,做量化金融这些年,我见过太多人一上来就搞复杂的数学模型,结果连数据都读不进去。嗯,这就像盖房子不打地基。今天咱们就把这四块基石——NumPy、Pandas、Matplotlib、SciPy——彻底搞明白。
核心逻辑:这四兄弟各司其职——NumPy管数值计算,Pandas管数据处理,Matplotlib管可视化,SciPy管优化求解。少了谁都不行。
3.1 NumPy基础——量化计算的发动机
NumPy,说白了就是Python里的数学引擎。我刚开始做量化时,用纯Python列表算收益率,跑一次要等半天。后来换成NumPy数组,速度直接起飞。
为什么这么快?因为NumPy底层是C语言写的,而且用了向量化操作。你想想看,同样的循环,Python是一步一步走,NumPy是一整片一起算。
核心数据结构:ndarray
import numpy as np
# 创建数组
prices = np.array([100.5, 101.2, 102.8, 103.1])
print(prices.shape) # (4,)
# 二维数组——模拟多只股票
portfolio = np.array([
[100.5, 50.2],
[101.2, 51.0],
[102.8, 50.8]
])
print(portfolio.shape) # (3, 2)
我的小技巧:创建数组时尽量指定dtype,比如 np.array([...], dtype=np.float64)。我曾经因为默认整数类型导致收益率计算全错,排查了一下午。
常用统计函数
returns = np.array([0.01, -0.02, 0.015, 0.005])
mean_return = np.mean(returns) # 平均收益率
std_return = np.std(returns) # 标准差(风险)
cov_matrix = np.cov(returns) # 协方差矩阵
print(f"平均收益: {mean_return:.4f}")
print(f"风险: {std_return:.4f}")
这里有个坑——np.cov()默认是按行计算协方差的。如果数据是每列一只股票,记得用rowvar=False。我当年第一次算投资组合方差时,结果怎么都对不上,就是这个参数搞的鬼。
3.2 Pandas基础——数据处理的瑞士军刀
Pandas,说白了就是Excel的超级升级版。我个人习惯把所有行情数据都装进DataFrame里,操作起来特别顺手。
DataFrame入门
import pandas as pd
# 创建DataFrame
data = {
'日期': ['2024-01-01', '2024-01-02', '2024-01-03'],
'茅台': [1680.0, 1695.0, 1702.0],
'五粮液': [135.0, 134.5, 136.2]
}
df = pd.DataFrame(data)
print(df.head())
时间序列处理
# 把日期列转成时间索引
df['日期'] = pd.to_datetime(df['日期'])
df.set_index('日期', inplace=True)
# 计算日收益率
returns = df.pct_change().dropna()
print(returns)
注意:pct_change()计算的是百分比变化,不是对数收益率。做均值方差优化时,我建议用对数收益率,因为它在时间上可加性更好。但这里先用简单收益率,方便理解。
数据清洗实战
# 处理缺失值——真实数据里常有停牌
df.fillna(method='ffill', inplace=True) # 用前一个交易日填充
# 筛选数据
df_filtered = df[df.index >= '2024-01-01']
# 滚动计算
df['20日均线'] = df['茅台'].rolling(window=20).mean()
我曾经处理过一份包含3000只股票的数据,里面有大量缺失值和异常值。用Pandas的链式操作,几行代码就搞定了。要是用Excel,估计得加班到天亮。
3.3 Matplotlib基础——让数据说话
做量化,光有数字不行,得画出来看。Matplotlib就是干这个的。我习惯用它画收益率曲线、有效前沿、还有风险收益散点图。
基础绘图
import matplotlib.pyplot as plt
# 设置中文字体——这个坑我踩过
plt.rcParams['font.sans-serif'] = ['SimHei']
plt.rcParams['axes.unicode_minus'] = False
# 画收益率曲线
plt.figure(figsize=(10, 6))
plt.plot(df.index, df['茅台'], label='茅台', linewidth=2)
plt.plot(df.index, df['五粮液'], label='五粮液', linewidth=2)
plt.title('股票价格走势')
plt.xlabel('日期')
plt.ylabel('价格')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
避坑指南:在Jupyter Notebook里,记得加%matplotlib inline。我曾经在服务器上跑脚本,忘了加这句,结果图全没了,白跑了一整夜。
子图布局——多维度展示
fig, axes = plt.subplots(2, 2, figsize=(12, 8))
# 左上:价格走势
axes[0, 0].plot(df.index, df['茅台'])
axes[0, 0].set_title('价格走势')
# 右上:收益率分布
axes[0, 1].hist(returns['茅台'], bins=20, alpha=0.7)
axes[0, 1].set_title('收益率分布')
# 左下:滚动波动率
axes[1, 0].plot(returns['茅台'].rolling(20).std())
axes[1, 0].set_title('20日滚动波动率')
# 右下:散点图
axes[1, 1].scatter(returns['茅台'], returns['五粮液'], alpha=0.5)
axes[1, 1].set_title('收益率相关性')
plt.tight_layout()
plt.show()
3.4 SciPy优化器介绍——求解最优权重
终于到了最核心的部分。均值方差优化的本质,就是求解一个带约束的优化问题。SciPy的minimize函数就是干这个的。
优化器核心参数
| 参数 | 说明 | 常用值 |
|---|---|---|
| fun | 目标函数(要最小化的东西) | 自定义函数 |
| x0 | 初始猜测值 | 均匀权重 |
| method | 优化算法 | 'SLSQP', 'trust-constr' |
| bounds | 变量取值范围 | (0, 1) 不允许做空 |
| constraints | 约束条件 | 权重之和=1 |
实战:最小化方差组合
from scipy.optimize import minimize
import numpy as np
# 假设我们有3只股票
returns = np.array([0.12, 0.08, 0.15]) # 年化收益率
cov_matrix = np.array([
[0.1, 0.02, 0.04],
[0.02, 0.08, 0.01],
[0.04, 0.01, 0.12]
])
# 目标函数:组合方差
def portfolio_variance(weights):
return weights.T @ cov_matrix @ weights
# 约束条件:权重之和为1
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
# 变量范围:不允许做空
bounds = tuple((0, 1) for _ in range(3))
# 初始猜测:均匀分配
initial_weights = [1/3, 1/3, 1/3]
# 求解
result = minimize(portfolio_variance,
initial_weights,
method='SLSQP',
bounds=bounds,
constraints=constraints)
print(f"最优权重: {result.x}")
print(f"最小方差: {result.fun:.4f}")
重要提醒:SLSQP方法对初始值敏感。我遇到过多次因为初始值选得不好,结果收敛到局部最优的情况。建议多试几个初始点,或者用basinhopping全局优化器。
优化器选择建议
- SLSQP:最常用,支持等式和不等式约束。适合中小规模问题。
- trust-constr:更稳健,适合约束复杂的场景。但速度稍慢。
- differential_evolution:全局优化,不怕局部最优。但计算量大。
我个人习惯先用SLSQP快速跑一遍,如果结果看起来不对劲,再换trust-constr验证。你想想看,优化器就像工具箱里的扳手,不同场景得用不同的工具。
本章核心要点:
- NumPy的向量化操作是量化计算的基础
- Pandas的DataFrame让数据处理变得优雅
- Matplotlib的可视化能帮你快速发现问题
- SciPy的minimize是求解最优权重的核心工具
好了,这四样工具都备齐了。下一章咱们就要真刀真枪地干——用这些工具实现完整的均值方差优化流程。到时候你会发现,原来那些复杂的数学公式,用代码实现起来其实挺简单的。