4. 信号生成逻辑:阈值设定、开仓信号、平仓信号、止损信号
信号生成,是整个价差交易系统的核心。说白了,前面算价差、做平稳性检验,都是为了这一刻——决定什么时候进场,什么时候离场。
我见过不少新手,花大量时间优化价差计算,结果在信号生成这块草草了事。嗯,这其实是个大坑。信号逻辑如果不够严谨,再好的价差模型也是白搭。
4.1 阈值设定:开仓的“扳机”在哪里
阈值,就是触发交易的那条线。我个人习惯用均值±N倍标准差来设定。为什么?因为价差在大多数时候会围绕均值波动,偏离到一定程度后,大概率会回归。
核心公式:
- 上阈值 = 均值 + k × 标准差
- 下阈值 = 均值 - k × 标准差
- 平仓阈值 = 均值 ± 0.5 × 标准差(或直接设为均值)
k值怎么选?这得看你的风险偏好。我在项目中遇到过这样的情况:k=2时信号太少,一年做不了几单;k=1时信号太多,频繁交易手续费吃掉了利润。后来我一般取k=1.5到2之间,具体用历史数据回测来定。
我的经验:
别死磕固定阈值。市场波动率会变,我建议用滚动窗口动态计算均值和标准差。比如取过去60个交易日的滚动数据,这样阈值会自适应市场环境。
4.2 开仓信号:什么时候扣动扳机
开仓信号,说白了就是价差突破阈值的那一刻。但这里有个细节——是突破就进,还是等确认?
我个人习惯用“突破+确认”两步走:
- 初步触发:价差穿越上阈值或下阈值
- 确认条件:连续N个周期(比如3根K线)都维持在阈值之外
为什么要加确认?因为有时候价差只是瞬间毛刺,马上又回来了。你想想看,如果一突破就进场,很容易被假突破来回打脸。我曾经吃过这个亏,后来就老实了。
注意:
确认周期别设太长。N=3到5比较合适。太长的话,等你确认完,价差可能已经回归了一大半,利润空间就没了。
开仓方向也很明确:
- 价差 > 上阈值 → 做空价差(卖高价差,买低价差)
- 价差 < 下阈值 → 做多价差(买高价差,卖低价差)
这里有个小技巧:开仓时不要一次性打满仓位。我一般分两批进场,第一批进60%,如果价差继续偏离,第二批再进40%。这样能降低滑点的影响。
4.3 平仓信号:见好就收
平仓比开仓更难。为什么?因为人性总是贪婪的,总想再多赚一点。但价差交易的核心是“回归”,一旦价差回到均值附近,就该走了。
我常用的平仓逻辑有三种:
| 平仓方式 | 触发条件 | 适用场景 |
|---|---|---|
| 均值平仓 | 价差回到均值线 | 标准回归策略 |
| 反向阈值平仓 | 价差穿越反向阈值(如0.5倍标准差) | 趋势较强时 |
| 时间平仓 | 持仓超过N个周期(如20根K线) | 防止价差不回归 |
我个人最常用的是“均值平仓+时间平仓”组合。价差回到均值就平掉大部分仓位,留一小部分等反向阈值。如果持仓太久还没回归,说明逻辑可能变了,果断离场。
核心原则:
平仓信号要明确,不要模棱两可。我见过有人设了“价差接近均值就平仓”,结果“接近”这个词害死人——到底多近才算接近?一定要量化,比如“价差在均值的±0.3倍标准差以内”。
4.4 止损信号:活下来比什么都重要
止损,是交易员的最后一道防线。价差交易虽然风险相对可控,但也会遇到价差持续不回归的情况。比如2015年股灾时,很多配对关系都失效了。
我常用的止损方式:
- 固定金额止损:每笔交易亏损达到总资金的1%-2%就砍
- 价差倍数止损:价差偏离到开仓阈值的2倍以上,说明逻辑可能失效
- 时间止损:持仓超过预设周期(如30根K线)仍不回归,强制平仓
血的教训:
我曾经在螺纹钢和热卷的配对交易中,价差偏离到3倍标准差还没止损,结果亏了5%。后来我给自己定了个铁律:价差突破2倍开仓阈值,无条件止损。别犹豫,犹豫就会败北。
止损信号要放在开仓信号之前判断。什么意思?就是每次检查开仓条件时,先检查是否触发了止损。如果触发了,先处理止损,再考虑新开仓。
4.5 信号生成的整体流程
把上面这些串起来,信号生成的逻辑就清晰了。我画了个流程图,方便你理解:
这个流程看起来简单,但每个环节都有坑。我建议你先把逻辑写清楚,再用代码实现。别一上来就写代码,容易漏掉边界条件。
4.6 代码实现示例
下面是一个简单的信号生成函数,用Python写的。你直接拿去改改就能用:
def generate_signals(spread, mean, std, k=1.5, confirm_period=3):
"""
生成交易信号
spread: 价差序列
mean: 均值
std: 标准差
k: 阈值倍数
confirm_period: 确认周期
"""
upper = mean + k * std
lower = mean - k * std
signals = []
position = 0 # 0:空仓, 1:多仓, -1:空仓
for i in range(len(spread)):
signal = 0
# 止损检查
if position == 1 and spread[i] < lower * 2:
signal = -1 # 平多止损
elif position == -1 and spread[i] > upper * 2:
signal = 1 # 平空止损
# 开仓检查
if position == 0:
if spread[i] > upper:
# 确认突破
if all(spread[i-confirm_period+1:i+1] > upper):
signal = -1 # 开空
elif spread[i] < lower:
if all(spread[i-confirm_period+1:i+1] < lower):
signal = 1 # 开多
# 平仓检查
if position == 1 and spread[i] >= mean:
signal = -1 # 平多
elif position == -1 and spread[i] <= mean:
signal = 1 # 平空
signals.append(signal)
if signal != 0:
position += signal
return signals
使用建议:
这段代码只是个框架。实际使用时,你还需要加入手续费、滑点、仓位管理等逻辑。我一般会在信号生成后,再跑一遍回测,看看夏普比率和最大回撤是否达标。
好了,信号生成的逻辑就这些。记住一句话:开仓要谨慎,平仓要果断,止损要坚决。这三条做到了,你的价差交易系统就成功了一半。
公众号:蓝海资料掘金营,微信deep3321