Files
qlib/config.yaml
Simon 23972e7063 feat: 股息率案例口径 + 策略库与图表统一 + 回测存档完整化
汇总三轮未提交的开发(每轮均在本机 MariaDB + 真实浏览器上验证):

1) 股息率案例(全市场股息率最高 n 只,默认 20,每 m 月择股)
   - 新增日频估值表 daily_basic + 迁移;股息率因子(dv_ratio / dividend_yield / TTM)
   - 名称历史表 stock_name_history:剔除 ST 按**择股日当时名称**判定,消除
     「曾高股息后 ST」的股息陷阱(实测 3.70pp 偏差)
   - 区间择股/调仓双周期(m 择股 / y 调仓)、指数成分与白名单、停牌近似剔除
   - 复权因子口径核对(4,164,742 行、缺失 0.0%)、收盘价成交与涨跌停拦单
   - 案例实测:2020-01-01~2026-09-04 总收益 +24.86%(年化 3.52%、回撤 -28.58%)

2) 策略库与前端统一
   - strategy 表 + CRUD/PUT 原地更新 + `describe_strategy` 按 spec 真实推导
     「一句话说明 + 计算公式 + 执行步骤 + 注意事项」(与引擎实执行规则同源)
   - 任何出现股票代码处都成对显示名称且可点击进个股页
   - 全站图表基座统一 TradingView Lightweight Charts(ECharts 依赖、
     锁文件、组件与文档标注一并清除),买卖点标记只落在真实交易日上

3) 回测存档完整化(可往复查看)
   - 同步端点(POST /api/backtests、/api/factor-tests)此前完全不落库 → 现在同样归档,
     归档 id 经响应头 X-Experiment-Id 返回(不破坏 response_model)
   - data_version 首次真实写入(数据快照指纹:最新交易日 + 各表规模)
   - 个股收益曲线默认**全量保存**(此前硬截断 60 只);超出体积预算才裁剪,
     并写 archive_meta(机器可读)+ unimplemented(人可读)如实标注
   - 列表 kind/q 过滤 + X-Total-Count(此前 limit=50 静默截断)、DELETE 归档
   - 只读归档页 /experiments/{id}(Server Component,SSR 直出**选股条件**与
     **交易执行依据**);结果视图按 kind 分发(backtest/factor_test/selection),
     非回测归档不套用回测口径
   - 新增 CLI:prune_experiments(保留策略,默认 dry-run)、
     restore_experiment_from_job(从 Job 副本按原 id 重建被删的历史归档,默认 dry-run)

门禁:pytest 388 passed、ruff All checks passed、tsc 0 错误、图表单测 7 passed、
next build 成功、契约脚本 verify_strategy_workspace 59/59(含按 kind 逐类验证归档页)。
2026-09-20 07:31:04 +08:00

91 lines
3.6 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# ============================================================
# 全局可配置项(可提交,不含任何密钥)
# 约定(见 AGENT.md §2 / §33):
# - 可配置项统一写入本文件(项目根 config.yaml)
# - 密钥统一放根目录 .env(见 .env.example),
# 本文件通过 *_env 字段引用对应环境变量名,不写明文
# ============================================================
app:
name: "qlib-platform"
version: "0.1.0"
debug: false
# 从 .env 读取应用密钥的环境变量名
secret_key_env: "APP_SECRET_KEY"
api:
prefix: "/api"
database:
# 数据库 URL 选择优先级:
# 1) 环境变量 database.url_env(如 DATABASE_URL,可在 .env 覆盖)
# 2) database.mysql(enabled: true 时由 host/port/db/user 组装 mysql+pymysql URL)
# 3) 兜底 sqlite:///./data/quant.db(相对路径自动解析到项目根 data/)
url_env: "DATABASE_URL"
echo: false
# Alembic 迁移脚本目录(相对 backend/)
migrations_dir: "app/infrastructure/persistence/migrations"
# ---- MySQL(当前默认库)----
# 2026-09 由 SQLite data/quant.db 全量迁移而来;2026-09 再由远端库
# (192.168.1.10/qlib)切换到本机 MariaDB 10.11(127.0.0.1/qlib),
# 数据为逐表一致副本(stock_daily 7,792,869 / adjust_factor 7,898,717 等)。
# host/port/db/user 明文可提交;密码经 password_env 引用 .env 变量
# (AGENT.md §33:密钥只放根目录 .env,本文件不写明文密码)。
mysql:
enabled: true
host: "127.0.0.1"
port: 3306
db: "qlib"
user: "qlib"
password_env: "MYSQL_PASSWORD"
charset: "utf8mb4"
data_source:
primary: "tushare"
fallback: "sina"
tushare_token_env: "TUSHARE_TOKEN"
storage:
# 相对项目根目录
raw_dir: "data/raw"
normalized_dir: "data/normalized"
parquet_dir: "data/parquet"
qlib_dir: "data/qlib"
job:
# 研究任务执行模式:
# subprocess —— 独立子进程执行(内存隔离 + RLIMIT 上限,防研究任务 OOM 拖垮 API 服务)
# local —— 本进程内执行(开发 / 单测,无隔离)
# 可用环境变量 JOB_MODE 覆盖(测试强制 local)。
mode: "subprocess"
# subprocess 模式下子进程虚拟地址空间上限(GB);达到上限任务以 MemoryError 失败,不会 OOM 整机
max_memory_gb: 6
# 并发研究子进程上限(超出直接失败并提示稍后再试)
max_concurrent_jobs: 2
research:
# 归档(Experiment.result_json)行为:
# archive_curve_limit —— 个股收益曲线(symbol_curves)数量上限:
# null = **完整存档**(默认,期内持有的每只都落库);填数字 = 按 |期末收益|
# 降序截断,且结果里会如实写入截断说明(unimplemented)与 archive_meta。
# 可用环境变量 QLIB_ARCHIVE_CURVE_LIMIT 覆盖。
archive_curve_limit: null
# archive_max_chars —— 归档结果 JSON 的字节预算(超预算时按 |期末收益| 降序裁剪
# 曲线并如实标注;MEDIUMTEXT 硬上限 16,777,215 字节,默认留约 28% 余量)。
# 可用环境变量 QLIB_ARCHIVE_MAX_CHARS 覆盖。
archive_max_chars: 12000000
agent:
llm:
# 大模型接入:URL 与模型名在此配置(明文、可提交);
# 密钥只放根目录 .env(LLM_API_KEY,见 .env.example)——本文件不写任何 Key。
# 可选:仍可通过 .env 的 LLM_BASE_URL / LLM_MODEL 覆盖下面两个值。
base_url: "https://dashscope.aliyuncs.com/compatible-mode/v1"
model: "qwen-plus"
base_url_env: "LLM_BASE_URL"
model_env: "LLM_MODEL"
api_key_env: "LLM_API_KEY"
logging:
level: "INFO"