4、情绪指标计算:换手率、波动率、成交量变异系数、涨跌停比
各位同学,今天我们来啃一块硬骨头——情绪指标的计算。
说实话,很多做量化的人一上来就搞机器学习模型,结果回测一塌糊涂。为什么?因为底层情绪数据没算对。我个人的习惯是,先把这些基础指标吃透,再谈策略。今天这4个指标,是我在实盘项目中反复打磨过的,每一个都有坑。
4.1 换手率:市场活跃度的体温计
换手率,说白了就是「股票转手的频率」。你想想看,一只股票如果没人买卖,换手率就是0。如果大家都在抢筹,换手率就飙升。
计算公式:
换手率 = 当日成交量 / 流通股本 × 100%
嗯,这里要注意:流通股本不是总股本。很多新手直接用总股本算,结果指标失真。我在项目中遇到过,某只银行股总股本很大,但大部分是国有股不流通,用总股本算出来的换手率低得离谱,完全没法用。
Python实现:
import pandas as pd
def calc_turnover_rate(volume, circulating_shares):
"""
计算换手率
:param volume: 当日成交量(股)
:param circulating_shares: 流通股本(股)
:return: 换手率(%)
"""
turnover = (volume / circulating_shares) * 100
return turnover.round(2)
# 示例
df['turnover_rate'] = calc_turnover_rate(df['volume'], df['circulating_shares'])
4.2 波动率:情绪的振幅
波动率反映的是价格上下跳动的剧烈程度。情绪越激动,波动率越大。我个人习惯用「日内振幅」来算,而不是用收盘价的标准差。为什么?因为日内数据更能捕捉到盘中情绪的瞬间爆发。
计算公式:
日内波动率 = (当日最高价 - 当日最低价) / 当日收盘价 × 100%
Python实现:
def calc_volatility(high, low, close):
"""
计算日内波动率
"""
vol = (high - low) / close * 100
return vol.round(2)
df['volatility'] = calc_volatility(df['high'], df['low'], df['close'])
4.3 成交量变异系数:量能的异常信号
这个指标很多人不重视,但我觉得它比单纯的成交量更有价值。成交量变异系数(CV)衡量的是成交量相对于其均值的离散程度。说白了,就是看今天的成交量是不是「不正常」。
计算公式:
成交量变异系数 = 当日成交量 / 过去N日成交量均值
为什么用比值而不是差值?因为不同股票的成交量基数不一样。茅台一天成交50亿,小盘股一天成交5000万,直接用差值没法比。用比值就标准化了。
Python实现:
def calc_volume_cv(volume, window=20):
"""
计算成交量变异系数
"""
mean_vol = volume.rolling(window=window).mean()
cv = volume / mean_vol
return cv.round(2)
df['volume_cv'] = calc_volume_cv(df['volume'])
4.4 涨跌停比:极端情绪的晴雨表
涨跌停比,这个指标我特别喜欢。它直接告诉你:今天市场是「疯狂做多」还是「恐慌出逃」。
计算公式:
涨跌停比 = 涨停家数 / (涨停家数 + 跌停家数)
注意:这个比值在0到1之间。大于0.7说明市场情绪亢奋,小于0.3说明恐慌。我曾经在2022年4月的一次回测中,发现这个指标连续3天低于0.2,随后大盘见底反弹。嗯,这就是情绪极值的威力。
Python实现:
def calc_limit_ratio(up_limit, down_limit):
"""
计算涨跌停比
"""
total = up_limit + down_limit
if total == 0:
return 0.5 # 没有涨跌停时,返回中性值
ratio = up_limit / total
return round(ratio, 4)
df['limit_ratio'] = calc_limit_ratio(df['up_limit_count'], df['down_limit_count'])
4.5 四个指标的综合应用框架
单独看一个指标,意义不大。把它们组合起来,才能形成完整的情绪画像。下面是我在项目中常用的框架图:
这个框架的核心逻辑是:四个指标先各自标准化到0-100区间,然后按权重合成一个综合情绪指数。权重怎么定?我建议用等权,简单有效。如果你有历史数据,也可以用PCA或者因子分析来优化权重。
4.6 实战中的注意事项
最后,分享几个我在实战中踩过的坑:
- 数据对齐: 不同股票的交易日可能不一样,合并数据时一定要用inner join,否则会出现空值。
- 极端值处理: 换手率和波动率偶尔会出现异常大的值,建议用99%分位数做截断处理。
- 参数敏感性: 成交量CV的窗口期N,我试过5、10、20、30,最终发现20日效果最稳定。你可以根据自己的回测周期调整。
- 不要过度优化: 这四个指标已经够用了。我见过有人加了十几个情绪指标,结果过拟合得一塌糊涂。
好了,这一章的内容就到这里。代码我已经贴出来了,你直接复制到自己的回测框架里就能用。如果遇到问题,欢迎在群里交流。