← Quant 101 总览
第 01 关 · 基础

看懂一只股票Price & Returns

量化的第一课不是“怎么赚钱”,而是“用什么眼睛看市场”。答案有点反直觉:不是价格,是收益率

1为什么不直接看价格?

茅台一股 1700 块、平安银行一股 10 块——你能说谁“涨得快”吗?不能。价格的绝对数没有可比性。我们真正关心的是涨跌了百分之几,这就是收益率。它把不同价位、不同股票、不同时间统统拉到同一把尺子上。

所以拿到任何价格数据,量化的第一个动作永远是:把价格转成收益率

2简单收益率 vs 对数收益率

两种算法,新手都要认识:

小波动时两者几乎相等(涨 1% ≈ 0.995%),只有大涨大跌时才看出差别。新手记住“有这两种、对数能加总”即可。

px = df["close"]                 # 复权收盘价
simple_ret = px.pct_change()       # 简单收益率
log_ret = np.log(px / px.shift(1)) # 对数收益率

3复权:新手第一个大坑

公司分红、送股的那天,股价会“凭空”跳水——因为一部分价值以现金/股份的形式发给你了。如果你直接用这种“未复权”价算收益,会低估真实回报

解决办法是用复权价。差别有多大?同一段时间、同一只茅台:

口径5 年总收益
前复权(正确)+213.9%
不复权(错误)+188.2%

差了整整 25 个百分点!取数时加一个参数就对了:

# 用 tushare 取前复权日线
df = ts.pro_bar(ts_code="600519.SH", api=pro,
                start_date="20190101", end_date="20240101", adj="qfq")

前复权 vs 后复权:锚点不同

复权有两种,区别在于“以哪一头为锚”:

前复权 qfq后复权 hfq
锚点今天(最新价=现价)最早(历史价不变)
历史价会变吗会(每次分红重算)不会(永久固定)
最适合看盘/技术分析回测/长期收益
关键认知:算收益率时两者等价

复权只是给整条价格序列乘一个因子,而收益率是比值、不受整体缩放影响——所以前复权和后复权算出来的收益率序列、年化、回测结果完全一样。差别只在“价格的绝对水平和锚点”。
正因如此,做回测用哪个都行;很多量化偏好后复权,是因为它历史不随新分红变动、更适合可复现的长期回测。本课用 qfq,纯粹因为它最新价直观、最常见——新手只要记住:算收益率两者等价,关键是千万别用不复权。

⚠ 铁律

量化一律用复权价(前复权 qfq / 后复权 hfq 皆可),绝不能用不复权价算收益——这是最容易、也最致命的新手错误之一。

4年化收益:能比较的“速度”

“5 年涨了 213%”听着猛,但换算成年化收益(CAGR)才知道每年多快、才能和别的标的比。用几何平均(不是简单除以年数):

years = len(px) / 252                          # 一年约 252 个交易日
cagr  = (px.iloc[-1]/px.iloc[0])**(1/years) - 1   # 茅台这5年 ≈ 26.8%

5收益率的分布:肥尾与风险

看右图那张直方图:大多数交易日是小涨小跌(中间高),但两端有“肥尾”——偶尔的暴涨暴跌比正态分布预测的更频繁。这正是风险的来源:你以为很罕见的大跌,其实没那么罕见。下一关我们就来度量它。

✍ 动手做

1. 把股票换成平安银行(000001.SZ)、宁德时代(300750.SZ),比比谁年化高、谁尾巴更肥。
2. 把区间改成 2021–2024(偏熊的一段),看年化变成多少——体会“同一只票、区间不同,结论天差地别”。
3. 想一想:一只票“年化 26%”但“单日能跌 8%”,你拿得住吗?(这就引出下一关。)

小结

量化研究的对象是收益率,不是价格;必须用复权价;年化(CAGR)是能跨标的比较的速度;收益率分布有肥尾,这是风险的源头。

以茅台为例:左=复权价走势,右=日收益率分布(中间高、两端“肥尾”)。
动手做 · 解题过程 + 参考答案先自己写,再点开对答案
1换股票,比谁年化高、谁尾巴更肥
思路 ·pro_bar 取前复权日线,pct_change() 转收益率;用几何平均算年化(CAGR),用峰度(kurtosis)衡量肥尾——峰度越大,极端涨跌越频繁。三只票跑同一段时间再排队。
import numpy as np
from scipy.stats import kurtosis
def cagr(px):                      # 几何年化
    return (px.iloc[-1]/px.iloc[0])**(252/len(px)) - 1
for code, name in [("600519.SH","茅台"),("000001.SZ","平安"),("300750.SZ","宁德")]:
    px = ts.pro_bar(ts_code=code, api=pro, adj="qfq",
                    start_date="20190101", end_date="20240101"
                    ).sort_values("trade_date")["close"]
    r = px.pct_change()
    print(name, f"年化{cagr(px)*100:.1f}%", f"峰度{kurtosis(r.dropna()):.1f}")
结果 · 宁德 33.6%(峰度1.6) > 茅台 26.8%(2.0) > 平安 2.1%(峰度2.5,尾巴最肥)。平安几乎不涨、却波动最剧烈——印证“高波动 ≠ 高收益”。
2把区间改成偏熊的 2021–2024
思路 · 只改 start_dateend_date,其余代码不动,重算茅台年化。同一只票、换个区间,结论可能完全翻转。
px = ts.pro_bar(ts_code="600519.SH", api=pro, adj="qfq",
                start_date="20210101", end_date="20240101"
                ).sort_values("trade_date")["close"]
print("茅台 2021-2024 年化", f"{cagr(px)*100:.1f}%")
结果 · 茅台 2021–2024 年化 −2.9%。从 2019 起算是 +26.8%/年,换个区间直接变负——“同一只票、区间不同,结论天差地别”,这正是回测最容易骗人的地方。
3思考:年化26%但单日能跌8%,你拿得住吗?
思路 · 这是开放思考题,不用写代码。关键认知:单日波动不可怕,真正让人割肉离场的是连续的深坑(最大回撤)
结果 · 答案留到第 02 关——我们会用最大回撤把“拿不拿得住”量化出来。
← 返回
课程总览
下一关 →
风险与收益的度量