20 日新高突破策略怎么回测?从规则、样本到期望值的完整流程
回测一个 20 日新高突破策略,就是先把"真突破"写成机器能判断的买卖条件,再套到几年的日线数据上,读出胜率、盈亏比、最大回撤和期望值四个数。突破系统天生胜率不高,能不能赚钱几乎全看盈亏比,所以回测的重点不是"对了几次",而是"赢的时候赢多少、输的时候输多少"。
本文要点
- 突破策略胜率常在 35%–45%,这不是缺陷。它靠少数大赢家覆盖多数小亏损,期望值取决于盈亏比。
- 四个数一起看:胜率、盈亏比、最大回撤、单笔期望值。单看任何一个都会被误导。
- 滑点对突破策略伤害特别大:次日高开 1.5% 进场,足以把薄利策略变成亏损策略。
- 固定 -5% 止损对高波动股太紧,用 atr14_pct 检查止损宽度。
- 样本要够:100 笔交易的胜率仍有正负 10 个百分点的误差,30 笔几乎说明不了什么。
第一步:把"真突破"写成规则
"突破新高就买"本身不能回测,因为它没定义什么叫突破、什么时候走。可回测的版本是:
买入(全部满足)
- 收盘价创 20 日新高(is_20d_breakout)。
- 成交量 > 20 日均量的 1.5 倍(vol_vs_avg20d > 1.5),排除无量假突破。
- ADX(14) > 25,趋势已成形,不是横盘里的偶然新高。
- MA20 在 MA50 之上,中期方向向上。
- 距下次财报 > 5 天,避免刚进场就撞上财报跳空。
卖出(任一触发)
- 浮亏 > 5%:止损。
- 浮盈 > 10%:止盈。
- 持有 >= 15 个交易日:时间止损,15 天还没走出来就不是你要的突破。
- 距下次财报 <= 2 天:财报前离场。
每条都是一个指标、一个比较符、一个数字。写到这个程度才能回测,也才能每天被扫描。参考把逻辑写成买入规则。
为什么突破策略胜率低,却可能赚钱
突破买的是"刚创新高"的价格,天然处在短期高位,相当一部分会在两三天内回落到区间里触发止损。所以突破系统的胜率很少超过 50%。
它能赚钱靠的是结构不对称:止损 -5%,止盈 +10%,单笔亏损被限制,赢的交易能拿到两倍于亏损的收益。只要赢的时候赢得够多,40% 的胜率也能有正期望值。读回测报告时,四个数要一起看:
| 指标 | 回答的问题 | 突破策略的典型形态 |
|---|---|---|
| 胜率 | 多少比例的交易赚钱 | 偏低,35%–45% |
| 盈亏比(Profit factor) | 总盈利 ÷ 总亏损 | 需要 > 1.2 才有实际意义 |
| 最大回撤 | 资金曲线从高点最多跌多少 | 连亏 5–7 笔很常见 |
| 单笔期望值 | 平均每笔交易赚或亏多少 | 正数、且能覆盖成本才算通过 |
胜率低的策略连亏是常态。每笔亏损概率 60% 时,连亏 5 笔的概率是 0.6 的 5 次方,约 7.8%;100 笔里出现一次 5–7 连亏几乎必然。这是最大回撤的来源,不是策略"坏了"。
一笔算得清的期望值例子
下面的数字是示例算术,不是实测结果,目的是让你会算。假设回测出 100 笔交易:
- 胜率 40%(40 笔赢,60 笔亏)。
- 赢的交易平均 +8%(有的打到 +10% 止盈,有的在时间止损时小赢离场)。
- 亏的交易平均 -4.5%(多数打到 -5% 止损,少数时间止损时小亏)。
单笔期望值 = 0.40 × 8% − 0.60 × 4.5% = 3.2% − 2.7% = +0.5%。
盈亏比 = (40 × 8) ÷ (60 × 4.5) = 320 ÷ 270 ≈ 1.19。
换成钱:账户 20,000 美元,单笔风险 1% 即 200 美元,止损 5%,仓位 = 200 ÷ 5% = 4,000 美元。每笔期望 +0.5% × 4,000 ≈ +20 美元,100 笔约 +2,000 美元,未扣手续费。有正期望,但很薄。
样本误差:胜率 40%、100 笔时,胜率的标准误差约为根号(0.4 × 0.6 ÷ 100) ≈ 4.9 个百分点,95% 区间大约 30%–50%。只有 30 笔时标准误差约 8.9 个百分点,区间宽到 22%–58%,"胜率 40%"基本没有信息量。先看交易笔数,再看胜率。
滑点:次日高开 1.5% 会怎样
突破在收盘确认,最早只能次日开盘成交。Stock Compass 的回测也是这样:信号日评估,次日开盘价成交,没有未来函数。问题是突破次日经常高开,假设平均比信号日收盘高 1.5%。
用最粗的近似,把每笔结果往下平移 1.5 个百分点:赢的从 +8% 变成 +6.5%,亏的从 -4.5% 变成 -6.0%。
新期望值 = 0.40 × 6.5% − 0.60 × 6.0% = 2.6% − 3.6% = -1.0%。
盈亏比 = (40 × 6.5) ÷ (60 × 6.0) = 260 ÷ 360 ≈ 0.72。
+0.5% 的薄利策略被 1.5% 滑点直接翻成亏损。实际情况更复杂(止损止盈按真实成本算,一部分影响会体现为胜率下降),但方向一样:突破策略对进场价格极度敏感。回测只看次日开盘成交的结果;实盘接受追不上就不追。
固定 -5% 止损对高波动股太紧
同一个 -5%,对不同股票意义完全不同。用 atr14_pct(14 日 ATR 占价格的百分比)衡量:
- 股票 A,atr14_pct = 1.5%:-5% 止损约 3.3 个 ATR,正常震荡打不到。
- 股票 B,atr14_pct = 4%:-5% 止损只有 1.25 个 ATR,一天正常波动就能把你扫出去,然后股价继续按突破方向走。
对 B 这类股票,-5% 止损会人为压低胜率,亏的都是"方向对、被震出去"的交易。两种处理:
- 按 ATR 定止损:止损 ≈ 2 × atr14_pct,B 放到 -8%;为保持单笔风险仍是 200 美元,仓位缩到 200 ÷ 8% = 2,500 美元。止损宽了,仓位小了,风险不变。
- 在买入条件里过滤:加一条 atr14_pct <= 2.5,只做 -5% 止损至少等于 2 个 ATR 的股票;高波动股另建止损更宽的策略。
下面的 JSON 用的是第二种。止损与仓位的配合见仓位管理。
大盘过滤与参数变体
突破在上涨的大盘里成功率更高,下跌的大盘里假突破更多。最简单的过滤是 market_index_vs_ma50_pct > 0:只在基准指数站在 50 日均线之上时接受买入。回测时对比开关这条过滤,交易笔数通常减少,重点看期望值和最大回撤有没有改善。
参数也别只跑一组。以下是示例算术,展示成交量阈值三档该怎么读:
| 成交量阈值 | 交易笔数 | 胜率 | 平均盈利 | 平均亏损 | 单笔期望值 | 盈亏比 |
|---|---|---|---|---|---|---|
| 1.3 倍 | 140 | 37% | +7.5% | -4.6% | -0.12% | 0.96 |
| 1.5 倍 | 100 | 40% | +8.0% | -4.5% | +0.50% | 1.19 |
| 2.0 倍 | 55 | 44% | +8.5% | -4.4% | +1.28% | 1.52 |
读法:阈值越高,信号越少、质量越高,方向符合逻辑。但 2.0 倍只有 55 笔,胜率误差区间宽得多,资金也更多闲置。三档结果平滑过渡,说明策略对这个参数不敏感,是好事;只有某一档特别好、两边都差,那一档很可能是拟合出来的运气。不要直接选表里最好的一行。
在 Stock Compass 里怎么设
回测是 Pro 功能,基于日线运行,信号日评估、次日开盘价成交,结果为未扣交易成本的毛收益。Stock Compass 不连接券商也不下单,只是每天用你的规则扫描股票池,把触发的股票放进当天的清单。完整策略如下:
{
"name": "20日新高真突破",
"market": "us",
"rules": {
"buy": {
"v": 2,
"outerOp": "OR",
"groups": [
{
"innerOp": "AND",
"conditions": [
{ "indicator": "is_20d_breakout", "operator": "==", "value": 1 },
{ "indicator": "vol_vs_avg20d", "operator": ">", "value": 1.5 },
{ "indicator": "adx_14", "operator": ">", "value": 25 },
{ "indicator": "ma20_above_ma50", "operator": "==", "value": 1 },
{ "indicator": "atr14_pct", "operator": "<=", "value": 2.5 },
{ "indicator": "market_index_vs_ma50_pct", "operator": ">", "value": 0 },
{ "indicator": "days_to_next_earnings", "operator": ">", "value": 5 }
]
}
]
},
"add": { "v": 2, "outerOp": "OR", "groups": [] },
"trim": { "v": 2, "outerOp": "OR", "groups": [] },
"exit": {
"v": 2,
"outerOp": "OR",
"groups": [
{ "innerOp": "AND", "conditions": [ { "indicator": "floating_loss_pct", "operator": ">", "value": 5 } ] },
{ "innerOp": "AND", "conditions": [ { "indicator": "floating_gain_pct", "operator": ">", "value": 10 } ] },
{ "innerOp": "AND", "conditions": [ { "indicator": "holding_days", "operator": ">=", "value": 15 } ] },
{ "innerOp": "AND", "conditions": [ { "indicator": "days_to_next_earnings", "operator": "<=", "value": 2 } ] }
]
}
}
}
买入条件逐条解释:
- is_20d_breakout == 1:收盘价创 20 日新高。
- vol_vs_avg20d > 1.5:成交量超过 20 日均量的 1.5 倍,单位是倍数。
- adx_14 > 25:趋势强度过关,见术语表 ADX。
- ma20_above_ma50 == 1:20 日均线在 50 日均线之上。
- atr14_pct <= 2.5:只做 -5% 止损至少等于 2 个 ATR 的股票。
- market_index_vs_ma50_pct > 0:基准指数在 50 日均线之上。
- days_to_next_earnings > 5:距下次财报超过 5 天。
四个卖出组用 OR 连接,任一触发即离场。floating_loss_pct 亏损时为正数,所以"浮亏超过 5%"写成 > 5。
一个细节:回测没有历史财报日历,两条 days_to_next_earnings 在回测里会被跳过并标注为未评估;它们在每天的实时信号扫描里正常生效。所以回测结果对应"不含财报过滤"的版本。
常见错误
- 用信号日收盘价回测。突破次日常高开,收盘价成交会系统性高估收益。
- 只看胜率。40% 胜率的突破策略可能很好,70% 胜率的策略也可能亏钱。先看期望值和盈亏比。
- 交易笔数太少就下结论。30 笔的胜率误差接近正负 18 个百分点。至少 100 笔,最好覆盖一轮涨跌周期。
- 所有股票用同一个 -5% 止损。高波动股会被正常震荡扫出。用 atr14_pct 检查止损宽度。
- 在参数表里挑最好的一行。相邻参数差异巨大说明是拟合不是规律,选中间、稳健的值。
小结
回测 20 日新高突破策略的流程很直接:把"真突破"写成可判定的买卖条件,跑在足够多的样本上,用次日开盘价成交,读四个数而不是一个数。突破策略胜率低是常态,能不能用取决于盈亏比、滑点和止损宽度是否匹配股票的波动。通过回测之后,真正的难题才开始:每天照同一套规则做。见每日买卖信号怎么用。
常见问题
20 日新高突破策略的胜率多少才正常?
多数突破系统的胜率在 35%–45% 之间,这是正常状态而不是问题。它靠不对称结构赚钱:亏损被止损限制在小额,赢的交易拿到更大的收益。评估这类策略要看单笔期望值和盈亏比,不能只看胜率。
回测至少要多少笔交易才可信?
胜率 40% 时,100 笔交易的胜率估计仍有大约正负 10 个百分点的误差;30 笔时误差接近正负 18 个百分点。至少要 100 笔,并且覆盖上涨和下跌两种市场阶段,再下结论。
为什么滑点对突破策略影响这么大?
突破在收盘确认,你最早只能在次日开盘成交,而突破次日经常高开。突破策略的优势通常很薄,平均比信号日收盘高 1.5% 进场,就足以把小幅正期望翻成负期望。回测一定要看次日开盘成交的结果。
止损用固定 -5% 还是按 ATR 定?
固定 -5% 适合 14 日 ATR 占价格不到 2.5% 的股票,这时止损至少有 2 个 ATR 的距离。对波动更大的股票它太紧,会被正常震荡扫出。要么把止损放宽到约 2 倍 atr14_pct、同时缩小仓位保持风险金额不变,要么在买入条件里把高波动股过滤掉。
Stock Compass 的回测包含交易成本和财报过滤吗?
回测基于日线,次日开盘价成交,结果是未扣手续费的毛收益,成本要另外当作一层折扣。回测没有历史财报日历,days_to_next_earnings 条件在回测中会被跳过并标注为未评估,但在每天的实时信号扫描里正常生效。Stock Compass 不连接券商,也不下单。