25 KiB
量化策略开发与向量化回测详解
quant_strategy_backtest_demo.py 学习文档
目标读者:零基础量化入门者
配套文件:quant_strategy_backtest_demo.py
前置知识:建议先阅读doc_01_data_pipeline.md
系列位置:第 2 篇 — 策略开发与回测篇
目录
1. 本篇概览
这篇文档对应量化交易的第二个核心环节:"有了干净的数据,怎么用它来赚钱?"
整个流程可以归纳为:
干净的价格数据
│
▼
计算技术指标(均线、RSI、MACD、布林带)
│
▼
制定交易规则 → 生成交易信号(买/卖/空仓)
│
▼
向量化回测引擎(模拟历史交易,扣除成本)
│
▼
计算绩效指标(夏普、最大回撤、胜率…)
│
▼
前向验证(防止过拟合)→ 判断策略是否值得继续研究
两种策略类型,代码各实现一种:
| 类型 | 代表指标 | 逻辑 | 适合市场环境 |
|---|---|---|---|
| 趋势跟随 (Trend Following) | 移动均线、MACD | 跟着趋势走,买涨跟涨 | 有明显趋势的牛市/熊市 |
| 均值回归 (Mean Reversion) | RSI、布林带 | 逆势操作,跌多了买、涨多了卖 | 震荡盘整市场 |
2. 合成价格数据:几何布朗运动 (Geometric Brownian Motion)
2.1 为什么用模拟数据?
- 真实数据需要付费数据源,这个 Demo 用合成数据让所有人都能直接运行
- 合成数据有"已知"的统计特性(我们自己设定的 μ 和 σ),便于验证代码正确性
- 通过调整参数可以模拟不同市场环境(牛市、熊市、震荡市)
2.2 GBM 公式直观理解
几何布朗运动 (GBM) 是描述股价随机游走的经典数学模型,也是期权定价公式(Black-Scholes)的基础。
离散形式(代码实现的):
P_t = P_{t-1} \times e^{\left(\mu - \frac{\sigma^2}{2}\right) \cdot \Delta t + \sigma \cdot \sqrt{\Delta t} \cdot \varepsilon_t}
用大白话解释这个公式:
- $P_t$:今天的价格
- $P_{t-1}$:昨天的价格
- $\mu$(mu):年化漂移率 (Annual Drift),相当于股票的"长期趋势倾斜度"。
\mu = 0.10表示每年平均上涨 10% - $\sigma$(sigma):年化波动率 (Annual Volatility),表示价格的"抖动剧烈程度"。
\sigma = 0.25表示年化波动 25% - $\Delta t = 1/252$:一个交易日是一年的 1/252
- $\varepsilon_t \sim N(0,1)$:每天的随机冲击,从标准正态分布中随机抽取
直觉:每天的价格变化 = 确定性漂移(趋势)+ 随机波动(噪声)
# 代码中的实现
dt = 1.0 / 252
epsilon = np.random.randn(n_days) # 随机冲击
log_returns = (mu - 0.5 * sigma**2) * dt + sigma * np.sqrt(dt) * epsilon
prices = s0 * np.exp(np.cumsum(log_returns)) # 累积乘积 → 价格路径
3. 技术指标详解 (Technical Indicators)
技术分析 (Technical Analysis) 的核心假设:过去的价格和成交量模式包含了预测未来走势的信息。技术指标就是从原始价格数据中提炼这些模式的数学工具。
⚠️ 注意:技术分析在学术界存在争议,有效市场假说 (Efficient Market Hypothesis) 认为价格已经反映了所有信息,技术分析无法持续获得超额收益。但在实践中,许多量化基金仍然将技术指标作为信号的一部分。
3.1 SMA 简单移动平均线 (Simple Moving Average)
公式:
\text{SMA}_n(t) = \frac{P_t + P_{t-1} + \cdots + P_{t-n+1}}{n}
直觉:取最近 n 天收盘价的算术平均数,形成一条平滑的"趋势线"。
关键参数 n 的选择:
| 窗口 n | 代号 | 特性 |
|---|---|---|
| 5、10 天 | 短期 (Short-term) | 贴近价格,反应快,但"噪声"多 |
| 20、30 天 | 中期 (Medium-term) | 月线级别的趋势 |
| 60、120 天 | 长期 (Long-term) | 季度级别的主要趋势,滞后但稳定 |
| 250 天 | 年线 (Annual) | 区分牛熊市的重要参考线 |
代码:
def sma(prices, window):
return prices.rolling(window=window).mean()
# rolling(window) = 创建一个滑动窗口
# .mean() = 对窗口内的值取平均
前 n-1 天为什么没有值?
计算 20 日均线需要 20 天数据,第 1-19 天的均线值是 NaN(数据不够)。第 20 天才有第一个有效均线值。
3.2 EMA 指数移动平均线 (Exponential Moving Average)
公式:
\text{EMA}_t = \alpha \cdot P_t + (1 - \alpha) \cdot \text{EMA}_{t-1}, \quad \alpha = \frac{2}{n+1}
与 SMA 的核心区别:SMA 对窗口内所有日期权重相等;EMA 给近期数据更高权重,越新的数据越重要。
形象比喻:
SMA 像"民主投票"——每一天的发言权相等;
EMA 像"资历制"——越近的日期说话越算数。
结果:EMA 比 SMA 对最近的价格变化反应更快,但也更"神经质"(更多小幅震动)。
def ema(prices, span):
return prices.ewm(span=span, adjust=False).mean()
# ewm = exponentially weighted moving (指数加权移动)
# span 对应公式中的 n,α = 2/(span+1)
3.3 RSI 相对强弱指数 (Relative Strength Index)
RSI 解决的问题:量化"最近一段时间,涨的力量和跌的力量哪个更强?"
计算步骤(以 14 天为例):
- 计算每天的涨跌:
delta = close.diff() - 上涨天的涨幅 (Gain):
delta > 0的部分 - 下跌天的跌幅 (Loss):
delta < 0的部分(取正值) - 用指数平均分别平滑 Gain 和 Loss:
avg_gain、avg_loss - 计算相对强弱 RS = avg_gain / avg_loss
- 转换:
RSI = 100 - 100 / (1 + RS)
结果范围:RSI 永远在 0 到 100 之间。
| RSI 值 | 解读 |
|---|---|
| > 70 | 超买 (Overbought):涨势过强,可能即将回调 |
| 50~70 | 偏强,多头占优 |
| 50 | 中性 (Neutral):多空势均力敌 |
| 30~50 | 偏弱,空头占优 |
| < 30 | 超卖 (Oversold):跌势过强,可能即将反弹 |
形象比喻:RSI 就像一个"疲劳度量表"。跑得太快(涨太猛)= 超买,该休息了;跌得太惨 = 超卖,该反弹了。
def rsi(prices, window=14):
delta = prices.diff()
gain = delta.clip(lower=0) # 只保留正值(涨的部分)
loss = -delta.clip(upper=0) # 只保留负值并取正(跌的部分)
avg_gain = gain.ewm(alpha=1.0/window, adjust=False).mean()
avg_loss = loss.ewm(alpha=1.0/window, adjust=False).mean()
rs = avg_gain / avg_loss # 相对强弱
return 100 - (100 / (1 + rs)) # 映射到 0~100
3.4 MACD 指数平滑异同移动平均线
MACD 解决的问题:用两条不同速度的 EMA 的"差距"来衡量趋势动能的变化。
三条线:
| 名称 | 计算 | 含义 |
|---|---|---|
| MACD 线 (DIF) | EMA(12) - EMA(26) | 快线(短期)减慢线(长期),反映近期动能 |
| 信号线 (DEA) | EMA(9) of MACD 线 | MACD 线的 9 日平均,平滑后的趋势 |
| 柱状图 (Histogram) | MACD 线 - 信号线 | 两线之差,放大了趋势变化 |
交叉信号:
| 信号 | 含义 |
|---|---|
| 金叉 (Golden Cross):MACD 线上穿信号线 | 买入信号,趋势转强 |
| 死叉 (Death Cross):MACD 线下穿信号线 | 卖出信号,趋势转弱 |
| 柱状图由负转正 | 多头动能开始占优 |
| 柱状图由正转负 | 空头动能开始占优 |
形象比喻:MACD 像赛跑中两个运动员的"领先差距"。快选手(短期均线)超过慢选手(长期均线)→ 金叉;被超过 → 死叉。
3.5 布林带 (Bollinger Bands)
布林带解决的问题:建立价格的"正常波动区间",判断当前价格是"正常"还是"过度偏离"。
三条线:
\text{中轨 (Middle Band)} = \text{SMA}(20)
\text{上轨 (Upper Band)} = \text{SMA}(20) + 2\sigma_{20}
\text{下轨 (Lower Band)} = \text{SMA}(20) - 2\sigma_{20}
其中 \sigma_{20} 是 20 日滚动标准差 (Rolling Standard Deviation)。
含义:在正态分布假设下,价格有 95% 的概率在上下轨之间运动。
| 价格位置 | 信号 |
|---|---|
| 触碰下轨 | 超卖区域,考虑买入 |
| 触碰上轨 | 超买区域,考虑卖出 |
| 带宽收窄 (Band Squeeze) | 波动率降低,预示即将有大行情 |
| 带宽突然扩大 | 大行情开始,追方向 |
4. 策略 A:双均线金叉/死叉 (MA Crossover)
4.1 策略逻辑
这是最经典的趋势跟随策略,逻辑非常直观:
短期均线(20日)代表"近期走势"
长期均线(60日)代表"长期趋势基准"
金叉(Golden Cross):
短期均线 从下方穿过 长期均线 → 近期走势开始强于长期 → 买入信号 🟢
死叉(Death Cross):
短期均线 从上方穿过 长期均线 → 近期走势开始弱于长期 → 卖出平仓信号 🔴
4.2 为什么用"均线上穿"而不是"价格本身"?
直接看价格太噪声(每天都有小涨小跌),用均线平滑后只关注真正的趋势转折。这是"降噪 (Noise Filtering)"的思想。
4.3 信号生成代码详解
# 计算两条均线
ma_short = sma(price, 20) # 短期均线(快线)
ma_long = sma(price, 60) # 长期均线(慢线)
# 原始信号:短线在长线上方为 1(看多),否则为 0
raw_signal = (ma_short > ma_long).astype(int)
# ⭐ 关键步骤:信号向后移动一天,避免前视偏差
# 今天收盘后判断方向,明天开盘才能交易
# 如果不 shift(1),等于"今天收盘价知道后立刻成交"——这在现实中做不到
ma_signal = raw_signal.shift(1).fillna(0)
为什么一定要 shift(1)?
假设均线在今天收盘后(16:00)产生了金叉信号。现实中,你看到这个信号后,最早也只能在明天的开盘(9:30)才能下单。如果不 shift,相当于"今天收盘价一出来就瞬间买入",这是不可能做到的,这叫未来函数 (Future Function) 或前视偏差 (Lookahead Bias)。
4.4 策略的适用条件与局限
✅ 适合:
- 有明显趋势的市场(牛市单边上涨,熊市单边下跌)
- 日线、周线级别的中长线交易
❌ 不适合:
- 震荡市(横盘整理):频繁金叉死叉,反复"买高卖低",交易成本侵蚀利润
- 高频交易:滞后性太大
5. 策略 B:RSI 均值回归 (RSI Mean Reversion)
5.1 策略逻辑
这是逆势策略 (Contrarian Strategy),核心思想:
"市场短期会过度反应,极端走势终将回归正常。"
"Markets overreact in the short term, and extreme moves will eventually revert."
RSI < 30(超卖):市场跌过头了 → 做多(买入),等反弹 🟢
RSI > 70(超买):市场涨过头了 → 做空(卖出),等回落 🔴
出场规则(Exit Rules):
多仓持有中,RSI 回升到 50 以上 → 平仓多头(涨回去了,获利了结)
空仓持有中,RSI 回落到 50 以下 → 平仓空头(跌回去了,获利了结)
5.2 均值回归的理论基础
均值回归 (Mean Reversion) 是统计学中的一个概念:当一个量偏离其长期均值过远时,有向均值靠拢的倾向。
在金融市场中表现为:
- 市场恐慌性下跌后,往往会有技术性反弹
- 过度追涨后,往往会有获利回吐
- 短期波动会均值回归,但长期趋势可能持续(这就是趋势策略存在的理由)
5.3 为什么 RSI 策略在本 Demo 中表现差?
看本 Demo 的回测结果:RSI 策略的夏普比率为负数,而 Buy & Hold 为正。
原因很简单:我们的模拟数据用的是 GBM,设定了 mu = 0.10(年化 10% 的正漂移)。这意味着数据有明显的上涨趋势。均值回归策略在趋势市中会频繁做空(RSI 超买),而市场偏偏持续上涨,造成亏损。
结论:没有"万能"策略。策略的有效性依赖市场环境:
- 趋势市 → 趋势策略赢
- 震荡市 → 均值回归策略赢
- 如何判断当前市场状态?这正是更高级的量化研究课题(策略择时、机制识别)
6. 向量化回测引擎 (Vectorized Backtest Engine)
6.1 什么是向量化?
向量化 (Vectorization) 指用 numpy/pandas 的数组运算一次性计算所有日期的结果,而不是用 Python for 循环逐日计算。
# 非向量化(慢)
results = []
for i in range(len(prices)):
r = signal[i] * daily_return[i] # 逐日计算
results.append(r)
# 向量化(快,pandas 内部是 C 语言实现)
strategy_returns = signal * daily_returns # 整个序列一次运算
速度差异:对于 1000 天的数据,向量化通常比 for 循环快 100-1000 倍。
6.2 回测核心逻辑
# 1. 每日收益率
daily_ret = prices.pct_change().fillna(0)
# 2. 策略每日收益率(持仓方向 × 市场收益率)
# signal = 1 时,策略收益 = 市场收益(同向)
# signal = 0 时,策略收益 = 0(空仓不参与)
# signal = -1 时,策略收益 = -市场收益(反向做空)
strat_ret_gross = signal * daily_ret
# 3. 扣除交易成本
position_change = signal.diff().abs() # 仓位变化量(换手)
cost = position_change * cost_per_trade # 每次换手扣除成本
# 4. 净收益率
strat_ret_net = strat_ret_gross - cost
# 5. 净值曲线(每日净收益率连乘)
equity = initial_capital * (1 + strat_ret_net).cumprod()
6.3 交易成本的重要性
成本模型 (Cost Model):
| 成本项 | 说明 | 典型值(A 股) |
|---|---|---|
| 佣金 (Commission) | 券商按交易金额收取 | 万分之三(0.03%)单边 |
| 印花税 (Stamp Duty) | A 股卖出时收取 | 万分之五(0.05%),仅卖出 |
| 滑点 (Slippage) | 信号价格与实际成交价的差 | 视流动性而定,通常 1-5 bp |
一个典型的坑:回测不计成本,结果漂亮,一上实盘就亏钱。
高频交易尤其明显:哪怕每次 0.1% 的成本,一天交易 10 次就是 1% 的消耗。
6.4 净值曲线 (Equity Curve) 的含义
初始资金 100万元
│ 每天乘以 (1 + 当天净收益率)
▼
...第 n 天的净值 = 100万 × (1 + r_1) × (1 + r_2) × ⋯ × (1 + r_n)
净值曲线是策略"假设从第一天以 100 万元开始运行"的账户价值随时间变化曲线。
7. 绩效指标详解 (Performance Metrics)
不能只看"总收益率"——一个策略可能靠运气在某段时间暴赚,但实际上风险极高。需要多维度评估。
7.1 总收益率 & 年化收益率 (CAGR)
总收益率 (Total Return):
\text{Total Return} = \frac{V_{end} - V_{start}}{V_{start}}
年化复合增长率 (CAGR, Compound Annual Growth Rate):
\text{CAGR} = \left(\frac{V_{end}}{V_{start}}\right)^{1/\text{years}} - 1
将总收益率折算成"每年平均增长多少",消除回测时间长短的影响,便于不同策略横向比较。
例子:5 年总收益 100%,CAGR = $(2)^{1/5} - 1 \approx 14.9%$(不是 100%/5 = 20%,因为有复利效应)
7.2 夏普比率 (Sharpe Ratio)
\text{Sharpe} = \frac{\text{年化收益率} - r_f}{\text{年化波动率}} = \frac{\bar{r} - r_f}{\sigma} \times \sqrt{252}
- $r_f$:无风险利率 (Risk-Free Rate),通常用国债利率,代码中简化为 0
- 含义:每承担 1 单位波动率,获得多少超额收益
| 夏普比率 | 评级 |
|---|---|
| < 0 | 不如存钱(还有风险) |
| 0 ~ 1 | 可接受,但不优秀 |
| 1 ~ 2 | 良好,值得关注 |
| > 2 | 优秀(或者有数据问题,需检查) |
| > 3 | 通常意味着回测存在 bug 或严重过拟合 |
局限:夏普比率假设收益率服从正态分布。如果有"小涨长期 + 偶尔大跌"的特征(如卖期权策略),夏普比率会虚高。
7.3 索提诺比率 (Sortino Ratio)
\text{Sortino} = \frac{\text{CAGR} - r_f}{\text{下行波动率 (Downside Std)}}
与夏普的区别:夏普把所有波动(涨和跌)都视为"风险";索提诺只把亏损日的波动视为风险(正向波动是好事,不应被惩罚)。
对于有正偏态(不对称上涨)的策略,索提诺比夏普更公平。
7.4 最大回撤 (Maximum Drawdown)
\text{Drawdown}(t) = \frac{V_t - \max_{s \leq t} V_s}{\max_{s \leq t} V_s}
\text{Max Drawdown} = \min_t \text{Drawdown}(t)
含义:从账户价值的历史最高点,最大跌了多少百分比。
为什么这是最重要的风险指标之一?
- 假设你的策略总收益 200%,但中间经历了 -70% 的最大回撤
- 你有没有能力扛过 -70% 而不放弃?(心理和资金层面)
- 如果你在最大回撤开始前一年进场,可能等了很多年才回本
经验规则:最大回撤超过 30% 的策略,很少有人能真实执行。
7.5 卡玛比率 (Calmar Ratio)
\text{Calmar} = \frac{\text{CAGR}}{|\text{Max Drawdown}|}
每承担 1 单位的最大回撤,获得多少年化收益。适合用于比较不同策略的"收益/最大损失"性价比。
7.6 胜率 & 盈亏比 (Win Rate & Profit Factor)
日胜率 (Daily Win Rate):有收益的交易日 / 总交易日
盈亏比 (Profit Factor):
\text{Profit Factor} = \frac{\text{总盈利金额}}{\text{总亏损金额(绝对值)}}
Profit Factor > 1 意味着策略是盈利的(赚的比亏的多)
一个重要的直觉:胜率和盈亏比是跷跷板关系。
| 策略类型 | 典型胜率 | 典型盈亏比 |
|---|---|---|
| 趋势跟随(如本 Demo 的 MA 策略) | 30%-40%(多次小亏) | > 2(偶尔大赚) |
| 均值回归(高频做市) | 60%-80%(频繁小赚) | < 1.5(偶尔大亏) |
8. 滚动前向验证与参数优化 (Walk-Forward Validation)
8.1 过拟合的危害
过拟合 (Overfitting) 是量化回测最大的陷阱:
在相同的历史数据上测试足够多的参数组合,总能找到一组让历史表现完美的参数。
但这些参数可能只是"碰巧"匹配了历史噪声,在未来数据上会失效。
例子:如果你测试了 1000 种均线参数组合,在同一段历史数据上,必然有几组看起来"完美",纯属随机巧合。这叫数据窥探偏差 (Data Snooping Bias) 或 p-hacking。
8.2 前向验证的正确做法
完整历史数据(1500天)
├─ 训练集 / In-Sample (80%,1200天)
│ 用于:网格搜索最优参数
│ 报告:训练集夏普(仅供参考)
│
└─ 测试集 / Out-of-Sample (20%,300天)
用于:用找到的"最优参数"在这段数据上跑一遍
报告:测试集夏普(这才是真正的绩效评估)
原则:这 300 天的数据在优化参数时绝对不能碰过!
夏普衰减 (Sharpe Decay):
通常,训练集夏普 > 测试集夏普。这是正常的,问题在于衰减多少:
- 训练集 2.0,测试集 1.5 → 轻微过拟合,可以接受
- 训练集 3.0,测试集 -0.5 → 严重过拟合,该策略不可用
8.3 网格搜索 (Grid Search)
for sw in [5, 10, 15, 20, 30]: # 短窗口候选值
for lw in [30, 40, 50, 60, 80, 100]: # 长窗口候选值
if sw >= lw:
continue # 逻辑约束:短窗口必须 < 长窗口
# 在训练集上运行回测,记录夏普
...
# 选出夏普最高的参数组合
# 再在测试集上验证
更严格的验证方法(代码未实现,但应了解):
滚动前向验证 (Rolling Walk-Forward):
[Train1] → [Test1]
[Train2] → [Test2]
[Train3] → [Test3]
...
汇报所有 Test 期的拼接结果
9. 收益率分布分析 (Return Distribution Analysis)
9.1 为什么要分析收益率分布?
夏普比率的计算假设收益率服从正态分布。如果分布严重偏离正态,夏普比率就不可靠。
9.2 偏度 (Skewness)
\text{Skewness} = \frac{\frac{1}{n}\sum(r_i - \bar{r})^3}{\sigma^3}
| 偏度值 | 含义 |
|---|---|
| 接近 0 | 左右对称(正态分布) |
| > 0 | 右偏(右尾长),有"意外大赚"的可能性 |
| < 0 | 左偏(左尾长),有"意外大亏"的可能性 ⚠️ |
金融数据的现实:大多数股票收益率分布是负偏态(崩盘比暴涨更极端)。
9.3 峰度 (Kurtosis / Excess Kurtosis)
- 正态分布的峰度 = 0(代码中 pandas 计算的是超额峰度)
- 金融收益率通常峰度 > 0(厚尾,Fat Tails)
含义:极端事件(±3σ 以外)发生的频率比正态分布预测的更高。这意味着基于正态分布计算的风险模型(如 VaR)会低估实际风险。
9.4 月度收益热力图 (Monthly Return Heatmap)
热力图直观展示每个月的盈亏情况:
- 🟢 绿色 → 盈利月份
- 🔴 红色 → 亏损月份
- 颜色越深 → 盈亏越大
用途:快速识别策略的"季节性"——某些策略在特定月份/季节表现特别好或特别差,这可能是利用了真实的市场规律,也可能是偶然的样本特征。
10. 术语速查表
| 中文 | English | 简要说明 |
|---|---|---|
| 技术分析 | Technical Analysis | 用历史价格/成交量预测未来走势 |
| 趋势跟随 | Trend Following | 顺势而为,买入上涨资产 |
| 均值回归 | Mean Reversion | 逆势操作,买入超跌资产 |
| 技术指标 | Technical Indicator | 从原始数据提炼交易信号的数学公式 |
| 简单移动平均线 | SMA (Simple Moving Average) | n 日收盘价的算术平均 |
| 指数移动平均线 | EMA (Exponential Moving Average) | 近期数据权重更高的加权平均 |
| 相对强弱指数 | RSI (Relative Strength Index) | 衡量涨跌动能的 0-100 震荡指标 |
| 超买 | Overbought | RSI > 70,涨势过强 |
| 超卖 | Oversold | RSI < 30,跌势过强 |
| 指数平滑异同移动平均 | MACD | 两条 EMA 之差,衡量趋势动能 |
| 布林带 | Bollinger Bands | 均线 ± 2 倍标准差的价格通道 |
| 带宽 | Band Width | 上轨与下轨之差,衡量波动率 |
| 金叉 | Golden Cross | 短线上穿长线,看涨信号 |
| 死叉 | Death Cross | 短线下穿长线,看跌信号 |
| 信号生成 | Signal Generation | 根据指标产生买卖指令的逻辑 |
| 前视偏差 | Lookahead Bias | 回测中使用了"当时无法知道"的未来数据 |
| 向量化回测 | Vectorized Backtest | 用数组运算一次性计算所有时间步 |
| 净值曲线 | Equity Curve | 账户价值随时间变化的曲线 |
| 无风险利率 | Risk-Free Rate | 国债等无风险资产的收益率 |
| 夏普比率 | Sharpe Ratio | 每单位总风险对应的超额收益 |
| 索提诺比率 | Sortino Ratio | 每单位下行风险对应的超额收益 |
| 最大回撤 | Maximum Drawdown (MDD) | 净值从峰值跌落的最大幅度 |
| 卡玛比率 | Calmar Ratio | CAGR 除以最大回撤 |
| 年化复合增长率 | CAGR | 考虑复利后的年均增长率 |
| 胜率 | Win Rate | 盈利次数 / 总次数 |
| 盈亏比 | Profit Factor | 总盈利 / 总亏损 |
| 过拟合 | Overfitting | 策略过度适配历史数据,泛化能力差 |
| 数据窥探偏差 | Data Snooping Bias | 在同一数据上测试太多参数导致的虚假优化 |
| 训练集 | In-Sample (IS) | 用于优化参数的历史数据段 |
| 测试集 | Out-of-Sample (OOS) | 用于验证的未见过的历史数据段 |
| 滚动前向验证 | Walk-Forward Validation | 用过去优化参数,在紧接着的未来上验证 |
| 网格搜索 | Grid Search | 枚举所有参数组合的暴力搜索法 |
| 正态分布 | Normal Distribution | 均值两侧对称的钟形分布 |
| 厚尾 | Fat Tails (Leptokurtosis) | 极端事件频率高于正态分布预测 |
| 偏度 | Skewness | 分布的左右不对称程度 |
| 峰度 | Kurtosis | 分布尾部的厚度(与正态分布对比) |
| 几何布朗运动 | GBM (Geometric Brownian Motion) | 描述股价随机游走的经典数学模型 |
| 年化波动率 | Annualized Volatility | 日波动率 × √252 |
| 滑点 | Slippage | 信号价格与实际成交价的差 |
| 佣金 | Commission | 券商收取的交易手续费 |