# A股个人量化选股与回测平台架构 > 版本:v2.0 > 定位:个人开发、A股、中低频选股/回测、AI Agent 二次开发 > 数据源优先级:Tushare > 新浪财经 > 当前数据库:SQLite > 未来数据库:MySQL > 核心量化引擎:Qlib > 前端:React / Next.js > 后端:FastAPI + Python --- ## 1. 项目目标 本项目不是简单给 Qlib 套一个 Web UI,而是构建一个独立的个人 A 股量化研究平台。 核心目标是形成完整的: ```text 数据 ↓ 因子 ↓ 因子研究 ↓ 复合因子 / 模型 ↓ 股票筛选 ↓ 交易信号 ↓ 组合构建 ↓ 回测 ↓ Experiment ↓ 实盘前候选与信号 ``` 总体业务架构: ```text Web / AI Agent ↓ Research Specification ↓ Application Services ├── Data Service ├── Universe Service ├── Factor Service ├── Factor Research Service ├── Selection Service ├── Signal Service ├── Portfolio Service ├── Model Service ├── Backtest Service └── Experiment Service ↓ Quant Engine ├── Qlib └── ML ↓ Standardized Results ↓ SQLite / Parquet / Qlib Dataset ``` AI Agent 作为独立能力层,通过受控 Tool 调用上述服务,而不是直接操作数据库或随意修改 Qlib 内部代码。 --- ## 2. 总体架构 ```text ┌──────────────────────────┐ │ React / Next │ │ │ │ Dashboard │ │ 股票池 │ │ 因子研究 │ │ 复合因子 │ │ 股票筛选 │ │ 交易信号 │ │ 组合管理 │ │ 回测 │ │ Experiment │ │ AI Research │ └────────────┬─────────────┘ │ REST / SSE ▼ ┌──────────────────────────┐ │ FastAPI │ │ │ │ API / DTO / Validation │ │ Job / Research Spec │ └────────────┬─────────────┘ │ ┌───────────────────────────┼───────────────────────────┐ │ │ │ ▼ ▼ ▼ Data Services Research Services Agent Service │ │ │ │ ┌───────────┼────────────┐ │ │ │ │ │ │ │ ▼ ▼ ▼ ▼ │ Factor Selection Signal Agent Tools │ Research Engine Engine │ │ │ │ │ └───────────┼────────────┘ │ ▼ │ Portfolio Engine │ │ │ ▼ │ Backtest Engine │ │ │ ▼ │ Qlib / ML │ ▼ DAO / Repository │ ├── SQLite ├── Parquet └── Qlib Dataset ``` --- ## 3. 核心设计原则 ### 3.1 Qlib 是量化计算引擎,不是整个业务系统 Qlib 主要负责: - Feature / Dataset - 模型训练 - Prediction - 部分 Portfolio - Backtest - 分析工具 本系统自己的业务层负责: - 股票池 - 因子定义 - 因子研究 - 复合因子 - 股票筛选 - 交易信号 - 组合构建 - 策略版本 - Experiment - AI Agent 因此: ```text Qlib = Quant Engine 本项目 = Quant Research Platform ``` ### 3.2 因子研究、股票筛选、交易信号必须分离 这是本架构的核心设计原则。 **Factor Research** 回答: > 这个因子有没有预测能力? **Selection Engine** 回答: > 在某一个历史/当前时点,哪些股票符合策略条件? **Signal Engine** 回答: > 什么时候应该买、卖或继续持有? **Portfolio Engine** 回答: > 买哪些股票、买多少、什么时候调仓? 完整关系: ```text Factor ↓ Factor Research ↓ Composite Factor / Model ↓ Selection Engine ↓ Candidate Stocks ↓ Signal Engine ↓ BUY / SELL / HOLD ↓ Portfolio Engine ↓ Backtest ``` --- ## 4. 数据源架构 ```text Data Service │ ┌────────┴────────┐ ▼ ▼ Tushare Sina Primary Secondary │ │ └────────┬────────┘ ▼ Normalization │ Validation │ Storage ``` ### 第一优先级:Tushare 用于: - 股票基本信息 - 日线行情 - 复权因子 - 指数 - 财务数据 - 分红送转 - 停复牌 - 行业/概念 - 其他可用数据 ### 第二优先级:新浪财经 主要作为: - Tushare 数据缺失补充 - 行情数据校验 - 特定实时/准实时数据补充 新浪数据必须经过统一 Adapter,禁止业务代码直接调用新浪接口。 --- ## 5. 数据采集流水线 ```text Scheduler ↓ Data Source Adapter ↓ Raw Response ↓ Schema Validation ↓ Normalization ↓ Deduplication ↓ Business Validation ↓ DAO ↓ SQLite ↓ Parquet Export ↓ Qlib Dataset ``` 目录: ```text data/ ├── sources/ │ ├── base.py │ ├── tushare.py │ └── sina.py ├── normalizers/ ├── validators/ └── service.py ``` 业务层只依赖: ```python MarketDataProvider ``` 而不是: ```python TushareClient ``` --- ## 6. 数据存储架构 ```text 业务元数据 ↓ SQLite 历史/分析型大数据 ↓ Parquet Qlib 计算数据 ↓ Qlib Dataset 实验/策略/任务元数据 ↓ SQLite ``` SQLite 用于: - 股票基础信息 - 数据源状态 - 数据同步记录 - 因子定义 - 因子研究记录 - 策略定义 - 选股规则 - 信号规则 - 组合配置 - 回测配置 - Experiment metadata - Job - 用户配置 - 系统配置 SQLite 不建议长期承载超大规模原始行情明细。 --- ## 7. DAO / Repository 设计 推荐: ```text SQLAlchemy 2.x + Repository Pattern + Pydantic DTO ``` 业务层禁止直接: ```python sqlite3.connect(...) ``` 也禁止在 Service 中直接写 SQL。 必须: ```text Service ↓ Repository / DAO Interface ↓ SQLite Repository ``` 未来: ```text Service ↓ Repository Interface ├── SQLite Repository └── MySQL Repository ``` 数据库切换主要通过: ```text DATABASE_URL ``` 例如: ```text SQLite: sqlite:///./data/quant.db MySQL: mysql+pymysql://user:password@host/quant ``` --- ## 8. 核心数据库表 ```text stock stock_daily stock_adjust_factor industry stock_industry index index_daily index_constituent_history trading_calendar suspend_data stock_st_data financial_indicator income_statement balance_sheet cashflow_statement factor_definition factor_test factor_composite factor_composite_component universe universe_rule selection_rule selection_result selection_snapshot signal_rule signal_event strategy strategy_factor strategy_selection strategy_signal strategy_portfolio portfolio portfolio_position backtest backtest_trade backtest_position backtest_metric experiment experiment_artifact experiment_factor_result experiment_selection_result experiment_signal_result job data_sync_log ``` `selection_result` 保存某个研究时点的选股结果: ```text selection_id strategy_id as_of_date symbol rank score selection_reason ``` `signal_event` 保存交易信号: ```text signal_id strategy_id symbol signal_date signal_type score trigger_reason price ``` 这样系统不仅能回答: > 这次回测赚了多少钱? 还能够回答: > 2023-08-15 为什么选择这只股票? 以及: > 2026-09-08 当前有哪些股票满足策略? --- ## 9. 时间与未来函数防护 所有研究数据必须明确: ```text trade_date report_date announce_date effective_date as_of_date ``` 财务数据必须按照 `announce_date` 控制可见性。 禁止: ```text 使用未来公告的财务数据回测过去 ``` 所有研究数据查询必须明确: ```text as_of_date ``` 只允许返回当时市场已经知道的数据。 同样,历史指数成分必须使用: ```text index_constituent_history ``` 禁止直接使用今天的指数成分股回测过去。 --- ## 10. Domain 层 核心领域对象: ```text Stock Universe Factor FactorTest CompositeFactor Model SelectionRule SelectionResult SignalRule SignalEvent Strategy Portfolio Backtest Experiment Job ``` 核心关系: ```text Universe ↓ Factor ↓ FactorTest ↓ CompositeFactor / Model ↓ SelectionRule ↓ SelectionResult ↓ SignalRule ↓ SignalEvent ↓ Portfolio ↓ Strategy ↓ Backtest ↓ Experiment ``` --- ## 11. Factor Engine Factor Engine 负责: ```text 原始数据 ↓ 因子计算 ↓ 标准化 ↓ 中性化 ↓ 因子值 ``` 支持: - 内置因子 - 技术因子 - 财务因子 - 估值因子 - 成长因子 - 质量因子 - 动量因子 - 波动率因子 - 自定义表达式 每个因子必须具有: ```text name description formula input_data frequency lookback direction normalization neutralization availability_rule version ``` --- ## 12. Factor Research Service 因子研究不是直接选股,而是评估因子的预测能力。 支持: ```text IC RankIC ICIR 分层收益 多空组合 累计收益 因子稳定性 因子相关性 行业暴露 市值暴露 换手率 不同市场阶段 ``` 典型流程: ```text Candidate Factors ↓ Data Validation ↓ IC / RankIC ↓ Layered Backtest ↓ Correlation ↓ Redundancy Removal ↓ Factor Combination ↓ Out-of-Sample Test ``` --- ## 13. Composite Factor Engine 复合因子负责把多个单因子组合成一个可用于选股的 Score。 例如: ```text CompositeScore = 0.25 × ROE + 0.20 × RevenueGrowth + 0.30 × Momentum60 + 0.10 × PE + 0.15 × Quality ``` 支持: - 固定权重 - Rank 加权 - Z-Score 加权 - IC 加权 - ICIR 加权 - 手工权重 - ML 模型输出 - 因子方向控制 - 标准化 - 行业中性化 - 市值中性化 注意: ```text Composite Factor ≠ Strategy ``` Composite Factor 只是生成: ```text Stock → Score ``` 真正决定买卖的仍然是 Selection + Signal + Portfolio。 --- ## 14. Selection Engine:股票筛选引擎 Selection Engine 是连接“研究”和“实际选股”的核心模块。 ### 14.1 三种选股模式 **A. 条件选股** ```text ROE > 15% AND PE < 30 AND Revenue Growth > 20% AND Close > MA60 ``` **B. 因子评分选股** ```text Composite Score ↓ Rank ↓ Top N ``` **C. 模型预测选股** ```text Historical Data ↓ Features ↓ LightGBM / Qlib Model ↓ Predicted Return ↓ Rank ↓ Top N ``` ### 14.2 Selection 输入 ```text Universe + Filters + Factor / Composite Factor / Model + Ranking + Top N / Top % + Constraints ``` ### 14.3 Selection 输出 ```text SelectionResult ├── as_of_date ├── symbol ├── rank ├── score ├── factor_values ├── filter_status ├── selection_reason └── metadata ``` Selection Engine 必须支持历史日期执行: ```text select( strategy_id, as_of_date="2024-06-30" ) ``` 因此: > 当前选股和历史回测选股必须使用同一套 Selection Engine。 --- ## 15. Signal Engine:交易信号引擎 Selection 解决: > 哪些股票值得关注? Signal 解决: > 什么时候交易? 典型输入: ```text SelectionResult + Price + Technical Indicators + Market Regime + Existing Position + Risk Rules ``` 输出: ```text BUY SELL HOLD WATCH ``` 例如: ```text Selection Rank <= 20 AND Close > MA60 AND Momentum20 > 0 AND Market Regime = Bull → BUY ``` 卖出: ```text Rank > 50 OR Close < MA60 OR Risk Rule Triggered → SELL ``` SignalEvent 必须记录: ```text signal_date symbol signal_type trigger_reason score price strategy_id ``` 这样可以解释: > 为什么这一天产生买入信号? --- ## 16. Portfolio Engine:组合构建 Signal 产生以后,不直接进入回测,而是进入 Portfolio Engine。 Portfolio Engine 负责: - 股票数量 - 仓位 - 权重 - 行业约束 - 单股上限 - 最大回撤控制 - 换手约束 - 调仓 - 现金管理 支持: ```text Equal Weight Score Weight Risk Weight Custom Weight ``` 例如: ```text Top 20 ↓ 过滤 BUY 信号 ↓ 剩余 12 只 ↓ 单股最大 10% ↓ 行业最大 25% ↓ 组合最终持仓 ``` --- ## 17. Strategy:完整策略定义 Strategy 不再只是 Factor + Model + Backtest,而是: ```text Strategy ├── Universe ├── Filters ├── Factors ├── Composite Factor ├── Model ├── Selection Rule ├── Signal Rule ├── Portfolio Rule ├── Rebalance Rule └── Risk Rule ``` 示例: ```yaml strategy: name: "质量成长动量策略" universe: type: "CSI300" filters: - market_cap > 10000000000 - is_st = false - suspended = false factors: - name: roe_ttm weight: 0.25 - name: revenue_growth weight: 0.20 - name: momentum_60 weight: 0.30 - name: pe weight: 0.10 - name: quality weight: 0.15 selection: method: composite_score top_n: 20 signal: buy: - score_rank <= 20 - close > ma60 sell: - score_rank > 50 - close < ma60 portfolio: weighting: equal max_position: 0.10 max_industry_weight: 0.25 rebalance: frequency: weekly ``` --- ## 18. Research Specification 前端、AI Agent 和后端统一使用自己的研究描述对象。 Research Specification 是系统最重要的业务契约之一。 处理流程: ```text Research Specification ↓ Validator ↓ Strategy Builder ↓ Selection Builder ↓ Signal Builder ↓ Portfolio Builder ↓ Qlib / ML Adapter ↓ Backtest ``` 前端和 Agent 不允许直接生成任意 Qlib 配置绕过这一层。 --- ## 19. 前端结构 第一阶段: ```text Dashboard 股票池 因子研究 复合因子 股票筛选 交易信号 回测 Experiment ``` 第二阶段: ```text 模型研究 Portfolio AI Research 数据管理 ``` --- ## 20. 前端输入 ### 股票池 支持: - 市场 - 股票类型 - 行业 - 市值 - 流动性 - 上市时间 - ST - 停牌 - 指数成分 - 历史指数成分 ### 因子 支持: - 内置因子 - 自定义表达式 - 因子组合 - 权重 - 标准化 - 中性化 ### 股票筛选 支持: - 条件筛选 - Top N - Top % - Score - Score Threshold - 等权 - Score 加权 - 行业约束 - 市值约束 - 流动性约束 - 单股权重上限 ### 交易信号 支持: - 买入条件 - 卖出条件 - 持有条件 - 趋势条件 - 技术指标 - 市场环境 - 风险条件 ### 回测 支持: - 起止日期 - 调仓频率 - 初始资金 - 手续费 - 印花税 - 滑点 - 涨跌停限制 - 停牌限制 - 成交约束 --- ## 21. 前端输出 ### 21.1 选股结果 ```text SelectionResult ├── as_of_date ├── universe ├── candidates │ ├── symbol │ ├── rank │ ├── score │ ├── factor_values │ └── selection_reason └── statistics ``` ### 21.2 信号结果 ```text SignalResult ├── symbol ├── signal ├── score ├── trigger_reason ├── price └── risk_flags ``` ### 21.3 回测结果 ```text BacktestResult ├── summary ├── equity_curve ├── drawdown ├── monthly_returns ├── yearly_returns ├── positions ├── trades ├── turnover ├── risk_metrics ├── factor_exposure ├── selection_history └── signal_history ``` 前端完全不需要理解 Qlib 内部对象。 --- ## 22. 异步 Job 所有耗时任务必须异步: ```text POST /api/backtests ↓ Job Created ↓ Worker ↓ Selection ↓ Signal ↓ Portfolio ↓ Qlib ↓ Result ``` 前端通过 SSE 接收: ```text queued running data_loading factor_calculation factor_research selection signal_generation portfolio_construction model_training backtesting analysis completed failed ``` 第一阶段: ```text FastAPI BackgroundTasks ``` 复杂后再引入: ```text Redis + Celery/RQ ``` 不要第一版过度工程化。 --- ## 23. Qlib Adapter Qlib 必须被封装: ```text quant/ ├── qlib_adapter/ │ ├── dataset.py │ ├── feature.py │ ├── model.py │ ├── backtest.py │ └── provider.py ``` 业务代码: ```python backtest_service.run(spec) ``` 而不是: ```python qlib.init(...) qlib.workflow(...) ``` 散落在项目各处。 --- ## 24. AI Agent 架构 Agent 只能调用受控 Tool: ```text Agent ├── search_stocks ├── inspect_factor ├── test_factor ├── create_composite_factor ├── screen_stocks ├── explain_selection ├── generate_signals ├── create_strategy ├── run_backtest ├── compare_experiments ├── get_backtest_result └── create_experiment ``` Agent 禁止: ```text 直接 SQL 直接修改数据库 直接删除数据 直接执行任意 shell 直接修改生产策略 直接调用 Qlib 内部 API 绕过业务层 ``` --- ## 25. 研究与回测一致性 这是本平台必须保证的关键原则: > **历史回测使用的选股、信号和组合逻辑,与当前实际选股使用的逻辑必须完全相同。** 正确方式: ```text Strategy Specification │ ┌───────────┼───────────┐ ▼ ▼ ▼ Historical Current Future Backtest Screen Signal │ │ │ └───────────┼───────────┘ ▼ Same Engine ``` 这样可以避免: ```text 回测一套逻辑 实际运行另一套逻辑 ``` --- ## 26. Experiment 可复现性 每次研究必须记录: ```text experiment_id data_version code_version strategy_version universe factor_version model_version selection_rule signal_rule portfolio_rule backtest_config start_date end_date result ``` 最好记录: ```text git commit ``` 目标: ```text 同一个 Experiment + 同一个数据版本 + 同一个代码版本 + 同一个 Strategy Version = 可以重新得到相同研究结果 ``` --- ## 27. 测试要求 必须测试: ```text Data Adapter DAO Repository Research Specification Future-data Protection Factor Factor Research Composite Factor Selection Engine Signal Engine Portfolio Engine Backtest API Experiment ``` 特别需要测试: ### Future Function ```text announce_date > as_of_date → 不得进入研究数据 ``` ### Survivorship Bias ```text 历史成分股 ≠ 当前成分股 ``` ### Selection / Backtest Consistency ```text 历史某日 Selection = Backtest 当日 Selection ``` ### Signal Consistency ```text 历史某日 Signal = Strategy Engine 在同一条件下重新计算的 Signal ``` --- ## 28. 开发目录 ```text quant-platform/ │ ├── frontend/ │ └── web/ │ ├── backend/ │ ├── app/ │ │ ├── api/ │ │ ├── application/ │ │ │ └── services/ │ │ │ ├── data_service.py │ │ │ ├── universe_service.py │ │ │ ├── factor_service.py │ │ │ ├── factor_research_service.py │ │ │ ├── composite_factor_service.py │ │ │ ├── selection_service.py │ │ │ ├── signal_service.py │ │ │ ├── portfolio_service.py │ │ │ ├── model_service.py │ │ │ ├── backtest_service.py │ │ │ └── experiment_service.py │ │ ├── domain/ │ │ │ ├── entities/ │ │ │ └── repositories/ │ │ ├── infrastructure/ │ │ ├── quant/ │ │ │ └── qlib_adapter/ │ │ ├── agent/ │ │ └── core/ │ │ │ └── tests/ │ ├── data/ │ ├── raw/ │ ├── normalized/ │ ├── parquet/ │ └── qlib/ │ ├── experiments/ ├── scripts/ ├── docker/ ├── docs/ ├── ARCHITECTURE.md ├── AGENT.md └── README.md ``` --- ## 29. MVP 开发阶段 ### Phase 1:数据 ```text Tushare ↓ 标准化 ↓ SQLite ↓ Parquet ``` 完成: - 股票列表 - 交易日历 - 日线 - 复权因子 - 基本财务指标 - 历史指数成分 ### Phase 2:因子 ```text Parquet ↓ Qlib Dataset ↓ 自定义因子 ↓ Factor Research ``` 完成: - 因子计算 - IC - RankIC - 分层 - 因子相关性 ### Phase 3:股票筛选 ```text Factor ↓ Composite Factor ↓ Selection Engine ↓ Top N ``` 完成: - 条件选股 - 多因子评分 - 复合因子 - Top N - 历史选股 - 当前选股 ### Phase 4:交易信号 ```text Selection ↓ Signal Engine ↓ BUY / SELL / HOLD ``` 完成: - 买入条件 - 卖出条件 - 技术指标 - 趋势条件 - 信号历史 ### Phase 5:组合与回测 ```text Selection ↓ Signal ↓ Portfolio ↓ Qlib Backtest ``` 完成: - 仓位 - 调仓 - 交易成本 - 涨跌停 - 停牌 - 回撤 - Sharpe - 换手率 ### Phase 6:Web ```text Dashboard 股票池 因子研究 复合因子 股票筛选 交易信号 回测 Experiment ``` ### Phase 7:AI Agent ```text 自然语言 ↓ Research Plan ↓ Tool ↓ Strategy ↓ Selection ↓ Signal ↓ Backtest ↓ Experiment ``` --- ## 30. 数据流总图 ```text Tushare │ ▼ Tushare Adapter │ 失败/缺失 ▼ Sina Adapter │ ▼ Raw Data │ ▼ Data Validator │ ▼ Normalization │ ┌───────┴────────┐ ▼ ▼ SQLite Parquet │ │ │ ▼ │ Qlib Dataset │ │ │ ┌───────┴────────┐ │ ▼ ▼ │ Factor Model │ │ │ │ └───────┬────────┘ │ ▼ │ Composite Factor │ │ │ ▼ │ Selection Engine │ │ │ Candidates │ │ │ ▼ │ Signal Engine │ │ │ BUY/SELL │ │ │ ▼ │ Portfolio Engine │ │ │ ▼ │ Backtest Engine │ │ └────────────────┤ ▼ Experiment │ ┌─────────┴─────────┐ ▼ ▼ Web Output AI Analysis ``` --- ## 31. 最终核心原则 这个系统必须坚持: 1. **Tushare 第一,新浪第二** 2. **数据源通过 Adapter 隔离** 3. **DAO / Repository 隔离数据库** 4. **SQLite 当前使用,SQLAlchemy 保证未来 MySQL 可切换** 5. **大量历史时序数据逐渐转 Parquet** 6. **Qlib 是计算引擎,不是整个系统** 7. **因子研究、股票筛选、交易信号、组合构建必须分层** 8. **Selection Engine 必须支持历史日期和当前日期** 9. **回测与实际选股必须使用同一套 Strategy Engine** 10. **前端只面对自己的 Domain API** 11. **前后端通过 Research Specification 解耦** 12. **所有耗时任务异步化** 13. **所有研究产生 Experiment** 14. **严格防止未来函数** 15. **严格防止幸存者偏差** 16. **AI Agent 只能通过 Tool 使用研究能力** 17. **第一阶段不做实盘** 18. **第一阶段不做复杂分布式架构** 19. **每个核心模块都必须可以被单元测试** 20. **系统最终输出不仅是回测收益,还必须能够解释“为什么选这只股票、为什么产生这个交易信号”。** 最终目标不是: > Qlib + Web 而是: > **一个以 Qlib 为量化计算引擎、以 Tushare 为主要数据源、以 Composite Factor + Selection + Signal + Portfolio 为策略核心、具备严格历史一致性和 AI Agent 接口的个人 A 股量化研究平台。**