# cc-cursor 使用指南 Mac Mini 单机量化研究平台,覆盖数据获取 → 因子计算 → 回测 → 参数优化 → ML 模型 → 情绪因子 → Agent 系统全链路。 --- ## 目录 1. [环境准备](#1-环境准备) 2. [数据库连接](#2-数据库连接) 3. [数据层 — DataManager](#3-数据层--datamanager) 4. [因子引擎 — FactorEngine](#4-因子引擎--factorengine) 5. [回测引擎 — VectorBTEngine](#5-回测引擎--vectorbtengine) 6. [参数优化 — OptunaEngine](#6-参数优化--optunaengine) 7. [ML 模型 — LightGBM / CatBoost](#7-ml-模型--lightgbm--catboost) 8. [情绪因子 — SentimentEngine](#8-情绪因子--sentimentengine) 9. [Agent 系统 — 命令行入口](#9-agent-系统--命令行入口) 10. [配置说明](#10-配置说明) 11. [完整示例](#11-完整示例) 12. [常见问题](#12-常见问题) --- ## 1. 环境准备 ### 硬件要求 - macOS / Linux(本系统开发于 Mac Mini) - 内存 ≥ 16GB(ML 模型训练推荐) - 网络:可访问东方财富 / 同花顺 API ### Python 环境 ```bash conda activate quant # Python 3.11.13 python --version # → 3.11.13 ``` ### 核心依赖 | 包 | 版本 | 用途 | |---|------|------| | pandas | 3.0 | 数据处理 | | numpy | 2.4 | 数值计算 | | akshare | 1.18 | A 股数据获取 | | vectorbt | 1.0 | 回测引擎 | | optuna | 4.9 | 参数优化 | | lightgbm | 4.6 | 梯度提升模型 | | catboost | 1.2 | 梯度提升模型 | | scikit-learn | 1.9 | 特征工程 | | sqlalchemy | 2.0 | 数据库 ORM | | pymysql | 1.2 | MySQL 连接 | ### 项目路径设置 从 `finance/` 目录运行代码。脚本开头加入: ```python import sys sys.path.insert(0, "/path/to/cc-cursor/finance") ``` --- ## 2. 数据库连接 ### 建立 SSH 隧道 ```bash bash shared/script/autossh.sh ``` 验证隧道: ```bash lsof -i :13306 | grep LISTEN ``` ### 连接信息 ``` Host: 127.0.0.1 Port: 13306 User: myquant Password: Database: myquant ``` ### 数据库表 所有表使用 `mac_` 前缀: | 表名 | 内容 | 说明 | |------|------|------| | `mac_stock_basic` | A 股列表 | 5,524 只股票 | | `mac_stock_daily` | 日线行情 | 按需同步 | | `mac_stock_financial` | 财务指标 | 同花顺核心指标 | | `mac_report` | 报告持久化 | 日报归档 | --- ## 3. 数据层 — DataManager ### 初始化 ```python from data.data_manager import DataManager dm = DataManager() dm.init_db() # 首次使用创建表(幂等操作) ``` ### 获取股票列表 ```python stocks = dm.get_stock_list() # → 5,524 只 A 股 stocks = dm.get_stock_list(force_refresh=True) # 强制刷新 ``` ### 获取日线数据 ```python daily = dm.get_daily("000001.SZ") # 全量日线 daily = dm.get_daily("000001.SZ", start="20240101", end="20241231") ``` ### 获取财务数据 ```python fina = dm.get_financial("000001.SZ") # → DataFrame: end_date, eps, bvps, roe, net_profit_margin, debt_to_assets ``` ### 数据同步 ```python n = dm.sync_daily("000001.SZ") # 增量同步到最新 ``` > 数据源优先级:Tushare(优先)→ AkShare(fallback)。DB 缓存优先。 --- ## 4. 因子引擎 — FactorEngine ### 因子注册表 ```python from factors.registry import get_factor, list_factors, list_categories print(list_categories()) # → 12 个分类 print(list_factors("RSI")) # → ['rsi_7', 'rsi_14'] print(len(list_factors())) # → 34 个因子 ``` ### 创建因子实例 ```python factor = get_factor("momentum_20") # 20 日动量 factor = get_factor("rsi_14") # 14 日 RSI factor = get_factor("roe") # ROE 基本面因子 factor = get_factor("news_sent_5") # 5 日新闻情绪因子 ``` ### 计算因子 ```python from factors.engine import FactorEngine engine_fe = FactorEngine(dm) factors = [ get_factor("momentum_20"), get_factor("rsi_14"), get_factor("volatility_20"), ] factor_df = engine_fe.compute("000001.SZ", factors) # → DataFrame: index=trade_date, columns=[momentum_20, rsi_14, volatility_20] ``` ### 截面因子 ```python cross = engine_fe.compute_universe( factors=[get_factor("momentum_20"), get_factor("rsi_14")], date="20250630", ts_codes=["000001.SZ", "600519.SH", "300750.SZ"], ) ``` --- ## 5. 回测引擎 — VectorBTEngine - 初始资金:100,000 元 | 手续费:0.03%(万三) | 方向:只做多 ### 创建引擎 ```python from backtest.vectorbt.engine import VectorBTEngine engine_bt = VectorBTEngine(initial_capital=100_000, commission=0.0003) ``` ### 使用内置策略 ```python from backtest.strategies.rsi_mean_revert import RSIMeanRevertStrategy strategy = RSIMeanRevertStrategy(oversold=30, overbought=70) report = engine_bt.run(strategy, price_df, factor_df) print(report.summary()) # → 收益=29.4% 年化=4.3% 回撤=-19.1% 夏普=0.37 胜率=77.1% ``` ### 内置策略清单 | 策略 | 类名 | 适用场景 | |------|------|----------| | 均线交叉 | `SMACrossStrategy(fast=5, slow=20)` | 趋势跟踪 | | RSI 反转 | `RSIMeanRevertStrategy(oversold=30, overbought=70)` | 均值回归 | | 动量突破 | `MomentumBreakoutStrategy(lookback=20, exit_period=10)` | 动量策略 | | 因子阈值 | `FactorCrossStrategy(factor_column, buy_threshold, sell_threshold)` | 通用因子 | | 因子轮动 | `FactorRotationStrategy(factor_name, top_n=5)` | 截面选股 | ### 自定义策略 ```python from backtest.base import BaseStrategy class MyStrategy(BaseStrategy): name = "my_strategy" category = "custom" def __init__(self, param_a=10): self.param_a = param_a def generate_signals(self, factor_df): signals = pd.Series(-1, index=factor_df.index) signals[factor_df["rsi_14"] < 30] = 1 # 超卖买入 signals[factor_df["rsi_14"] > 70] = 0 # 超买卖出 return signals ``` ### 回测报告字段 `total_return`, `cagr`, `max_drawdown`, `sharpe_ratio`, `calmar_ratio`, `annual_volatility`, `win_rate`, `profit_factor`, `total_trades`, `avg_hold_days`, `equity_curve`, `drawdown_curve`, `monthly_returns`, `trades_df` --- ## 6. 参数优化 — OptunaEngine ### 使用预置搜索空间 ```python from optimizer.engine import OptunaEngine from optimizer.space import rsi_revert_space opt_engine = OptunaEngine(engine_bt) result = opt_engine.optimize( strategy_class=RSIMeanRevertStrategy, search_space=rsi_revert_space, price_df=price_df, factor_df=factor_df, metric="sharpe", # sharpe/cagr/calmar/total_return n_trials=200, ) print(result.summary()) # → 最优参数: oversold=13, overbought=66 # → 最优目标 (sharpe): 0.5985 ``` ### Walk-Forward 验证 ```python wf_result = opt_engine.optimize_walk_forward( strategy_class=RSIMeanRevertStrategy, search_space=rsi_revert_space, price_df=price_df, factor_df=factor_df, metric="sharpe", n_trials=80, train_window=756, test_window=252, ) ``` ### 自定义搜索空间 ```python from optimizer.space import SearchSpace my_space = SearchSpace(params=[ {"name": "fast", "type": "int", "low": 2, "high": 30, "step": 1}, {"name": "slow", "type": "int", "low": 15, "high": 120, "step": 5}, ]) ``` --- ## 7. ML 模型 — LightGBM / CatBoost ### 特征工程 ```python from models.features import FeatureEngine fe = FeatureEngine(lookahead=5, label_type="regression") X, y = fe.build(factor_df, price_df, fit=True) # → Winsorize(1%/99%) → ffill → median fill → RobustScaler → 标签计算 ``` ### LightGBM 训练 ```python from models.lightgbm.model import LightGBMModel model = LightGBMModel( params={"n_estimators": 200, "learning_rate": 0.03, "num_leaves": 15}, eval_ratio=0.2, ) model.fit(X_train, y_train) pred = model.predict(X_test) ic = pred.corr(y_test) ``` ### CatBoost 训练 ```python from models.catboost.model import CatBoostModel model = CatBoostModel( params={"iterations": 200, "learning_rate": 0.03, "depth": 5}, eval_ratio=0.2, ) model.fit(X_train, y_train) ``` ### ML 策略回测 ```python from models.backtest_integration import MLStrategy, MLBenchmark strategy = MLStrategy(model, fe, buy_quantile=0.7, sell_quantile=0.3, rebalance_freq=5) report = engine_bt.run(strategy, price_df, factor_df) # 多模型对比 benchmark = MLBenchmark([lgb_model, cb_model], fe, price_df, factor_df) df = benchmark.run() # → model × (IC, return, sharpe, win_rate, trades) ``` ### 重要约束 - lookahead 固定,不输入模型(防目标泄露) - 交叉验证用 TimeSeriesSplit(不 shuffle) - 特征工程严禁使用未来数据 --- ## 8. 情绪因子 — SentimentEngine ### 配置 API Key 编辑 `finance/.env`: ```bash QWEN_API_KEY=sk-your-key-here QWEN_MODEL=qwen-turbo ``` ### 使用情绪引擎 ```python from factors.sentiment.sentiment_engine import SentimentEngine sent = SentimentEngine(dm) sent_df = sent.compute("000001.SZ", max_news=20) # → DataFrame: (trade_date, news_sent_5, news_conf_5, sent_delta_5) ``` ### 新闻数据源 | 数据源 | 说明 | |--------|------| | AkShare `stock_news_em` | 东方财富个股新闻 | | MariaDB `xwlb_daily_ext` | 新闻联播分割数据 | | MCP `trendradar-news` | 外部新闻聚合服务 | ### 日期对齐机制 - 新闻联播:`news_date + 1 day`(晚间播出 → 次日市场影响) - 非交易日 → 对齐到最近交易日 --- ## 9. Agent 系统 — 命令行入口 ### CLI 命令 ```bash python finance/cli/agent_cli.py daily # 5 步完整流程 python finance/cli/agent_cli.py picks 15 # 选股 Top 15 python finance/cli/agent_cli.py risk # 风险评估 python finance/cli/agent_cli.py research # 因子研究(IC 评估) python finance/cli/agent_cli.py report 20260603 # 生成日报 python finance/cli/agent_cli.py warmup 50 # 首次预热缓存 ``` ### 每日流程 ``` [Step 1/5] 增量同步 → 只更新已缓存股票 [Step 2/5] 风险评估 → RiskAgent: high/medium/low + 仓位 [Step 3/5] 股票打分 → SelectionAgent: 多因子等权打分 [Step 4/5] 情绪因子 → SentimentEngine.compute() [Step 5/5] 生成日报 → ReportAgent: .md + .html + 解读 ``` ### 4 个 Agent | Agent | 职责 | |-------|------| | ResearchAgent | 因子 IC/IC_IR 评估 | | SelectionAgent | 多因子股票打分(等权) | | RiskAgent | 波动率+回撤→仓位建议 | | ReportAgent | 市场+选股+情绪+风险→日报 | ### Demo 验证脚本 ```bash python finance/cli/demo_data_manager.py --ts_code 600519.SH python finance/cli/demo_factor_engine.py --ts_code 300750.SZ python finance/cli/demo_backtest.py --ts_code 000001.SZ python finance/cli/demo_optimizer.py --ts_code 000001.SZ --trials 100 python finance/cli/demo_ml.py --ts_code 000001.SZ --lookahead 5 python finance/cli/demo_sentiment.py --ts_code 600519.SH python finance/cli/demo_sentiment_detail.py --ts_code 600519.SH --date 20260603 ``` --- ## 10. 配置说明 ### 环境变量(`finance/.env`) ```bash # ── Qwen API ────────────────────── QWEN_API_KEY=sk-xxx # DashScope API Key QWEN_MODEL=qwen-turbo # qwen-turbo/plus/max # ── 数据库 ─────────────────────── MAC_DB_HOST=127.0.0.1 MAC_DB_PORT=13306 MAC_DB_USER=myquant MAC_DB_PASSWORD= MAC_DB_NAME=myquant # ── Tushare ────────────────────── TUSHARE_TOKEN=your_token_here # ── 情绪分析范围 ───────────────── SENTIMENT_SCOPE_TYPE=index SENTIMENT_SCOPE_INDEXES=000300,000905 SENTIMENT_MAX_NEWS_PER_STOCK=20 ``` --- ## 11. 完整示例 ### 示例 1:快速回测 ```python import sys; sys.path.insert(0, "finance") from data.data_manager import DataManager from factors.registry import get_factor from factors.engine import FactorEngine from backtest.vectorbt.engine import VectorBTEngine from backtest.strategies.rsi_mean_revert import RSIMeanRevertStrategy dm = DataManager(); dm.init_db() price = dm.get_daily("000001.SZ").set_index("trade_date") engine_fe = FactorEngine(dm) factor_df = engine_fe.compute("000001.SZ", [get_factor("rsi_14")]) engine_bt = VectorBTEngine() report = engine_bt.run(RSIMeanRevertStrategy(30, 70), price, factor_df) print(report.summary()) ``` ### 示例 2:策略寻优 + Walk-Forward ```python from optimizer.engine import OptunaEngine from optimizer.space import rsi_revert_space opt_engine = OptunaEngine(engine_bt) result = opt_engine.optimize( RSIMeanRevertStrategy, rsi_revert_space, price, factor_df, metric="sharpe", n_trials=200, ) print(result.summary()) wf = opt_engine.optimize_walk_forward( RSIMeanRevertStrategy, rsi_revert_space, price, factor_df, n_trials=80, train_window=756, test_window=252, ) ``` ### 示例 3:ML 训练 + 回测 ```python from models.features import FeatureEngine from models.lightgbm.model import LightGBMModel from models.backtest_integration import MLStrategy fe = FeatureEngine(lookahead=5) X, y = fe.build(factor_df, price, fit=True) split = int(len(X) * 0.7) model = LightGBMModel(params={"n_estimators": 200, "learning_rate": 0.03}) model.fit(X.iloc[:split], y.iloc[:split]) strategy = MLStrategy(model, fe) report = engine_bt.run(strategy, price, factor_df) ``` --- ## 12. 常见问题 ### Q: SSH 隧道连接失败? ```bash lsof -i :13306 | grep LISTEN bash shared/script/autossh.sh ``` ### Q: AkShare 返回 RemoteDisconnected? 系统已内置 3 次递增间隔重试 + fallback 机制。如果持续失败:等待 30 秒后重试,或检查网络。 ### Q: 因子计算结果全是 NaN? - 技术因子:前 N 个周期内 NaN 是正常的(如 20 日动量前 19 天为 NaN) - 基本面因子:检查财务数据是否已同步 - 情绪因子:检查是否配置了 `QWEN_API_KEY` ### Q: 回测结果为 0 笔交易? - 检查策略参数是否过于严格 - 使用 `OptunaEngine.optimize()` 寻找更优参数 ### Q: 模型训练只有 2 棵树? 单股票预测噪声比低,建议: - 设置 `eval_ratio=0.0` 禁用早停 - 降低 `learning_rate` 到 0.01 - 增加 `min_data_in_leaf` 防止过拟合 ### Q: 日报中选股为空? 需要先同步目标股票池的数据: ```bash python finance/cli/agent_cli.py warmup 50 ``` --- ## 13. 文档索引 | 文档 | 内容 | |------|------| | [架构说明](architecture.md) | 项目架构、数据流、设计原则 | | [开发指南](development.md) | 环境搭建、开发约定、模块说明 | | [部署说明](deployment.md) | 本地环境、服务器、uWSGI、rsync 部署 | | [因子与表结构速查](reference.md) | 34 因子注册表、DB 表结构、数据源接口 | | [数据层详解](data-layer.md) | DataManager、数据库、缓存策略、已知 Bug | | [因子引擎详解](factors.md) | 因子计算、情绪引擎、新闻源 | | [回测引擎详解](backtest.md) | VectorBT、策略、信号工具、Optuna | | [ML 模型详解](ml-models.md) | 特征工程、LightGBM/CatBoost、ML 策略 | | [Agent 系统详解](agents.md) | Agent 架构、CLI、日报 | | [DJAPI 接口](api.md) | Django API 端点参考 | | [日报查询 API](news_report_api.md) | news/reports + news/events 接口 | | [日报数据库](db_schema_v1.1.md) | news_report / news_event 表结构 |