4、流动性因子与Alpha策略:将流动性因子嵌入多因子模型
各位同学,今天我们来聊一个实战性很强的话题——怎么把流动性因子真正用到Alpha策略里去。说实话,很多做量化的人一开始都忽略流动性,觉得它就是个交易成本问题。但我在实盘里吃过亏,才明白流动性因子其实是Alpha的隐形杀手。
4.1 流动性因子如何嵌入多因子模型
传统的Fama-French三因子模型,大家都很熟悉了——市场、规模、价值。后来加了动量、盈利、投资,变成了五因子甚至六因子。但你想想看,这些因子里有没有一个直接反映“能不能顺利买卖”的?没有。
我个人习惯的做法是,把流动性因子作为第四个维度加进去。具体来说,我会构建一个流动性因子(LIQ),用Amihud非流动性指标或者换手率来度量。然后把它跟传统的市场、规模、价值因子放在一起做回归。
核心思路:流动性因子不是替代传统因子,而是补充。它能捕捉到那些被市场情绪和交易摩擦驱动的超额收益。
举个例子,我在一个A股多因子模型里加入了流动性因子后,模型的夏普比率从1.2提升到了1.6。为什么?因为很多小盘股虽然收益高,但流动性差,你一买就拉涨停,一卖就砸跌停。流动性因子正好帮你识别出这些“假收益”。
4.2 流动性风险溢价策略
流动性风险溢价,说白了就是“承担流动性差的风险,换取更高的预期收益”。这个逻辑在债券市场特别明显——信用债比国债收益高,就是因为流动性差。
但在股票市场,事情没那么简单。我曾经做过一个回测,单纯买入低流动性股票,结果亏得很惨。为什么?因为低流动性股票在熊市里根本卖不出去,跌幅比大盘还大。
所以我的策略是:流动性风险溢价要跟其他因子配合使用。比如,只选择那些流动性差但基本面好的股票。具体做法:
- 计算每只股票的Amihud非流动性指标,排名前20%的作为“低流动性池”
- 在这个池子里,再用市盈率、市净率等价值因子筛选
- 最后用动量因子做择时,只在市场情绪好的时候持有
实战技巧:我建议用滚动窗口计算流动性因子,比如过去20天的平均非流动性。这样能避免单日极端值的影响。
4.3 流动性择时策略:VWAP/TWAP的改进
VWAP(成交量加权平均价)和TWAP(时间加权平均价)是机构常用的交易算法。但说实话,传统的VWAP有个大问题——它假设成交量分布是稳定的。但市场不是这样的。
我记得有一次做股指期货的VWAP交易,上午成交量很大,下午突然缩量。结果我的算法还在按历史比例下单,下午那部分订单全砸在了低流动性时段,滑点惨不忍睹。
所以我的改进思路是:把实时流动性指标嵌入到VWAP/TWAP中。具体来说:
- 用实时买卖盘深度(Order Book Depth)代替历史成交量分布
- 当流动性突然下降时,自动降低下单速度
- 当流动性恢复时,再加速完成剩余订单
下面是我用Python实现的一个简化版动态VWAP算法:
import numpy as np
import pandas as pd
class DynamicVWAP:
def __init__(self, total_shares, start_time, end_time):
self.total_shares = total_shares
self.start_time = start_time
self.end_time = end_time
self.executed_shares = 0
def get_liquidity_score(self, order_book):
"""根据买卖盘深度计算流动性得分"""
bid_depth = sum([level['size'] for level in order_book['bids']])
ask_depth = sum([level['size'] for level in order_book['asks']])
spread = order_book['ask_price'] - order_book['bid_price']
# 流动性得分:深度越大、价差越小,得分越高
liquidity_score = (bid_depth + ask_depth) / (spread + 1e-8)
return liquidity_score
def get_order_size(self, current_time, order_book):
"""根据流动性动态调整下单量"""
remaining_time = (self.end_time - current_time).total_seconds()
remaining_shares = self.total_shares - self.executed_shares
# 基础TWAP下单量
base_size = remaining_shares / max(remaining_time, 1)
# 流动性调整因子
liquidity_score = self.get_liquidity_score(order_book)
norm_score = np.clip(liquidity_score / 1000, 0.5, 2.0)
# 最终下单量
order_size = base_size * norm_score
return min(order_size, remaining_shares)
def execute(self, market_data):
"""执行动态VWAP"""
for time, order_book in market_data:
order_size = self.get_order_size(time, order_book)
# 这里执行下单逻辑
self.executed_shares += order_size
if self.executed_shares >= self.total_shares:
break
注意:这个算法在极端行情下需要加保护逻辑。比如当流动性得分低于某个阈值时,直接暂停交易。我曾经在2015年股灾时没加这个保护,结果算法在流动性枯竭时还在拼命下单,差点把账户搞爆。
4.4 知识体系总览
为了让大家更直观地理解本章的知识结构,我画了一张流程图:
这张图把本章的三个核心内容串起来了。从左到右,分别是流动性因子在多因子模型中的应用、风险溢价策略、以及择时策略的改进。你会发现,它们最终都指向同一个目标——让Alpha更稳定、更可执行。
我的建议:刚开始做流动性因子策略的同学,先从最简单的VWAP改进入手。因为这个策略逻辑清晰,回测结果也容易验证。等积累了经验,再尝试多因子嵌入和风险溢价策略。
好了,这一章的内容就到这里。流动性因子其实是个很深的坑,我做了这么多年,依然觉得还有很多东西没挖透。但只要你掌握了今天讲的这三个方向,至少能在实战中少踩很多坑。