7b41bb8c6d
feat(scripts): 迁移轮动策略定时调度器
...
新增文件:
- scripts/daily_scheduler.py: 定时调度器,支持交易日判断、回测执行、OSS上传、钉钉推送
- scripts/run_rotation.py: 回测入口脚本,支持Flask API和本地数据源切换
- config/settings.py: 配置管理模块,支持钉钉多群配置
功能:
1. 每天15:30自动检查交易日
2. 交易日执行策略回测生成报告
3. 上传报告图片到OSS
4. 发送图片链接到钉钉群
修复:
- 添加oss2库SyntaxWarning过滤(Python 3.12兼容)
- 钉钉消息精简为标题+图片格式
2026-05-18 00:57:59 +08:00
2789713637
fix(report): 修复 generate_legacy_report 重复日期导致的 reindex 失败
...
问题:nav_series 或 backtest_result.index 存在重复日期时,
reindex() 抛出 'cannot reindex on an axis with duplicate labels'
修复:
- 先检查并去除 nav_series 的重复日期
- 同时检查并去除 backtest_result.index 的重复日期
- 使用 duplicated(keep='last') 保留最后一条记录
2026-05-14 01:21:07 +08:00
7121e78e70
fix(report): 修复 generate_legacy_report 数据类型处理
...
- benchmark_data 可能是 Series 或 DataFrame,添加类型判断
- etf_nav_data 现在是字典格式 {etf_code: DataFrame},修正解析逻辑
- 正确从 DataFrame.attrs 中提取净值和溢价率数据
2026-05-14 01:10:12 +08:00
aeb95a6f4c
refactor: 配置文件迁移到策略目录(模块自包含)
...
迁移内容:
- config/strategies/rotation.yaml → strategies/rotation/config.yaml
路径更新(核心文件):
- strategies/rotation/strategy.py(注释示例)
- scripts/generate_legacy_report.py(config_path)
- run_rotation.py(注释和默认参数)
- datasource/hybrid_source.py(from_yaml示例和fetch_rotation_data)
保留:
- config/strategies/cci.yaml(无对应策略目录,暂保留)
设计原则:策略模块自包含,配置与实现同目录,方便移植和复制
验证:策略加载成功(候选池11只,回测区间2019-01-01 ~ 2026-05-12)
2026-05-12 22:14:35 +08:00
412177837f
fix: 报告生成器数据对齐修复
...
修复内容:
1. 指数价格获取改用index_data而非index_close
- 原问题:index_close对齐后N225最后几天的值为nan
- 修复:从原始OHLCV获取close,用ffill填充缺失值
2. ETF净值数据对齐到回测日期
- 原问题:etf_nav_data索引与backtest_result不对齐
- 修复:用reindex(backtest_result.index, method='ffill')
3. ETF价格数据同样对齐到回测日期
修复后报告显示:
- 日经225指数最新价: 62713.65(原为nan)
- 创业板指溢价率: +3.70%⚠️
- 日经225溢价率: +0.85%
2026-05-12 01:50:30 +08:00
38a31357d1
feat: 新框架集成原引擎报告生成模块
...
新增 scripts/generate_legacy_report.py:
- 使用新框架运行回测
- 将数据格式转换为原引擎格式
- 调用原引擎 generate_performance_report 生成报告
输出文件:
- rotation_legacy_chart.png (净值曲线+回撤+持仓分布)
- rotation_legacy_metrics.json (策略指标JSON)
- rotation_legacy_nav.csv (净值曲线数据)
用法:python scripts/generate_legacy_report.py
2026-05-12 01:42:25 +08:00
1fca536c95
refactor: 归档旧代码,保留新框架结构
...
归档内容:
- core/ (数据源、因子计算、通用工具) → archive/legacy_core/
- strategies/rotation/engine.py, portfolio.py, report.py → archive/legacy_core/
- scripts/ (run_rotation, daily_scheduler) → archive/legacy_scripts/
- examples/ → archive/legacy_examples/
- tests/ (实验、对比测试) → archive/legacy_tests/
- 单独文件 (fetch_*.py, 动量.py, 全球市场.py等) → archive/single_files/
保留新结构:
- framework/ (抽象接口)
- strategies/shared/ (定制组件)
- strategies/rotation/strategy.py (新策略)
- 外层配置: .env, .dockerignore, build-and-push.sh, hk_ecs.pem, README.md, requirements.txt
- Docker相关: Dockerfile, Dockerfile_base, docker-compose.yml
更新README反映新框架架构
2026-05-11 23:34:23 +08:00
6b59855c28
experiment(rotation): 同大类扩充与纳指vs标普替换对比实验
...
技术修复:
- SOCKS5代理IPv6问题:socks5:// → socks5h:// (hybrid_source.py, yfinance_source.py)
目录整理:
- scripts/ → 仅保留策略入口(daily_scheduler, run_rotation, run_cci_screener)
- 实验脚本移至 tests/experiments/
- 工具脚本移至 tests/utils/
- 实验记录新增 docs/experiments/
- results/ 添加到 gitignore
实验结果:
实验001 - 同大类扩充(添加标普500):
├─ 累计收益: 1467.35% → 1176.26% (-291%)
├─ CAGR: 48.10% → 43.82% (-4.28%)
├─ 调仓次数: 459 → 501 (+42次)
└─ 结论: 添加同大类标的不增加跨类分散,反而侵蚀收益
实验002 - 纳指vs标普替换对比:
├─ 累计收益: 1467.35% → 1118.77% (-348%)
├─ CAGR: 48.10% → 42.87% (-5.22%)
├─ Sharpe: 2.21 → 2.08 (-0.13)
├─ MaxDD: -17.33% → -15.14% (+2.18%)
└─ 结论: 纳指100优于标普500,成长风格更适合动量策略
策略建议:
- 保持纳指100作为美股大类代表
- 不添加同大类新标的(避免类内切换成本)
- 新增标的应优先考虑新大类(增加跨类分散)
2026-05-06 20:43:38 +08:00
d0a9d66a11
feat(config): 添加CU.SHF有色金属期货信号源,移除冗余上证红利
...
讨论背景:
- 159980.SZ(有色ETF)是商品型基金,跟踪上期所有色金属期货价格指数
- 应使用期货价格(CU.SHF沪铜)作为信号源,与黄金(AU.SHF)/原油(CL.NYM)保持一致
- 上证红利(000015.SH)与中证红利低波(H30269.CSI)高度相关,同属A股大类
在diversified模式下只能选1个,保留两个无实际意义
配置变更:
- rotation.yaml: 新增CU.SHF→159980.SZ映射(market=COMMODITY)
- rotation.yaml: 移除000015.SH上证红利(与红利低波冗余)
- hybrid_source.py: FUTURES_CODE_MAP新增CU.SHF铜期货
- ab_test_iterations.py: 同步更新有色market为COMMODITY
实证结果 - CU.SHF加入前后对比(11只池,2019-2026):
无CU(11只): CAGR=47.37%, Sharpe=2.25, MaxDD=-17.86%, Calmar=2.65
含CU(12只): CAGR=46.16%, Sharpe=2.21, MaxDD=-17.86%, Calmar=2.58
影响: CAGR-1.2%, 商品大类内部竞争加剧(黄金/原油/有色三选一)
2020/2022铜价暴涨时有色贡献额外收益,整体影响很小
实证结果 - 移除上证红利后(11只,2019-2026):
含上证红利: CAGR=46.16%, Sharpe=2.21, MaxDD=-17.86%, Calmar=2.58
移除后: CAGR=46.42%, Sharpe=2.22, MaxDD=-17.33%, Calmar=2.68
所有指标均改善,消除冗余标的提升选择效率
实证结果 - diversified=true vs false(11只,select_num=3):
true(跨类分散): CAGR=46.45%, Sharpe=2.22, MaxDD=-17.33%, Calmar=2.68
false(纯Top3): CAGR=44.19%, Sharpe=2.13, MaxDD=-18.12%, Calmar=2.44
关键差异在2022年(+17.63%): false模式选3只商品同时回调
结论: diversified=true全面优于false,保持当前配置
最终候选池(11只,7大类):
A股: 创业板(399006.SZ), 红利低波(H30269.CSI)
美股: 纳指100(NDX) | 日本: 日经225(N225) | 欧洲: 德国DAX(GDAXI)
港股: 恒生指数(HSI), 恒生科技(HSTECH.HK)
商品: 黄金(AU.SHF), 原油(CL.NYM), 有色金属(CU.SHF)
固收: 30年国债(931862.CSI)
2026-04-30 13:37:46 +08:00
c1fbd2c7db
feat(strategy): finalize global rotation system with advanced risk controls
...
Summary of updates:
1. Core Logic (engine.py): Added 'score > 0' filtering to support automatic cash positions during market downturns.
2. Experimental Analysis: Added scripts/analyze_negative_scores.py, scripts/test_select_num.py, and scripts/ab_test_iterations.py.
3. Documentation: Created docs/strategy_evolution_report.md detailing the evolution from benchmark to the final 47% CAGR version.
4. Configuration: Finalized rotation.yaml with 11 core assets and optimal risk parameters.
2026-04-30 00:56:20 +08:00
e946dbe804
docs(experiment): add experimental backtest script and pool analysis
...
实验与分析文档补充:
1. 脚本: scripts/full_pool_top3_backtest.py
- 用于快速测试不同标的池组合的脚本。
- 支持跨大类 Top 1 逻辑的独立验证。
2. 文档: data_logic_analysis.md
- 记录了从 43 只全市场池精简到 11 只核心池的逻辑推演。
- 详细对比了“相关性管理”对回撤的影响数据。
2026-04-30 00:15:21 +08:00
2829f80427
feat(backtest): 消除前视偏差,实现动态ETF池重建
...
消除回测前视偏差(Look-Ahead Bias):
- 新增 ETFDataCache 本地缓存系统,预下载全量ETF(含已退市)基础信息和日线数据
- 改造 ETFUniverseBuilder 支持纯历史模式,每个时间点只使用当时可获得的数据
- 动量.py 新增 dynamic 模式,回测中每60交易日动态重建ETF候选池
- momentum_experiment.py 同步支持动态重建
- 新增 ETF筛选引擎文档和动态池方案文档
无前视偏差实验结果(6组对比,2015-2026):
A: 全仓1只 CAGR=3.32%, MaxDD=-63.19%, Sharpe=0.26
B: 等权3只 CAGR=3.40%, MaxDD=-49.72%, Sharpe=0.30 ← 最优
C: 反波动率3只 CAGR=1.73%, MaxDD=-38.59%, Sharpe=0.21
D: 等权5只 CAGR=2.77%, MaxDD=-42.39%, Sharpe=0.29
E: 反波动率5只 CAGR=-0.37%, MaxDD=-19.56%, Sharpe=-0.03
F: 动量>0全选等权 CAGR=2.02%, MaxDD=-43.27%, Sharpe=0.24
最优方案: B(等权3只)夏普、Calmar、CAGR三项均最高
2026-04-29 22:15:01 +08:00
e301a08724
注释加密货币(BTC/ETH)并新增回测数据导出脚本
...
变更内容:
- rotation.yaml: 注释掉BTC和ETH加密货币配置,候选池从22只缩减为20只
- 新增 scripts/export_rotation_data.py: 导出回测原始数据到本地文件夹
回测结果 (2020-02-14 ~ 2026-04-28, 20只标的, 无加密货币):
- 累计收益: 171.36% (基准沪深300: 20.16%)
- CAGR(年化): 17.48% (基准: 2.89%)
- 年化夏普比率: 0.90 (基准: 0.26)
- 最大回撤: -30.85% (基准: -45.60%)
- Calmar比率: 0.57
- 日胜率: 52.49%
- 调仓次数: 478次 (年均80次, 平均持仓3.1天)
2026-04-28 20:28:35 +08:00
4a500ca5bf
feat(notify): 支持钉钉多群推送 & 添加轮动策略核心逻辑文档
...
- settings.py: 新增 get_all_dingtalk_configs() 自动扫描所有钉钉群配置
- notify.py: 新增 send_to_all_groups() 多群推送函数
- daily_scheduler.py: 报告和错误通知改用多群推送
- .env: 添加第二个钉钉群配置 (DINGTALK_WEBHOOK_2/SECRET_2)
- 轮动策略核心逻辑.md: 策略核心逻辑总结文档
2026-04-23 22:58:16 +08:00
ec749314bc
feat(data-source): 支持指数-ETF双轨数据获取及因子计算
...
- 新增使用Tushare获取A股ETF价格及净值数据的私有方法
- fetch_all方法支持接收完整代码配置,区分指数与ETF及市场类别
- 指数数据和ETF数据分别下载,ETF净值数据用于溢价率计算
- 采用A股交易日为主交易日历,非A股数据前向填充对齐
- 调整因子计算,支持指数价格计算因子,ETF价格计算收益率
- run_rotation脚本和RotationStrategy引擎适配指数-ETF配置格式
- 代码结构优化,增强多市场及加密货币处理能力
2026-03-25 22:01:44 +08:00
d500090305
fix(scripts): 修正日报发送标题及文本内容
...
- 将发送图文消息的标题由“ETF轮动策略日报”改为“ETF轮动策略调仓日报”
- 调整发送图文消息中文本内容,去除默认提示
- 发送报告时不再传递固定摘要文本,改为传空字符串
- 修复了每日任务中报告发送的文本逻辑问题
2026-03-19 22:59:38 +08:00
fb2f814111
feat(docker): 优化镜像支持中文字体及调度运行模式
...
- 基础镜像中添加多款中文字体,支持中文显示
- 主镜像安装中文字体并设置上海时区环境变量
- Dockerfile中创建日志目录并修改默认启动命令为定时调用调度器脚本
- 构建脚本支持动态镜像名,自动构建基础镜像,完善运行容器示例
- docker-compose修改为仅启动调度器服务,挂载相关配置、密钥、数据和日志目录
- 依赖更新,丰富金融数据、技术分析、绘图、机器学习及环境变量支持库
- 调度脚本参数调整,支持立即运行并退出及非后台模式运行切换
- 报告绘图中优先使用基础镜像预装的中文字体配置,提高字体兼容性和显示效果
2026-03-19 22:53:06 +08:00
76feec6824
fix(scheduler): 修复格式和代码风格问题,调整默认执行时间
...
- 规范了代码中的字符串引号统一使用双引号
- 调整了部分代码的参数换行和缩进格式
- 在load_dotenv调用中添加了缺失的空行
- 优化了日志打印字符串内引号使用一致性
- 修改主函数默认执行时间由15:30调整为09:00
- 修正字典取值和列表拼接中的引号使用,避免潜在错误
- 规范函数定义参数列表的格式,提高代码可读性
2026-03-19 21:57:24 +08:00
8d24fb91eb
refactor(scheduler): 重构每日任务调度逻辑并优化配置路径
...
- 将等待目标时间逻辑改为基于schedule库的定时任务调度
- 支持后台守护进程模式持续执行定时任务
- 优化命令行参数说明,默认执行时间改为15:30
- 简化立即执行和循环运行的逻辑
- 修改SSH私钥路径为相对于项目根目录
- 更新rotation.yaml配置中指数及加密货币标签说明
- 回测开始日期由2022-01-01调整为2020-01-01
refactor(report): 优化轮动策略绩效报告图表与指标展示
- 新增策略与基准绩效指标对比表格,展示累计收益、年化收益等关键指标
- 调整绩效表布局,增加绩效指标面板高度,保持与信号表格一致视觉
- 丰富绘图函数参数,支持传入绩效指标字典避免重复计算
- 规范调仓信号表操作列索引及样式,保持统一字体大小和行高
- 净值曲线、回撤及持仓分布面板分离,调整图表索引和标题名称
- 优化持仓分布图显示,提升整体报告信息完整性与易读性
2026-03-19 21:56:17 +08:00
098c13a006
feat(notification): 增加钉钉发送图片和文件功能,支持OSS图片上传
...
- 在DingTalkBot中添加发送图片消息(自动压缩)功能,支持大小限制自动处理
- 添加发送图文混合消息、发送文件消息接口,优化钉钉通知能力
- 实现发送本地图片链接和通过OSS上传图片再发送Markdown图文两种机制
- 新增阿里云OSS上传工具模块,支持文件和图片上传及预签名URL生成
- 创建每日任务调度脚本,实现每日交易日检查、策略执行、结果上传并通知
- 调整回测策略开始日期至2022年,适配最新数据范围
2026-03-19 21:21:52 +08:00
062f500369
refactor(rotation): 统一与配置文件代码映射和基准指数使用方式
...
- 将默认代码映射字典和基准指数改为可被策略配置覆盖的形式
- 修改配置文件rotation.yaml中候选池配置从列表变为代码与名称的字典映射
- 在运行脚本中加载配置时支持字典格式的code_list和benchmark,兼容旧格式列表
- 更新回测策略引擎通过配置动态获取基准指数代码
- 打印输出和函数调用中统一使用从配置加载的代码映射和基准名称数据
2026-03-19 00:33:06 +08:00
9b154a1a25
feat(rotation): 增加最新调仓信号展示功能
...
- 配置中取消固定end_date,改为默认使用当前日期
- 添加打印最新调仓信号的功能,显示持仓明细及调出品种
- 在报告生成流程中调用最新调仓信号打印函数
- 图表展示中新增最新调仓信号表格,支持颜色区分调入、调出和维持
- 优化报告图表布局,调整画布高度适应信号表内容
- 删除无用test.py测试脚本及相关冗余代码
2026-03-19 00:22:25 +08:00
02ba6a5df2
fix(scripts): 修正报告保存路径默认值
...
- 将报告保存路径前缀默认值由 "report" 修改为 "results/report"
- 确保报告文件默认保存在更合适的目录结构中
2026-03-18 23:38:07 +08:00
988c2335fb
chore(config): 添加环境变量示例及.gitignore更新
...
- 新增 .env.example,包含 Tushare API、钉钉机器人和PostgreSQL数据库配置模板
- 更新.gitignore,忽略本地配置文件如 .env.local 和 config_local.py
- 添加对报表文件命名规则的支持,保留示例文件不忽略
- 删除废弃的 chart.py 及相关图表模块代码
- 新增 config/settings.py,实现从环境变量读取配置的统一接口
- 设置数据目录及缓存目录,确保目录存在,提高配置管理规范性
2026-03-18 23:33:40 +08:00