rolling()计算均线需注意三点:一是显式指定时间窗口(如'20d')并确保索引或on参数正确;二是设min_periods=20避免虚假信号;三是全程用float64、不提前截断或fillna(0),以保精度与逻辑正确。

直接用 rolling() 就能算,但窗口对齐方式、缺失值处理和时间序列频率是三个最容易出错的地方。
rolling() 默认按行数滚动,不认日期
如果你的 DataFrame 索引是 DatetimeIndex,但没指定 on 参数或没设 freq,rolling(20) 就只是取最近 20 行——哪怕中间缺了 5 天数据,它也照算,结果会偏移。
- 正确做法:显式指定时间窗口,比如
df['close'].rolling('20D', on='date')(要求date列是datetime64) - 或者先用
df.set_index('date').sort_index(),再用rolling('20D') - 别依赖默认整数窗口算“20日均线”,除非你确认数据每天一条且无缺失
min_periods 参数决定 NaN 出现位置
默认 min_periods=1,第一行就出值;但均线需要满窗才有效,否则开头一堆虚假信号。
SkillSub Pro - Python 题解与代码注释双功能技能功能概述SkillSub Pro - Python 题解与代码注释双功能技能是一项面向实际任务的技能,主要用于SkillSub Pro 是一个 Python 题解生成与代码注释的 双功能合体技能 ,专为学生、算法学习者和开发者设计;✅ 一个技能,两种用途 :;核心要点📝 题解模式 :输入题目/题号,自动生成完整 Python 题解(含详细注释、解题思路、复杂度分析);💬 注释模式 :输入 Python 代码,自动添加详细中。它将相关步骤、
- 计算 20 日均线时,应设
min_periods=20,前 19 行close.rolling(20, min_periods=20).mean()全是NaN - 若用时间窗口如
'20D',min_periods仍生效,但实际满足天数的数据点不足时也会返回NaN - 注意:设了
min_periods后,len(result) == len(df)不变,只是开头/空档处填NaN
close.rolling().mean() 和 pd.Series.rolling().mean() 没区别,但链式调用易丢精度
很多人写 df['close'].rolling(20).mean().round(2),看起来没问题,但浮点累积误差+截断可能让回测信号错位。
- 建议中间不截断:
df['ma20'] = df['close'].rolling(20, min_periods=20).mean(),最后统一格式化显示 - 避免在 rolling 后立刻接
.fillna(0)—— 把本该跳过的信号强行补 0,会干扰策略逻辑 - 如果原始
close是float32,rolling 前最好转float64:df['close'].astype('float64').rolling(...)
真正麻烦的不是调用函数,而是确认你的索引对齐了时间、窗口覆盖了交易日、min_periods 匹配业务定义——比如 A 股的“20日”指 20 个**交易日**,不是自然日,这时候得先 resample 成日频再 dropna,或者用自定义 offset。这些细节一漏,回测就跑偏。
Python免费学习笔记(深入):立即使用
在学习笔记中,你将探索 Python 的核心概念和高级技巧!










