量化的第一课不是“怎么赚钱”,而是“用什么眼睛看市场”。答案有点反直觉:不是价格,是收益率。
茅台一股 1700 块、平安银行一股 10 块——你能说谁“涨得快”吗?不能。价格的绝对数没有可比性。我们真正关心的是涨跌了百分之几,这就是收益率。它把不同价位、不同股票、不同时间统统拉到同一把尺子上。
所以拿到任何价格数据,量化的第一个动作永远是:把价格转成收益率。
两种算法,新手都要认识:
r = 今天价 / 昨天价 − 1。最直观。lr = ln(今天价 / 昨天价)。它有个好性质——可以直接相加:把每天的对数收益加起来,就等于整段的对数收益。统计建模里更常用。小波动时两者几乎相等(涨 1% ≈ 0.995%),只有大涨大跌时才看出差别。新手记住“有这两种、对数能加总”即可。
px = df["close"] # 复权收盘价
simple_ret = px.pct_change() # 简单收益率
log_ret = np.log(px / px.shift(1)) # 对数收益率
公司分红、送股的那天,股价会“凭空”跳水——因为一部分价值以现金/股份的形式发给你了。如果你直接用这种“未复权”价算收益,会低估真实回报。
解决办法是用复权价。差别有多大?同一段时间、同一只茅台:
| 口径 | 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")
量化一律用复权价(qfq 前复权 / hfq 后复权)。这是最容易、也最致命的新手错误之一。
“5 年涨了 213%”听着猛,但换算成年化收益(CAGR)才知道每年多快、才能和别的标的比。用几何平均(不是简单除以年数):
years = len(px) / 252 # 一年约 252 个交易日
cagr = (px.iloc[-1]/px.iloc[0])**(1/years) - 1 # 茅台这5年 ≈ 26.8%
看右图那张直方图:大多数交易日是小涨小跌(中间高),但两端有“肥尾”——偶尔的暴涨暴跌比正态分布预测的更频繁。这正是风险的来源:你以为很罕见的大跌,其实没那么罕见。下一关我们就来度量它。
1. 把股票换成平安银行(000001.SZ)、宁德时代(300750.SZ),比比谁年化高、谁尾巴更肥。
2. 把区间改成 2021–2024(偏熊的一段),看年化变成多少——体会“同一只票、区间不同,结论天差地别”。
3. 想一想:一只票“年化 26%”但“单日能跌 8%”,你拿得住吗?(这就引出下一关。)
量化研究的对象是收益率,不是价格;必须用复权价;年化(CAGR)是能跨标的比较的速度;收益率分布有肥尾,这是风险的源头。
