金融量化入门:Pandas 时间序列处理与技术指标实战(含金叉死叉 / 均线策略)

目录

一、基础准备:数据与环境

1.1 环境安装

1.2 数据获取示例(Tushare)

二、核心操作 1:时间序列数据预处理

2.1 列类型转换(字符串→时间格式)

2.2 数据移位:shift () 实现 “前后对比”

三、核心操作 2:时间序列重采样(resample)

3.1 常用频率编码表(量化必背)

3.2 重采样实战:筛选买卖点日期

四、核心操作 3:滑动窗口与均线计算(rolling)

4.1 均线计算实战

4.2 窗口计算扩展

五、实战案例:均线金叉死叉策略实现

5.1 信号逻辑定义

5.2 代码实现与结果验证

5.3 结果可视化(直观验证)

六、总结与扩展

扩展方向


在金融量化分析中,时间序列数据处理是核心基础 —— 无论是股票 K 线、期货合约还是加密货币行情,所有策略逻辑的实现都依赖于对数据的高效清洗、转换与指标计算。本文基于 Pandas 库,从数据预处理到技术指标落地,手把手讲解量化分析中的关键操作,最终通过 “均线金叉死叉” 案例展示策略逻辑的实现,适合量化入门者与数据分析师参考。

一、基础准备:数据与环境

在开始前,需确保环境已安装核心库。金融数据常用 Tushare(A 股)、Yahoo Finance(美股)或聚宽 API 获取,本文以股票日度数据为例(含dateopenclosehighlow等字段)。

1.1 环境安装

# 安装核心库
pip install pandas numpy matplotlib tushare  # tushare用于获取A股数据

1.2 数据获取示例(Tushare)

import pandas as pd
import tushare as ts

# 设置Tushare token(需注册账号获取:https://tushare.pro/)
ts.set_token("你的Tushare Token")
pro = ts.pro_api()

# 获取贵州茅台(600519.SH)2020-2024年日度数据
df = pro.daily(ts_code="600519.SH", start_date="20200101", end_date="20240531")
print("原始数据结构:")
print(df.head())

原始数据中,date字段为字符串格式(如20200102),无法直接用于时间序列分析,需先进行类型转换与索引设置

二、核心操作 1:时间序列数据预处理

时间序列的核心是 “时间有序性”,因此第一步必须确保数据按时间排序,并将时间字段设为索引 —— 这是后续重采样、滑动窗口计算的前提。

2.1 列类型转换(字符串→时间格式)

Pandas 的to_datetime()可将字符串格式的日期转换为datetime64类型,支持多种格式(如202001022020-01-02)。

# 1. 转换日期格式:字符串→datetime
df["date"] = pd.to_datetime(df["date"])  # 自动识别"20200102"为2020-01-02

# 2. 按日期升序排序(避免数据乱序)
df = df.sort_values("date").reset_index(drop=True)

# 3. 设置date为索引(方便后续按时间筛选、重采样)
df.set_index("date", inplace=True)  # inplace=True:直接修改原DataFrame

print("处理后的数据结构:")
print(df.head())
print("索引类型:", df.index.dtype)  # 输出:datetime64[ns]

2.2 数据移位:shift () 实现 “前后对比”

在量化分析中,经常需要对比 “当前值” 与 “前 N 期值”(如当日开盘价与昨日收盘价的差值),shift()方法可实现数据的上移 / 下移

方法效果应用场景示例
shift(1)数据下移 1 行(取前 1 期)当日开盘价 - 昨日收盘价
shift(-1)数据上移 1 行(取后 1 期)当日收盘价 - 明日开盘价
shift(5)数据下移 5 行(取前 5 期)计算 5 期前的均线值

实战示例:筛选 “开盘价较昨日收盘价下跌≥2%” 的日期

# 计算:(当日开盘价 - 昨日收盘价) / 昨日收盘价 ≤ -2%
# shift(1):获取昨日收盘价(close列下移1行)
price_drop_condition = (df["open"] - df["close"].shift(1)) / df["close"].shift(1) <= -0.02

# 筛选满足条件的日期索引
drop_dates = df[price_drop_condition].index
print("开盘价较昨日收盘价下跌≥2%的日期:")
print(drop_dates[:10])  # 输出前10个日期

三、核心操作 2:时间序列重采样(resample)

高频数据(如分钟级)往往噪声较多,需通过重采样转换为低频数据(如日度、周度),或按业务需求生成周期性报表(如月度第一个交易日、年度最后一个交易日)。

Pandas 的resample()方法支持灵活的频率设置,核心逻辑是:按指定频率分组,对组内数据聚合(如取首值、尾值、均值)

3.1 常用频率编码表(量化必背)

频率类型频率编码含义应用场景示例
高频10S每 10 秒传感器实时温度数据
30min每 30 分钟股票分时数据、交通流量
1H每 1 小时服务器负载监控
BH每个工作日的每小时工作时间客服咨询量
中频1D每天日销售额、DAU(日活用户)
BD每个工作日(周一至周五)工作日订单量、考勤数据
W-SUN每周日(默认周结)周销售额、WAU(周活用户)
W-MON每周一(自定义周结)企业周一结上周报表
低频BMS每月第一个工作日月初业绩目标、月度计划
BM每月最后一个工作日月度财务结账
QS-JAN季度初(1/4/7/10 月 1 日)季度预算规划
BA每年最后一个工作日年度财务总结

3.2 重采样实战:筛选买卖点日期

在量化策略中,常需按 “月度第一个交易日买入”“年度最后一个交易日卖出” 的逻辑设置买卖点,resample()+ 聚合函数可高效实现。

# 假设用"收盘价"作为信号列,筛选买卖点日期
con = df["close"]  # 信号列(实际可替换为策略信号,如均线交叉)

# 1. 买入点:每月第一个工作日(BMS)的第一个数据(即当日收盘价)
buy_dates = con.resample("BMS").first()
print("月度买入日期及收盘价:")
print(buy_dates.head())

# 2. 卖出点:每年最后一个工作日(BA)的最后一个数据,排除最后一年(避免未结束周期)
sell_dates = con.resample("BA").last()[:-1]
print("\n年度卖出日期及收盘价:")
print(sell_dates.head())

四、核心操作 3:滑动窗口与均线计算(rolling)

技术分析中,移动平均线(MA) 是最基础的指标(如 MA5、MA30),其本质是 “固定窗口内数据的均值”。Pandas 的rolling()方法可快速实现滑动窗口计算,支持均值、求和、最大值等聚合操作。

4.1 均线计算实战

# 1. 计算5日均线(MA5):窗口大小=5,聚合函数=均值
df["MA5"] = df["close"].rolling(window=5).mean()

# 2. 计算30日均线(MA30):窗口大小=30,聚合函数=均值
df["MA30"] = df["close"].rolling(window=30).mean()

# 3. 查看结果(前35行,MA30需30个数据才会有值,前29行为NaN)
print("收盘价与均线数据:")
print(df[["close", "MA5", "MA30"]].head(35))

4.2 窗口计算扩展

除均值外,rolling()还支持多种聚合函数,满足不同分析需求:

# 1. 5日最高价(窗口内最大值)
df["MA5_high"] = df["high"].rolling(5).max()

# 2. 30日成交量总和(窗口内求和)
df["MA30_volume"] = df["vol"].rolling(30).sum()

# 3. 5日收盘价标准差(窗口内波动率)
df["MA5_std"] = df["close"].rolling(5).std()

五、实战案例:均线金叉死叉策略实现

“金叉” 与 “死叉” 是均线策略的核心信号:

  • 金叉:短期均线上穿长期均线(如 MA5 从下向上穿过 MA30),视为买入信号;
  • 死叉:短期均线下穿长期均线(如 MA5 从上向下穿过 MA30),视为卖出信号。

5.1 信号逻辑定义

基于 MA5 与 MA30 的位置关系,定义两个中间条件,再通过 “前后对比” 筛选出交叉点:

  1. s1:MA5 < MA30(短期均线在长期均线下方);
  2. s2:MA5 > MA30(短期均线在长期均线上方);
  3. 死叉:当日s1为 True,且前一日s2为 True(MA5 从上方下穿 MA30);
  4. 金叉:当日s2为 True,且前一日s1为 True(MA5 从下方上穿 MA30)。

5.2 代码实现与结果验证

# 1. 确保MA5和MA30已计算(参考第四章)
# 2. 定义中间条件
df["s1"] = df["MA5"] < df["MA30"]  # MA5在MA30下方
df["s2"] = df["MA5"] > df["MA30"]  # MA5在MA30上方

# 3. 计算死叉信号(当日s1=True,前一日s2=True)
df["death_cross"] = df["s1"] & df["s2"].shift(1)

# 4. 计算金叉信号(当日s2=True,前一日s1=True)
df["gold_cross"] = df["s2"] & df["s1"].shift(1)

# 5. 筛选金叉和死叉日期
gold_dates = df[df["gold_cross"]].index
death_dates = df[df["death_cross"]].index

print("2023年以来的金叉日期:")
print(gold_dates[gold_dates >= "2023-01-01"])

print("\n2023年以来的死叉日期:")
print(death_dates[death_dates >= "2023-01-01"])

5.3 结果可视化(直观验证)

通过 Matplotlib 绘制收盘价、均线及交叉点,直观查看策略信号:

import matplotlib.pyplot as plt

# 设置中文字体(避免乱码)
plt.rcParams["font.sans-serif"] = ["SimHei"]
plt.rcParams["axes.unicode_minus"] = False

# 选取2023年数据绘图
plot_data = df.loc["2023-01-01":"2023-12-31"]

# 创建画布
fig, ax = plt.subplots(figsize=(12, 6))

# 绘制收盘价、MA5、MA30
ax.plot(plot_data.index, plot_data["close"], label="收盘价", color="blue", alpha=0.6)
ax.plot(plot_data.index, plot_data["MA5"], label="MA5", color="red", linewidth=2)
ax.plot(plot_data.index, plot_data["MA30"], label="MA30", color="green", linewidth=2)

# 标记金叉(绿色上三角)和死叉(红色下三角)
gold_points = plot_data[plot_data["gold_cross"]]
death_points = plot_data[plot_data["death_cross"]]
ax.scatter(gold_points.index, gold_points["close"], marker="^", color="green", s=100, label="金叉")
ax.scatter(death_points.index, death_points["close"], marker="v", color="red", s=100, label="死叉")

# 设置图表属性
ax.set_title("2023年贵州茅台收盘价与均线金叉死叉", fontsize=14)
ax.set_xlabel("日期", fontsize=12)
ax.set_ylabel("价格(元)", fontsize=12)
ax.legend()
plt.xticks(rotation=45)
plt.tight_layout()

# 保存图片
plt.savefig("gold_death_cross_2023.png", dpi=300)
plt.show()

运行代码后,会生成包含 “收盘价、MA5、MA30、金叉、死叉” 的可视化图,可直观看到策略信号的触发时机。

六、总结与扩展

本文从 Pandas 基础操作出发,覆盖了金融量化的核心数据处理流程:

  1. 数据预处理:日期类型转换、索引设置、数据移位;
  2. 重采样:按业务需求生成周期性数据(如月度买入点);
  3. 滑动窗口:计算均线等技术指标;
  4. 策略实现:基于均线的金叉死叉信号筛选。

扩展方向

  • 策略优化:加入成交量、MACD 等其他指标,避免单一均线信号的误判;
  • 回测框架:结合BacktraderVectorBT,对金叉死叉策略进行回测(计算收益率、最大回撤等);
  • 高频策略:将日度数据替换为分钟级数据,利用resample("5min")实现高频策略逻辑。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值