10. 风险控制体系:最大回撤控制、止损止盈设置、黑天鹅事件应对
做基差交易,很多人只盯着利润。但我得说,风险控制才是真正的核心。没有风控的交易,就像在高速上蒙眼开车——早晚要出事。
我个人习惯,在搭建任何一个套利模型之前,先把风控框架搭好。说白了,先想好怎么死,再想怎么活。这一章,我就把我在实战中打磨出来的风控体系,掰开揉碎了讲给你听。
核心观点:基差交易的风险控制,不是事后补救,而是事前设计。它应该嵌入到策略的每一个环节里。
10.1 最大回撤控制:守住你的底线
最大回撤,这个词听起来很学术。但说白了,就是你账户从最高点跌下来,最多亏了多少。我见过太多人,策略赚了50%就飘了,结果一次回撤20%就扛不住清盘了。
我个人习惯,把最大回撤分成三个层级来管:
- 账户级回撤:整个资金账户的最大回撤。我一般设15%。到了这个线,全部策略暂停。
- 策略级回撤:单个基差策略的回撤。通常设8%-10%。到了就减仓50%。
- 单笔交易回撤:一笔开仓后的浮亏。设2%-3%。到了直接砍。
我的经验:回撤控制不是死的。市场波动大的时候,我会把阈值收窄。比如去年8月那波行情,我把策略级回撤从10%临时改到6%。为什么?因为波动率翻倍了,同样的回撤幅度,实际风险大了很多。
代码实现上,我习惯用滚动窗口来计算动态回撤:
def calculate_drawdown(equity_curve, window=252):
"""
计算滚动最大回撤
equity_curve: 净值序列
window: 滚动窗口(交易日)
"""
rolling_max = equity_curve.rolling(window=window, min_periods=1).max()
drawdown = (equity_curve - rolling_max) / rolling_max
# 当前回撤
current_dd = drawdown.iloc[-1]
# 最大回撤
max_dd = drawdown.min()
return current_dd, max_dd, drawdown
# 实战中,我每5分钟跑一次这个函数
current_dd, max_dd, _ = calculate_drawdown(equity, window=60)
if current_dd < -0.08: # 回撤超过8%
reduce_position(0.5) # 减半仓
send_alert("回撤预警:策略级回撤触及8%")
10.2 止损止盈设置:让利润奔跑,让亏损停止
基差交易有个特点——它不像单边趋势,止损止盈的设置逻辑不太一样。你想想看,基差本身是有均值回归属性的,所以止损不能设得太窄,否则容易被来回打脸。
我一般用三种止损方式:
| 止损类型 | 适用场景 | 参数设置(我的习惯) |
|---|---|---|
| 固定价差止损 | 基差偏离历史均值时 | 基差超出均值±2个标准差 |
| 时间止损 | 持仓超过预期周期 | 超过5个交易日未回归,强制平仓 |
| 波动率止损 | 市场剧烈波动时 | ATR的3倍作为止损宽度 |
避坑指南:我曾经犯过一个错——把止损设得太精确。比如基差到5.32就止损,5.31就不动。结果呢?市场流动性一差,滑点直接把我打穿。后来我改成区间止损,比如5.20-5.40之间触发,留出缓冲带。
止盈方面,我比较推荐移动止盈。基差回归到均值附近后,不要急着全平。让利润再飞一会儿:
def trailing_stop(current_spread, entry_spread, target_spread, trail_percent=0.3):
"""
移动止盈逻辑
current_spread: 当前基差
entry_spread: 开仓基差
target_spread: 目标基差(均值)
trail_percent: 回撤触发比例
"""
# 计算已经实现的利润比例
profit_pct = (entry_spread - current_spread) / entry_spread
# 如果利润超过目标,启动移动止盈
if profit_pct >= target_spread:
# 从最高利润点回撤 trail_percent 就止盈
high_water_mark = max(high_water_mark, profit_pct)
if (high_water_mark - profit_pct) >= trail_percent:
return "close_position"
return "hold"
10.3 黑天鹅事件应对:当极端行情来敲门
说实话,黑天鹅事件是基差交易最大的敌人。为什么?因为基差交易假设市场是正常运行的。一旦出现极端行情,比如2020年3月的流动性危机,基差会瞬间扭曲到你无法想象的地步。
我经历过最惨的一次,是2022年某品种的逼仓行情。基差从正常的+50,一夜之间拉到+800。我的空头仓位直接爆仓。那次之后,我彻底重构了黑天鹅应对体系。
现在我的做法是:
- 熔断机制:当基差偏离历史均值超过5个标准差时,强制平掉所有仓位。不管盈亏,先出来再说。
- 压力测试:每周跑一次极端情景模拟。比如假设基差瞬间扩大3倍,看看账户能不能扛住。
- 仓位上限:单个品种的仓位不超过总资金的20%。这是最后的防线。
核心原则:在黑天鹅面前,不要想着「扛一扛就过去了」。基差交易的杠杆通常不低,扛单的结果往往是爆仓。我的原则是——先活下来,机会有的是。
代码实现上,我写了一个熔断监控器:
class CircuitBreaker:
def __init__(self, z_score_threshold=5.0, lookback=100):
self.z_score_threshold = z_score_threshold
self.lookback = lookback
self.history = []
def check(self, current_spread):
"""
检查是否触发熔断
返回: (triggered, message)
"""
self.history.append(current_spread)
if len(self.history) < self.lookback:
return False, "数据不足"
# 计算Z-score
mean = np.mean(self.history[-self.lookback:])
std = np.std(self.history[-self.lookback:])
z_score = (current_spread - mean) / std
if abs(z_score) > self.z_score_threshold:
return True, f"熔断触发!Z-score: {z_score:.2f}"
return False, "正常"
# 实战中,这个检查每秒跑一次
breaker = CircuitBreaker(z_score_threshold=5.0)
is_triggered, msg = breaker.check(current_spread)
if is_triggered:
emergency_close_all() # 紧急平仓所有头寸
嗯,说到这,我想强调一点。风控体系不是写几个函数就完事了。它需要你持续监控、定期复盘、不断迭代。我每个月都会把回撤记录拉出来看一遍,问问自己:哪些亏损是可以避免的?哪些风控规则需要调整?
记住一句话:好的风控,让你在市场上活得久。活得久,才能赚得多。
一个小技巧:我习惯在交易终端上放三个数字——当前回撤、最大回撤、可用资金。每次开仓前扫一眼。如果回撤已经接近阈值,哪怕信号再好,我也会放弃。这不是怂,这是纪律。
公众号:蓝海资料掘金营,微信deep3321