4. 延迟与执行策略:滑点的隐形推手
做配对交易这么多年,我踩过最大的坑,就是低估了「延迟」的威力。
你想想看,信号算得再准,如果执行的时候慢了半拍,利润可能就全没了。说白了,延迟就是你的交易指令从大脑传到手脚的时间差。这个时间差里,市场可能已经变天了。
4.1 延迟的来源:到底慢在哪?
延迟不是单一的问题,它是一连串环节的累加。我个人习惯把延迟拆成三块来看:
- 网络延迟:你的电脑到交易所服务器,物理距离决定了光速上限。我在国内做A股时,服务器放上海和放深圳,延迟能差5-10毫秒。别小看这几毫秒,高频场景下就是天堂和地狱。
- 交易所撮合延迟:交易所的撮合引擎处理订单需要时间。行情越火爆,排队越长。我记得有一次股指期货秒级波动,我的限价单在队列里等了整整200毫秒才成交,价差已经跑了两个tick。
- API调用延迟:你用的交易接口,不管是CTP、FIX还是REST,每次请求都有开销。REST API尤其慢,一次请求可能几十到几百毫秒。我曾经用REST做高频配对,结果发现大部分时间都花在了HTTP握手和序列化上。
核心结论:延迟是累加的。网络10ms + 撮合50ms + API 30ms = 90ms。这90ms里,价差可能已经偏离你的入场点好几个bp了。
4.2 延迟对配对交易信号衰减的影响
配对交易的核心是「价差回归」。你算出价差偏离了均值,准备开仓。但信号从生成到执行,中间有延迟。
为什么会衰减?因为价差是动态的。你看到价差偏离2个标准差时下单,等订单到达交易所,价差可能已经回归了1个标准差。你实际成交的价差,远不如信号指示的那么有利。
我在项目中遇到过这样的情况:一个统计套利策略,理论夏普比2.5,实盘跑下来只有1.2。查了半天,发现是延迟导致信号衰减了40%以上。后来加了延迟模拟回测,才把预期调准。
我的建议:回测时一定要加入延迟模型。最简单的做法是,在信号生成时间戳上加上一个随机延迟(比如50-200ms),再判断成交价。你会发现,很多看起来漂亮的策略,加了延迟就原形毕露了。
4.3 TWAP(时间加权平均价格)策略
TWAP,说白了就是把一个大单拆成很多小单,按时间均匀地扔出去。目标是让成交价接近这段时间的平均价。
适用场景:你不想影响市场,只想低调地完成交易。比如你每天要调仓1000手,用TWAP拆成每5分钟20手,市场几乎感觉不到你的存在。
代码实现其实不复杂:
def twap_executor(total_quantity, total_seconds, interval_seconds):
"""
TWAP执行器
:param total_quantity: 总交易量
:param total_seconds: 总执行时间(秒)
:param interval_seconds: 每次下单间隔(秒)
"""
num_slices = total_seconds // interval_seconds
slice_qty = total_quantity // num_slices
remaining = total_quantity % num_slices
orders = []
for i in range(num_slices):
qty = slice_qty + (1 if i < remaining else 0)
orders.append({
'time': i * interval_seconds,
'quantity': qty
})
return orders
# 示例:1000手,10分钟,每30秒一次
orders = twap_executor(1000, 600, 30)
print(f"共{len(orders)}笔订单,每笔约{orders[0]['quantity']}手")
注意:TWAP有个致命弱点——它不关心成交量。如果市场流动性枯竭,你的小单也可能砸出大坑。我曾经在下午收盘前用TWAP,结果最后几分钟流动性骤降,滑点比一次性下单还大。
4.4 VWAP(成交量加权平均价格)策略
VWAP比TWAP聪明一点。它根据历史成交量分布来分配订单。流动性好的时段多下点,流动性差的时段少下点。
你想想看,开盘和收盘通常成交量最大,中午最清淡。VWAP会把更多订单放在活跃时段,这样你的成交价更接近市场真实均价。
实现思路:先获取历史成交量分布,然后按比例分配:
def vwap_executor(total_quantity, volume_profile):
"""
VWAP执行器
:param total_quantity: 总交易量
:param volume_profile: 列表,每个时间段的成交量占比(总和为1)
"""
orders = []
for i, vol_ratio in enumerate(volume_profile):
qty = int(total_quantity * vol_ratio)
if qty > 0:
orders.append({
'time_slot': i,
'quantity': qty,
'weight': vol_ratio
})
return orders
# 示例:假设一天分13个半小时时段,成交量占比已知
volume_profile = [0.12, 0.10, 0.09, 0.08, 0.07, 0.06, 0.05,
0.06, 0.07, 0.08, 0.09, 0.10, 0.03]
orders = vwap_executor(10000, volume_profile)
print(f"最大单笔:{max(o['quantity'] for o in orders)}手")
实战经验:我个人更偏爱VWAP。TWAP太机械,容易在流动性枯竭时吃亏。VWAP至少尊重市场规律。但要注意,历史成交量分布不一定代表未来。遇到突发新闻,成交量分布会完全变形。这时候我会手动暂停算法,等市场稳定再说。
4.5 延迟与执行策略的关系图
下面这张图,是我自己梳理的延迟影响链路。你看一眼就明白了:
从图里你能看到,信号生成后,经过延迟,信号已经衰减了。这时候再用TWAP或VWAP去执行,其实是在跟时间赛跑。选对策略,能帮你把衰减的损失补回来一部分。
一个小技巧:如果你做的是日内配对,建议用VWAP。如果是隔夜持仓,TWAP就够了。为什么?因为日内成交量分布不均匀,VWAP能帮你避开流动性陷阱。隔夜的话,时间跨度长,均匀分配反而更稳定。
嗯,关于延迟和执行策略,今天就聊这么多。记住一句话:信号是理论,执行是现实。延迟就是横在两者之间的那道坎。跨过去,你的策略才算真正落地。
公众号:蓝海资料掘金营,微信deep3321