# stock_zt_backtest **Repository Path**: Gandi_95/stock_zt_backtest ## Basic Information - **Project Name**: stock_zt_backtest - **Description**: No description available - **Primary Language**: Python - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2026-04-28 - **Last Updated**: 2026-04-30 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # 涨停股票回测分析程序 基于 Python 的 A 股涨停股票回测分析工具,通过识别实体涨停板并结合震荡幅度、价格重心、上攻空间等多维度条件判断买入信号,统计买入后不同周期的收益表现。 ## 功能特性 - **数据获取**:通过 REST API 获取涨停数据、日线数据和交易日历,支持批量接口(30只股票/批)+ 数据缓存机制 - **涨停板识别**:识别涨幅 ≥9.5% 的实体涨停板,排除开盘即涨停的"一字板" - **时间窗口范围遍历**:支持设定观察天数范围(如4~7天),自动遍历每个N值寻找最优买入信号 - **自定义规则判断**: - 震荡幅度:涨停后 N 天内股价波动不超过 8.0% - 价格重心:当前最低价高于涨停当日最低价 - 上攻空间:当前最高价不超过涨停最高价的 8% - 买入信号:收盘价在涨停开盘价附近(可通过 buy_signal_pct 调整区间,支持在开盘价上下浮动) - **涨幅统计**:买入后 1/3/5/10 天的最大涨幅和最大收盘涨幅 - **结果输出**:控制台格式化展示 + CSV 文件导出 - **今日扫描**:支持扫描最近20个交易日涨停股票,实时获取今日买入信号 - **GUI 界面**:专业级股票分析 GUI,含 K 线图可视化、结果表格、交互式操作 - **参数优化**:支持按市值分组(小盘/中盘/大盘/超大盘)独立优化,含参数敏感性分析和完整性能指标(年化收益率、最大回撤、夏普比率) ## 环境要求 - Python 3.10+ - requests 库 - PyQt5 - matplotlib - mplfinance - pandas - numpy ## 前置条件 本程序依赖 StockData 数据服务提供的 API。使用前请确保 StockData 服务已启动: ```bash # 在 StockData 项目目录下启动 API 服务 cd D:\TraeProjects\StockData python main.py serve ``` 服务默认运行在 `http://127.0.0.1:8000`(使用 127.0.0.1 避免 IPv6 解析延迟问题)。 ## 使用方法 ### 方式一:回测分析 GUI(推荐) ```bash python gui_main.py ``` 启动后界面包含三个区域: - **左侧参数面板**:设置日期范围、观察天数范围(最小天/最大天)、幅度阈值等参数,支持"扫描今日买入"和"开始回测分析"两种模式 - **右上结果表格**:展示所有买入信号,支持筛选、排序、导出 CSV,双击行可查看 K 线 - **右下 K 线图**:专业金融 K 线图(finplot),含 5/10/20/30 日均线,支持缩放、拖拽、周期切换、指标切换 GUI 操作说明: - **扫描今日买入**:点击橙色按钮扫描最近20个交易日涨停股票,获取今日买入信号(使用实时数据) - **开始回测分析**:点击绿色按钮进行历史数据回测分析 - 在筛选框输入股票代码或名称可实时过滤结果 - 双击表格行或右键选择"查看K线图"可加载对应股票 - 鼠标滚轮缩放 K 线图,左键拖拽左右平移 - 周期下拉框切换日线/周线 - 点击"导出CSV"按钮保存结果 ### 方式二:模拟交易 GUI ```bash python trade_main.py ``` 模拟交易系统提供完整的模拟买卖流程,暗色主题界面,包含以下功能: - **账户概览**:实时显示总资产、可用资金、持仓市值、总盈亏、胜率 - **今日信号**:自动获取买入信号,勾选后确认买入(含二次确认) - **当前持仓**:显示持仓详情、盈亏、卖出倒计时,支持手动卖出 - **交易记录**:完整买卖历史,支持导出 CSV - **资产曲线**:matplotlib 绘制总资产和收益率走势图 - **自动运行**:开启后每个交易日 14:50 自动获取信号并执行卖出 - **自动卖出**:持仓满 3 个交易日后自动卖出(可关闭) - **数据持久化**:账户数据自动保存到 `output/trade/account.json` 交易规则: - 起始资金 100,000 元 - 买入数量为 100 股的整数倍 - 手续费 0.03%(最低 5 元),卖出印花税 0.1% - 持仓满 3 个交易日后自动卖出 ### 方式三:命令行模式 ```bash # 回测模式 python main.py --start-date 20260401 --end-date 20260423 # 今日扫描模式(使用优化后的默认参数,自动导出到 output/scan/YYYYMMDD.csv) python main.py --scan-today ``` ### 命令行参数 | 参数 | 说明 | 默认值 | 适用模式 | | ------------------------ | ---------------------- | -------------------------- | -------- | | `--start-date` | 回测起始日期 (YYYYMMDD) | 必填(回测模式) | 回测 | | `--end-date` | 回测结束日期 (YYYYMMDD) | 必填(回测模式) | 回测 | | `--scan-today` | 启用今日扫描模式 | 不启用 | 扫描 | | `--lookback-days` | 扫描回溯交易日数 | 20 | 扫描 | | `--oscillation-days-min` | 观察天数范围下限 | 4 | 通用 | | `--oscillation-days-max` | 观察天数范围上限 | 7 | 通用 | | `--max-oscillation` | 最大震荡幅度百分比 | 8.0 | 通用 | | `--max-attack` | 最大上攻空间百分比 | 8 | 通用 | | `--buy-signal-pct` | 买入信号接近涨停开盘价百分比 | 2 | 通用 | | `--min-limit-up-pct` | 最小涨停涨幅百分比 | 9.5 | 通用 | | `--api-url` | 数据 API 地址 | http://127.0.0.1:8000 | 通用 | | `--export-csv` | 导出 CSV 文件路径 | scan模式默认 output/scan/YYYYMMDD.csv | 通用 | | `--show-failed` | 显示未触发买入信号的记录 | 不显示 | 扫描 | ### 命令行使用示例 ```bash # 基本回测 python main.py --start-date 20260401 --end-date 20260423 # 今日扫描模式(扫描最近20个交易日,获取今日买入信号) python main.py --scan-today # 今日扫描 + 自定义策略参数(覆盖新默认值) python main.py --scan-today --oscillation-days-min 3 --oscillation-days-max 10 --max-oscillation 15.0 --max-attack 10.0 --buy-signal-pct 1.5 --min-limit-up-pct 9.32 # 今日扫描并导出结果 python main.py --scan-today --export-csv today_signals.csv # 自定义观察天数范围 5~8 天,最大震荡幅度 12% python main.py --start-date 20260401 --end-date 20260423 --oscillation-days-min 5 --oscillation-days-max 8 --max-oscillation 12 # 自定义上攻空间和买入信号阈值 python main.py --start-date 20260401 --end-date 20260423 --max-attack 6 --buy-signal-pct 1.5 # 导出 CSV 结果 python main.py --start-date 20260401 --end-date 20260423 --export-csv output/result.csv # 指定远程 API 地址 python main.py --start-date 20260401 --end-date 20260423 --api-url http://192.168.1.100:8000 # 完整参数组合(使用优化默认值) python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 8.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 \ --export-csv output/backtest_202604.csv ``` ## 输出结果 ### GUI 界面输出 - **回测模式**:结果表格展示买入信号列表,含股票代码、名称、涨停日期、买入价格、各周期涨幅 - **扫描模式**:结果表格展示扫描结果,含股票代码、名称、涨停日期、涨停开盘价、买入日期、买入价格、窗口N、涨停后天数、信号状态 - K 线图:专业金融 K 线(finplot)+ 均线(MA5/MA10/MA20/MA30)+ 成交量柱状图 - 支持筛选排序、右键菜单、CSV 导出 ### 命令行输出 程序运行后会在控制台展示: - 买入信号列表(股票代码、名称、涨跌停日期、买入日期、买入价格) - 条件判断结果(震荡幅度、价格重心、上攻空间是否通过) - 各周期涨幅统计(最大涨幅、最大收盘涨幅) - 未触发买入信号的记录及原因(使用 --show-failed 参数) - 汇总统计(平均涨幅、胜率) ### CSV 导出 使用 `--export-csv` 参数或将 GUI 表格导出为 CSV 文件,包含以下列: **回测模式:** ``` 股票代码, 名称, 涨停日期, 涨停开盘价, 涨停最高价, 涨停最低价, 震荡幅度, 价格重心, 上攻空间, 时间窗口N, 买入信号, 买入日期, 买入价格, 1天最大涨幅(%), 1天最大收盘涨幅(%), 1天实际天数, 3天最大涨幅(%), 3天最大收盘涨幅(%), 3天实际天数, 5天最大涨幅(%), 5天最大收盘涨幅(%), 5天实际天数, 10天最大涨幅(%), 10天最大收盘涨幅(%), 10天实际天数 ``` **扫描模式:** ``` 股票代码, 名称, 涨停日期, 涨停开盘价, 买入日期, 买入价格, 窗口N, 涨停后天数, 信号状态 ``` ## 项目结构 ``` stock_zt_backtest/ ├── config.py # 配置模块(所有可调参数、批量大小、缓存开关) ├── data_fetcher.py # 数据获取模块(对接API服务、批量接口、重试机制) ├── data_cache.py # 数据缓存模块(线程安全缓存、命中统计) ├── today_scanner.py # 今日扫描模块(实时数据获取、买入信号检测) ├── limit_up_detector.py # 涨停板识别模块 ├── signal_analyzer.py # 信号分析模块(4大判断规则) ├── gain_calculator.py # 涨幅计算模块 ├── market_cap.py # 市值计算与分类模块 ├── result_formatter.py # 结果输出模块(控制台+CSV) ├── kline_widget.py # K线图组件(finplot+交互) ├── kline_window.py # K线图窗口(独立窗口、信号标注、周期切换) ├── result_table.py # 结果表格组件(排序/筛选/导出/双模式支持) ├── param_panel.py # 参数配置面板(双按钮布局) ├── main_window.py # GUI主窗口(布局/信号连接/双Worker支持) ├── param_optimizer.py # 参数优化脚本(全市场+市值分组两阶段搜索) ├── report_generator.py # 优化报告生成器(JSON + PDF + 分段报告) ├── account_manager.py # 账户管理模块(资金/持仓/交易记录/持久化) ├── trade_engine.py # 交易引擎(信号获取/买入/卖出/价格查询) ├── trade_scheduler.py # 交易调度器(交易日历/14:50定时触发) ├── trade_gui.py # 模拟交易GUI(暗色主题/持仓/信号/资产曲线) ├── main.py # 命令行入口(回测+扫描双模式) ├── gui_main.py # 回测分析GUI入口 ├── trade_main.py # 模拟交易GUI入口 └── README.md # 使用说明 ``` ## API 接口说明 ### 日线数据接口 本程序使用批量日线数据接口获取多只股票数据: ``` GET /api/daily?ts_codes=000001.SZ%2C600036.SH&start_date=20260423&end_date=20260428&include_realtime_data=true ``` **参数说明:** - `ts_codes`:股票代码列表,多个股票用英文逗号分隔(最多30只/批) - `start_date`:开始日期(YYYYMMDD格式) - `end_date`:结束日期(YYYYMMDD格式) - `include_realtime_data`:是否获取当天实时数据(仅扫描模式使用) **错误处理:** - 单次请求最多30只股票,程序自动分批次处理 - 支持重试机制(默认3次),处理超时、限流(429)等异常 - 批量请求失败时自动降级为单只请求 ### 涨停数据接口 程序根据查询日期范围自动选择接口: ``` # start_date ≥ 20260325 使用标准接口(仅支持最近一个月数据) GET /api/limit_up?start_date=20260401&end_date=20260428 # start_date < 20260325 使用历史接口(支持任意历史时间范围) GET /api/limit_up_simple?start_date=20260101&end_date=20260428 ``` **接口选择规则:** | start_date 范围 | 使用接口 | 适用场景 | |----------------|---------|---------| | ≥ 20260325 | `/api/limit_up` | 今日扫描、近期回测 | | < 20260325 | `/api/limit_up_simple` | 历史回测(跨月、跨季) | 两个接口返回的数据格式由 `data_fetcher.py` 自动归一化为统一的扁平列表结构 `[{trade_date, code, name, ...}]`,上层调用方无需感知差异。 ## 判断规则说明 系统通过在设定的时间窗口范围 `[N_min, N_max]` 内遍历每个 N 值,寻找符合条件的买入信号。遍历顺序从 `N_min` 到 `N_max`,一旦某个 N 值满足所有规则并产生买入信号,立即返回该结果(优先取最小 N,越早发现买入机会越好)。 ### 1. 震荡幅度判断规则 在股票出现涨停板之后的连续 N 天时间窗口内,计算该时间段内股票价格的整体波动幅度。具体计算方式为:(N 天内最高价 - N 天内最低价) / 涨停板当天收盘价 × 100%。该波动幅度必须严格控制在预设阈值范围内,系统默认阈值为 8%,允许根据实际需求进行参数调整。 ### 2. 价格重心判断规则 在涨停板之后的 N 天时间窗口内,需满足每日最低价持续高于涨停板当天最低价的条件。该规则确保股价在涨停之后维持上升趋势,未出现实质性回调,价格重心保持上移态势。 ### 3. 上攻空间判断规则 在涨停板之后的 N 天时间窗口内,每日最高价不得超过涨停板当天最高价的 (1 + 阈值%) 倍。此规则用于限制短期过度追高,确保股价在合理区间内运行,避免出现异常波动。 ### 4. 买入信号判断规则 买入信号区间的语义与 `buy_signal_pct` 参数的取值有关: **当 `buy_signal_pct >= 0`(默认行为):** - 买入区间:`[lu_open, lu_open × (1 + buy_signal_pct / 100)]` - 含义:收盘价不低于涨停开盘价,且不高于开盘价的 `(1 + pct%)` 倍 **当 `buy_signal_pct < 0`(扩展支持):** - 买入区间:`[lu_open × (1 + buy_signal_pct / 100), lu_open]` - 含义:允许在涨停开盘价**下方**买入,区间宽度为 `|buy_signal_pct|%,适合在价格回调时买入` 例如:`buy_signal_pct = -2.0` 时,区间为 `[lu_open×0.98, lu_open]`,即在开盘价下方2%以内买入。 需特别注意: - **不跌破要求**:收盘价必须在买入区间内 - **买入信号时间要求**:买入信号的出现时间点必须在第 N 天及之后(包含第 N 天当日) - 从基准时间点(涨停日)开始计算,经过 N 天周期后(包含第 N 天当日),买入信号的出现才被视为符合规则要求 - 买入信号以该条件第一次出现的交易日作为有效买入点,后续再次出现相同条件时不再重复标记 ### 关键参数说明 - **时间窗口范围**:`oscillation_days_min` 和 `oscillation_days_max` 分别表示观察天数范围的下限和上限(默认 4~7 天),系统在此范围内遍历每一个 N 值进行判断 - **阈值参数**:包括震荡幅度阈值和上攻空间阈值,支持根据市场环境和个股特性进行自定义调整 - **结果输出**:每条买入信号记录实际使用的 `window_n` 值,标明是哪个 N 值触发的买入信号
## 参数优化指南 ### 优化报告说明 程序提供了 `param_optimizer.py` 参数优化脚本,支持全市场优化和按市值分组独立优化,输出完整的性能指标和敏感性分析。 ```bash python param_optimizer.py ``` 优化流程包含三个层次: 1. **全市场优化** — 不区分市值,整体参数搜索 2. **市值分组优化** — 按市值分组(小盘/中盘/大盘/超大盘)独立执行阶段一+阶段二优化 3. **参数敏感性分析** — 评估每个参数对策略表现的影响程度 ### 市值分组定义 | 分组 | 总市值范围 | 说明 | |------|-----------|------| | 小盘股 (small_cap) | < 50亿 | 高弹性,高波动 | | 中盘股 (mid_cap) | 50~200亿 | 平衡型,兼顾成长与稳定性 | | 大盘股 (large_cap) | 200~1000亿 | 稳健型,流动性好 | | 超大盘股 (mega_cap) | > 1000亿 | 超大型蓝筹,波动最小 | ### 优化输出文件 运行后生成以下文件(保存在 `output/param_optimization/` 目录): | 文件 | 内容 | |------|------| | `all_results_*.csv` | 所有参数组合的详细结果(含市值分组标识) | | `report_*.txt` | 全市场优化文本报告 | | `segment_report_*.txt` | **市值分组优化报告**(含最优参数、性能指标、敏感性分析、横向对比) | | `report_*.json` | 结构化JSON报告(含分段优化数据) | | `report_*.pdf` | 可视化PDF报告(含市值分组性能对比图表) | ### 全年回测优化结果(20250401 ~ 20260408) 基准参数回测结果: - 总记录: 9136 条涨停记录 - 买入信号: 228 个 - 1天胜率: 48.7% | 3天胜率: 64.9% | 5天胜率: 69.3% | 10天胜率: 75.7% #### 各周期最优参数 | 时间周期 | 最优胜率 | 最优参数组合 | 买入信号数 | |---------|---------|-------------|-----------| | 1天 | 58.3% | osc_min=4, osc_max=9, max_osc=8.0, max_atk=6.0, buy_pct=1.5 | 72 | | 3天 | 80.4% | osc_min=4, osc_max=7, max_osc=8.0, max_atk=8.0, buy_pct=2.0 | 51 | | 5天 | 80.5% | osc_min=4, osc_max=9, max_osc=8.0, max_atk=10.0, buy_pct=2.0 | 113 | | 10天 | 84.3% | osc_min=4, osc_max=9, max_osc=8.0, max_atk=10.0, buy_pct=2.0 | 113 | #### 综合最优参数(推荐) 综合得分公式: `0.3*1D胜率 + 0.25*3D胜率 + 0.25*5D胜率 + 0.2*10D胜率` **Top 3 综合最优参数:** ``` #1 综合得分: 73.97 python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 8.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 信号: 112 | 1D胜率:58.0% | 3D胜率:78.6% | 5D胜率:80.4% | 10D胜率:84.1% #2 综合得分: 73.93 python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 10.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 信号: 113 | 1D胜率:57.5% | 3D胜率:78.8% | 5D胜率:80.5% | 10D胜率:84.3% #3 综合得分: 73.75 python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 6.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 信号: 109 | 1D胜率:57.8% | 3D胜率:78.9% | 5D胜率:79.8% | 10D胜率:83.7% ``` ### 市值分组优化结果解读 分段报告 (`segment_report_*.txt`) 包含三个主要章节: **一、各市值分组最优参数汇总** 每个分组独立执行阶段一(单参数扫描)和阶段二(网格搜索),输出该市值分组的最优参数组合及以下性能指标: - 年化收益率(Annualized Return) - 最大回撤(Max Drawdown) - 夏普比率(Sharpe Ratio) - 总收益率 - 各周期(1/3/5/10天)胜率及平均涨幅 **二、参数敏感性分析** 对每个分组内的核心参数(不含市值过滤参数),评估其变动对5天胜率和信号数量的影响,输出: - 各参数基准值和基准胜率 - 参数最大敏感度(对5D胜率的最大影响百分比) - 前3个最敏感的参数变动方向(值、变动幅度、对胜率和信号量的影响) **三、市值分组横向对比** 以表格形式横向对比四个分组的:年化收益、最大回撤、夏普比率、各周期胜率、总信号数。 ### 关键发现 1. **最优时间窗口**: `oscillation_days_min=4` 普遍优于 `oscillation_days_min=3`,表明涨停后第4天开始观察效果更好 2. **最优震荡幅度**: `max_oscillation=8.0` 已作为新默认值,更严格的波动控制有助于筛选优质标的 3. **最优上攻空间**: `max_attack=8.0~10.0` 效果较好,允许一定上攻空间可捕捉更多机会 4. **最优买入信号阈值**: `buy_signal_pct=2.0` 优于 `buy_signal_pct=1.5`,信号范围略宽可增加样本量而不显著降低胜率 5. **buy_signal_pct 扩展范围**: 支持 `-2.0` 到 `5.0`,负值允许在开盘价下方买入,为价格回调策略提供参数空间 6. **市值分组差异**: 不同市值规模的股票最优参数存在差异,超大盘股(>1000亿)因样本较少可能无法满足最小样本量要求而被跳过 ### 历史数据查询说明 使用 `limit_up_simple` 接口查询历史数据时,需设置 `limit=20000` 以获取完整数据: ``` GET /api/limit_up_simple?start_date=20250401&end_date=20260408&limit=20000 ``` 默认 limit=1000 只会返回最近1000条记录,无法满足跨月或跨季度查询需求。 ### 推荐回测命令 ```bash # 综合最优参数(推荐) python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 8.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 \ --export-csv output/optimal_backtest.csv # 追求10天胜率(长期持有) python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 9 \ --max-oscillation 8.0 --max-attack 10.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 \ --export-csv output/long_term_backtest.csv # 追求3天胜率(短期持有) python main.py --start-date 20250401 --end-date 20260408 \ --oscillation-days-min 4 --oscillation-days-max 7 \ --max-oscillation 8.0 --max-attack 8.0 \ --buy-signal-pct 2.0 --min-limit-up-pct 9.5 \ --export-csv output/short_term_backtest.csv ```