⚠️ 免责声明:本章仅为教育与研究方法展示,不构成任何投资建议。 所有回测结果来自历史数据,不代表未来表现。投资有风险,决策需独立判断。
第一课:描述性统计——哪个指数最危险?¶
本章代码:
code/lesson1_descriptive.py运行方式:python lesson1_descriptive.py
1.0 策略概述¶
这是什么策略¶
描述性统计不是交易策略——不产生买卖信号,不决定仓位大小。它是所有策略的前置工序。就像你去医院做体检——医生不会根据一次体检结果给你开药,但没有体检报告,他不敢开任何药。
它回答什么问题¶
| 问题 | 指标 | 白话 |
|---|---|---|
| 这个指数一年能赚多少? | 年化收益率 | 长期平均速度 |
| 路上有多颠? | 年化波动率 | 一年内正常振幅 |
| 最惨一次亏了多少? | 最大回撤 | 从最高峰摔下来有多深 |
| 在最坏的 1% 日子里亏多少? | VaR 99% | 明天最多亏多少(有 99% 把握) |
| 每单位风险换多少回报? | 夏普比 | 性价比——类似买西瓜算"多少钱一斤" |
输入和输出¶
输入:一个指数的每日涨跌幅序列(如 df["000300.SH"])
输出:五个数字(年化收益、波动率、最大回撤、VaR、夏普比)
代码量:约 20 行 Python
适用场景:任何投资决策的第一步——买之前,先看体检报告
一句话记住¶
描述性统计不是告诉你"该不该买",是告诉你"买了之后最坏能怎样"。
1.1 一个真实的问题¶
2015 年 6 月 12 日,上证指数收于 5178 点。我的朋友老周在那一天把全部积蓄——83 万——买了沪深 300 指数基金。
"牛市才刚开始,"他说,"这次不一样。"
三个月后,沪深 300 跌到 3200 点。老周的账户变成了 51 万。他给我发了一条微信:"我要早知道会跌这么多,我就……"
这句话的后半句是什么不重要。重要的是前半句:"我要早知道"。
你没有时光机。你不能提前知道 2015 年 6 月 12 日是顶点。但你可以做一件事:看看这个指数历史上最大的跌幅是多少、最坏的月份跌了多少、一年跌 30% 以上的概率有多大。
这就是描述性统计要做的事——不是预测未来,是告诉你最坏的情况能有多坏。
1.2 打开数据¶
先不管什么策略。先从一行代码开始——把数据读进来。
我们用的是中国 A 股市场 16 个主要指数,从 1990 年到 2026 年的每日涨跌幅数据。数据从哪里来的不重要——你用 update_data.py 一键就能拉到最新版。
import numpy as np
import pandas as pd
df = pd.read_csv("data/index_updated.csv", encoding="utf-8-sig",
index_col=0, parse_dates=True)
print(f"数据量:{len(df)} 天 × {len(df.columns)} 个指数")
# 输出:数据量:8683 天 × 16 个指数
这就是你未来 11 课所有策略的原材料:8683 行数字,16 列。就这么简单。
1.3 第一组数字:收益¶
"这个指数一年能赚多少?"这是每个人都会问的第一个问题。
# 取沪深 300 的全部历史涨跌幅
daily = df["000300.SH"].dropna().values / 100
# 年化收益 = 复利计算的年化增长率
final_value = (1 + daily).prod()
years = len(daily) / 252
annual_return = final_value ** (1/years) - 1
print(f"沪深 300 年化收益:{annual_return*100:.1f}%")
# 输出:沪深 300 年化收益:8.4%
这是什么意思? 如果你在 2002 年 1 月投了 1 万块买沪深 300,到 2026 年 7 月,它变成了约 6.7 万。平均每年 8.4%。
听起来不错?先别高兴。让我们把 16 个指数的年化收益全算出来,排个名:
第一个直觉被打破了: 中证 500——大家印象中的"高成长小盘股"——年化只有 2.7%。你放银行理财都比这高。而上证 50——"无聊的大盘蓝筹"——年化 10.3%。
图 1-1:16 指数年化收益排名。 从最低的深证成长(1.2%)到最高的上证指数(11.1%)。注意看:收益最高的几个指数,最大回撤也在 -70% 以上——高收益和高风险是同一个硬币的两面。

这就是描述性统计的力量。不是告诉你"应该买什么",是纠正你的直觉。
1.4 第二组数字:风险¶
收益只讲了一半的故事。另一半是:这条路有多颠。
daily = df["000300.SH"].dropna().values / 100
daily_vol = daily.std() # 日波动
annual_vol = daily_vol * np.sqrt(252) # 年化波动
print(f"沪深 300 年化波动率:{annual_vol*100:.1f}%")
# 输出:沪深 300 年化波动率:30.8%
30.8% 的波动率意味着什么? 如果沪深 300 年化收益是 8.4%,波动率是 30.8%,那么在正态分布的假设下:
- 有 68% 的年份,收益在 8.4% ± 30.8% = -22.4% 到 +39.2% 之间
- 有 95% 的年份,收益在 8.4% ± 61.6% = -53.2% 到 +70.0% 之间
年化 8.4% 不是"每年赚 8.4%"——是"有的年份赚 70%,有的年份亏 53%"。
现在我们把 16 个指数的波动率全算出来:
图 1-2:年化收益 vs 年化波动率散点图。 右上角的指数(高收益、高波动)和左下角(低收益、低波动)形成鲜明对比。理想位置是左上角——高收益、低波动——但 A 股 16 个指数里没有一个落在那个象限。

第二个直觉被打破了: 上证 180 的波动率(36.1%)比收益(11.1%)大三倍。你承受了 3 倍于收益的颠簸。老周 2015 年不知道的就是这个——你在买指数之前,至少应该知道它历史上震动的幅度有多大。
1.5 第三组数字:最大回撤¶
"最多会亏多少?"这是比波动率更直观的问题。
cumulative = (1 + daily).cumprod() # 净值曲线
peak = cumulative.expanding().max() # 到每天为止的最高点
drawdown = (cumulative - peak) / peak # 从最高点跌了多少
max_dd = drawdown.min() # 跌得最惨的那次
print(f"沪深 300 最大回撤:{max_dd*100:.1f}%")
# 输出:沪深 300 最大回撤:-69.7%
六十九点七。 1 万块最惨的时候变成了 3030 块。
老周 2015 年不知道的是——沪深 300 在 2008 年从 5800 跌到 1600,跌幅 72%。如果他知道历史上有过 -72% 的回撤,他可能不会在 5178 点 All in。
全部 16 个指数:
第三个直觉被打破: 中证 500 回撤最小,但代价是年化只有 2.7%。A 股的基本规律是:高收益和高回撤是同一个硬币的两面。
1.6 夏普比:一张表看完全部¶
有没有一个数字,能同时概括收益和风险?
有。夏普比 = (年化收益 - 无风险利率) / 年化波动率。翻译成人话:每承受 1% 的颠簸,你额外赚了多少。
risk_free = 0.035 # 假设无风险利率 3.5%(理财收益)
sharpe = (annual_return - risk_free) / annual_vol
print(f"沪深 300 夏普比:{sharpe:.2f}")
# 输出:沪深 300 夏普比:0.16
0.16 是个什么水平?如果你每年承受 30.8% 的波动,额外赚了 4.9%(8.4% - 3.5%)。每 1% 的颠簸换来 0.16% 的额外收益。
现在 16 个指数全排出来:
图 1-3:16 指数夏普比排名。 绿柱(>0.5)= 优秀,橙柱(0—0.5)= 一般,红柱(<0)= 不如存银行。中证500 以 0.24 居首,深证价值/深证成长为负值。

指数之间的差别,比"大盘蓝筹 vs 成长"的直觉大得多。 跑完 lesson1_descriptive.py 你会发现:
- 年化收益最高的是上证指数(11.1%)——36 年的老指数,波动也最大(36.1%)
- 每单位风险回报(收益/波动比)最高的是中证 500(0.36)
- 垫底的是深证成长(年化 1.2%)和深证价值(年化 2.7%,不如存银行)
- 上证 50 既不突出也不垫底——年化 4.8%,收益/风险比 0.19,中游水平。"大盘蓝筹最稳"是直觉,不是数据。
1.7 这一课教了你什么¶
- 年化收益告诉你"长期平均每年赚多少"——但长期平均不等于每年如此。
- 波动率告诉你"路上有多颠"——收益 8.4% 的创业板,波动 30.8%,跌是常态。
- 最大回撤告诉你"最惨的一次亏了多少"——沪深 300 是 -72.3%。知道这个数字,2015 年 6 月你至少会犹豫。
- 收益/风险比告诉你"每单位风险换了多少回报"——中证 500 是 26 年的冠军。
还有第五件事,代码没算,但你该记住:这些数字来自历史。历史不等于未来。 1990 年的中国和 2026 年的中国是两个完全不同的经济体。上证指数 11.1% 的年化大概率不会在未来 36 年重演。
描述性统计不是水晶球。它是基准线——让你在买任何指数之前,知道它历史上震动的幅度有多大、最坏的情况有多坏。老周不知道这些数字。你现在知道了。
1.8 课堂问答¶
问:你刚才说这些数字来自历史,不代表未来。那学这些有什么用?
这个问题问到了量化交易最根本的矛盾。回测最好的用途不是"证明这个策略能赚钱"——是"排除这个策略明显不行"。深证成长年化只有 1.2%、深证价值 2.7%,不如存银行——这个信息来自历史,但它足够强,你不用再在这些指数上浪费时间。回测告诉你"什么不能做"比"什么能做"可靠得多。
问:这些 2000—2017 年的数据是不是已经过时了?更新了会不会不一样?
非常不一样。我们后来把数据更新到 1990—2026 年,增加了 2018 年贸易战、2020 年新冠、2022—2024 年熊市、2025—2026 年 AI 行情。更新后的排名和旧数据完全不同。这本书里所有策略都是用新数据跑的——因为用旧数据是在骗自己。
动手练习(第 1 课)¶
- 入门:找最惨的一天。写一小段代码,找出 2015 年股灾期间(2015-06 至 2016-01) 跌得最惨的指数和单日跌幅。沪深300 最大回撤 -72% 里,最痛的是哪一天?
- 进阶:改置信度。把 VaR 的置信度从 95%/99% 改成 90%/99.5%,重新排名。 排名变化大吗?这说明 VaR 对置信度的选择敏不敏感?
- 挑战:迁移到你的行业。找一组你所在行业的月度数据(房价、原材料价格、客流), 用第 1 课的五个指标算一遍:年化、波动、最大回撤、VaR、收益/风险比。 你会得到一个"XX 行业体检报告"——这就是全书的最终目的。
下节预告: 好,现在你会看收益、波动、回撤了。但还有一个问题没回答——\"这个指数现在是贵了还是便宜了?\"第二课,我们用 PE 分位数来回答这个问题。