# MACD金叉死叉回测程序 - 操作手册[淘股吧]

## 一、程序功能简介

本程序用于验证 MACD 金叉/死叉信号在A股市场的实际表现:
- 读取所有A股日线数据,计算 MACD 指标
- 识别金叉(买入信号)和死叉(卖出信号)
- 统计信号出现后,持有 1/2/3/5/10/20 天的平均收益率
- 按申万一级行业分组统计,对比不同行业的效果
- 计算相对沪深300指数的超额收益
- 将所有结果输出为格式化的 Excel 文件

---

## 二、环境准备

### 2.1 安装 Python

需要 Python 3.8 或以上版本。如果还没安装:

1. 百度搜索Python,进入官网
2. 下载最新版 Python
3. 安装时 **务必勾选 Add Python to PATH **

安装完成后,打开命令提示符(Win+R 输入 cmd),输入以下命令验证:

```
python --version
```

能看到版本号(如 Python 3.12.x)即安装成功。

### 2.2 安装依赖库

打开命令提示符,输入以下命令(一行一行执行):

```
pip install pandas numpy numba openpyxl
```

四个库的用途:
| 库名 | 用途 |
|------|------|
| pandas | 数据处理(表格操作) |
| numpy | 数值计算 |
| numba | 代码加速 |
| openpyxl | Excel文件读写 |

---

## 三、数据准备

### 3.1 文件夹结构

准备一个文件夹,里面放入所有股票的 CSV 文件。结构如下:

```
你的数据文件夹/
├── sh600000.csv (浦发银行)
├── sh600001.csv (邯郸钢铁
├── sz000001.csv (平安银行
├── sz000002.csv (万科A)
├── ...
└── sh000300.csv (沪深300指数,也可放在其他位置)
```

### 3.2 股票 CSV 格式要求

- **编码**:GBK
- **第一行**:说明文字(程序会自动跳过)
- **第二行**:列名(表头)
- **必须包含的列**:

| 列名 | 说明 | 示例 |
|------|------|------|
| 股票代码 | 6位代码带市场前缀 | sh 600000 |
| 股票名称 | 股票名称 | 浦发银行 |
| 交易日期 | 日期 | 2000-01-04 |
| 开盘价 | 当日开盘价 | 27.00 |
| 最高价 | 当日最高价 | 27.88 |
| 最低价 | 当日最低价 | 26.80 |
| 收盘价 | 当日收盘价 | 27.75 |
| 前收盘价 | 前一交易日收盘价 | 27.00 |
| 成交量 | 当日成交量 | 1000000 |
| 新版申万一级行业名称 | 行业分类 | 银行 |

### 3.3 指数 CSV 格式要求

沪深300指数文件(如 sh000300.csv)的格式:
- **编码**:GBK
- **列名**(英文):

| 列名 | 说明 |
|------|------|
| candle_end_time | 交易日期 |
| open | 开盘价 |
| high | 最高价 |
| low | 最低价 |
| close | 收盘价 |
| amount | 成交额 |
| volume | 成交量 |
| index_code | 指数代码 |

---

## 四、配置与运行

### 4.1 修改配置

打开 `macd_backtest.py`(或 `macd_backtest_注释版.py`),找到文件顶部的配置区域,修改三个路径:

```python
# ============== 用户配置(请修改为本地路径) ==============
# 1. 股票数据文件夹路径(改为你自己的)
file_path = r‘D:\你的路径\股票数据文件夹/‘

# 2. 沪深300指数文件路径(改为你自己的)
index_path = r‘C:\你的路径\sh000300.csv‘

# 3. 结果输出路径(改为你自己的)
output_path = r‘C:\你的路径\输出文件夹/‘
```

**注意事项:**
- 路径用英文引号包裹,前面加 `r`(如 `r‘D:\data\‘`),避免反斜杠被转义
- 路径最后要有 `/` 或 `\`
- 路径中不要有中文空格等特殊字符
- 输出文件夹必须提前创建好

### 4.2 可选参数修改

如果需要调整分析范围,可以修改以下参数:

```python
# 交易成本(一般不需要改)
c_rate = 1.5 / 10000 # 佣金费率:万分之一点五
t_rate = 1 / 1000 # 印花税率:千分之一

# 持有天数(可以自己增减)
day_list = [1, 2, 3, 5, 10, 20]

# 测试时间段
start_time = ‘20070101‘ # 开始日期
end_time = ‘20261231‘ # 结束日期
```

### 4.3 运行程序

打开命令提示符,cd 到代码所在目录,运行:

```
cd C:\你的路径\
python macd_backtest.py
```

或者直接双击 `macd_backtest.py` 文件(前提是 Python 已关联 .py 后缀)。

### 4.4 运行过程

程序运行后会显示进度信息:

```
共发现 5511 个文件
测试时间段: 20070101 - 20261231
==================================================
已处理 100/5511 个文件
已处理 200/5511 个文件
...
已处理 5500/5511 个文件

成功处理 4900 个股票文件
总共有 350000 条信号记录

正在按行业分析MACD信号...
正在分析总体MACD信号...

结果已保存到: C:\你的路径\基础金叉死叉.xlsx

==================================================
分析完成!
共分析 31 个行业
看涨信号样本数: 175000
看跌信号样本数: 175000
```

**说明:**
- 成功处理 4900 个 意味着有 4900 只股票产生了有效信号
- 部分股票可能因为数据格式不符、上市时间太短、没有行业分类等原因被跳过,属于正常现象
- 首次运行时,numba 的 JIT 编译会需要一些时间(会自动缓存,之后运行更快)

---

## 五、结果文件说明

运行完成后,会在输出路径下生成 `基础金叉死叉.xlsx` 文件。

### 5.1 Excel 中的 Sheet

| Sheet名 | 内容 |
|---------|------|
| 汇总 | 所有行业的完整数据,底部附有总体分析结果 |
| 各行业名 | 每个申万一级行业的独立统计 |
| 看涨信号汇总 | 所有行业的金叉信号统计 |
| 看跌信号汇总 | 所有行业的死叉信号统计 |
| 总体分析 | 不分行业的整体统计 |

### 5.2 各列含义

| 列名 | 含义 | 怎么看 |
|------|------|--------|
| 行业名称 | 申万一级行业分类 | 如 银行 、 电子 等 |
| 信号类型 | 金叉或死叉 | 金叉=看涨信号,死叉=看跌信号 |
| 持有天数 | 信号后持有多少天 | 1=第二天开盘买入第三天卖出 |
| 上涨概率 | 信号后上涨的比例 | 金叉看这个值,越高越好 |
| 下跌概率 | 信号后下跌的比例 | 死叉看这个值,越高越好 |
| 平均上涨收益 | 盈利交易的平均盈利幅度 | 正数,如 2% 表示平均赚 2% |
| 平均下跌收益 | 亏损交易的平均亏损幅度 | 负数,如 -2% 表示平均亏 2% |
| 每笔平均收益 | 所有交易的平均收益 | 正=赚钱策略,负=亏钱策略 |
| 超额收益 | 相比沪深300多赚的部分 | 正=跑赢大盘,负=跑输大盘 |
| 样本数量 | 参与统计的信号总数 | 样本越多,统计越可靠 |

### 5.3 如何判断信号是否有用

看金叉(看涨信号)的结果:
1. **上涨概率 > 50%**:说明金叉后涨的概率比跌的概率大,信号有一定预测力
2. **每笔平均收益 > 0**:说明按金叉信号交易整体是赚钱的
3. **超额收益 > 0**:说明不是 牛市里随便买都涨 ,而是信号本身有Alpha
4. **上涨概率和平均收益不能只看一个**:如果上涨概率55%但平均每次赚0.1%亏1%,整体还是亏

看死叉(看跌信号)的结果:
1. **下跌概率 > 50%**:说明死叉后跌的概率更大
2. **每笔平均收益 < 0**:说明死叉后持有确实会亏钱
3. **超额收益 < 0**:说明跑输大盘

---

## 六、常见问题

### Q1: 运行报错 No module named ‘xxx‘
**原因**:缺少依赖库。
**解决**:执行 `pip install xxx` 安装对应的库。

### Q2: 运行报错 FileNotFoundError
**原因**:路径配置错误,程序找不到数据文件。
**解决**:检查 `file_path` 和 `index_path` 是否正确,注意斜杠方向和盘符。

### Q3: 运行报错 UnicodeDecodeError
**原因**:CSV文件编码不是GBK。
**解决**:检查文件编码,或用记事本打开CSV后 另存为 选择GBK编码。

### Q4: 没有有效的股票数据
**原因**:所有股票都被过滤掉了。
**解决**:检查CSV格式是否正确,特别是列名是否包含 `新版申万一级行业名称`。

### Q5: 首次运行特别慢
**原因**:numba 首次运行需要编译加速函数。
**解决**:等待编译完成即可,后续运行会快很多(编译结果会被缓存)。

### Q6: 能否修改MACD参数?
**可以**。在 `cal_macd` 函数中找到以下代码,修改数字即可:
```python
ema12 = fast_ewma(close_array, 12) # 12改为其他数字,如 5
ema26 = fast_ewma(close_array, 26) # 26改为其他数字,如 34
dea = fast_ewma(dif, 9) # 9改为其他数字,如 5
```
常用参数组合:
- 默认(12,26,9):最通用
- 短线(5,34,5):更灵敏,信号更多但假信号也多
- 长线(19,39,9):更稳定,信号少但更可靠

### Q7: 结果中有很多行业,怎么快速找到最有效的?
在 看涨信号汇总 sheet中,按 每笔平均收益 列降序排列,就能看到哪些行业的金叉信号最赚钱。Excel操作:选中表头 -> 数据 -> 排序 -> 按该列降序。