一套量化策略写得多复杂,并不能直接说明它是否值得交易。
均线、RSI、机器学习模型,甚至更复杂的 Agent,最终都会落到几个非常朴素的问题:
有多大概率赚钱?赚的时候能赚多少?这样的机会多久出现一次?每次承担多大风险?
对应到策略运行,就是四个最值得持续监控的维度:
胜率、盈亏比、交易频率和仓位。
它们并不能描述交易系统的全部风险,但非常适合回答一个实际问题:
一套策略的统计优势,究竟是怎样转化成最终收益和回撤的?
本文结合加密货币市场和 FMZ 策略实现,重点讨论这四个维度如何联动,以及怎样把它们变成实盘中的监控和风险约束。
本文仅用于策略研究与程序设计,不构成任何投资建议。
一、先别看收益率,先看单笔净期望
设:
- 胜率为 \(p\);
- 平均盈利是平均亏损的 \(b\) 倍;
- 单笔手续费、滑点和资金费用折算为平均亏损的 \(c\) 倍。
把平均亏损标准化为 1 个风险单位,那么单笔净期望可以写成:
\[ E=p\times b-(1-p)-c \]
这条公式已经把胜率、盈亏比和交易成本放进了同一个框架。
例如一套 BTC 永续策略:
- 胜率 42%;
- 实际盈亏比 2.2:1;
- 单笔综合成本约 0.08 个风险单位。
则:
\[ E=0.42\times2.2-0.58-0.08=0.264 \]
也就是说,在这些统计参数能够保持的前提下,每完成一次交易,平均净期望约为 0.264 个风险单位。
如果每笔计划承担账户权益的 0.5%,一个月有 12 次有效交易,那么在不考虑复利和风险重叠的简化条件下:
\[ 12\times0.264\times0.5\%=1.584\% \]
这不是收益预测。
它真正说明的是:
胜率本身没有意义,盈亏比本身也没有意义。真正值得观察的是成本之后的组合期望。
二、胜率与盈亏比必须放在一起看
这是四个维度中最容易被错误优化的一组。
很多策略可以通过改变离场方式轻易提高胜率。
比如:
- 更早止盈;
- 放宽止损;
- 亏损后继续等待;
- 通过补仓降低平均成本。
结果往往是:
胜率提高了,但平均盈利下降,平均亏损扩大,尾部损失变得更加危险。
一个胜率 85%、平均盈利 0.3R、平均亏损 2.5R 的策略:
\[ 0.85\times0.3-0.15\times2.5=-0.12R \]
依然是负期望。
反过来,趋势策略完全可能只有 30%—40% 左右的胜率,却依靠少数大趋势覆盖大量小亏损。
所以实盘中真正值得保存的,不只是一个总胜率,而是:
| 指标 | 作用 |
|---|---|
| 滚动胜率 | 判断近期命中率是否变化 |
| 平均盈利 R | 判断盈利是否仍能充分扩张 |
| 平均亏损 R | 判断止损是否仍然有效 |
| 单笔期望 R | 判断策略当前是否仍有统计优势 |
| 最大单笔亏损 R | 发现尾部风险和执行异常 |
| MFE / MAE | 判断止盈、止损与实际价格路径是否匹配 |
这里尤其推荐使用 R 倍数,而不是直接比较 USDT 盈亏。
定义:
\[ R_{\text{realized}} = \frac{\text{本次净盈亏}} {\text{开仓时计划风险金额}} \]
例如:
一笔交易赚 100 USDT,但原计划只承担 50 USDT 风险,那么结果是 +2R。
另一笔赚了 300 USDT,但承担了 500 USDT 风险,实际上只有 +0.6R。
后者赚的钱更多,但前者对风险的利用效率明显更高。
三、频率真正要看的是“有效机会”
频率并不是简单地统计一天或者一个月交易多少次。
至少应该区分三个概念:
信号频率、订单频率、完整交易频率。
一套策略一个月可能只有 20 次真正的入场机会,却提交、修改和撤销了几千张订单。
这时真正增长的不一定是 Alpha,而可能是:
- 手续费;
- 买卖价差;
- 滑点;
- API 和订单状态管理压力;
- 重复下单概率;
- 市场冲击。
所以比“交易次数”更重要的是:
每增加一笔交易,是否仍然具有足够的净优势?
假设分钟级策略平均每笔毛优势只有 0.06%,完整开平仓成本已经达到 0.05%。
真正剩下的空间只有 0.01%。
只要实盘成交稍微差一点,正期望就可能消失。
另一方面,交易次数也不能无限减少。
一年只有几笔交易时,即使全部盈利,也很难判断这是长期优势还是某一段行情刚好适合策略。
因此真正值得优化的不是“高频”或“低频”,而是:
在交易成本可以承受的情况下,尽可能获得更多相对独立的正期望机会。
这里的“独立”非常重要。
BTC、ETH、SOL 在同一时间全部出现做多信号,看起来是三次机会,但它们可能只是同一个加密市场风险因子的三种表现。
同时开三笔,并不等于获得了三份独立优势。
所以实盘还应该监控:
- 同方向风险;
- 多品种相关性;
- 同一时间窗口的集中信号;
- 总名义敞口;
- 总计划止损风险。
四、仓位不是杠杆,而是风险预算
仓位是四个维度中真正把“统计优势”转化成账户结果的变量。
正确的计算顺序应该是:
先决定最多允许亏多少,再反推应该买多少。
例如:
账户权益:
\[ 10,000\ USDT \]
单笔最大计划风险:
\[ 0.5\% \]
则风险预算为:
\[ 10,000\times0.5\%=50\ USDT \]
如果入场价到止损价的距离为 2.5%,则名义仓位约为:
\[ \frac{50}{2.5\%}=2,000\ USDT \]
这里真正决定风险的是:
止损距离 × 名义仓位。
杠杆主要影响保证金占用。
当然,真实市场里还存在滑点、跳价、流动性不足和强平风险,所以“计划亏损 50 USDT”并不意味着实际亏损一定精确等于 50 USDT。
这也是为什么系统不仅要记录计划风险,还必须记录:
\[ \text{实际亏损}/\text{计划风险} \]
如果一套策略原本计划每次最多亏 1R,但实盘不断出现 -1.5R、-2R,首先应该检查的不是信号,而是执行和风险控制。
单笔风险之外,还要控制组合风险
假设系统同时持有:
- BTC 多单;
- ETH 多单;
- SOL 多单。
每笔计划风险都是账户的 0.5%。
单独看都不大。
但如果它们本质上暴露在同一个市场方向,真正需要考虑的是三笔交易同时止损。
因此仓位管理至少需要三道风险限制:
| 风险层 | 示例 |
|---|---|
| 单笔风险 | ≤ 0.5% |
| 同方向累计风险 | ≤ 1% |
| 全组合计划风险 | ≤ 1.5% |
具体数值并不是重点。
重点是:
不能只限制单笔仓位,而不限制相关仓位叠加之后的组合风险。
五、四个维度真正形成的是一条盈利链
把前面的关系放在一起,一套策略在单位时间里的简化期望可以写成:
\[ E_{\text{period}} \approx N\times E_R\times r \]
其中:
- \(E_R\):平均每笔净期望,以 R 表示;
- \(N\):有效交易机会数量;
- \(r\):单笔风险占账户权益的比例。
更一般地,如果每笔风险并不相同,则更接近:
\[ E_{\text{period}} \approx \sum_i E_{R,i}\times r_i \]
这说明一个很重要的问题:
四个维度不能分别最大化。
提高止盈目标,可能增加盈亏比,却降低胜率。放宽信号条件,可能增加交易频率,却降低单笔期望。扩大仓位可以放大收益,同样会放大回撤和模型误差。减少止损可能提高短期胜率,却可能把风险转移到少数极端亏损上。
真正需要优化的是:
成本、回撤和执行约束之下,四个维度形成的整体结构。
六、在 FMZ 中,真正需要记录的并不多
如果完整策略源码已经存在,文章没有必要再逐个介绍 GetTicker()、GetDepth() 或下单接口。
四维框架真正需要的是一份统一的交易记录。
每次完整平仓后,至少保存:
第一组:交易身份与时间
| 字段 | 含义 | 作用 |
|---|---|---|
symbol | 交易品种,例如 BTC_USDT.swap | 用于分别统计 BTC、ETH 或不同策略品种的表现 |
direction | 交易方向,例如多头 long、空头 short | 判断多空两侧的表现是否存在明显差异 |
entryTime | 实际建立仓位的时间 | 用于分析入场时段、市场环境和交易频率 |
exitTime | 仓位完全退出的时间 | 与入场时间结合计算持仓周期 |
holdingTime | 从实际入场到完全平仓的持续时间 | 判断策略持仓时间是否发生明显变化 |
第二组:开仓时的风险基准
| 字段 | 含义 | 作用 |
|---|---|---|
plannedRisk | 开仓时计划最多承担的风险金额,例如 50 USDT | 作为之后计算 R 倍数和检查风险偏差的基准 |
equityAtEntry | 建仓时账户的总权益 | 用于计算这笔交易实际占用了账户多少风险 |
第三组:真实收益与交易成本
| 字段 | 含义 | 作用 |
|---|---|---|
grossPnl | 不考虑额外费用时,这笔交易产生的交易盈亏 | 用来观察策略信号本身创造了多少毛利润 |
fee | 开仓、平仓以及其他成交产生的手续费 | 判断手续费侵蚀了多少策略优势 |
funding | 永续合约持仓期间实际支付或获得的资金费用 | 对持仓时间较长的永续策略尤其重要 |
netPnl | 扣除相关现金成本后的最终净盈亏 | 用于计算真实胜率、实际盈亏比和最终期望 |
slippage | 理论成交价格与实际成交价格之间的偏差 | 用于衡量执行质量,而不只是信号质量 |
其中滑点最好单独作为执行质量指标保存。
需要特别注意定义:
如果 grossPnl 已经使用真实成交价计算,那么买卖价格偏离理论价格造成的影响实际上已经进入交易盈亏。
此时再把同一笔滑点重复从 netPnl 中扣除,就可能造成双重计算。
因此系统应该明确区分:
现金成本和执行归因成本。
一个更稳妥的四维统计函数
原理其实很简单。
与其重新通过胜率和平均盈亏反推期望,不如直接对每笔已经标准化的 realizedR 求平均。
javascript
function average(arr) {
if (!arr || arr.length === 0) {
return 0
}
return arr.reduce((sum, x) => sum + x, 0) / arr.length
}
function calcFourDimensions(trades) {
if (!trades || trades.length === 0) {
return null
}
const rs = trades.map(t => t.realizedR)
const wins = rs.filter(r => r > 0)
const losses = rs.filter(r => r < 0)
const avgWinR = wins.length ? average(wins) : 0
const avgLossR = losses.length ? Math.abs(average(losses)) : 0
return {
count: trades.length,
winRate:
wins.length / trades.length,
payoffRatio:
avgLossR > 0
? avgWinR / avgLossR
: null,
expectancyR:
average(rs),
avgRiskRate:
average(
trades
.filter(t => t.equityAtEntry > 0)
.map(t => t.plannedRisk / t.equityAtEntry)
)
}
}
这里最重要的是:
javascript
expectancyR = average(realizedR)
这样保本交易就是 0,不需要人为把所有交易重新划分成“赢”和“输”之后再计算期望。
同时建议维护至少两个滚动窗口,例如:
text
最近20~30笔
最近100笔
再与历史回测基准比较。
全历史统计只适合回答“这套策略过去总体表现怎样”。
滚动统计才适合回答:
它现在是否还在按照原来的方式工作?
七、用一个简单策略测试四维框架
为了观察四个维度,没有必要使用复杂信号。
反而应该尽量让 Alpha 部分保持简单。
例如可以使用这样一个研究策略:
| 项目 | 规则 |
|---|---|
| 市场 | BTC_USDT.swap / ETH_USDT.swap |
| 周期 | 1 小时 |
| 入场 | 已完成 K 线突破此前 20 根 K 线区间 |
| 波动率 | ATR(14) |
| 初始止损 | 2 × ATR |
| 单笔风险 | 账户权益 0.5% |
| 同方向风险 | ≤ 1% |
| 总组合风险 | ≤ 1.5% |
| 离场 | 初始止损、反向突破或追踪止损 |
这个策略本身不是本文要证明的 Alpha。
它只是一个实验载体。
我们真正观察的是:
信号经过仓位、成本和执行之后,四个维度发生了什么变化。
例如:
回测里:
text
胜率 41%
盈亏比 2.4
月均交易 11
平均风险 0.5%
实盘滚动窗口突然变成:
text
胜率 34%
盈亏比 1.3
月化频率 27
实际风险 0.8%
这时问题已经不只是“最近运气不好”。
它可能意味着:
假突破增加,使胜率下降;提前离场或趋势缩短,使盈亏比下降;震荡造成重复入场,使频率快速增加;滑点和成交异常,使实际风险超过计划值。这才是“四维体检”真正有价值的地方。
八、策略失效要区分两种情况
实盘中最容易混淆的是:
策略统计退化和系统执行故障。
两者应该完全不同地处理。
第一类:统计退化
例如:
- 滚动期望持续下降;
- 胜率和盈亏比同时恶化;
- 有效频率下降;
- 成本占毛利润比例明显提高;
- 回撤超出过去正常区间。
这种情况通常还有观察空间。
可以先降低风险,让系统继续积累样本。
第二类:系统故障
例如:
- 行情数据异常;
- 本地仓位和交易所仓位不一致;
- 重复下单;
- 订单状态无法确认;
- 止损没有真实提交或执行;
- 实际风险频繁突破系统上限。
这种问题不需要等统计显著性。
应该直接停止新增风险。
因为这已经不是 Alpha 是否有效的问题,而是系统是否还能正确执行的问题。
可以把处理机制压缩成三级
| 状态 | 典型情况 | 动作 |
|---|---|---|
| 正常/观察 | 单个指标轻微偏离,期望仍为正 | 保持参数,继续观察 |
| 降低风险 | 多个统计指标同步恶化 | 单笔风险减半,降低组合上限 |
| 停止开仓 | 期望持续为负或执行系统异常 | 停止新增仓位并排查 |
这里还有一个原则:
不要因为最近亏损,就立即重新优化参数。
否则很容易把正常的随机波动误判成策略失效,然后不断追逐最近一段行情。
九、回测真正需要验证的只有三道关
与其堆很多漂亮指标,不如重点检查三个问题。
第一关:成本之后还有没有优势
手续费、滑点、资金费用、买卖价差加入之后,策略是否仍然保持正期望?
如果一加入合理交易成本就失效,那么原来的优势很可能只是理想成交造成的。
第二关:优势是否只存在于某一组参数
把突破周期从 20 改成 18、19、21、22;把 ATR 止损从 2 调整到 1.8 或 2.2;换一段时间;换 BTC、ETH;重新测试。如果只有一个极窄参数组合表现优秀,需要高度警惕过拟合。
第三关:回测统计能不能在真实执行中复现
小资金实盘阶段真正需要验证的是:
- realizedR 是否符合预期
- 实际成本是否接近假设
- 订单状态是否可靠
- 止损风险是否受控
- 交易频率是否异常
- 组合风险是否正确
这里的重点不是赚多少钱。
而是确认:
回测中的四维结构,在真实市场里是否仍然存在。
最后
量化交易不是一场“猜价格比赛”。
策略也不需要每次都正确。
真正需要建立的是一条稳定的盈利链:
text
**有统计优势的信号**
↓
**合理的实际盈亏比**
↓
**足够但不过度的有效交易频率**
↓
**能够承受连续亏损和模型误差的仓位**
胜率告诉我们有多经常赚钱。盈亏比告诉我们一次盈利可以覆盖多少次亏损。频率决定统计优势能否在有限时间里兑现,同时决定成本会不会把优势吃掉。仓位则决定在优势兑现之前,账户能不能活下来。代码只是把这些规则持续执行下去。
真正成熟的量化系统,应该始终知道三件事:
-
1、这一次最多准备亏多少。
-
2、长期为什么可能赚钱。
-
3、什么情况下应该停止继续承担风险。
完整 FMZ 策略源码沿用原文链接:策略源码
本策略仅用于量化研究和程序设计,不构成投资建议。
- 1



