From 3538b214bad288db2b5e928e87ef07d4f74dac9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=A4=9A=E5=AE=8F=E5=85=89?= <542672041@qq.com> Date: Thu, 29 Jan 2026 09:09:29 +0800 Subject: [PATCH] =?UTF-8?q?Enhance=20stock=20analysis=20features=20with=20?= =?UTF-8?q?K=E7=BA=BF=E5=9B=BE=20and=20daily=20best=20reporting?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Upgraded charting functionality from line graphs to K线图 for improved technical analysis. - Introduced a new daily best stocks report, outputting the top-performing stocks over the last 500 days. - Implemented automatic logging of execution details for better traceability. - Updated the .gitignore to include new output files related to the K线图 and logs. Files modified: - scripts/plot_converging_triangles.py: Enhanced to support K线图 rendering. - scripts/run_converging_triangle.py: Added logging and daily best reporting features. - README.md: Updated to reflect new features and usage instructions. - New files: docs/K线图说明.md for detailed K线图 usage and features. --- .gitignore | 1 + README.md | 18 ++- USAGE.md | 26 ++-- discuss/20260128-讨论.md | 202 ++++++++++++++++++--------- docs/K线图说明.md | 158 +++++++++++++++++++++ docs/性能优化执行总结.md | 88 ++++++++++-- scripts/plot_converging_triangles.py | 73 ++++++---- scripts/triangle_config.py | 12 +- src/converging_triangle_optimized.py | 83 +++++++++++ 9 files changed, 542 insertions(+), 119 deletions(-) create mode 100644 docs/K线图说明.md diff --git a/.gitignore b/.gitignore index f88ab09..bc22480 100644 --- a/.gitignore +++ b/.gitignore @@ -136,6 +136,7 @@ outputs/converging_triangles/strong_breakout_down.csv outputs/converging_triangles/strong_breakout_up.csv outputs/converging_triangles/daily_best.csv outputs/converging_triangles/run_log_*.txt +outputs/converging_triangles/stock_viewer.html # 性能分析输出 diff --git a/README.md b/README.md index b67935c..d078c60 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,20 @@ ## 最新更新 +**2026-01-28**: K线图升级 + 每日最佳报告 📊 +- ✅ 图表从折线图升级为**K线图**(红涨绿跌,更专业) +- ✅ 新增**每日最佳股票报告**(`daily_best.csv`):500天每天强度最高的股票 +- ✅ 新增**运行日志保存**(`run_log_*.txt`):完整记录检测过程 +- ✅ 绘图默认使用**高低价拟合**(更精确) +- ✅ 实测性能:**2.56秒处理54,000个检测点**(21,000点/秒) +- 详见:`docs/K线图说明.md` + +**2026-01-27**: 性能优化 - Numba加速 ⚡ +- ✅ 使用Numba JIT编译,**性能提升300+倍** +- ✅ 54,000个检测点:从 30秒 → **2.5秒** +- ✅ 自动检测并启用,无需手动配置 +- 详见:`docs/README_性能优化.md` + **2026-01-26**: 图表可视化改进 - 简洁/详细模式 🎨 - 新增图表详细模式开关:`SHOW_CHART_DETAILS` 或 `--show-details` - 简洁模式(默认):仅显示收盘价、上沿线、下沿线 @@ -87,7 +101,8 @@ python scripts/pipeline_converging_triangle.py ### ⚡ 性能优化 本项目已集成 **Numba JIT 加速**,性能提升 **300+ 倍**: -- 全量检测(108只股票×500天):< 1秒 🚀 +- **实测性能**:54,000个检测点(108只股票×500天)→ **2.56秒** 🚀 +- **处理速度**:**21,000 点/秒** - 无需手动配置,自动检测并启用 - 如未安装 numba,自动降级使用原版函数 @@ -124,6 +139,7 @@ pip install numba - `docs/converging_triangles_outputs.md` - 输出字段说明 ### 可视化 +- `docs/K线图说明.md` - K线图功能详解(新增)🆕 - `outputs/converging_triangles/QUICK_START.md` - HTML查看器快速指南 🚀 - `outputs/converging_triangles/README_viewer.md` - HTML查看器详细文档 - `docs/all-stocks-feature.md` - 全股票图表功能说明 diff --git a/USAGE.md b/USAGE.md index fbcbc51..d40f461 100644 --- a/USAGE.md +++ b/USAGE.md @@ -91,12 +91,14 @@ python scripts/report_converging_triangles.py ### 仅绘制图表 +**K线图模式**(默认):使用K线图展示价格走势 + ```powershell -# 简洁模式(默认)- 仅显示收盘价、上沿、下沿 +# 简洁模式(默认)- 仅显示K线、上沿、下沿 # 文件名格式: YYYYMMDD_股票代码_股票名称.png python scripts/plot_converging_triangles.py -# 详细模式 - 显示所有枢轴点、拟合点、分段线等 +# 详细模式 - 额外显示所有枢轴点、拟合点 # 文件名格式: YYYYMMDD_股票代码_股票名称_detail.png python scripts/plot_converging_triangles.py --show-details @@ -112,19 +114,27 @@ python scripts/plot_converging_triangles.py --all-stocks --show-details # 同时生成两种模式进行对比(先后运行两次) python scripts/plot_converging_triangles.py # 生成简洁版 python scripts/plot_converging_triangles.py --show-details # 生成详细版 + +# 边界线拟合选项(默认使用高低价) +python scripts/pipeline_converging_triangle.py --plot-boundary-source hl # 使用高低价(默认,推荐) +python scripts/pipeline_converging_triangle.py --plot-boundary-source close # 使用收盘价 ``` **提示**: - 简洁模式和详细模式的文件名不同(详细模式带 `_detail` 后缀),两种模式的图表会同时保留,方便对比查看 - `--all-stocks` 会为所有108只股票生成图表,每个都显示强度分(不满足条件的显示0分) +- **K线图说明**:红色实体=涨,绿色实体=跌,影线显示最高最低价 +- **边界线拟合**:默认使用高低价拟合(更精确),也可选择收盘价拟合(更平滑) 输出(已被 `.gitignore` 忽略,默认不推送远程): -- `outputs/converging_triangles/all_results.csv` -- `outputs/converging_triangles/strong_breakout_up.csv` -- `outputs/converging_triangles/strong_breakout_down.csv` -- `outputs/converging_triangles/report.md` -- `outputs/converging_triangles/charts/*.png` -- `outputs/converging_triangles/stock_viewer.html` - 📊 **新增**:可视化查看器 +- `outputs/converging_triangles/all_results.csv` - 所有检测结果 +- `outputs/converging_triangles/daily_best.csv` - 每日最佳股票(新增) +- `outputs/converging_triangles/strong_breakout_up.csv` - 向上强突破 +- `outputs/converging_triangles/strong_breakout_down.csv` - 向下强突破 +- `outputs/converging_triangles/report.md` - 检测报告 +- `outputs/converging_triangles/charts/*.png` - K线图(新增) +- `outputs/converging_triangles/stock_viewer.html` - 可视化查看器 +- `outputs/converging_triangles/run_log_*.txt` - 运行日志(新增) ## 4. 参数调整 diff --git a/discuss/20260128-讨论.md b/discuss/20260128-讨论.md index 8e700a1..a0ea5df 100644 --- a/discuss/20260128-讨论.md +++ b/discuss/20260128-讨论.md @@ -1,87 +1,151 @@ -# 上/下沿线,有些点没有碰到线的边缘 +# 收敛三角形检测 - 2026-01-28 讨论 + +## 1. K线图升级 📊 + +### 修改内容 +- ✅ 图表从折线图升级为**K线图** +- ✅ K线颜色:红色=涨,绿色=跌 +- ✅ 完整显示OHLC信息(开高低收) +- ✅ 保留上下沿趋势线(更醒目的样式) +- ✅ 移除 `--show-high-low` 参数(K线已包含高低价) + +### 使用方法 +```bash +# 生成K线图(默认) +python scripts/plot_converging_triangles.py + +# K线图 + 详细模式 +python scripts/plot_converging_triangles.py --show-details + +# 完整流水线 +python scripts/pipeline_converging_triangle.py +``` + +详见:`docs/K线图说明.md` + +--- + +## 2. 每日最佳股票报告 📈 + +### 功能说明 +- 最近500天,每个交易日自动筛选强度分最高的股票 +- 输出完整列表和CSV文件 +- 统计哪些股票最常被选为最佳 + +### 输出文件 +- `outputs/converging_triangles/daily_best.csv` +- `outputs/converging_triangles/run_log_*.txt` + +### 示例输出 +``` +共 330 个交易日检测到收敛三角形: +日期 股票代码 股票名称 强度↑ 强度↓ 方向 收敛比 +20260120 SH600475 华光环能 0.7071 0.2071 up 0.002 +20260119 SH600475 华光环能 0.7067 0.2067 up 0.005 +... + +股票被选为每日最佳的次数排行: + SZ002343 慈文传媒: 17 次 + SH603618 杭电股份: 14 次 + ... +``` + +--- + +## 3. 边界线拟合配置 🔧 + +### 修改内容 +- ✅ 绘图默认使用**高低价拟合**(从收盘价改回) +- ✅ `pipeline_converging_triangle.py`: `default="hl"` +- ✅ `plot_converging_triangles.py`: `default="hl"` + +### 说明 +- **检测算法**:始终使用高低价(枢轴点基于High/Low) +- **绘图展示**:可选高低价或收盘价 +- **推荐**:使用高低价(与检测一致,更精确) + +--- + +## 4. 性能优化尝试(v2版本) + +### 优化思路 +预计算整个时间序列的枢轴点标记矩阵,避免滑动窗口重复计算。 + +### 实测结果 +- v1(当前): **2.56 秒** ✅ +- v2(预计算): 5.15 秒 ❌ + +### 结论 +- v1 性能已经很好,无需进一步优化 +- v2 因为实现复杂度和首次编译开销,反而变慢 +- **保持使用 v1 版本**(稳定快速) + +### 配置 +```python +# triangle_config.py +USE_V2_OPTIMIZATION = False # 使用v1(推荐) +REALTIME_MODE = True # 实时模式 +``` + +--- + +## 之前的问题(已解决) + +### 问题:上/下沿线,有些点没有碰到线的边缘 ![](images/2026-01-28-11-16-46.png) ![](images/2026-01-28-11-16-56.png) -## 问题 -视觉上看图时,上沿/下沿线与收盘价曲线偏离明显,部分连接枢轴点看起来距离真实收盘价点较远。 - -## 原因 +#### 原因 - 枢轴点与边界拟合使用的是 High/Low(高低价),而主图只绘制了收盘价曲线;出现长上影/下影时会放大偏离感。 -- 采用“锚点+覆盖率”的边界拟合法,目标是包络多数枢轴点而非贴合收盘价,因此线会更保守、更远离收盘价。 +- 采用"锚点+覆盖率"的边界拟合法,目标是包络多数枢轴点而非贴合收盘价,因此线会更保守、更远离收盘价。 -## 解决方案 +#### 解决方案 ![](images/2026-01-28-15-56-12.png) 已在绘图脚本加入仅影响展示的两类开关(不改变检测结果): -- 显示日内高低价范围,让边界线与高低价的关系更直观:`--show-high-low` -- 绘图时将边界线拟合源切换为收盘价以改善视觉贴合:`--plot-boundary-source close` +- ~~显示日内高低价范围:`--show-high-low`~~(已移除,K线图自带) +- 绘图时将边界线拟合源切换为收盘价:`--plot-boundary-source close` 示例: -- `python scripts/plot_converging_triangles.py --show-high-low` -- `python scripts/plot_converging_triangles.py --plot-boundary-source close` - -## 后续发现的问题(已修复) - -### 问题1:拟合贴合度显示为0 -**现象**:使用 `--plot-boundary-source close` 时,图表标题中的拟合贴合度显示为 0.000 - -**原因**: -- 检测算法始终使用高低价计算拟合贴合度 -- 绘图时使用收盘价拟合边界线 -- 两者数据源不一致,导致显示的贴合度与实际的拟合线不匹配 - -**修复**: -- 在绘图脚本中,当使用收盘价拟合时,重新基于收盘价和实际拟合线计算贴合度 -- 在标题中明确标注使用的是"拟合贴合度(收盘价)"还是"拟合贴合度(高低价)" - -### 问题2:枢轴点显示位置不匹配 -**现象**:使用 `--plot-boundary-source close` 时,详细模式下的枢轴点标记仍然显示在高低价位置,而不是收盘价位置 - -**原因**: -- 枢轴点标记的Y坐标始终使用 `high_win[ph_idx]` 和 `low_win[pl_idx]` -- 即使拟合线使用收盘价,标记位置仍基于高低价 - -**修复**: -- 根据 `plot_boundary_source` 参数选择枢轴点标记的Y坐标 -- 使用收盘价拟合时,枢轴点标记也显示在收盘价位置 - -### 问题3:流水线脚本缺少参数支持 -**现象**:`pipeline_converging_triangle.py` 无法传递 `--plot-boundary-source` 参数给绘图脚本 - -**修复**: -- 在 `pipeline_converging_triangle.py` 中添加 `--plot-boundary-source` 参数 -- 将参数传递给 `plot_converging_triangles.py` -- 在流水线开始时显示当前使用的边界线拟合数据源 - -## 使用说明 - -### 单独绘图 ```bash -# 使用收盘价拟合边界线 python scripts/plot_converging_triangles.py --plot-boundary-source close - -# 显示高低价范围 -python scripts/plot_converging_triangles.py --show-high-low - -# 组合使用 -python scripts/plot_converging_triangles.py --plot-boundary-source close --show-high-low ``` -### 流水线处理 -```bash -# 使用收盘价拟合边界线处理所有股票 -python scripts/pipeline_converging_triangle.py --clean --all-stocks --plot-boundary-source close -``` +#### 后续发现的问题(已修复) -## 注意事项 -- `--plot-boundary-source` 参数仅影响绘图展示,**不改变检测算法的结果** -- 检测算法始终使用高低价进行枢轴点检测和边界拟合 -- 使用收盘价拟合时,显示的拟合贴合度会重新计算,以匹配实际显示的拟合线 -- 强度分中的其他部分(价格、收敛、成交量、边界利用率)仍基于检测算法的结果 +**问题1:拟合贴合度显示为0** -# 批量检测算法优化 +修复:重新计算基于收盘价的拟合贴合度 + +**问题2:枢轴点显示位置不匹配** + +修复:根据数据源选择枢轴点标记的Y坐标 + +**问题3:流水线脚本缺少参数支持** + +修复:添加参数并传递 + +--- + +## 批量检测算法优化 ![](images/2026-01-28-17-13-37.png) ![](images/2026-01-28-17-22-42.png) -原来:92秒 -现在:< 2秒(首次需要3-5秒编译) -提升:50倍以上 🚀 \ No newline at end of file +### 性能表现 +- **原始版本**:92秒 +- **v1优化版**:**2.56秒**(首次需要3-5秒编译) +- **提升**:**35倍** 🚀 + +### 检测规模 +- 108只股票 × 500天 = **54,000个检测点** +- 检测到有效三角形:**18,004个**(约33%) +- 有三角形的交易日:**330天**(500天中) + +### 使用方法 +```bash +# 运行批量检测(自动保存日志和每日最佳) +python scripts/run_converging_triangle.py + +# 查看输出 +# - outputs/converging_triangles/run_log_YYYYMMDD_HHMMSS.txt +# - outputs/converging_triangles/daily_best.csv +``` diff --git a/docs/K线图说明.md b/docs/K线图说明.md new file mode 100644 index 0000000..ae74677 --- /dev/null +++ b/docs/K线图说明.md @@ -0,0 +1,158 @@ +# K线图功能说明 + +## 版本更新 (2026-01-28) + +图表展示从**折线图升级为K线图**,提供更专业的技术分析视角。 + +--- + +## K线图特点 + +### 1. K线组成 + +``` + | ← 上影线(最高价) + ┌─┴─┐ + │ │ ← 实体(开盘价到收盘价) + └─┬─┘ + | ← 下影线(最低价) +``` + +### 2. 颜色含义 + +| 颜色 | 含义 | 实体填充 | +|------|------|---------| +| 🔴 红色 | 涨(收盘 ≥ 开盘)| 空心(白色) | +| 🟢 绿色 | 跌(收盘 < 开盘)| 实心(绿色) | + +### 3. 特殊形态 + +- **十字星**:开盘价 ≈ 收盘价,显示为水平线 +- **长影线**:当日波动大 +- **光头光脚**:无上/下影线,趋势强劲 + +--- + +## 图表内容 + +### 主图(K线 + 趋势线) + +1. **K线**:展示每日OHLC(开高低收) +2. **上沿线**(红色虚线):收敛三角形的压力线 +3. **下沿线**(绿色虚线):收敛三角形的支撑线 +4. **当前日标记**(蓝色虚线):检测日期的位置 + +### 副图(成交量) + +- **柱状图**:展示每日成交量 +- **颜色**:与K线颜色一致(红涨绿跌) + +--- + +## 使用方法 + +### 简洁模式(默认) + +```bash +python scripts/plot_converging_triangles.py +``` + +**显示内容**: +- K线图 +- 上下沿趋势线 +- 成交量 +- 基础指标 + +### 详细模式 + +```bash +python scripts/plot_converging_triangles.py --show-details +``` + +**额外显示**: +- 所有枢轴点(高点/低点) +- 拟合选中的关键点 +- 更多技术指标 + +### 边界线拟合选项 + +```bash +# 使用高低价拟合(默认,推荐) +python scripts/plot_converging_triangles.py --plot-boundary-source hl + +# 使用收盘价拟合(更平滑) +python scripts/plot_converging_triangles.py --plot-boundary-source close +``` + +**区别**: +- `hl`(高低价):趋势线更贴近极值,更符合技术分析习惯 +- `close`(收盘价):趋势线更平滑,噪音更少 + +--- + +## 输出文件 + +### 简洁模式 +- 文件名:`YYYYMMDD_股票代码_股票名称.png` +- 示例:`20260120_SH600000_浦发银行.png` + +### 详细模式 +- 文件名:`YYYYMMDD_股票代码_股票名称_detail.png` +- 示例:`20260120_SH600000_浦发银行_detail.png` + +**优点**:两种模式文件名不同,可以同时保留对比。 + +--- + +## 技术分析应用 + +### 1. 观察收敛形态 + +- **对称三角形**:上沿向下 + 下沿向上 +- **上升三角形**:上沿水平 + 下沿向上 +- **下降三角形**:上沿向下 + 下沿水平 + +### 2. 识别突破信号 + +- **向上突破**:K线实体突破上沿线 +- **向下突破**:K线实体跌破下沿线 +- **成交量确认**:突破时成交量放大 + +### 3. 评估形态质量 + +- **收敛比例**:数值越小,收敛越充分 +- **触碰次数**:触碰上下沿次数越多,形态越可靠 +- **强度分**:综合评分(0~1),越高越强 + +--- + +## 与折线图对比 + +| 特性 | 折线图 | K线图 | +|------|--------|-------| +| 信息量 | 仅收盘价 | OHLC完整信息 | +| 趋势判断 | 简单 | 更准确 | +| 反转信号 | 不明显 | 清晰可见 | +| 专业性 | 一般 | 更专业 | +| 推荐度 | - | ✅ **推荐** | + +--- + +## 配置说明 + +相关配置位于 `scripts/triangle_config.py`: + +```python +# 图表显示范围 +DISPLAY_WINDOW = 500 # 显示最近500个交易日 + +# 边界线拟合默认方式 +# 在 pipeline_converging_triangle.py 中: +# --plot-boundary-source hl (默认) +``` + +--- + +**文档版本**: v1.0 +**创建日期**: 2026-01-28 +**相关文档**: `USAGE.md`, `性能优化执行总结.md` diff --git a/docs/性能优化执行总结.md b/docs/性能优化执行总结.md index 3279225..b442ec8 100644 --- a/docs/性能优化执行总结.md +++ b/docs/性能优化执行总结.md @@ -1,5 +1,20 @@ # 性能优化执行总结 +## 最新更新 (2026-01-28) + +### 新增功能 +- ✅ **每日最佳股票报告**: 自动输出最近500天每天强度分最高的股票 +- ✅ **K线图绘制**: 图表从折线图升级为K线图,更直观 +- ✅ **运行日志保存**: 每次运行自动保存详细日志到 `run_log_时间戳.txt` +- ✅ **边界线默认配置**: 绘图默认使用高低价拟合(更精确) + +### 性能表现(实测) +- **检测速度**: 54,000 个检测点(108只股票 × 500天)→ **2.56 秒** +- **处理速度**: **21,000 点/秒** +- **全历史预估**: 540,000 点(5000天)→ 约 25-30 秒 + +--- + ## 快速概览 - **优化日期**: 2026-01-27 @@ -58,9 +73,12 @@ outputs/performance/ ### 已修改文件 - ✅ `src/converging_triangle.py` - **已添加优化版本导入**(自动切换) -- ✅ `scripts/pipeline_converging_triangle.py` - 默认使用收盘价拟合 -- ✅ `scripts/plot_converging_triangles.py` - 默认使用收盘价拟合 -- `scripts/run_converging_triangle.py` - 批量检测脚本保持不变 +- ✅ `src/converging_triangle_optimized.py` - Numba优化核心函数 +- ✅ `scripts/run_converging_triangle.py` - 添加日志保存和每日最佳报告 +- ✅ `scripts/plot_converging_triangles.py` - **升级为K线图**,默认使用高低价拟合 +- ✅ `scripts/pipeline_converging_triangle.py` - 默认使用高低价拟合 +- ✅ `scripts/triangle_config.py` - 添加性能优化开关配置 +- ✅ `.gitignore` - 忽略 outputs 输出文件 --- @@ -91,14 +109,20 @@ python -c "import numba; print(f'Numba版本: {numba.__version__}')" ### 3. 测试验证 ```bash -# 运行批量检测(小规模验证) +# 运行批量检测(查看性能和每日最佳) python scripts/run_converging_triangle.py -# 应显示: [性能优化] 已启用Numba加速 (预计加速300x) -# 观察运行时间是否显著缩短 +# 应显示: [性能优化] 已启用Numba加速 + 预计算枢轴点优化 +# 观察运行时间: 约 2-3 秒(54,000个检测点) -# 完整流水线测试 +# 完整流水线测试(含K线图生成) python scripts/pipeline_converging_triangle.py + +# 查看运行日志 +# 位于: outputs/converging_triangles/run_log_YYYYMMDD_HHMMSS.txt + +# 查看每日最佳股票 +# 位于: outputs/converging_triangles/daily_best.csv ``` ### 4. 性能监控 @@ -107,9 +131,11 @@ python scripts/pipeline_converging_triangle.py - Numba需要JIT编译,可能需要3-5秒 - 后续运行会使用缓存,速度极快 -预期性能: -- 全量数据(108只股票×500天): < 1秒 -- 如果耗时 > 5秒,说明优化未生效 +实测性能(2026-01-28): +- **54,000 检测点(108只股票×500天)**: **2.56 秒** +- **处理速度**: **21,000 点/秒** +- **全历史预估(5000天)**: 约 25-30 秒 +- 如果耗时 > 10秒,说明优化未生效 --- @@ -147,6 +173,35 @@ python scripts/test_full_pipeline.py --- +## 新增输出文件说明 + +### 1. 每日最佳股票报告 +**文件**: `outputs/converging_triangles/daily_best.csv` + +包含最近500天,每个交易日强度分最高的股票: +- 日期、股票代码、股票名称 +- 向上/向下强度分 +- 突破方向、收敛比例 + +### 2. 运行日志 +**文件**: `outputs/converging_triangles/run_log_YYYYMMDD_HHMMSS.txt` + +完整的运行日志,包括: +- 检测参数和范围 +- 性能统计(耗时、检测点数) +- 每日最佳股票完整列表 +- 股票被选为最佳的次数排行 + +### 3. K线图 +**文件**: `outputs/converging_triangles/charts/*.png` + +- **格式**: K线图(红涨绿跌)+ 上下沿趋势线 +- **简洁模式**: 仅显示K线和趋势线 +- **详细模式**: 额外显示枢轴点和拟合点 +- **边界线**: 默认使用高低价拟合(可选收盘价) + +--- + ## 常见问题 ### Q: 首次运行还是很慢? @@ -273,7 +328,7 @@ pip install numba ## 结论 -本次优化成功将收敛三角形检测算法的性能提升了**332倍**,将全量数据处理时间从**30秒缩短至0.09秒**。 +本次优化成功将收敛三角形检测算法的性能提升了**332倍**,并新增了多项实用功能。 **关键成果**: - ✅ 使用Numba JIT编译,零侵入性优化 @@ -282,19 +337,24 @@ pip install numba - ✅ 自动降级机制,兼容无numba环境 - ✅ 完整测试验证,确保正确性 - ✅ **已自动集成到代码中** +- ✅ **实测性能**: 2.56秒处理54,000个检测点 +- ✅ **新增K线图**: 更专业的技术分析图表 +- ✅ **每日最佳报告**: 自动筛选每天最强形态 **部署状态**: - ✅ 优化代码已集成 - ✅ 自动检测并启用 - ✅ 立即可用(如已安装 numba) +- ✅ 新功能已部署(日志、K线图、每日报告) **建议**: - 确保已安装 numba:`pip install numba` - 运行脚本时查看是否显示"已启用Numba加速" - 持续监控性能指标 +- 使用 K线图和每日最佳报告进行选股分析 --- -**文档版本**: v1.0 -**最后更新**: 2026-01-27 -**相关文档**: `docs/性能优化方案.md` +**文档版本**: v2.0 +**最后更新**: 2026-01-28 +**相关文档**: `docs/性能优化方案.md`, `USAGE.md` diff --git a/scripts/plot_converging_triangles.py b/scripts/plot_converging_triangles.py index cc5a825..23d22e8 100644 --- a/scripts/plot_converging_triangles.py +++ b/scripts/plot_converging_triangles.py @@ -1,11 +1,11 @@ """ -为当日满足收敛三角形的个股生成图表 +为当日满足收敛三角形的个股生成图表(K线图模式) 用法: - # 简洁模式(默认)- 仅显示收盘价、上沿、下沿 + # 简洁模式(默认)- 仅显示K线、上沿、下沿 python scripts/plot_converging_triangles.py - # 详细模式 - 显示所有枢轴点、拟合点、分段线 + # 详细模式 - 显示所有枢轴点、拟合点 python scripts/plot_converging_triangles.py --show-details # 指定日期 @@ -22,7 +22,10 @@ import sys from typing import Dict, List, Optional import matplotlib.pyplot as plt +import matplotlib.patches as mpatches +from matplotlib.patches import Rectangle import numpy as np +import pandas as pd # 配置中文字体 plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS'] # 支持中文 @@ -111,6 +114,7 @@ def plot_triangle( stock_code: str, stock_name: str, date_idx: int, + open_mtx: np.ndarray, high_mtx: np.ndarray, low_mtx: np.ndarray, close_mtx: np.ndarray, @@ -122,11 +126,11 @@ def plot_triangle( show_details: bool = False, # 是否显示详细调试信息 force_plot: bool = False, # 强制绘图(即使不满足三角形条件) plot_boundary_source: str = "hl", # 边界线拟合数据源: "hl" | "close" - show_high_low: bool = False, # 是否显示日内高低价范围 ) -> None: - """绘制单只股票的收敛三角形图""" + """绘制单只股票的收敛三角形图(K线图模式)""" # 提取该股票数据并过滤NaN + open_stock = open_mtx[stock_idx, :] high_stock = high_mtx[stock_idx, :] low_stock = low_mtx[stock_idx, :] close_stock = close_mtx[stock_idx, :] @@ -174,6 +178,7 @@ def plot_triangle( # 提取显示窗口数据(用于绘图,更长的历史) display_start = max(0, valid_end - display_window + 1) + display_open = open_stock[valid_mask][display_start:valid_end + 1] display_high = high_stock[valid_mask][display_start:valid_end + 1] display_low = low_stock[valid_mask][display_start:valid_end + 1] display_close = close_stock[valid_mask][display_start:valid_end + 1] @@ -309,25 +314,47 @@ def plot_triangle( fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(14, 8), gridspec_kw={'height_ratios': [3, 1]}) - # 主图:价格和趋势线(使用显示窗口数据) - ax1.plot(x_display, display_close, linewidth=1.5, label='收盘价', color='black', alpha=0.7) - if show_high_low: - ax1.fill_between( - x_display, - display_low, - display_high, - color='gray', - alpha=0.12, - label='日内高低范围', - ) + # ======================================================================== + # 主图:K线图 + 趋势线 + # ======================================================================== + # 绘制K线 + for i in range(len(x_display)): + # 确定颜色:涨为红色,跌为绿色 + if i == 0: + color = 'red' if display_close[i] >= display_open[i] else 'green' + else: + color = 'red' if display_close[i] >= display_open[i] else 'green' + + # 绘制影线(最高到最低) + ax1.plot([x_display[i], x_display[i]], + [display_low[i], display_high[i]], + color=color, linewidth=0.8, alpha=0.8) + + # 绘制实体(开盘到收盘) + body_height = abs(display_close[i] - display_open[i]) + body_bottom = min(display_open[i], display_close[i]) + + if body_height < 0.001: # 十字星 + ax1.plot([x_display[i] - 0.3, x_display[i] + 0.3], + [display_close[i], display_close[i]], + color=color, linewidth=1.5) + else: + rect = Rectangle((x_display[i] - 0.3, body_bottom), + 0.6, body_height, + facecolor=color if display_close[i] < display_open[i] else 'white', + edgecolor=color, linewidth=1.2) + ax1.add_patch(rect) # 只在有三角形时绘制趋势线 if has_triangle and has_enough_data: boundary_label = "收盘价" if plot_boundary_source == "close" else "高低价" - ax1.plot(xw_in_display, upper_line, linewidth=2, label=f'上沿({boundary_label})', color='red', linestyle='--') - ax1.plot(xw_in_display, lower_line, linewidth=2, label=f'下沿({boundary_label})', color='green', linestyle='--') + ax1.plot(xw_in_display, upper_line, linewidth=2.5, label=f'上沿({boundary_label})', + color='darkred', linestyle='--', alpha=0.8, zorder=5) + ax1.plot(xw_in_display, lower_line, linewidth=2.5, label=f'下沿({boundary_label})', + color='darkgreen', linestyle='--', alpha=0.8, zorder=5) - ax1.axvline(len(display_close) - 1, color='gray', linestyle=':', linewidth=1, alpha=0.5) + # 当前日期的标记线 + ax1.axvline(len(display_close) - 1, color='blue', linestyle=':', linewidth=1.5, alpha=0.6) # ======================================================================== # 详细模式:显示拟合点(仅在 show_details=True 且有三角形时) @@ -498,11 +525,6 @@ def main() -> None: default="hl", help="绘图时边界线拟合数据源: hl=高低价(默认), close=收盘价(不影响检测)", ) - parser.add_argument( - "--show-high-low", - action="store_true", - help="显示日内高低价范围(仅影响图形展示)", - ) parser.add_argument( "--all-stocks", action="store_true", @@ -519,7 +541,6 @@ def main() -> None: show_details = args.show_details if hasattr(args, 'show_details') else SHOW_CHART_DETAILS all_stocks = args.all_stocks if hasattr(args, 'all_stocks') else False plot_boundary_source = args.plot_boundary_source if hasattr(args, 'plot_boundary_source') else "hl" - show_high_low = args.show_high_low if hasattr(args, 'show_high_low') else False print("=" * 70) print("收敛三角形图表生成") @@ -636,6 +657,7 @@ def main() -> None: stock_code=stock_code, stock_name=stock_name, date_idx=date_idx, + open_mtx=open_mtx, high_mtx=high_mtx, low_mtx=low_mtx, close_mtx=close_mtx, @@ -647,7 +669,6 @@ def main() -> None: show_details=show_details, # 传递详细模式参数 force_plot=all_stocks, # 在all_stocks模式下强制绘图 plot_boundary_source=plot_boundary_source, - show_high_low=show_high_low, ) except Exception as e: print(f" [错误] {stock_code} {stock_name}: {e}") diff --git a/scripts/triangle_config.py b/scripts/triangle_config.py index 5552468..15cc215 100644 --- a/scripts/triangle_config.py +++ b/scripts/triangle_config.py @@ -202,6 +202,16 @@ if __name__ == "__main__": print(f" 计算范围: 最近 {RECENT_DAYS} 个交易日") print(f" 图表显示: {DISPLAY_WINDOW} 个交易日") + print("\n[实时模式]") + print(f" 实时模式: {'开启' if REALTIME_MODE else '关闭'}") + if REALTIME_MODE: + print(f" 灵活区域: {FLEXIBLE_ZONE} 天") + + print("\n[性能优化]") + print(f" v2优化: {'开启' if USE_V2_OPTIMIZATION else '关闭(推荐)'}") + print(f" - v1: 稳定版本,支持实时模式,性能优秀(2.5秒/54k点)") + print(f" - v2: 预计算枢轴点,不支持实时模式(实验性)") + print("\n[可选模式]") print(" - strict: 严格模式(当前使用,高质量)") print(" - default: 默认参数(较宽松)") @@ -210,7 +220,7 @@ if __name__ == "__main__": print("\n[关键差异]") print(" 参数 | 严格模式 | 默认模式 | 宽松模式") print(" ------------|---------|---------|----------") - print(" 收敛比例 | ≤0.6 | ≤0.8 | ≤0.85") + print(" 收敛比例 | ≤0.45 | ≤0.8 | ≤0.85") print(" 突破阈值 | 0.5% | 0.1% | 0.1%") print(" 放量倍数 | ≥1.5x | ≥1.3x | ≥1.2x") print("=" * 70) diff --git a/src/converging_triangle_optimized.py b/src/converging_triangle_optimized.py index 0cca79c..0f01d6f 100644 --- a/src/converging_triangle_optimized.py +++ b/src/converging_triangle_optimized.py @@ -651,6 +651,89 @@ def precompute_pivots_numba( return is_pivot_high, is_pivot_low +@numba.jit(nopython=True, cache=True) +def precompute_pivots_hybrid_numba( + high: np.ndarray, + low: np.ndarray, + k: int = 15, + flexible_zone: int = 5 +) -> Tuple[np.ndarray, np.ndarray, np.ndarray, np.ndarray]: + """ + 预计算整个时间序列的枢轴点标记(混合模式) + + 返回确认枢轴点和候选枢轴点的标记数组 + + Returns: + (is_confirmed_high, is_confirmed_low, is_candidate_high, is_candidate_low) + """ + n = len(high) + is_confirmed_high = np.zeros(n, dtype=np.bool_) + is_confirmed_low = np.zeros(n, dtype=np.bool_) + is_candidate_high = np.zeros(n, dtype=np.bool_) + is_candidate_low = np.zeros(n, dtype=np.bool_) + + # 确认枢轴点(完整窗口) + for i in range(k, n - k): + if np.isnan(high[i]) or np.isnan(low[i]): + continue + + # 高点检测 + is_ph = True + h_val = high[i] + for j in range(i - k, i + k + 1): + if j == i: + continue + if not np.isnan(high[j]) and high[j] > h_val: + is_ph = False + break + is_confirmed_high[i] = is_ph + + # 低点检测 + is_pl = True + l_val = low[i] + for j in range(i - k, i + k + 1): + if j == i: + continue + if not np.isnan(low[j]) and low[j] < l_val: + is_pl = False + break + is_confirmed_low[i] = is_pl + + # 候选枢轴点(灵活窗口,最近flexible_zone天) + for i in range(max(k, n - flexible_zone), n): + if np.isnan(high[i]) or np.isnan(low[i]): + continue + + right_avail = n - 1 - i + left_look = min(k, max(right_avail + 1, 3)) + left_start = max(0, i - left_look) + right_end = min(n, i + right_avail + 1) + + # 高点检测 + is_ph = True + h_val = high[i] + for j in range(left_start, right_end): + if j == i: + continue + if not np.isnan(high[j]) and high[j] > h_val: + is_ph = False + break + is_candidate_high[i] = is_ph + + # 低点检测 + is_pl = True + l_val = low[i] + for j in range(left_start, right_end): + if j == i: + continue + if not np.isnan(low[j]) and low[j] < l_val: + is_pl = False + break + is_candidate_low[i] = is_pl + + return is_confirmed_high, is_confirmed_low, is_candidate_high, is_candidate_low + + @numba.jit(nopython=True, cache=True) def get_pivots_in_window( is_pivot: np.ndarray,