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>
3.7 KiB
3.7 KiB
CLAUDE-data.md — 数据层 + 数据库
DataManager (finance/data/data_manager.py)
双数据源:Tushare(优先)→ AkShare(fallback)。DB 缓存优先。
from data.data_manager import DataManager
dm = DataManager()
dm.init_db() # 首次建表(幂等)
关键方法
stocks = dm.get_stock_list() # → 5524 只, DB 优先
daily = dm.get_daily("000001.SZ") # DB优先 → Tushare → AkShare
fina = dm.get_financial("000001.SZ") # 同花顺 + fallback
n = dm.sync_daily("000001.SZ") # 增量同步: latest>=today → 跳过
指数 vs 个股路由
_try_fetch() 自动检测 is_index_code():
000001.SH/399001.SZ→fetch_index_daily()(Tushareindex_daily/ AkShareindex_zh_a_hist)000001.SZ/600519.SH→fetch_daily()(stock daily)
数据源 (finance/data/sources/)
akshare_source.py—AkShareSource(个股+指数+财务)tushare_source.py—TushareSource(需TUSHARE_TOKEN,available=False自动跳过)
数据库 (finance/database/)
连接
from database.connection import get_engine, test_connection
# get_engine() 自动检测断连 → 运行 autossh.sh → 重建引擎
表结构(mac_ 前缀)
| 表 | 内容 | 主键 |
|---|---|---|
mac_stock_basic |
A股列表, 5524只 | ts_code |
mac_stock_daily |
日线 OHLCV | (ts_code, trade_date) |
mac_stock_financial |
财务指标 | (ts_code, end_date) |
mac_report |
报告持久化 | id |
DAO (finance/database/dao.py)
_DAILY_COLS/_FINA_COLS— 入库前字段筛选get_latest_trade_date(ts_code)→ 增量判断save_report()/query_reports()→ 报告管理
配置
# SSH 隧道
bash shared/script/autossh.sh
# host: 127.0.0.1:13306 user: myquant database: myquant
缓存策略
sync_daily: 已缓存且最新 → 0.04s 跳过- 未缓存 → 提示
agent_cli.py warmup - 每日增量只更新已缓存股票,未缓存统计跳过
⚠️ 已知 Bug 速查(避免重复踩坑)
B1: .env 加载路径
- 症状: Tushare available=False, QWEN_API_KEY 读不到
- 根因:
load_dotenv()不传路径,从 CWD 找 .env,而非finance/ - 修复:
config/settings.py用Path(__file__).parent.parent / ".env" - 加固:
tushare_source.py,qwen_client.py,news_source.py顶部import config.settings
B2: SSH 重连只生效一次
- 症状: 第一次断连能恢复,第二次断连无法恢复
- 根因:
_ssh_auto_attempted全局变量设 True 后永不重置 - 修复: 移除该变量。
get_engine()每次断连都触发_reconnect_ssh()→dispose()→ 重建
B3: 连接池半开连接
- 症状:
_test_engine()返回 True 但实际查询报_read_bytes超时 - 根因: 池中有活连接也有死连接,test 取到活的,查询取到死的
- 修复:
pool_pre_ping=True+pool_recycle=600+ 断连时_engine.dispose()
B4: save_daily 主键冲突
- 症状:
IntegrityError: Duplicate entry '000001.SZ-20260603' - 根因: Tushare 返回的数据含已存在的日期,
append模式遇主键冲突 - 修复: 写入前
DELETE FROM mac_stock_daily WHERE ts_code IN (...) AND trade_date IN (...)
B5: 数据不更新排查清单
- 检查 SSH 隧道:
lsof -i :13306 | grep LISTEN - 检查 Tushare:
python -c "from data.sources.tushare_source import TushareSource; print(TushareSource().available)" - 检查最新数据:
from database.dao import get_latest_trade_date; print(get_latest_trade_date('000001.SZ')) - 手动触发 sync:
dm.sync_daily('000001.SZ') - 预期行为: T+1 数据产出,节假日无新数据属于正常