Skip to content

Latest commit

 

History

History
637 lines (497 loc) · 19.6 KB

File metadata and controls

637 lines (497 loc) · 19.6 KB

A股形态预测系统 - 设计文档

版本: v1.0 更新时间: 2026-01-05

1. 系统架构

1.1 整体架构图

┌─────────────────────────────────────────────────────────────────┐
│                        前端展示层 (Frontend)                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │  首页搜索     │  │  分析页面     │  │  关于页面     │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│         ↓                  ↓                  ↓                   │
│  ┌──────────────────────────────────────────────────────┐       │
│  │         JavaScript (Vanilla) + Bootstrap 5           │       │
│  │  - 股票搜索与自动补全                                  │       │
│  │  - Chart.js 图表可视化                               │       │
│  │  - 多层参数调节面板                                   │       │
│  │  - 中英文双语支持                                     │       │
│  └──────────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────┘
                              ↓ HTTP/REST API
┌─────────────────────────────────────────────────────────────────┐
│                     API 服务层 (FastAPI)                         │
│  ┌──────────────────────────────────────────────────────┐       │
│  │                    路由端点                            │       │
│  │  GET  /api/predict          - 预测接口                 │       │
│  │  GET  /api/analyze          - 完整分析接口             │       │
│  │  GET  /api/stocks/search    - 股票搜索接口             │       │
│  │  POST /api/multi-layer-detect - 多层检测接口           │       │
│  └──────────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                     业务逻辑层 (Core Logic)                      │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ 数据加载器     │  │地标点检测器    │  │ 序列提取器    │          │
│  │DataLoader    │  │LandmarkDetector│  │SequenceExtractor│        │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│         ↓                  ↓                  ↓                   │
│  ┌──────────────────────────────────────────────────────┐       │
│  │              多层过滤系统 (Multi-Layer Filter)         │       │
│  │  Layer 1: ZigZag 算法                                  │       │
│  │  Layer 2: 统计确认 (频率+偏离度)                       │       │
│  │  Layer 3: 趋势强度过滤                                 │       │
│  │  Layer 4: 时间间隔验证                                 │       │
│  └──────────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                     数据访问层 (Data Layer)                       │
│  ┌──────────────┐  ┌──────────────┐  ┌──────────────┐          │
│  │ 股票数据库     │  │ 数据获取器    │  │ 缓存管理器    │          │
│  │StockDB       │  │Fetcher       │  │CacheManager  │          │
│  └──────────────┘  └──────────────┘  └──────────────┘          │
│         ↓                  ↓                  ↓                   │
│  ┌──────────────────────────────────────────────────────┐       │
│  │                   数据源                               │       │
│  │  - 本地 SQLite 数据库 (历史周线数据)                   │       │
│  │  - 行情平台 API (实时数据获取 - 待实现)                │       │
│  │  - stocks.json (股票基本信息: 代码/名称/拼音)          │       │
│  └──────────────────────────────────────────────────────┘       │
└─────────────────────────────────────────────────────────────────┘

1.2 数据流

用户输入股票代码
    ↓
前端: 股票搜索自动补全 (本地 stocks.json)
    ↓
前端: 点击"分析"按钮
    ↓
API: GET /api/predict?symbol={code}
    ↓
后端: DataLoader 从本地数据库加载周线数据
    ↓
后端: LandmarkDetector 执行 ZigZag 算法
    ↓
后端: MultiLayerDetector 应用4层过滤
    ↓
后端: SequenceExtractor 提取时间序列
    ↓
后端: PatternDetector 检测数学规律
    ↓
后端: 返回预测结果 JSON
    ↓
前端: 显示预测结果
    ↓
用户: 点击"查看完整分析"
    ↓
API: GET /api/analyze?symbol={code}&include_secondary=true
    ↓
后端: 返回完整地标点 + 图表数据
    ↓
前端: Chart.js 渲染图表 + 地标点标注

2. 核心模块设计

2.1 数据源设计

2.1.1 本地数据库

位置: data/weekly/*.csv 或 SQLite 数据库

数据格式:

日期,开盘,最高,最低,收盘,成交量
2020-01-03,45.50,47.80,45.20,47.50,12345678

数据来源:

  • 当前: 手动从行情软件导出或使用 Tushare/AKShare 等库获取
  • 未来计划: 直接对接行情平台 API

数据粒度: 周线 (Weekly OHLCV)

  • 周线原因: 平滑日间噪音,减少数据点,使形态点更明显

数据更新:

  • 脚本位置: scripts/update_stock_db.py
  • 建议频率: 每周收盘后更新一次

2.1.2 股票基本信息

位置: data/stocks.json

数据结构:

{
  "000001": {
    "code": "000001",
    "name": "平安银行",
    "pinyin": "payh",
    "full_pinyin": "pinganyinhang",
    "market": "sz",
    "industry": "银行"
  },
  "600519": {
    "code": "600519",
    "name": "贵州茅台",
    "pinyin": "gzmt",
    "full_pinyin": "guizhoumaotai",
    "market": "sh",
    "industry": "白酒"
  }
}

用途:

  • 前端搜索自动补全
  • 支持代码、拼音、名称搜索

2.2 地标点检测设计

2.2.1 ZigZag 算法 (Layer 1)

原理: 基于价格变化百分比识别趋势转折点。当价格变化超过阈值时,认为趋势发生反转。

算法实现 (core/landmark_detector.py):

def detect_landmarks(weekly_prices, threshold=0.10):
    """
    参数:
        weekly_prices: 周线收盘价序列
        threshold: 价格变化阈值 (默认 10%)

    返回:
        landmarks: [
            {
                'index': 52,           # 周索引
                'date': '2021-01-08',  # 日期
                'type': 'low',         # 类型: low/high
                'price': 45.20,        # 价格
                'level': 'primary'     # 级别: primary/secondary
            }
        ]
    """

当前参数: threshold = 10%

问题:

  • ❌ 对震荡市过于敏感,产生大量伪信号
  • ❌ 对单边趋势行情,可能会错过重要的趋势中途调整点

2.2.2 多层过滤系统

Layer 2: 统计确认

# 过滤条件
min_frequency = 2       # 该点在相似价格水平出现次数
min_deviation_pct = 0.20  # 与邻近点价格偏离度

目的: 过滤掉偶然的价格波动点

问题:

  • ❌ 参数设定过于经验化,缺乏自适应性
  • ❌ 对不同行业/市值的股票,应该使用不同参数

Layer 3: 趋势强度过滤

min_trend_strength = 0.50  # 线性回归 R² 值

目的: 确保地标点处于明确的趋势中

问题:

  • ❌ R² = 0.50 的阈值是否合适?
  • ❌ 对不同类型的趋势(单边、震荡、反转)应该分别处理

Layer 4: 时间间隔验证

min_weeks_same_type = 10    # 同类型地标点最小间隔(周)
min_weeks_alternating = 4    # 交替类型地标点最小间隔(周)

目的: 避免过于密集的地标点

问题:

  • ❌ 时间间隔是硬编码的,无法适应不同周期长度的趋势

2.3 ⚠️ 已知问题: 地标点检测不完整

问题描述

当前的地标点检测结果存在以下问题:

  1. 遗漏重要点位

    • 一些明显的重要高点/低点未被标记
    • 特别是长期趋势的转折点
  2. 标记次要点位

    • 一些无关紧要的小波动被标记为地标点
    • 特别是在震荡整理阶段
  3. 原因分析

    a) ZigZag 算法的局限性

    • ZigZag 是基于百分比变化的算法
    • 对不同价格区间的敏感度不同
    • 例: 10元的股票涨10%是1元,100元的股票涨10%是10元

    b) 固定阈值不适应所有股票

    • 当前使用固定的10%阈值
    • 不同波动性的股票应该使用不同阈值
    • 例: 科技股 vs 银行股

    c) 缺乏成交量确认

    • 当前只基于价格变化
    • 重要的转折点通常伴随成交量放大
    • 地量可能表明缺乏确认

    d) 缺乏多重时间框架分析

    • 当前只看周线数据
    • 月线级别的重要点位可能被忽略
    • 日线级别的精确入场时机被忽略

改进方向

短期改进 (可快速实施)

  1. 自适应阈值

    # 根据股票历史波动率动态调整阈值
    atr = calculate_average_true_range(prices, period=14)
    threshold = atr / current_price * 2  # 2倍ATR作为阈值
  2. 成交量过滤

    # 要求重要低点伴随放量
    if landmark['type'] == 'low':
        volume_confirm = volume[i] > ma_volume[i-20:i].mean() * 1.5
  3. 价格区间聚类

    # 将相似价格区间的点聚类,识别真正的支撑/阻力位
    from sklearn.cluster import DBSCAN
    price_levels = DBSCAN(eps=price_range*0.02).fit_predict(prices)

中期改进 (需要更多开发)

  1. 多时间框架分析

    • 结合月线、周线、日线
    • 月线定方向,周线找点位,日线定时机
  2. 机器学习方法

    • 训练模型识别重要点位
    • 特征: 价格变化率、成交量、振幅、时间跨度等
    • 标签: 手动标注的历史重要点位
  3. 形态识别增强

    • 识别经典技术形态 (头肩顶/底、双顶/底、三角形等)
    • 这些形态的转折点通常更可靠

长期改进 (研究性)

  1. 市场情绪整合

    • 整合舆情数据、新闻情感分析
    • 重要点位通常与重大事件相关
  2. 资金流向分析

    • 整合主力资金流向数据
    • 重要转折通常伴随资金方向变化

2.4 序列提取与模式识别

2.4.1 时间序列提取

原理: 将地标点日期转换为从IPO开始的周索引

示例:

股票 601933 上市日期: 2017-01-03 (第0周)
重要低点:
  2018-01-05 → 第52周
  2024-01-05 → 第366周
  2026-01-05 → 第680周

2.4.2 模式检测

当前支持的模式:

  1. 等差数列 (Arithmetic)

    • 例: 52, 366, 680, 994 (间隔314周)
  2. 等比数列 (Geometric)

    • 例: 52, 104, 208, 416 (间隔倍增)

检测方法 (core/pattern_detector.py):

def find_pattern(sequence):
    """
    1. 计算序列中所有相邻间隔
    2. 统计间隔的频率
    3. 找到出现频率最高的间隔
    4. 验证是否构成规律
    """

问题:

  • ❌ 只能识别简单的线性规律
  • ❌ 无法识别复杂模式 (如斐波那契数列、周期性波动等)

2.5 预测生成

当前实现:

# 如果发现等差规律,间隔为314周
next_landmark_week = last_landmark_week + 314

输出格式:

{
  "symbol": "601933",
  "name": "人保财险",
  "predicted_week": 994,
  "predicted_range": "2026-01-01 至 2026-01-31",
  "weeks_to_prediction": 314,
  "pattern_expression": "52 + 314n (n≥0)",
  "pattern_frequency": 3,
  "confidence": "HIGH"
}

3. 前端设计

3.1 技术选型

为什么选择原生 JavaScript 而不是 React/Vue?

优势:

  • ✅ 轻量级,无构建步骤
  • ✅ 易于理解和修改
  • ✅ 快速迭代

劣势:

  • ❌ 大型应用时代码组织困难
  • ❌ 缺乏组件化

结论: 对于当前规模的项目,原生JS + Bootstrap 是合适的选择。

3.2 页面结构

/                    - 首页 (搜索 + 预测结果)
/analysis/{symbol}   - 分析页面 (图表 + 地标点表格)
/about               - 关于页面 (原理说明)
/history             - 历史记录页面 (待实现)

3.3 图表设计

使用的库: Chart.js 4.4.0

图表配置:

{
  type: 'line',
  data: {
    labels: ['2020-01-03', '2020-01-10', ...],
    datasets: [
      {
        label: '收盘价',
        data: [45.2, 47.5, ...],
        borderColor: 'rgba(54, 162, 235, 1)',
        fill: true,
        tension: 0.1  // 轻微平滑
      },
      {
        label: '低点标记',
        data: [null, null, 42.5, null, ...],
        pointStyle: 'triangle',
        pointRadius: 10,
        showLine: false
      },
      {
        label: '高点标记',
        data: [null, 48.5, null, ...],
        pointStyle: 'triangle',
        rotation: 180,
        showLine: false
      }
    ]
  }
}

问题:

  • ❌ 图表加载大量数据点时性能较差
  • ✅ 解决方案: 数据采样或分页

4. 性能优化

4.1 当前瓶颈

  1. 数据加载: 每次请求都从磁盘读取CSV

    • 优化: 使用数据库 + 缓存
  2. ZigZag 计算: O(n) 复杂度,但 n 可能很大

    • 优化: 预计算并缓存结果
  3. 图表渲染: 500+ 数据点时卡顿

    • 优化: 数据采样、懒加载

4.2 缓存策略

当前实现:

# 简单的内存缓存
@lru_cache(maxsize=128)
def load_stock_data(symbol: str):
    ...

改进方向:

  • Redis 缓存层
  • 数据库查询结果缓存
  • 静态资源 CDN 加速

5. 部署方案

5.1 开发环境

cd web
uvicorn app:app --host 0.0.0.0 --port 8000 --reload

5.2 生产环境

推荐方案:

  1. 应用服务器: Gunicorn + Uvicorn

    gunicorn web.app:app -w 4 -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:8000
  2. 反向代理: Nginx

    • 静态文件服务
    • SSL/TLS 终止
    • 请求限流
  3. 容器化: Docker

    FROM python:3.10-slim
    WORKDIR /app
    COPY requirements.txt .
    RUN pip install -r requirements.txt
    COPY . .
    CMD ["uvicorn", "web.app:app", "--host", "0.0.0.0", "--port", "8000"]

6. 测试策略

6.1 单元测试

待补充:

# tests/test_landmark_detector.py
def test_zigzag_detection():
    prices = [100, 105, 110, 115, 110, 105, 100]
    landmarks = detect_landmarks(prices, threshold=0.05)
    assert landmarks[0]['type'] == 'low'
    assert landmarks[1]['type'] == 'high'

6.2 集成测试

待补充:

# tests/test_api.py
def test_predict_endpoint():
    response = client.get("/api/predict?symbol=600519")
    assert response.status_code == 200
    assert 'predicted_week' in response.json()

6.3 回测验证

待实现:

  • 使用历史数据验证预测准确性
  • 计算准确率、召回率等指标

7. 未来路线图

Phase 1: 优化地标点检测 (1-2个月)

  • 实现自适应阈值
  • 添加成交量确认
  • 价格区间聚类
  • 多时间框架分析

Phase 2: 增强模式识别 (2-3个月)

  • 支持复杂模式 (斐波那契、周期性)
  • 机器学习模型训练
  • 经典技术形态识别

Phase 3: 数据源优化 (1个月)

  • 对接实时行情API
  • 自动数据更新脚本
  • 数据质量检查

Phase 4: 用户体验优化 (1个月)

  • 移动端适配
  • 图表交互优化
  • 预测结果导出

Phase 5: 部署与运维 (持续)

  • Docker 容器化
  • CI/CD 流水线
  • 监控告警系统

8. 附录

8.1 参数调优记录

参数 初始值 当前值 调优日期 原因
layer1_threshold 5% 10% 2026-01-05 减少伪信号
layer2_min_freq 1 2 2026-01-05 过滤偶然点
layer2_min_dev 10% 20% 2026-01-05 提高确认度
layer3_trend_str 0.30 0.50 2026-01-05 需要明确趋势
layer4_same_type 6周 10周 2026-01-05 避免过密
layer4_alternating 2周 4周 2026-01-05 避免过密

8.2 测试股票列表

代码 名称 行业 特点
600519 贵州茅台 白酒 长期趋势明显
000001 平安银行 银行 波动较小
300364 中文在线 传媒 波动较大
601933 人保财险 保险 周期性明显
000858 五粮液 白酒 与茅台对比

8.3 参考资料

算法参考:

技术文档:

市场研究:

  • A股市场特征研究
  • 技术分析有效性探讨

文档维护: 本文档应随着系统演进持续更新

最后更新: 2026-01-05 维护者: 系统开发团队