# 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 环境 conda activate quant # 确认 Python 版本 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 脚本开头加入: ```python import sys sys.path.insert(0, "/path/to/cc-cursor/finance") ``` --- ## 2. 数据库连接 ### 建立 SSH 隧道 系统通过 SSH 隧道连接远程 MariaDB: ```bash bash shared/script/autossh.sh ``` 验证隧道: ```bash lsof -i :13306 | grep LISTEN # → ssh ... localhost:13306 (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` | 财务指标 | 同花顺核心指标 | ### 测试连接 ```python from database.connection import test_connection if test_connection(): print("数据库连接成功") else: print("请先建立 SSH 隧道: bash shared/script/autossh.sh") ``` --- ## 3. 数据层 — DataManager ### 初始化 ```python from data.data_manager import DataManager dm = DataManager() dm.init_db() # 首次使用创建表(幂等操作) ``` ### 获取股票列表 ```python # 从 DB 缓存读取(已缓存的 5,524 只 A 股) stocks = dm.get_stock_list() # → DataFrame: index=ts_code, columns=[name, area, industry, ...] # 强制从 AkShare 刷新 stocks = dm.get_stock_list(force_refresh=True) ``` ### 获取日线数据 ```python # 获取单只股票日线(DB 缓存优先,缺失自动补拉) daily = dm.get_daily("000001.SZ") # → DataFrame: trade_date, open, high, low, close, vol, amount, ... # 指定日期范围 daily = dm.get_daily("000001.SZ", start="20240101", end="20241231") # 直接用索引 price = daily.set_index("trade_date").sort_index() close = price["close"] ``` ### 获取财务数据 ```python fina = dm.get_financial("000001.SZ") # → DataFrame: end_date, eps, bvps, roe, net_profit_margin, debt_to_assets, ... # 数据源: stock_financial_abstract_ths(同花顺) # 覆盖: 主板/创业板/科创板 ``` ### 数据同步 ```python # 增量同步:从 DB 最新日期到今天的缺失数据 n = dm.sync_daily("000001.SZ") # 批量同步全部股票(谨慎使用,耗时长) total = dm.sync_all_daily() ``` --- ## 4. 因子引擎 — FactorEngine ### 因子注册表 ```python from factors.registry import get_factor, list_factors, list_categories # 查看所有因子分类 print(list_categories()) # → ['动量', 'RSI', 'MACD', '量价', '布林', 'ATR', '均线', '波动率', '换手率', '振幅', '基本面', '情绪'] # 查看某个分类下的因子 print(list_factors("RSI")) # → ['rsi_7', 'rsi_14'] # 查看全部因子 all_factors = list_factors() print(len(all_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 日新闻情绪因子 # 自定义参数 from factors.technical.momentum import MomentumFactor factor = MomentumFactor(period=60) ``` ### 计算因子 ```python from factors.engine import FactorEngine engine_fe = FactorEngine(dm) # 单股票多因子 factors = [ get_factor("momentum_20"), get_factor("rsi_14"), get_factor("volatility_20"), get_factor("ma_dev_20"), ] factor_df = engine_fe.compute("000001.SZ", factors) # → DataFrame: index=trade_date, columns=[momentum_20, rsi_14, volatility_20, ma_dev_20] # 查看因子值 print(factor_df.tail()) print(factor_df.describe()) ``` ### 截面因子 ```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"], ) # → DataFrame: index=ts_code, columns=[momentum_20, rsi_14] ``` ### 因子质量检查 ```python # 查看 NaN 率 total = len(factor_df) for col in factor_df.columns: nan_pct = factor_df[col].isna().sum() / total * 100 print(f"{col}: NaN {nan_pct:.1f}%") # 正常范围: 技术因子 0.3%-2.1%, 基本面因子 0% ``` --- ## 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) ``` ### 读取回测报告 ```python # 一行摘要 print(report.summary()) # → 收益=29.4% 年化=4.3% 回撤=-19.1% 夏普=0.37 胜率=77.1% 交易=70笔 # 字典格式 metrics = report.to_dict() # → {'total_return': 29.4, 'cagr': 4.3, 'sharpe_ratio': 0.37, ...} # 获取净值曲线 equity = report.equity_curve # pd.Series drawdown = report.drawdown_curve # pd.Series # 逐笔交易 trades = report.trades_df # pd.DataFrame ``` ### 内置策略清单 | 策略 | 类名 | 适用场景 | |------|------|----------| | 均线交叉 | `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): # factor_df 包含因子值和 close 列 # 返回: 1=买入, 0=卖出, -1=持有 signals = pd.Series(-1, index=factor_df.index) signals[factor_df["rsi_14"] < 30] = 1 # RSI 超卖买入 signals[factor_df["rsi_14"] > 70] = 0 # RSI 超买卖出 return signals report = engine_bt.run(MyStrategy(param_a=20), price_df, factor_df) ``` ### 截面回测(多股票) ```python report_xs = engine_bt.run_cross_section( strategy, price_universe={"000001.SZ": df1, "600519.SH": df2}, factor_universe={"000001.SZ": f1, "600519.SH": f2}, ) # → 等权组合回测报告 ``` --- ## 6. 参数优化 — OptunaEngine ### 使用预置搜索空间 ```python from optimizer.engine import OptunaEngine from optimizer.space import rsi_revert_space, sma_cross_space from backtest.strategies.rsi_mean_revert import RSIMeanRevertStrategy opt_engine = OptunaEngine(engine_bt) # 优化 RSI 反转策略参数 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, # 试验次数 ) ``` ### 读取优化结果 ```python print(result.summary()) # → 最优参数: oversold=13, overbought=66 # → 最优目标 (sharpe): 0.5985 # 最优参数的回测报告 best_report = result.best_report # 参数重要性 for k, v in sorted(result.param_importance.items(), key=lambda x: -x[1]): print(f" {k}: {v:.4f}") # 试验记录 trials = result.trials_df # pd.DataFrame ``` ### 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=252 * 3, # 3 年训练 test_window=252, # 1 年测试 ) print(wf_result.summary()) # → 各窗口参数变化 + 整体收益 ``` ### 快捷函数 ```python from optimizer.presets import ( optimize_sma_cross, optimize_rsi_revert, optimize_momentum_breakout, ) result = optimize_rsi_revert(price_df, factor_df, engine_bt, n_trials=100) ``` ### 自定义搜索空间 ```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}, ]) result = opt_engine.optimize(MyStrategy, my_space, price_df, factor_df) ``` --- ## 7. ML 模型 — LightGBM / CatBoost ### 特征工程 ```python from models.features import FeatureEngine # lookahead=5: 预测未来 5 个交易日收益 fe = FeatureEngine(lookahead=5, label_type="regression") # 构建特征矩阵和标签 X, y = fe.build(factor_df, price_df, fit=True) # → X: 标准特征矩阵(去极值 → 缺失填充 → RobustScaler) # → y: 未来 5 日收益率(%) print(f"特征: {X.shape[1]} 列, 样本: {X.shape[0]} 行") print(f"标签: mean={y.mean():.2f}%, std={y.std():.2f}%") ``` ### 数据划分 ```python # 时间序列划分(前 70% 训练,后 30% 测试) n = len(X) split = int(n * 0.7) X_train, X_test = X.iloc[:split], X.iloc[split:] y_train, y_test = y.iloc[:split], y.iloc[split:] print(f"训练集: {len(X_train)} 行") print(f"测试集: {len(X_test)} 行") ``` ### LightGBM 训练 ```python from models.lightgbm.model import LightGBMModel model = LightGBMModel( params={ "n_estimators": 200, "learning_rate": 0.03, "num_leaves": 15, }, early_stopping=100, eval_ratio=0.2, # 20% 做验证集 ) model.fit(X_train, y_train) pred = model.predict(X_test) # 评估 ic = pred.corr(y_test) print(f"测试集 IC: {ic:.4f}") ``` ### 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) pred = model.predict(X_test) ``` ### 特征重要性 ```python # LightGBM imp = model.get_feature_importance(importance_type="gain") print(imp.head(10)) # → feature, importance, importance_pct # CatBoost imp = model.get_feature_importance() print(imp.head(5)) ``` ### 交叉验证 ```python # 5 折时间序列 CV(不 shuffle) cv_df = model.cv_evaluate(X_train, y_train, n_folds=5) print(cv_df) # → 各折 IC + MSE, 均值 ``` ### 模型持久化 ```python # 保存 model.save("models/lightgbm_000001.pkl") # 加载 model = LightGBMModel.load("models/lightgbm_000001.pkl") ``` ### ML 策略回测 ```python from models.backtest_integration import MLStrategy, MLBenchmark # 预测值分位 → 交易信号 strategy = MLStrategy( model=model, feature_engine=fe, buy_quantile=0.7, # 预测值最高的 30% 买入 sell_quantile=0.3, # 预测值最低的 30% 卖出 rebalance_freq=5, # 每 5 日调仓 ) report = engine_bt.run(strategy, price_df, factor_df) # 多模型对比 benchmark = MLBenchmark( models=[lgb_model, cb_model], feature_engine=fe, price_df=test_price, factor_df=test_factor, ) df = benchmark.run() print(df) # → model × (IC, total_return, sharpe, win_rate, trades) ``` --- ## 8. 情绪因子 — SentimentEngine ### 配置 API Key 编辑 `finance/.env`: ```bash # DashScope API(推荐) QWEN_API_KEY=sk-your-key-here QWEN_MODEL=qwen-turbo # 或本地 Ollama # QWEN_LOCAL_BASE_URL=http://localhost:11434/v1 # QWEN_LOCAL_MODEL=qwen2.5:7b ``` ### 配置分析范围 ```bash # 按指数成分股分析(沪深300 + 中证500) SENTIMENT_SCOPE_TYPE=index SENTIMENT_SCOPE_INDEXES=000300,000905 # 按板块分析 # SENTIMENT_SCOPE_TYPE=sector # SENTIMENT_SCOPE_SECTORS=银行,电力设备,医药生物 # 按自定义列表 # SENTIMENT_SCOPE_TYPE=custom # SENTIMENT_SCOPE_CUSTOM=000001.SZ,600519.SH,300750.SZ ``` ### 使用情绪引擎 ```python from factors.sentiment.sentiment_engine import SentimentEngine from factors.sentiment.news_source import NewsSource from factors.sentiment.qwen_client import QwenClient sent = SentimentEngine(dm, qwen_client=QwenClient(), news_source=NewsSource()) # 单股票情绪因子 sent_df = sent.compute("000001.SZ", max_news=20) # → DataFrame: (trade_date, news_sent_5, news_conf_5, sent_delta_5) # 批量计算 results = sent.compute_batch( ts_codes=["000001.SZ", "600519.SH", "300750.SZ"], max_news=10, ) ``` ### 新闻数据源 系统聚合三个数据源: | 数据源 | 说明 | 配置 | |--------|------|------| | AkShare `stock_news_em` | 东方财富个股新闻 | `use_akshare=True` | | MariaDB `xwlb_daily_ext` | 新闻联播分割数据 | `use_xwlb=True` | | MCP `trendradar-news` | 外部新闻聚合服务 | `use_mcp=True` | ```python news = NewsSource( use_akshare=True, # 启用东方财富 use_xwlb=True, # 启用新闻联播 use_mcp=False, # 关闭 MCP ) news_df = news.fetch("000001.SZ", start="20260501", end="20260603") # → DataFrame: date, title, content, source, url ``` ### 日期对齐机制 - **AkShare 新闻**:`发布时间` 直接保留 → `align_news_to_trading_days` 对齐到最近交易日 - **新闻联播**:`news_date + 1 day`(晚间播出 → 次日市场影响)→ 对齐到交易日 ``` 周五新闻联播 → +1 = 周六 → align → 下周一交易日 ``` --- ## 9. Agent 系统 — 命令行入口 ### 注册 Agent ```python from agents.orchestrator import AgentOrchestrator engines = { "dm": dm, "fe": engine_fe, "bt": engine_bt, "opt": opt_engine, "sent": sent, } orch = AgentOrchestrator(**engines) orch.setup() # → [Orchestrator] 已注册 4 个 Agent: ['research', 'selection', 'risk', 'report'] ``` ### CLI 命令 ```bash # 完整每日流程(同步行情 → 风险评估 → 选股打分 → 生成日报) python finance/cli/agent_cli.py daily # 今日选股 Top 15 python finance/cli/agent_cli.py picks 15 # 风险评估 python finance/cli/agent_cli.py risk # 因子研究(IC 评估) python finance/cli/agent_cli.py research # 生成指定日期日报 python finance/cli/agent_cli.py report 20260603 ``` ### 每日流程输出 ``` ============================================================ [Orchestrator] 每日流程 — 20260603 ============================================================ [Step 1/4] 同步行情... 0 条(已是最新) [Step 2/4] 风险评估... high, 仓位 30% [Step 3/4] 股票打分... 1 只 [Step 4/4] 生成日报... reports/daily_20260603.md ``` ### 日报输出 日报保存到 `finance/reports/daily_YYYYMMDD.md`,内容包含: - **市场概览**:上证/深证/创业板 收盘价、涨跌幅、5日/20日趋势 - **今日推荐**:TOP 15 股票打分排名 - **风险评估**:风险等级、建议仓位、止损线、预警 ### 编程调用 ```python # 各 Agent 独立调用 selection_result = orch.picks(date="20260603", top_n=15) risk_result = orch.risk_check() research_result = orch.run_research_cycle() report_result = orch.generate_report(date="20260603") ``` --- ## 10. 配置说明 ### 环境变量(`finance/.env`) ```bash # ── Qwen API ────────────────────── QWEN_API_KEY=sk-xxx # DashScope API Key QWEN_MODEL=qwen-turbo # 模型选择: qwen-turbo/plus/max # ── 本地 Ollama(可选) ────────── # QWEN_LOCAL_BASE_URL=http://localhost:11434/v1 # QWEN_LOCAL_MODEL=qwen2.5:7b # ── 数据库 ─────────────────────── MAC_DB_HOST=127.0.0.1 MAC_DB_PORT=13306 MAC_DB_USER=myquant MAC_DB_PASSWORD= MAC_DB_NAME=myquant # ── 情绪分析范围 ───────────────── SENTIMENT_SCOPE_TYPE=index SENTIMENT_SCOPE_INDEXES=000300,000905 SENTIMENT_MAX_NEWS_PER_STOCK=20 # ── MCP 新闻服务(可选) ───────── NEWS_MCP_URL=http://192.168.1.160:3333/mcp ``` ### 回测参数 ```python VectorBTEngine( initial_capital=100_000, # 初始资金(元) commission=0.0003, # 手续费(万三) ) ``` ### Optuna 参数 ```python opt_engine.optimize( n_trials=200, # 试验次数 metric="sharpe", # 优化目标 # 可选: cagr, calmar, total_return, return_over_dd, win_rate, profit_factor ) ``` ### ML 模型参数 ```python # LightGBM 推荐参数 LightGBMModel(params={ "n_estimators": 200, "learning_rate": 0.03, "num_leaves": 15, "min_data_in_leaf": 20, "feature_fraction": 0.7, "bagging_fraction": 0.7, }) # CatBoost 推荐参数 CatBoostModel(params={ "iterations": 200, "learning_rate": 0.03, "depth": 5, "min_data_in_leaf": 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(oversold=30, overbought=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()) # Walk-Forward 验证 wf = opt_engine.optimize_walk_forward( RSIMeanRevertStrategy, rsi_revert_space, price, factor_df, n_trials=80, train_window=756, test_window=252, ) print(wf.summary()) ``` ### 示例 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) print(report.summary()) print(model.get_feature_importance().head(5)) ``` ### 示例 4:每日 Agent 运行 ```python from agents.orchestrator import AgentOrchestrator orch = AgentOrchestrator( dm=dm, fe=engine_fe, bt=engine_bt, opt=opt_engine, sent=sent, ) orch.setup() results = orch.run_daily() # 获取结果 sel = results["selection"] risk = results["risk"] report_path = results["report"]["report_path"] print(f"日报: {report_path}") ``` --- ## 12. 常见问题 ### Q: SSH 隧道连接失败? ```bash # 检查端口 lsof -i :13306 | grep LISTEN # 重新建立 bash shared/script/autossh.sh ``` ### Q: AkShare 返回 RemoteDisconnected? 这是 AkShare 的 curl_cffi 在连续请求时偶发的连接问题。系统已内置 3 次递增间隔重试 + fallback 机制,通常第 2-3 次重试会成功。如果持续失败: - 等待 30 秒后重试 - 减少并发请求频率 - 检查网络是否能访问 eastmoney.com ### Q: 因子计算结果全是 NaN? - 技术因子:前 N 个周期内 NaN 是正常的(如 20 日动量前 19 天为 NaN) - 基本面因子:检查财务数据是否已同步(`dm.get_financial(ts_code)`) - 情绪因子:检查是否配置了 `QWEN_API_KEY` ### Q: 回测结果为 0 笔交易? - 检查策略参数是否过于严格(如 RSI oversold=10 过少触发) - 使用 `OptunaEngine.optimize()` 寻找更优参数 - 检查因子值是否合理(`factor_df.describe()`) ### Q: 模型训练只有 2 棵树? 当验证集损失不下降时,早停会在很少的迭代后触发。这是单股票预测的正常现象(信号噪声比低)。建议: - 设置 `eval_ratio=0.0` 禁用早停 - 降低 `learning_rate` 到 0.01 - 增加 `min_data_in_leaf` 防止过拟合 ### Q: 情绪因子返回空? - 确认 `.env` 中 `QWEN_API_KEY` 已配置 - 检查网络是否能访问 `dashscope.aliyuncs.com` - 如果使用本地 Ollama,确认服务运行中:`curl http://localhost:11434/api/tags` ### Q: 日报中选股为空? 日报只对 DB 中有日线缓存的股票打分。需要先同步目标股票池的数据: ```python # 同步单只 dm.sync_daily("000001.SZ") # 按范围批量同步(需先配置 SENTIMENT_SCOPE) codes = sent.get_scope_stocks() for code in codes[:10]: dm.sync_daily(code) ``` --- ## 13. CLI 脚本参考 所有脚本位于 `finance/cli/`,需在项目根目录或 `finance/` 下运行。 --- ### 13.1 Agent 系统入口 — `agent_cli.py` ```bash cd finance && python cli/agent_cli.py <命令> [参数] ``` | 命令 | 说明 | 示例 | |------|------|------| | `daily [DATE]` | 完整每日流程(增量同步已缓存→评估风险→选股→日报) | `agent_cli.py daily` | | `picks [N] [DATE]` | 多因子选股 Top N(需已缓存) | `agent_cli.py picks 15` | | `risk` | 市场风险评估(等级、仓位、止损) | `agent_cli.py risk` | | `research` | 因子发现:遍历因子计算 IC/IC_IR 排名 | `agent_cli.py research` | | `report [DATE]` | 生成日报(含三指数行情+选股+情绪+风险评估) | `agent_cli.py report` | | `warmup [N]` | 首次批量预热范围股票到 DB 缓存(每批 N 只,默认 50) | `agent_cli.py warmup 50` | **`daily` 流程**: ``` [Step 1/4] 增量同步 → 只更新已缓存股票(最新则 0.04s 跳过) → 未缓存提示:运行 'agent_cli.py warmup' 首次预热 [Step 2/4] 风险评估 → high/medium/low + 仓位建议 + 预警 [Step 3/4] 股票打分 → DB 缓存命中率 + 多因子等权打分 → Top 15 [Step 4/4] 日报生成 → 三指数行情 (Tushare) + 情绪摘要 + 风险预警 → reports/daily_YYYYMMDD.md ``` **数据源优先级**:Tushare → AkShare(`.env` 配置 `TUSHARE_TOKEN`) --- ### 13.2 数据层验证 — `demo_data_manager.py` ```bash python cli/demo_data_manager.py [--ts_code CODE] [--start YYYYMMDD] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 测试股票代码 | | `--start` | `20250101` | 起始日期 YYYYMMDD | 5 步验证:数据库连接 → 建表 → 股票列表 → 日线获取(双源fallback) → 增量同步。 --- ### 13.3 因子引擎验证 — `demo_factor_engine.py` ```bash python cli/demo_factor_engine.py [--ts_code CODE] [--ts_code2 CODE] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 测试股票代码 | | `--ts_code2` | `600519.SH` | 截面测试第二只股票 | 验证:因子注册表(12分类/34因子)→ 技术因子计算(describe统计) → 基本面因子(ROE/PE/PB/EP) → NaN 覆盖率检查 → 双股票截面因子。 --- ### 13.4 回测引擎验证 — `demo_backtest.py` ```bash python cli/demo_backtest.py [--ts_code CODE] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 回测股票代码 | 测试 5 个内置策略: | 策略 | 参数 | |------|------| | SMACrossStrategy | (5,20) / (10,60) | | RSIMeanRevertStrategy | (30,70) / (20,80) | | MomentumBreakoutStrategy | lookback=20 | | FactorCrossStrategy | momentum_20 > 0 | | FactorRotationStrategy | momentum top 20% | --- ### 13.5 参数优化验证 — `demo_optimizer.py` ```bash python cli/demo_optimizer.py [--ts_code CODE] [--trials N] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 回测股票代码 | | `--trials` | `200` | Optuna 试验次数 | 对 RSI 反转策略执行参数寻优 + Walk-Forward 验证。输出最优 vs 默认对比表 + 参数重要性排序。 --- ### 13.6 ML 模型验证 — `demo_ml.py` ```bash python cli/demo_ml.py [--ts_code CODE] [--lookahead N] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 训练股票代码 | | `--lookahead` | `5` | 预测未来 N 日收益 | 完整 ML pipeline:特征工程(25因子→Winsorize→RobustScaler) → LightGBM训练(IC/CV) → CatBoost训练 → MLBenchmark对比(IC/收益/夏普/胜率)。 --- ### 13.7 情绪因子快速验证 — `demo_sentiment.py` ```bash python cli/demo_sentiment.py [--ts_code CODE] [--no-qwen] ``` | 参数 | 默认值 | 说明 | |------|--------|------| | `--ts_code` | `000001.SZ` | 测试股票代码 | | `--no-qwen` | flag | 跳过 Qwen API 调用 | 6 步验证:新闻数据源(三源聚合) → 日期对齐 → Qwen 客户端状态 → SentimentEngine全链路 → 分析范围解析。 适合快速检查情绪因子系统是否就绪。 --- ### 13.8 情绪因子详细演示 — `demo_sentiment_detail.py` ```bash python cli/demo_sentiment_detail.py [选项] ``` 最详细的情绪因子脚本,支持完整命令行参数和逐步输出。 | 参数 | 类型 | 默认值 | 说明 | |------|------|--------|------| | `--ts_code` | str | `000001.SZ` | 股票代码,多个用逗号分隔 | | `--date` | str | 今天 | 目标日期 YYYYMMDD | | `--start` | str | date-30天 | 起始日期 YYYYMMDD | | `--end` | str | date | 结束日期 YYYYMMDD | | `--scope-type` | str | - | 分析范围:`index`/`sector`/`custom`/`all` | | `--scope-indexes` | str | `000300` | 指数代码(逗号分隔) | | `--scope-sectors` | str | - | 板块名称(逗号分隔) | | `--max-news` | int | .env 配置 | 最大新闻条数 | | `--max-analyze` | int | `50` | Qwen API 分析最大条数(控制成本) | | `--no-xwlb` | flag | - | 禁用新闻联播数据源 | | `--no-akshare` | flag | - | 禁用东方财富数据源 | | `--no-mcp` | flag | - | 禁用 MCP 数据源 | | `--source` | str | - | 仅用指定数据源:`xwlb`/`akshare`/`mcp` | | `--no-qwen` | flag | - | 跳过 Qwen API 调用(仅演示数据流) | 使用示例: ```bash # 默认演示(000001.SZ,最近30天,全数据源) python cli/demo_sentiment_detail.py # 指定股票和日期 python cli/demo_sentiment_detail.py --ts_code 600519.SH --date 20260603 # 多股票 + 日期范围 python cli/demo_sentiment_detail.py --ts_code 000001.SZ,300316.SZ --start 20260501 --end 20260603 # 按指数成分股分析 python cli/demo_sentiment_detail.py --scope-type index --scope-indexes 000300 # 按板块分析 python cli/demo_sentiment_detail.py --scope-type sector --scope-sectors 银行,电力设备 # 只看东方财富新闻,不调用 Qwen python cli/demo_sentiment_detail.py --source akshare --no-qwen --max-news 20 ``` 输出 6 步详情: ``` Step 0: 初始化引擎(显示数据源、API状态、范围、Tushare可用性) Step 1: 按数据源分别拉取新闻(xwlb/AkShare/MCP 各自数量 + 双源fallback) Step 2: 新闻详情(按来源分开展示标题/内容/链接) Step 3: 日期对齐(xwlb +1day偏移 + 非交易日对齐 + DB缓存检查→sync补齐) Step 4: Qwen 情绪分析(每条新闻的分数/置信度/主题/来源标签) Step 5: 因子计算(weighted sent / confidence-weighted / momentum + 公式说明) Step 6: 结果输出(因子值表 + 历史统计 + 每新闻情绪贡献明细) ``` --- ### 13.9 脚本一览 | 脚本 | 参数 | 用途 | 数据源 fallback | |------|------|------|:---:| | `agent_cli.py` | 子命令 + 参数 | 日常操作入口 | ✅ | | `demo_data_manager.py` | `--ts_code` `--start` | Sprint 0 验证 | ✅ | | `demo_factor_engine.py` | `--ts_code` `--ts_code2` | Sprint 1 验证 | ✅ | | `demo_backtest.py` | `--ts_code` | Sprint 2 验证 | ✅ | | `demo_optimizer.py` | `--ts_code` `--trials` | Sprint 3 验证 | ✅ | | `demo_ml.py` | `--ts_code` `--lookahead` | Sprint 4 验证 | ✅ | | `demo_sentiment.py` | `--ts_code` `--no-qwen` | Sprint 5 快速验证 | ✅ | | `demo_sentiment_detail.py` | 14 个 argparse 参数 | Sprint 5 详细演示 | ✅ |