Files
myquant/docs/usage.md
T
simonandClaude Opus 4.7 271a9343a5 Initial commit: cc-cursor 全链路量化研究平台
7 Sprints 全部完成:
  Sprint 0: 基础设施 (DataManager + MariaDB)
  Sprint 1: 因子引擎 (34因子/12分类)
  Sprint 2: VectorBT 回测 (5策略+截面)
  Sprint 3: Optuna 优化 (+Walk-Forward)
  Sprint 4: ML 模型 (LightGBM+CatBoost)
  Sprint 5: Qwen 情绪因子 (三源新闻+日期对齐)
  Sprint 6: Agent 系统 (4Agent+日报.md/.html)

生产加固 (15项): Tushare双源fallback, SSH自动恢复, pool_pre_ping,
  save_daily先删后插, load_dotenv绝对路径, 日报5d/20d修复,
  RiskAgent改上证指数, 昨日对比+数据截止, mac_report utf8mb4,
  CLAUDE-*.md 9条已知Bug, demo全参数化, djapi数据源归一化,
  indexDatas API修正

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-06-07 15:59:05 +08:00

29 KiB
Raw Blame History

cc-cursor 使用指南

Mac Mini 单机量化研究平台,覆盖数据获取 → 因子计算 → 回测 → 参数优化 → ML 模型 → 情绪因子 → Agent 系统 全链路。


目录

  1. 环境准备
  2. 数据库连接
  3. 数据层 — DataManager
  4. 因子引擎 — FactorEngine
  5. 回测引擎 — VectorBTEngine
  6. 参数优化 — OptunaEngine
  7. ML 模型 — LightGBM / CatBoost
  8. 情绪因子 — SentimentEngine
  9. Agent 系统 — 命令行入口
  10. 配置说明
  11. 完整示例
  12. 常见问题

1. 环境准备

硬件要求

  • macOS / Linux(本系统开发于 Mac Mini
  • 内存 ≥ 16GB(ML 模型训练推荐)
  • 网络:可访问东方财富 / 同花顺 API

Python 环境

# 激活 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 脚本开头加入:

import sys
sys.path.insert(0, "/path/to/cc-cursor/finance")

2. 数据库连接

建立 SSH 隧道

系统通过 SSH 隧道连接远程 MariaDB

bash shared/script/autossh.sh

验证隧道:

lsof -i :13306 | grep LISTEN
# → ssh ... localhost:13306 (LISTEN) ...

连接信息

Host:     127.0.0.1
Port:     13306
User:     myquant
Password: <your-db-password>
Database: myquant

数据库表

所有表使用 mac_ 前缀,与已有表隔离:

表名 内容 说明
mac_stock_basic A 股列表 5,524 只股票
mac_stock_daily 日线行情 按需同步
mac_stock_financial 财务指标 同花顺核心指标

测试连接

from database.connection import test_connection

if test_connection():
    print("数据库连接成功")
else:
    print("请先建立 SSH 隧道: bash shared/script/autossh.sh")

3. 数据层 — DataManager

初始化

from data.data_manager import DataManager

dm = DataManager()
dm.init_db()  # 首次使用创建表(幂等操作)

获取股票列表

# 从 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)

获取日线数据

# 获取单只股票日线(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"]

获取财务数据

fina = dm.get_financial("000001.SZ")
# → DataFrame: end_date, eps, bvps, roe, net_profit_margin, debt_to_assets, ...
# 数据源: stock_financial_abstract_ths(同花顺)
# 覆盖: 主板/创业板/科创板

数据同步

# 增量同步:从 DB 最新日期到今天的缺失数据
n = dm.sync_daily("000001.SZ")

# 批量同步全部股票(谨慎使用,耗时长)
total = dm.sync_all_daily()

4. 因子引擎 — FactorEngine

因子注册表

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

创建因子实例

# 按名称获取(使用默认参数)
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)

计算因子

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())

截面因子

# 计算多只股票在某一天的因子值
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]

因子质量检查

# 查看 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%(万三)
  • 方向:只做多

创建引擎

from backtest.vectorbt.engine import VectorBTEngine

engine_bt = VectorBTEngine(
    initial_capital=100_000,
    commission=0.0003,
)

使用内置策略

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% 交易=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) 截面选股

自定义策略

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)

截面回测(多股票)

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

使用预置搜索空间

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,          # 试验次数
)

读取优化结果

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 验证

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())
# → 各窗口参数变化 + 整体收益

快捷函数

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)

自定义搜索空间

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

特征工程

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}%")

数据划分

# 时间序列划分(前 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 训练

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 训练

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)

特征重要性

# 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))

交叉验证

# 5 折时间序列 CV(不 shuffle
cv_df = model.cv_evaluate(X_train, y_train, n_folds=5)
print(cv_df)
# → 各折 IC + MSE, 均值

模型持久化

# 保存
model.save("models/lightgbm_000001.pkl")

# 加载
model = LightGBMModel.load("models/lightgbm_000001.pkl")

ML 策略回测

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

# 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

配置分析范围

# 按指数成分股分析(沪深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

使用情绪引擎

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
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

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 命令

# 完整每日流程(同步行情 → 风险评估 → 选股打分 → 生成日报)
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 股票打分排名
  • 风险评估:风险等级、建议仓位、止损线、预警

编程调用

# 各 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

# ── 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=<your-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

回测参数

VectorBTEngine(
    initial_capital=100_000,   # 初始资金(元)
    commission=0.0003,         # 手续费(万三)
)

Optuna 参数

opt_engine.optimize(
    n_trials=200,              # 试验次数
    metric="sharpe",           # 优化目标
    # 可选: cagr, calmar, total_return, return_over_dd, win_rate, profit_factor
)

ML 模型参数

# 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:快速回测

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

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())

示例 3ML 训练 + 回测

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 运行

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 隧道连接失败?

# 检查端口
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: 情绪因子返回空?

  • 确认 .envQWEN_API_KEY 已配置
  • 检查网络是否能访问 dashscope.aliyuncs.com
  • 如果使用本地 Ollama,确认服务运行中:curl http://localhost:11434/api/tags

Q: 日报中选股为空?

日报只对 DB 中有日线缓存的股票打分。需要先同步目标股票池的数据:

# 同步单只
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

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

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

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

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

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

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

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

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 调用(仅演示数据流)

使用示例:

# 默认演示(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 详细演示