|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
76faf78a42
|
fix: 完整匹配原引擎剔除逻辑和因子对齐顺序
关键修复:
1. OHLCV整行dropna()剔除逻辑(匹配原引擎)
- 国债 931862.CSI 因 open/high/low 全空被剔除
- 原引擎: df = index_ohlcv_data[code].dropna()
- 新框架: 同样逻辑
2. 因子计算顺序:先计算因子再对齐到A股交易日历
- 原引擎: factor_series = rolling(n).apply(); factor_aligned = reindex(ffill)
- 新框架: 同样顺序,避免ffill填充的重复值影响rolling窗口
对比结果:
| 指标 | 原引擎 | 新框架(修复后) |
|------|--------|---------------|
| 累计收益 | 1804% | 1999% |
| 信号匹配率 | - | 90.3% |
| 调仓次数 | 459 | ~578 |
剩余195%收益差距可能来自收益计算细节差异
|
2026-05-12 01:14:07 +08:00 |
|
|
|
f5d748257e
|
fix: 关键修复-境外数据对齐到A股交易日历后计算因子
问题根因:
- 2019-02-18等日期是A股交易日但不是美股交易日(总统日假期)
- 新框架因子计算使用原始境外数据索引,导致这些日期因子值为NaN
- 原引擎使用 reindex(a_share_dates, method='ffill') 前向填充
修复:
- 因子计算前将所有标的数据对齐到A股交易日历
- 使用前向填充(ffill)处理境外市场交易日缺失
收益对比:
- 原引擎: 1804% 累计收益, 459次调仓
- 新框架(修复后): 1703% 累计收益, 578次调仓
剩余差异:
- 新框架保留国债(931862.CSI),原引擎剔除
- 信号匹配率36.5%,但收益接近说明策略逻辑有效
|
2026-05-12 01:01:32 +08:00 |
|
|
|
19131c41dd
|
fix: 数据源路由修复与因子计算改进
1. 修复期货路由逻辑:NYMEX期货(.NYM)走YFinance而非Tushare
2. 添加SSH隧道路径修复(原引擎)
3. 因子计算只使用close列(处理部分指数只有收盘价的情况)
4. 添加数据不足和缺失率剔除日志
收益对比:
- 原引擎(剔除国债): 累计1804%, 调仓459次
- 新框架: 累计772%, 调仓1276次
差异原因待查:
- 国债剔除逻辑不同
- 调仓频率差异
|
2026-05-12 00:47:43 +08:00 |
|
|
|
a7a4a69153
|
fix: 修复回测日期对齐问题,优化收益率计算
- 使用对齐后的index_close数据计算日收益率
- 添加日期对齐逻辑确保信号和收益率数据一致
- 修复pivot重复索引问题,使用pivot_table
- 修复tushare期货接口调用(futures_daily -> fut_daily)
回测结果:
- 最终净值: 0.9435
- 累计收益: -5.65%
- 信号日期: 2302天
|
2026-05-12 00:12:46 +08:00 |
|
|
|
e56bd39400
|
feat: 创建数据源模块 datasource/
核心功能:
- ssh_tunnel.py: SSH隧道管理器(连接香港ECS)
- tushare_source.py: A股数据获取(指数、ETF、期货)
- yfinance_source.py: 境外数据获取(港股、美股)
- hybrid_source.py: 混合数据源(整合所有)
使用方式:
from datasource import HybridDataSource
source = HybridDataSource.from_yaml('config/strategies/rotation.yaml')
result = source.fetch_all()
更新 RotationStrategy 使用新数据源模块
|
2026-05-12 00:03:25 +08:00 |
|
|
|
e6b2c8cfb7
|
fix: 适配归档数据源接口,添加dotenv加载
- 使用 fetch_all() 替代 fetch_batch()
- 添加 from dotenv import load_dotenv 加载环境变量
- 返回完整数据结构(index_data, etf_data, nav_data, benchmark)
回测验证成功:
- 累计收益: 164.47%
- 最终净值: 2.6447
- 信号日期: 1780 天
|
2026-05-11 23:56:05 +08:00 |
|
|
|
893a75a27f
|
refactor: 将回测逻辑整合到策略类,简化执行入口
重构 RotationStrategy:
- 添加 from_yaml() 从配置创建实例
- 添加 get_data() 获取数据
- 添加 compute_factors() 计算因子
- 添加 generate_signals() 生成信号
- 添加 run_backtest() 完整回测流程
简化 run_rotation.py:
- 从 264 行简化为 9 行
- 只做策略调用入口
执行方式:
python run_rotation.py --config config/strategies/rotation.yaml
python run_rotation.py --save-path results/my_rotation
代码方式:
strategy = RotationStrategy.from_yaml('config/strategies/rotation.yaml')
result = strategy.run_backtest()
|
2026-05-11 23:50:40 +08:00 |
|
|
|
de31271ab3
|
feat(rotation): 实现轮动策略(使用框架抽象+定制组件)
- RotationStrategy: 继承StrategyBase,使用MomentumFactor+TopNSelector
- 实现before_entry溢价过滤、dynamic_stoploss动态止损、custom_exit自定义出场
- 策略配置从类属性读取,支持config覆盖
|
2026-05-11 23:09:49 +08:00 |
|