|
|
61b6f0b0a3
|
docs: V3轮动策略核心逻辑文档
核心内容:
- V2 vs V3核心差异对比表
- 动态阈值机制详解(三层守卫)
- 短债双重角色:阈值参考 + 空余仓位填充
- 三步筛选流程:动态阈值 → 类内竞争 → 跨类排序+填充
- 具体示例:正常/危机/极端危机三种场景
- V3关键修复:重复代码计分 + 数据守卫 + 空信号状态保持
- 三次修复历程:74a664d → be8ca02 → 18bc9b8
- V3配置示例与回滚方案
回测绩效:
- CAGR: 27.81%
- 最大回撤: -24.36%
- 夏普: 1.40
- Calmar: 1.14
|
2026-05-19 01:13:43 +08:00 |
|
|
|
18bc9b8c44
|
fix: V3动态阈值根因2子问题和根因3修复
根因2子问题: bond无数据时不填充
- 问题: be8ca02无条件填充导致2002-2007年信号中出现931862.CSI
- 但执行器找不到收益数据,2/3仓位收益为0,引发-31.92%回撤
- 修复: generate()中过滤前检查bond_has_data,传入_grouped_selection
- 填充条件改为: bond_code存在 AND bond_has_data
- bond有数据(含负值)→填充 ✓; bond无数据(NaN)→不填充 ✓
根因3: 空target时保持旧持仓而非清仓
- 问题: _apply_rebalance_control中target为空时清仓
- 但独立脚本的行为是保持旧持仓
- 修复: else分支改为pass,保持current_held不变
- 在有bond数据期target不会为空,空target仅发生在2002-2007
修复后验证结果:
- CAGR: 27.81% (预期28.03%, 差异-0.22%)
- 最大回撤: -24.36% (预期-24.35%, 差异≈0) ✓
- 夏普: 1.40 (预期1.40) ✓
- 回撤区间: 2015-05~2016-06 (与预期一致) ✓
- Calmar: 1.14 (预期1.15)
净值: 334.46 → 394.80 (+18%)
|
2026-05-19 01:06:20 +08:00 |
|
|
|
be8ca023f7
|
fix: V3动态阈值两处根因修复
根因1: _check_rebalance重复代码计分Bug
- 问题: "CL=F,931862.CSI,931862.CSI"中短债只计一次得分
- 修复: 直接遍历持仓列表计算得分,而非遍历factor_cols做in判断
- 影响: 278天应防御时继续持有风险资产
根因2: 短债填充依赖阈值过滤
- 问题: 短债动量为负时(钱荒等)不填充防御仓位
- 修复: 无条件填充短债(防御机制不应依赖动量阈值)
- 影响: 17天仓位不满(1/3或2/3空置)
修复后结果:
- 净值: 292.56 → 334.46 (+14.4%)
- 夏普: 1.33 → 1.41 (+0.08)
- 持仓3只: 92.3% → 99.4% (满仓率提升)
- 短债填充更积极: 28.7%时间持有短债
|
2026-05-19 00:38:04 +08:00 |
|
|
|
957769b501
|
docs: 添加V3动态阈值实施方案文档
详细说明了:
1. 当前代码流程分析
2. 需要修改的文件及具体代码
3. V2 vs V3逻辑对照表
4. 关键注意事项(BOND角色转变、信号格式兼容等)
5. 验证方式与预期结果
6. 回滚方案
|
2026-05-19 00:01:25 +08:00 |
|
|
|
74a664d4ff
|
feat: V3动态阈值实施方案落地
核心逻辑:
1. config.yaml新增bond_threshold配置块
2. selectors.py新增动态阈值逻辑:
- _get_dynamic_threshold(): 阈值=短债动量×ratio
- _grouped_selection(): BOND不参与竞争,空余仓位填充短债
3. strategy.py传入bond_threshold_config
回测验证:
- 最终净值: 292.56
- 累计收益: 29155.96%
- 持仓3只: 92.3%(满仓率提升)
- 短债填充: 27.7%时间启用(空余仓位)
信号特征:
- 短债可重复出现表示仓位占比
- 例如 "NDX,931862.CSI,931862.CSI" → NDX 33%, 短债 67%
|
2026-05-18 23:58:10 +08:00 |
|
|
|
3e6d9d1fdb
|
refactor(config): 统一钉钉多群配置命名格式
.env 配置命名统一:
- 群1: DINGTALK_WEBHOOK_1 + DINGTALK_SECRET_1
- 群2: DINGTALK_WEBHOOK_2 + DINGTALK_SECRET_2
settings.py 读取逻辑简化:
- 从 i=1 开始读取编号配置
- 移除不带编号的默认配置处理
|
2026-05-18 22:23:01 +08:00 |
|
|
|
3ca403f38a
|
fix(config): 修复钉钉多群配置读取逻辑
问题:原逻辑从 i=1 开始查找 DINGTALK_WEBHOOK_1(不存在),
导致群2(DINGTALK_WEBHOOK_2)未被读取。
修复:
- 群1使用不带编号的 DINGTALK_WEBHOOK + DINGTALK_SECRET
- 从 i=2 开始读取编号配置
验证:成功读取到2个钉钉群配置
|
2026-05-18 22:20:28 +08:00 |
|
|
|
8476d0e7cd
|
docs(config): 补充短债指数收益归因实证结论
实证分析结论:
- 标的收益占比:约17%(债券本身增长)
- 决策收益占比:约83%(避险决策贡献)
核心发现:
短债指数的价值主要来自正确避险决策,而非债券本身增长。
这验证了动量轮动策略的核心逻辑:通过仓位选择规避下跌风险。
|
2026-05-18 01:02:58 +08:00 |
|
|
|
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 |
|
|
|
79c6ab8620
|
feat(rotation): 恢复短债指数931862.CSI作为BOND大类防御资产
配置变更:
- 恢复使用931862.CSI(中证0-9个月国债指数,短债指数)
- name从'30年国债'修正为'短债指数'(修正标注错误)
- etf设为null(无对应ETF可交易,直接用指数数据)
- 注释掉000012.SH配置(上证国债指数)
收益对比验证:
| 配置 | 最终净值 | 累计收益 | 说明 |
|------|---------|---------|------|
| 931862.CSI(短债) | 264.54 | 26354% | ✓ 当前配置 |
| 000012.SH(综合国债) | 216.30 | 21530% | 已注释 |
| 收益差异 | +48.24 | +4824% | 短债高18.2% |
决策原因:
1. 短债指数久期<1年,波动极小,熊市防御效果最佳
2. 000012.SH是综合国债指数,包含短债到长债,波动较大
3. 之前000012.SH错误映射到511520.SH(政金债ETF),指数-ETF不匹配
4. 931862.CSI虽无对应ETF,但数据覆盖19年(2007开始),回测充分
数据验证:
- 931862.CSI: 4335条数据 (2007-12-31 ~ 2026-05-14)
- 数据年数: 约19年
关键发现:
- 短债指数因其极低波动特性,在熊市动量稳定
- 红利低波(H30269)归类为A股,与创业板竞争A股Top1
- 短债指数(931862)单独作为BOND大类,自动入选
- 实现红利低波+短债同时持仓的双重防御机制
|
2026-05-17 00:55:03 +08:00 |
|
|
|
b419701c77
|
feat(rotation): 红利低波归类A股提升收益52%
配置变更:
- H30269.CSI(红利低波)从BOND改为A股大类
- 931862.CSI(短债指数)保持BOND大类
- start_date调整为2002-01-01
回测验证:
- 新配置净值264.54,累计收益26354%
- 旧配置净值173.83,累计收益17283%
- 收益提升52%
关键发现:
- 红利低波作为A股可与创业板指竞争,优胜者入选
- 短债单独作为BOND自动入选
- 之前同属BOND时只能选1个,无法同时持有
- 新配置可实现'红利低波+短债'同时持仓
|
2026-05-16 23:28:23 +08:00 |
|
|
|
969385f39c
|
feat(rotation): 采用红利低波+短债指数组合作为防御类资产
配置变更:
- H30269.CSI(红利低波指数)归类为BOND大类
- 931862.CSI(短债指数)归类为BOND大类
- 添加正确的标注说明(注明实际是红利低波和短债指数)
防御效果分析:
- 红利低波提供'类债券'股票防御(高股息+低波动)
- 短债指数提供真正的债券防御(极低波动)
- 2008年熊市短债指数持仓172天(55%),贡献主要防御效果
回测验证:
- 组合配置净值173.83,累计收益17283%
- 比单红利低波配置高50%(115.14 → 173.83)
- 2008年少亏23%(-43.87% → -20.85%)
删除旧报告:红利低波防御配置分析报告.md
创建新报告:防御类资产组合配置分析报告.md
|
2026-05-16 22:54:51 +08:00 |
|
|
|
48bf3fde2e
|
fix(rotation): 纠正指数代码标注,H30269.CSI为红利低波而非国债
配置变更:
- H30269.CSI正确标注为'红利低波'(中证红利低波动指数)
- 移除错误配置的931862.CSI(中证0-9个月国债指数,无对应ETF)
- 红利低波归类为DEFENSIVE大类(防御类资产)
分析发现:
- 之前'双国债配置'实际是红利低波+短债指数组合
- 红利低波具有'类债券'属性(高股息+低波动)
- 但本质仍是股票,熊市防御有限
- 短债指数才是2008年防御的主力
收益对比:
- 错误标注(双国债): 净值173.83
- 正确配置(红利低波): 净值115.14
- 差异原因:移除短债指数后防御能力下降
删除旧报告:国债配置实证分析报告.md
创建新报告:红利低波防御配置分析报告.md
|
2026-05-16 22:41:53 +08:00 |
|
|
|
306b4022da
|
feat(rotation): 增加双国债配置实现动态久期选择
配置变更:
- 移除错误标注的H30269.CSI(标注为中证红利低波)
- 添加10年国债(931862.CSI)配置,久期8年,波动3-5%
- 添加30年国债(H30269.CSI)配置,久期20年,波动10-15%
- 修正ETF映射:931862→512890, H30269→511090
实证分析结果:
- 方案C(双国债)累计收益17283%,为三种配置最优
- 动态久期选择机制:牛市选30年获取弹性,熊市选10年增强防御
- 债券持仓占比43.9%(10年18.6% + 30年25.3%)
- 详细分析见 docs/experiments/国债配置实证分析报告.md
|
2026-05-16 22:21:27 +08:00 |
|
|
|
63c56f0001
|
feat(execution): 回测调仓事件记录功能增强
新增调仓事件记录功能,详细记录每次调仓的信息:
核心改进:
1. BacktestExecutor新增_apply_trade_cost_with_events方法
- 记录每次调仓的基本信息(持仓变化、调入调出标的)
- 记录换手率、调仓成本、持仓天数、当日收益
2. 新增_enrich_rebalance_events方法
- 补充净值信息(调仓前净值、调仓后净值、净值变化%)
3. strategy.py保存调仓记录到CSV
- 新增rebalances.csv文件
- 返回结果包含rebalance_events
调仓记录字段:
- 调仓前持仓、调仓后持仓
- 调入标的、调出标的
- 换手率、调仓成本
- 持仓天数、当日收益
- 调仓前净值、调仓后净值、净值变化%
应用场景:
- 分析每次调仓对收益的影响
- 评估调仓决策质量
- 统计调仓频率与效果
|
2026-05-16 21:15:31 +08:00 |
|
|
|
6308627f8c
|
docs(experiments): 添加2001年收益深度分析章节
从四个维度分析2001年-41.1%收益的根因:
1. 策略原理层面:
- 短期动量陷阱(25天窗口在长期下跌中产生噪音信号)
- 分散化选股约束(必须从US/HK/EU/JP选Top3)
- 空仓机制触发条件(所有标的动量<0才触发)
2. 信号分布分析:
- 空仓31天(9.9%),部分生效但触发时机不理想
- 股票持仓占比过高(NDX+HSI+GDAXI+N225≈167%)
- 商品持仓不足(GC=F仅30.6%)
3. 大跌月份持仓分析:
- 2月(-18%): HSI持仓87.5%,空仓仅8.3%
- 3月(-18.2%): GC=F持仓57.7%,空仓19.2%
4. 宏观市场环境:
- 互联网泡沫破裂(2000-2002)
- 911事件冲击
- 缺乏债券等防御资产
改进建议:
- 增加长期动量过滤(60/120天)
- 放松分散化约束
- 增加止损机制
- 回测起点后移至2005年
|
2026-05-16 20:57:40 +08:00 |
|
|
|
c782830f75
|
docs(experiments): 轮动策略改进版回测分析报告
新增改进版策略分析报告,展示空仓机制和大类冠军二次过滤后的表现:
核心内容:
- 策略改进说明:空仓机制、大类冠军二次过滤、min_score配置化
- 版本对比分析:累计收益+2708%、最大回撤改善10.8%
- 月度收益详细表格:2000-2026年完整数据
- 空仓天数统计:131天(1.6%),集中在2000-2002年
关键对比:
| 指标 | 原版 | 改进版 | 改善 |
|------|------|--------|------|
| 累计收益 | 11872% | 14580% | +2708% |
| 最大回撤 | -71.9% | -61.1% | +10.8% |
| 空仓天数 | 4天 | 131天 | +127天 |
|
2026-05-16 20:49:23 +08:00 |
|
|
|
a475e1b314
|
feat(strategy): 分组选股增强-大类冠军二次过滤确保组合动量达标
核心改进:
- selectors.py: _grouped_selection增加二次过滤,大类冠军得分不足时跳过该大类
- strategy.py: min_score参数可配置,从策略配置读取
- config.yaml: min_score=0.0(过滤负动量),保留注释说明更高阈值的权衡
设计原则:
- 组合中每个标的动量得分都必须>=min_score
- 大类冠军得分不足时不强制持有,持仓数量动态调整
- min_score=0保持简单稳健,更高阈值虽能改善回撤但可能错过机会
实验验证:
- min_score=0: 累计收益14580%, 最大回撤-61.1%, 空仓131天
- min_score=0.02: 累计收益17052%, 最大回撤-61.0%, 但2000年恶化
- 决策:保持min_score=0,避免阈值选择的trick问题
|
2026-05-16 20:38:57 +08:00 |
|
|
|
788120387a
|
docs: 更新回测分析报告反映空仓机制优化效果
主要更新内容:
- 回测概况:累计收益14580%(+2708%),年化25.2%,最大回撤-61.1%(改善10.8%)
- 年度收益:2000年-8.3%(改善17.7%),2001年-41.1%(改善7.6%)
- 回撤分析:新增空仓机制效果说明,低点净值从0.34提升至0.48
- 策略特点:新增空仓机制优势,已实现改进与待优化建议分离
|
2026-05-16 11:49:40 +08:00 |
|
|
|
acec96539b
|
fix(strategy): 添加负动量空仓机制避免持仓惯性亏损
当所有候选标的动量得分低于min_score时,策略自动清仓而非继续持有之前的负动量组合。
修复问题:
- 旧逻辑:target为空时继续持有current_held(负动量标的)
- 新逻辑:target为空时清仓(current_held='')
回测效果:
- 累计收益从11872%提升至14580%(+2708%)
- 最大回撤从-71.9%改善至-61.1%(+10.9%)
- 2000年互联网泡沫期间空仓77天(24.8%)
- 2001年空仓31天,收益从-48.7%改善至-41.1%
|
2026-05-16 11:42:36 +08:00 |
|
|
|
bed92027fc
|
fix(premium): 溢价率计算改用动态匹配原则
修复 _calculate_premium_series 方法,改为动态匹配净值日期:
原问题:
- 统一使用T-1净值规则导致A股/港股/商品ETF溢价率计算错误
- 如创业板ETF用T-1净值而非当天净值,溢价率从0.76%变成0.19%
修复方案:
- 优先使用当天净值(A股/港股/商品/债券/日本QDII)
- 当天净值不存在时使用T-1净值(美股QDII/欧洲QDII/原油QDII)
验证结果:
- 11只ETF全部验证通过,与集思录数据完全一致
|
2026-05-16 10:27:07 +08:00 |
|
|
|
06fc62c51b
|
test(premium): add ETF溢价率计算验证脚本及校验报告
新增验证脚本 tests/verify_premium_calculation.py,支持批量验证config.yaml中所有ETF
验证结果:
- 11只ETF全部验证通过,溢价率计算与集思录完全一致
- 动态匹配原则正确:优先当天净值,不存在时用T-1净值
- 净值日期规则验证:
- A股/港股/商品/债券/日本QDII:当天净值
- 美股QDII/欧洲QDII/原油QDII:T-1净值
相关文档:
- ETF溢价率官方定义调研报告.md
- ETF溢价率计算校验报告.md
|
2026-05-16 10:24:28 +08:00 |
|
|
|
13be83965b
|
fix(datasource): QDII溢价率计算修复净值日期滞后一天对齐
问题: 溢价率计算使用同一天收盘价+净值,但QDII净值T+1披露
修复: 将净值索引后移一天,T日收盘价配T-1日净值
参考: 集思录做法(价格日期配前一日净值)
验证数据(513100.SH):
- 2026-05-15: 收盘价2.100, 净值(5/14)2.0200, 溢价率3.96% ✓
|
2026-05-16 08:57:20 +08:00 |
|
|
|
4c7538e6e1
|
docs: 月度收益表格增加年收益列
修改内容:
- 表格新增年收益列,直观展示各年度整体表现
- 年收益超过50%或跌幅超过20%用粗体标注
- 高亮年份: 2000(-26%), 2001(-48.7%), 2007(136.7%), 2008(-22.5%), 2024(82.1%)
|
2026-05-16 01:32:36 +08:00 |
|
|
|
c8e30dcbdf
|
docs: 轮动策略回测分析报告(2000-2026)
内容:
- 年度收益汇总(26年完整数据)
- 月度收益详细表格(317个月)
- 4次重大回撤分析(互联网泡沫、金融危机、A股调整、新冠疫情)
- 策略特点总结与改进建议
|
2026-05-16 01:28:29 +08:00 |
|
|
|
6ccb121764
|
fix(strategy): 修复收益率计算交易日不对齐问题
问题: 指数数据使用各市场原始交易日,直接pct_change导致大量NaN
修复: 先在原始交易日历计算收益率,再用ffill对齐到A股日历
效果: 收益从44.55%恢复到11961.88%(年化15.7%,26年周期)
|
2026-05-16 01:23:55 +08:00 |
|
|
|
28f3ddcd4f
|
fix(strategy): 收益计算改为使用指数数据
- 原逻辑: 优先使用ETF价格计算收益,导致回测起点被ETF最早日期限制(2011-12-09)
- 新逻辑: 使用指数数据计算收益,可从2000年开始回测(8240天)
- ETF数据仅用于报告显示溢价率,不参与收益计算
- 注意: 2000-2005年只有7只标的有数据,分散度不足导致净值下跌48%
|
2026-05-16 00:52:15 +08:00 |
|
|
|
2c1689089d
|
revert(execution): 恢复动态权重仓位分配逻辑
- 恢复原逻辑: 按实际持仓数量等权分配
- 选出2只时每只权重50%,选出1只时权重100%
- 收益计算恢复为 np.mean(returns)
- 交易成本恢复为 swapped/len(old)
- 固定仓位逻辑记录在 docs/experiments/仓位分配逻辑修改分析.md
|
2026-05-16 00:34:12 +08:00 |
|
|
|
e0d6f81ea1
|
docs: 仓位分配逻辑修改分析文档
- 记录动态权重vs固定仓位逻辑对比
- 分析收益下降原因(4479%→1678%)
- 说明固定仓位设计意义与改进方向
|
2026-05-16 00:31:14 +08:00 |
|
|
|
444dc0e751
|
refactor(execution): 改为固定仓位分配逻辑
- 原逻辑: 按实际持仓数量等权(选出2只时权重50%)
- 新逻辑: 按select_num固定等权(选出2只时权重33.3%+现金33.3%)
- 缺失仓位用现金替代,收益为0
- 交易成本按固定仓位比例计算
- 目的: 保持稳定风险敞口,避免仓位不足时波动放大
|
2026-05-16 00:18:19 +08:00 |
|
|
|
07463f68e1
|
fix(strategy): 消除pandas pct_change弃用警告
- 添加 fill_method=None 参数避免 FutureWarning
- pandas 未来版本将移除默认 fill_method='pad' 行为
|
2026-05-15 23:38:45 +08:00 |
|
|
|
80c7fe0ba8
|
refactor(log): 优化回测日志输出格式
- strategy.py: 在数据获取前打印回测配置区间说明
- flask_api_source.py: 使用API返回的实际数据范围(date_range)
- 原问题: 日志显示请求参数的start_date,而非实际数据范围
- 修改后: 各标的显示实际数据时间周期(如创业板2010年开始)
|
2026-05-15 23:34:52 +08:00 |
|
|
|
cbd60894b9
|
fix(strategy): 修复债券指数OHLCV数据处理逻辑
- 问题: 债券指数(931862.CSI)只有close数据,open/high/low全是None
- 原代码: 检查列存在后整行dropna → 数据变成0条
- 修复: 检查列存在 + 检查数据是否有效(不全为None)
- 如果OHLCV无效 → 使用close列单独dropna
- 结果: 30年国债4330条数据正常参与回测
- 收益影响: 累计收益+258%, Sharpe+0.04
|
2026-05-15 23:26:54 +08:00 |
|
|
|
85c20b4626
|
refactor(strategy): 取消数据不足标的剔除逻辑,保留所有标的以暴露策略问题
- compute_factors: 不剔除数据不足/缺失率高的标的
- 改为警告并保留,因子值NaN时信号生成自动跳过
- 目的:暴露策略自身问题,后续支持更多大类资产
- 回测配置改为start_date=2000-01-01以测试更长历史
|
2026-05-15 23:18:44 +08:00 |
|
|
|
763713213c
|
refactor(config): 有色金属标的改用COMEX铜期货替代上期所
- CU.SHF -> HG=F: COMEX铜期货(2000年至今)
- 原因:上期所主力合约数据仅2018年后,COMEX铜数据更长
- ETF保持不变(159980.SZ 有色金属ETF)
- 配合之前替换:AU.SHF->GC=F, CL.NYM->CL=F
|
2026-05-15 22:21:55 +08:00 |
|
|
|
4f1207dc4d
|
refactor(config): 商品标的改用COMEX/WTI期货替代上期所
- AU.SHF -> GC=F: COMEX黄金期货(2000年至今)
- CL.NYM -> CL=F: WTI原油期货(2000年至今)
- 原因:上期所主力合约数据仅2018年后,COMEX/WTI数据更长
- ETF保持不变(518880.SH 黄金ETF, 160723.SZ 原油ETF)
|
2026-05-15 21:57:32 +08:00 |
|
|
|
18ef2a1704
|
feat(datasource): 加密货币数据支持分钟级时间精度
- flask_server.py: dataframe_to_json 增加 asset_type 参数,crypto 使用 '%Y-%m-%d %H:%M:%S' 格式
- ccxt_source.py: 移除 normalize() 调用,保留完整时间精度
- ETF/指数数据保持天级精度 '%Y-%m-%d' 不变
|
2026-05-15 21:25:08 +08:00 |
|
|
|
a49002f622
|
fix(datasource): 溢价率计算改用同一天市价与净值
问题:之前用 ffill 将前一天净值填充到当天,导致溢价率偏差过大
例如:5月13日市价 4.048 vs 5月12日净值 3.946 → 溢价率 2.58%
修复:
- 不使用 ffill,只计算有净值日期的溢价率
- 使用 price_df 和 nav_df 的交集日期计算
- 溢价率 = (当天市价 - 当天净值) / 当天净值
- 5月12日市价 3.94 vs 净值 3.946 → 溢价率 ~0%
注意:净值 T+1 公布,最新一天溢价率可能无法计算
|
2026-05-14 01:31:39 +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 |
|
|
|
6a5d4dacd4
|
fix(datasource): 修复溢价率计算重复日期导致的 reindex 失败
问题:长时间范围 ETF 数据获取时,出现 'cannot reindex on an axis with duplicate labels' 错误
修复:
- 在 _calculate_premium_series 中先检测并去除重复日期
- price_df 和 nav_df 的索引都使用 duplicated(keep='last') 去重
- 确保 reindex 操作正常执行
|
2026-05-14 01:15:03 +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 |
|
|
|
72e980e956
|
refactor(rotation): 利用 Flask API 内联的 ETF 净值和溢价率数据
- 移除单独的 fetch_etf_nav 调用
- 从 ETF OHLCV DataFrame.attrs 中提取净值和溢价率
- 新增 etf_premium_data 字段存储溢价率详情
- 减少一次 API 请求,提高数据获取效率
|
2026-05-14 01:03:31 +08:00 |
|
|
|
d62763b0bd
|
feat(flask): OHLCV 端点自动附加 ETF 净值和溢价率
flask_server.py:
- 当 asset_type 为 china_etf 时,自动调用 fetch_etf_with_nav
- 响应中添加 nav、premium_series、latest_premium、premium_stats
flask_api_source.py:
- 解析 ETF 数据中的净值和溢价率信息
- 将 nav_df、premium_series、premium_stats 存入 DataFrame.attrs
|
2026-05-14 00:57:37 +08:00 |
|
|
|
d4047d4cf4
|
fix(flask_api_source): 修复 fetch_etf_nav zstd 解压与溢价率解析
- 处理 zstd 响应的 JSON 解析问题
- 正确解析 Flask server 返回的净值数据结构
- 添加 premium_series、latest_premium、premium_stats 到 DataFrame attrs
|
2026-05-14 00:51:23 +08:00 |
|
|
|
4fe21a7cd4
|
fix(datasource): 修复 zstd 响应 JSON 解析问题
- flask_api_source.py: 添加 requests.exceptions.JSONDecodeError 捕获
- flask_server.py: 启用 flask-compress gzip 压缩
- requirements.txt: 添加 flask-compress>=1.14
- strategy.py: 修复 flask_api 配置读取方式
问题原因:Traefik Ingress 使用 zstd 压缩响应,
requests.response.json() 解析失败,但 json.loads(response.text) 成功
|
2026-05-14 00:27:30 +08:00 |
|
|
|
020e90aa2b
|
feat(rotation): 添加 Flask API 配置
- 新增 flask_api 配置块
- url: https://k3s.tokenpluse.xyz
- enabled: true
- 支持策略通过远程 API 获取数据
|
2026-05-13 23:55:26 +08:00 |
|
|
|
0a9795febb
|
feat(strategy): rotation策略支持Flask API数据获取
- 新增 flask_api_source.py: Flask API远程数据源模块
- 修改 strategy.py: get_data() 支持通过Flask API获取数据
使用方式:
strategy.get_data(use_flask_api=True) # 通过部署服务获取
strategy.get_data(use_flask_api=False) # 本地HybridDataSource
配置项:
flask_api_url: 可在config.yaml中指定API地址
|
2026-05-13 23:49:26 +08:00 |
|
|
|
416f708d53
|
feat(datasource): 实现加密货币数据获取功能
- 新增 ccxt_source.py: CCXT + OKX 加密货币数据源
- 新增 socks2http.py: SOCKS5 转 HTTP 代理转换器
- 修改 universal_fetcher.py: 添加 _fetch_crypto 方法,支持 timeframe 参数
- 修改 flask_server.py: API 支持 timeframe 参数,加密货币不缓存
支持的 timeframe: 1d, 1h, 4h, 15m, 1m
测试验证: BTC 数据获取成功
|
2026-05-13 23:30:32 +08:00 |
|
|
|
105af19690
|
feat(strategy): 新增纯美股动量轮动策略
新增美股轮动策略模块:
- strategies/us_rotation/config.yaml: 47只美股标的池,动量窗口250天,Top5选股
- strategies/us_rotation/strategy.py: USRotationStrategy实现
- run_us_rotation.py: 回测入口脚本
回测结果 (2016-2026, 约10年):
- 总收益: 7675% (年化52.49%)
- 基准NDX收益: 540% (年化19.72%)
- 超额年化收益: 32.78%
- 夏普比率: 1.33 (基准0.80)
- 最大回撤: 42.15%
- 卡玛比率: 1.25
- 胜率: 56.1%
- 平均持仓: 2.7天
年度最佳: 2020年+221% (超额176%)
年度防守: 2022年-10.5% (基准-33.7%, 超额+23.3%)
持仓Top5: NVDA(35.8%), AMD(30.1%), SHOP(26%), AVGO(23.9%), FICO(23.3%)
|
2026-05-13 01:27:09 +08:00 |
|
|
|
a712bc0f03
|
fix(datasource): 支持US_STOCK和HK_STOCK类型数据获取
- universal_fetcher.py: 添加 _fetch_us_stock 和 _fetch_hk_stock 方法
- flask_server.py: SSH_HOST 修正为正确的IP地址 8.218.167.69
- 测试 META 获取成功,info 字段在最外层返回179个属性
|
2026-05-13 00:38:01 +08:00 |
|