返回列表 发布新帖

散户量化工具箱①:用 Python 跑通你的第一个双均线回测(附全套代码)

16 0
发表于 昨天 15:25 | 显示全部楼层 阅读模式

迅投社区发布稿:《散户量化工具箱①:用 Python 跑通你的第一个双均线回测(附全套代码)》

写策略的第一课,不是选股,不是择时,是亲手跑通一个回测。今天把全套代码贴出来,在沪深300 十一年真实数据上跑,结果如实公开——包括它跑不赢买入持有这个扎心事实。

一、数据获取(baostock,免费)

import baostock as bs
import pandas as pd

bs.login()
rs = bs.query_history_k_data_plus(
    'sh.000300', 'date,open,high,low,close,volume',
    start_date='2015-01-01', end_date='2026-09-01',
    frequency='d', adjustflag='3')
rows = []
while rs.error_code == '0' and rs.next():
    rows.append(rs.get_row_data())
df = pd.DataFrame(rows, columns=rs.fields)
bs.logout()

实测 5000+ 交易日约 3.3 秒。注意当日数据 19:00 后才更新。

二、策略:5 日线上穿 20 日线买,下穿卖

df['pct'] = df['close'].pct_change().fillna(0)
df['ma_f'] = df['close'].rolling(5).mean()
df['ma_s'] = df['close'].rolling(20).mean()
df = df.dropna(subset=['ma_s']).copy()

raw = (df['ma_f'] > df['ma_s']).astype(int)   # 1=持仓 0=空仓
pos = raw.shift(1).fillna(0)                  # ★ T日信号,T+1才执行
trades = pos.diff().abs().fillna(0)           # 调仓记换手

nav = (1 + pos * df['pct'] - trades * 0.001).cumprod()   # 含单边千1成本

shift(1) 是全段代码的命门:信号由收盘价算出,当天不可能按收盘价成交。少这一行,回测好看一半,也假一半。

三、结果(沪深300,2015→2026)

  • 双均线(零成本):年化 1.61%,回撤 −31.6%
  • 双均线(单边千1):年化 −0.07%,回撤 −36.5%
  • 买入持有:年化 2.40%,回撤 −46.7%
  • 十一年共交易 94 次(188 次单边)

教科书第一策略,跑不赢买入持有。

四、三个发现

  1. 均线策略死于震荡:A 股近年震荡占比高,金叉死叉反复打脸。策略没有好坏,只有适应的市场环境。
  2. 成本是新手最大盲区:94 笔交易,零成本 1.6%,千1成本归零。
  3. 回撤仍有 36%:择时只是比扛单(−47%)好,不是保险箱。

五、这个回测真正的价值

学的不是策略,是检验闭环:数据 → 信号 → 严格执行 → 计入成本 → 客观统计。跑通一次,下次看到「年化 50% 神器」你会本能问三句:数据真实吗?执行严格吗?成本算了吗?

进阶篇(防坑三件套:参数网格/样本外/成本压测、凯利公式仓位实测)已在本系列后续文章,欢迎跟更。


本文仅供量化学习,不构成投资建议。历史回测不代表未来表现。

更多量化工程实操内容,欢迎关注公众号「晋盈投资」(不荐股、不承诺收益)。

客服专线

400-080-8112

用思考的速度交易,用真诚的态度合作,我们是认真的!
  • 关注公众号
  • 添加微信客服
Copyright © 2001-2026 迅投QMT社区 版权所有 All Rights Reserved. 京ICP备2025122616号-3
关灯
扫一扫添加微信客服
QQ客服返回顶部
快速回复 返回顶部 返回列表