# 量化策略开发与向量化回测详解
## `quant_strategy_backtest_demo.py` 学习文档

> **目标读者**：零基础量化入门者  
> **配套文件**：`quant_strategy_backtest_demo.py`  
> **前置知识**：建议先阅读 `doc_01_data_pipeline.md`  
> **系列位置**：第 2 篇 — 策略开发与回测篇

---

## 目录

1. [本篇概览](#1-本篇概览)
2. [合成价格数据：几何布朗运动](#2-合成价格数据几何布朗运动-geometric-brownian-motion)
3. [技术指标详解](#3-技术指标详解-technical-indicators)
   - [3.1 SMA 简单移动平均线](#31-sma-简单移动平均线-simple-moving-average)
   - [3.2 EMA 指数移动平均线](#32-ema-指数移动平均线-exponential-moving-average)
   - [3.3 RSI 相对强弱指数](#33-rsi-相对强弱指数-relative-strength-index)
   - [3.4 MACD 指数平滑异同移动平均线](#34-macd-指数平滑异同移动平均线)
   - [3.5 布林带 Bollinger Bands](#35-布林带-bollinger-bands)
4. [策略 A：双均线金叉/死叉](#4-策略-a双均线金叉死叉-ma-crossover)
5. [策略 B：RSI 均值回归](#5-策略-brsi-均值回归-rsi-mean-reversion)
6. [向量化回测引擎](#6-向量化回测引擎-vectorized-backtest-engine)
7. [绩效指标详解](#7-绩效指标详解-performance-metrics)
8. [滚动前向验证与参数优化](#8-滚动前向验证与参数优化-walk-forward-validation)
9. [收益率分布分析](#9-收益率分布分析-return-distribution-analysis)
10. [术语速查表](#10-术语速查表)

---

## 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)$：每天的随机冲击，从标准正态分布中随机抽取

**直觉**：每天的价格变化 = 确定性漂移（趋势）+ 随机波动（噪声）

```python
# 代码中的实现
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) | 区分牛熊市的重要参考线 |

**代码**：

```python
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 对最近的价格变化反应更快，但也更"神经质"（更多小幅震动）。

```python
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 天为例）：

1. 计算每天的涨跌：`delta = close.diff()`
2. 上涨天的涨幅 (Gain)：`delta > 0` 的部分
3. 下跌天的跌幅 (Loss)：`delta < 0` 的部分（取正值）
4. 用指数平均分别平滑 Gain 和 Loss：`avg_gain`、`avg_loss`
5. 计算相对强弱 RS = avg_gain / avg_loss
6. 转换：`RSI = 100 - 100 / (1 + RS)`

**结果范围**：RSI 永远在 0 到 100 之间。

| RSI 值 | 解读 |
|--------|------|
| > 70 | **超买 (Overbought)**：涨势过强，可能即将回调 |
| 50~70 | 偏强，多头占优 |
| 50 | **中性 (Neutral)**：多空势均力敌 |
| 30~50 | 偏弱，空头占优 |
| < 30 | **超卖 (Oversold)**：跌势过强，可能即将反弹 |

**形象比喻**：RSI 就像一个"疲劳度量表"。跑得太快（涨太猛）= 超买，该休息了；跌得太惨 = 超卖，该反弹了。

```python
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 信号生成代码详解

```python
# 计算两条均线
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` 循环逐日计算。

```python
# 非向量化（慢）
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 回测核心逻辑

```python
# 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)

```python
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 | 券商收取的交易手续费 |

---

*上一篇：[数据管道](doc_01_data_pipeline.md)*  
*下一篇：[事件驱动回测引擎](doc_03_event_driven_backtest.md)*
