策略
SOL 宏观公告后突破延续,多空策略(SOLUSDT.BYBIT 永续合约,由预定 US 事件门控:在 FOMC/CPI/NFP/PCE 后一小时内交易顺势区间突破,采用时间 + ATR 止损,3 参数)
结局: 已放弃
SolMacroEventBreakoutContinuationLS
结局总结
SolMacroEventBreakoutContinuationLS 试图通过仅在计划内 US 宏观数据发布后的一小时内、在 SOL 永续合约上交易趋势对齐的区间突破,来利用信息驱动的重新定价,其使用确定性硬编码事件日历并路由到 Bybit。代码忠实地实现了该假设(72 发出信号 = 72 提交订单,均衡的 42 多头 / 30 空头,交易所托管的 ATR 括号单加时间止损),在一个决定性的约 5 年、72 笔交易的样本上给出了公平检验。但结果明显为负:total_return -24.59%,夏普比率 -0.662,且 0.657 的 profit_factor 即使在扣费前也低于 1,亏损分布在大多数年份以及平静和压力两种状态中。分析师在回测评审关卡将其放弃为 negative_expectancy,前提在 SOL 上被证伪,因为任何参数调整都无法提升一个在成本前毛利为负的优势;优化、分析和风险评审均未进入。
假设
一个基于 LONG-SHORT 的单一品种方向性策略,标的为 SOLUSDT.BYBIT(线性 USD-M 永续合约),其入场被严格门控 ENTIRELY 于计划内 US 宏观数据发布的时间戳。事件日历(FOMC 利率决议 ~8 次/年 @ 14:00 ET,CPI ~12 次/年 @ 08:30 ET,非农就业 ~12 次/年 @ 08:30 ET,PCE ~12 次/年 @ 08:30 ET)是 KNOWN HISTORY —— 硬编码的 UTC 时间戳,无需新闻/情绪数据源,可在 SOL 多年的 Bybit 历史数据上完整回测。每年 ~44 个事件 × ~5-6 个可用年份 ≈ 220-260 个事件窗口。这NOT是一种连续动量/状态门控机制(L92),也NOT是 24/7 时钟上的时段/开盘区间季节性交易(L79/L89 针对的是日内 VWAP/US 现金开盘的反转,触发次数达数千次)——它只在固定、稀疏、外生的宏观日程上触发,并顺势捕捉信息驱动的重新定价。路由到 BYBIT 以填补语料库中最空的交易场所(3011 个实验中占 1 个),并以 LONG-SHORT 表达以填补低于目标的方向桶;选择 SOL 而非 BTC/ETH(44%/已被过度挖掘),因为其更高的宏观贝塔会放大事件后的波动,从而提高单笔交易相对手续费的捕获能力。FEE ARITHMETIC:在 FOMC/CPI/NFP 发布日,SOL 的已实现日内振幅通常为 3-7%;与趋势对齐的突破延续可捕获该摆动的约 1.0-1.5%。Bybit 线性合约 taker 费率 RT 约 0.11%。即使在现实的 45% 胜率下,平均盈利 ~avg_win 1.6% / 平均亏损 ~avg_loss 0.9%(ATR 止损),毛期望值 ≈ 0.45*1.6 - 0.55*0.9 = +0.225%/笔,扣除 0.11% RT 手续费后净约 ~+0.11% —— >2x 倍于 0.10% 的低费率门槛,这是通过选择性实现的,而非靠一个被摩擦损耗的小优势硬拼。趋势对齐(只在与 3 日趋势同向时做突破)是在本已稀有的外生触发器之上的震荡过滤器,而不是一个从低于费率的信号中人为制造优势的状态门控。
第 2 次迭代以最小改动修复了唯一报告的问题(leverage_set_but_unused):现在 position_size() 会读取 self.config.leverage DIRECTLY(此前的 getattr(self.config, 'leverage', ...) 写法未被识别为杠杆引用),并将其作为名义本金上限使用:max_notional = equity * max_notional_frac * self.config.leverage。杠杆确实会起约束作用——以 1.5% 为止损的 risk_pct 仓位,若采用通常约为 1-1.5% 的发布后 ATR 止损,则需要相当于权益 1.0-1.5x 的名义本金,这只有在 2x 保证金下才可能实现,因此回测与 1x 完全相同是 NOT。其他内容均未改变:宏观日历安排、冻结的发布前区间、连续的 ATR 距离信号、趋势对齐过滤器、止盈止损组合单退出机制以及时间止损;这些内容此前已通过第 1 层静态分析。
在一个决定性的 72 笔交易 / 1788 天(约 5 年)样本上期望值为负:profit_factor 0.657(<1 —— 这是成本前的毛 NEGATIVE,佣金仅为毛值的 15.4%,所以这是一个亏损信号而非对费用敏感),total_return -24.59%,期望值 -$342.8/笔,夏普比率 -0.662,CI [-1.474, 0.216] 横跨零轴。优化无法提升一个在成本前就为负的优势。代码忠实地实现了宏观发布后趋势对齐突破的假设(72 发出信号 = 72 提交订单,均衡的 42 多头 / 30 空头,硬编码宏观日历,交易所托管的 ATR 括号单 + 时间止损),因此这是一次公平的检验,而 QA 的疑虑在完整历史上得到证实:FOMC/CPI/NFP/PCE 之后的突破延续未能在 SOL 上捕获预期的 1.0-1.5% 摆动(胜率 0.375,空头腿 0.267)。失败是跨状态 WIDE 的 —— 该组合在平静(-34.0%)和压力(-17.8%)波动率三分位中都亏损(only_one_regime=true,利润仅局限于正常三分位),并且在 6 个日历年中 4 个亏损(2022 -4.3%,2023 -1.2%,2025 -13.0%,2026 -9.6%)—— 这与稳健的事件驱动优势恰恰相反。调整 3 参数无法挽救一个在大多数状态和年份中毛利为负的 PF-0.657 信号;不值得投入 2 小时的 walk-forward。abandon_class=negative_expectancy(前提在 SOL 上被证伪)。
实现
多空 SOLUSDT Bybit 线性永续合约策略,在预定 US 宏观数据发布(FOMC 14:00 ET,CPI/NFP/PCE 08:30 ET)后一小时内交易 ONLY,采用完全由日历推导的硬编码事件日程。每次数据发布时,冻结发布前 2h 的高低区间;若 15m 收盘价突破该区间超过 entry_atr_mult ATR,且方向与过去 3 日收益方向一致,则每个事件交易一次。风险通过交易场所管理的 OUO 止盈止损组合单管理(基于 ATR 缩放的止损 + R 倍数止盈),以便在剧烈的发布后 K 线中于 K 线内部触发退出,另设按 K 线数量计时的时间止损。仓位规模按照 ATR 止损风险占权益的 risk_pct 计算,并以 max_notional_frac 倍杠杆 × 权益为上限。
验证结果
如果基类的门控条件为 calculate_signal() 且调用 self.min_bars_required(),则无需更改;否则应重命名以避免遮蔽,并通过预期的钩子设置预热期。
min_bars_required() 覆盖了基模板方法(静态分析器标记为 base_shadow)。这看起来是有意为之——策略需要较长的预热期(trend_bars + atr_period + 5 = 389 根 K 线)来初始化 ATR/趋势缓冲区——而 Python 的多态机制意味着该覆盖方法会被基循环使用 IS。这不是缺陷,但请确认基模板实际调用的是实例方法(而非私有缓存值),以确保预期的 389 根 K 线预热期生效。
验证当 use_bracket_orders 为 true 时,基模板是从 self.parameters 读取 stop_loss_pct/take_profit_pct(而不是读取 __init__ 时获取的快照),以确保每个事件覆盖的设置能传递到已提交的止盈止损组合单。
should_enter() 在每次入场时都会修改 self.parameters['stop_loss_pct'] / ['take_profit_pct'],使交易场所止盈止损组合单的各个部分能够根据 ATR 自适应。这依赖基模板在提交时、且紧接着 should_enter/position_size 之后,于同一调用栈中读取 self.parameters 中的这些键。该机制合理,配置也包含有效的非零默认值(0.02 / 0.036),因此不会拒绝止盈止损组合单入场;但这与基模板之间存在一项隐式约定。
外生触发稀疏:沙盒在 208 天内产生了 9 笔交易,事件到交易的通过率约为 36%。按 SOL 在 Bybit 上约 5-6 年的历史数据(每年约 44 个事件)外推,仅意味着约 95-130 笔交易——统计检验效力处于临界水平(L16/L26)。沙盒冒烟测试的净结果也为负(PF 0.23,avg_trade_return_pct -0.36%,三个波动率三分位组均为负),且只基于一次未经优化的抽样;趋势对齐过滤器 + entry_atr_mult 门槛可能过于严格,难以积累足以得出明确结论的样本。建议分析师确认全历史交易数超过约 100,且每笔交易的净优势在扣除 Bybit 0.11% RT 后仍然存在,再着手优化。
回测评审
- 夏普
- -0.66
- 总收益率
- -24.59%
- 最大回撤
- 28.82%
- 总交易数
- 72
- 胜率
- 37.5%
- 盈利因子
- 0.66
机制得到了忠实且确定性的实现:72 已触发 = 72 已提交,多空平衡,42 做多 / 30 做空,宏观日历为硬编码且不存在前视,交易场所管理的 ATR 止盈止损组合单 + 时间止损。
对于这种交易频率,该样本具有决定性:在 1788 天(约 5 年)内的 72 笔交易,足以消除 QA 对约 100 笔交易样本的担忧;结果并非处于临界边缘,而是明确为负。
毛利为负的信号:profit_factor 0.657(<1 BEFORE 成本 —— 佣金仅为毛值的 15.4%),因此任何参数调整都无法提升一个在扣费前就为负的优势。
全面负期望:total_return -24.6%,期望收益为每笔 -$342.8,夏普比率 -0.662,其 CI [-1.474, 0.216] 跨越零,索提诺比率 -0.20,recovery_factor -0.865。
跨市场状态普遍失败,而非断崖式失效:在平静(-34.0%)和压力(-17.8%)三分位组中均亏损(only_one_regime=true,仅在正常三分位组盈利 +14.6%),并且在 4 / 6 个日历年份中为负(2022 -4.3%,2023 -1.2%,2025 -13.0%,2026 -9.6%)。
完整历史数据证实了 QA 对优势的担忧,且结果更糟:宏观事件后顺势突破未能捕获预期波动——胜率 0.375(空头腿 0.267),假突破过滤器并未创造出优势。
迭代历史
验证失败(leverage_set_but_unused):配置设定了 leverage=2.0,但策略在仓位规模计算中从未引用杠杆。请据此计算仓位——名义本金 = 权益 * 比例 * 杠杆 / 价格(读取 self.config.leverage)——或将杠杆设为 1.0。按当前写法,杠杆不起作用,回测与 1x 完全相同。
结局总结
手续费计算逻辑看似合理还不够;SOL 上的宏观事件后顺势突破未能捕获预期波动,并在 6 年中的 4 年以及平静和压力波动率市场状态下均亏损,表明策略前提已被证伪,而非仅仅对手续费敏感。
分析师在优化前的回测审查关卡放弃了该策略:信号在扣除成本前毛收益已为负(profit_factor 0.657,佣金仅占毛收益的 15.4%),因此参数调整无法挽救,前向滚动优化也不值得进行。
一种多空 SOLUSDT.BYBIT 永续合约策略,仅在预定 US 宏观数据发布后的一小时内触发(FOMC/CPI/NFP/PCE),通过硬编码的事件日历筛选交易,顺势交易发布前区间的突破,设置 ATR 止损和按 K 线数量计时的时间止损。
在 1788 天(约 5 年)内进行了 72 笔交易,结果亏损:total_return -24.59%,夏普比率 -0.662(CI [-1.474, 0.216]),profit_factor 0.657,期望收益为每笔 -$342.84,胜率 0.375(空头腿 0.267),最大回撤 28.82%。
Stratmill 是研究与模拟交易工具,不提供财务建议,也不是经纪商。回测与模拟结果均为假设性结果。交易存在亏损风险。