换手率指标详细分析 Skill
一、指标概述
1.1 换手率的定义
换手率(Turnover Rate),又称周转率,是指在一定时期内某只股票的成交量(或成交金额)与其流通股本(或流通市值)的比率。其本质衡量的是市场中股票所有权转移的频率,即"股票换手的速度"。换手率是衡量股票流通性和市场活跃程度最核心的量化指标之一。
从微观层面来看,换手率反映了投资者对该股票的交易热情和参与意愿。一只换手率高的股票,意味着大量投资者在短时间内进行了买卖操作,市场分歧较大;而换手率低的股票,则表明持股者倾向于持有,市场共识度较高。
1.2 换手率反映股票流通性和市场活跃度
换手率与股票流通性呈正相关关系。流通性好的股票,投资者可以以较低的交易成本快速买入或卖出,而不会对价格产生显著影响。换手率正是这种流通性的直接度量。
在市场实践中,换手率能够揭示以下关键信息:
- 市场情绪温度计:换手率升高通常意味着市场情绪升温,投资者交易意愿增强;换手率降低则暗示市场趋于冷淡。
- 筹码分布变化:持续的高换手率意味着筹码在快速换手,原有持仓者可能在离场,新资金在入场。
- 流动性风险评估:极低的换手率可能意味着流动性不足,大额交易可能面临较大的滑点风险。
- 主力行为追踪:异常的换手率变化往往是主力资金进出市场的信号。
1.3 换手率在技术分析中的重要性
在技术分析体系中,换手率占据着不可替代的地位,其重要性体现在以下几个方面:
第一,换手率是量价分析的核心补充。单纯观察成交量存在一个固有缺陷——大盘股和小盘股的成交量天然存在数量级差异,无法直接比较。换手率通过将成交量标准化为比率,消除了股本规模的影响,使得不同股票之间的横向比较成为可能。
第二,换手率是识别趋势可靠性的关键指标。在上升趋势中,适度的换手率表明趋势有资金支撑;在下跌趋势中,缩量换手可能意味着抛压减轻。换手率与价格走势的配合关系,能够帮助投资者判断趋势的健康程度。
第三,换手率是发现主力行为的重要窗口。机构资金的建仓、拉升、洗盘、出货等操作,都会在换手率上留下 distinctive 的痕迹。通过系统性地分析换手率的变化模式,投资者可以在一定程度上"跟踪"主力的操作轨迹。
第四,换手率在选股策略中具有筛选价值。通过设定换手率阈值,可以快速筛选出市场关注度高的活跃个股,或者排除流动性不足的标的,从而提高交易效率和风险管理水平。
二、计算公式详解
2.1 A股换手率计算
A股市场中最常用的换手率计算公式如下:
换手率 = 成交量 ÷ 流通股本 × 100%
其中:
- 成交量:指统计周期内的累计成交股数(单位:股)。
- 流通股本:指公司总股本中可以在二级市场自由交易的股份数量(单位:股)。
注意事项:
- 流通股本应使用最新数据,因为限售股解禁会导致流通股本发生变化。
- 部分数据平台提供的换手率可能基于自由流通股本计算(扣除大股东长期持有的股份),结果会更高。
- 计算日换手率时,成交量使用当日成交量;计算周换手率时,使用一周内每日成交量之和。
2.2 相对换手率与绝对换手率
在实际应用中,换手率分为两种口径:
相对换手率(总股本口径)
相对换手率 = 成交量 ÷ 总股本 × 100%
相对换手率以公司总股本为分母,包含了限售股等不能在二级市场交易的股份。这一指标在A股早期较为常用,但由于大量股份处于限售状态,相对换手率往往偏低,不能真实反映市场的实际交易活跃度。
绝对换手率(实际流通盘口径)
绝对换手率 = 成交量 ÷ 实际流通股本 × 100%
绝对换手率以实际流通股本为分母,只计算可以在二级市场自由交易的股份。这一指标更准确地反映了市场真实的交易活跃程度,是目前主流数据平台和投资者普遍采用的口径。
两者差异与实战意义
| 对比维度 | 相对换手率 | 绝对换手率 |
|---|---|---|
| 分母 | 总股本 | 实际流通股本 |
| 数值 | 偏低 | 偏高 |
| 准确性 | 较低 | 较高 |
| 适用场景 | 历史数据对比 | 实战交易分析 |
实战意义:对于限售股占比较大的公司(如次新股),两者的差异尤为显著。例如,一家总股本10亿股但实际流通仅2亿股的公司,若当日成交4000万股,相对换手率为4%,而绝对换手率高达20%。后者更能反映该股当日的真实交易热度。因此,在进行换手率分析时,强烈建议使用绝对换手率。
2.3 国外换手率计算
在欧美等成熟市场,换手率的计算方式有所不同,通常以金额为基准:
换手率 = 成交金额 ÷ 流通市值 × 100%
其中:
- 成交金额:统计周期内的累计成交金额(单位:美元或当地货币)。
- 流通市值:流通股本乘以当前股价。
差异原因:
- 成熟市场中,股票价格差异巨大(从几美元到几千美元),单纯以股数计算的换手率无法反映真实的资金活跃程度。
- 以金额计算的换手率能够更直观地反映资金流向和市场活跃度。
- 对于ADR(美国存托凭证)等特殊品种,以金额计算更为准确。
2.4 多周期换手率
换手率可以根据不同的统计周期进行计算,以满足不同分析需求:
日换手率
日换手率 = 当日成交量 ÷ 流通股本 × 100%
日换手率是最常用的换手率指标,反映单日内的交易活跃程度。A股市场日换手率的正常范围通常在1%-5%之间。
周换手率
周换手率 = 本周累计成交量 ÷ 流通股本 × 100%
= Σ(每日成交量) ÷ 流通股本 × 100%
周换手率用于观察一周内的资金进出情况,能够平滑单日异常波动,更好地反映中期趋势。正常范围通常在5%-25%之间。
月换手率
月换手率 = 本月累计成交量 ÷ 流通股本 × 100%
= Σ(每日成交量) ÷ 流通股本 × 100%
月换手率反映较长时间内的筹码换手情况,常用于判断主力建仓或出货的中长期行为。正常范围通常在20%-100%之间。
年换手率
年换手率 = 本年累计成交量 ÷ 流通股本 × 100%
= Σ(每日成交量) ÷ 流通股本 × 100%
年换手率反映全年的交易活跃程度,A股市场个股年换手率通常在200%-1000%之间,远高于成熟市场(通常在50%-200%之间),这体现了A股市场短线交易活跃的特征。
2.5 换手率移动平均
为了消除短期波动噪音,实践中常使用换手率的移动平均值:
5日平均换手率
MA5换手率 = (T日换手率 + T-1日换手率 + ... + T-4日换手率) ÷ 5
5日平均换手率反映近一周的平均交易活跃度,适合短线分析。
10日平均换手率
MA10换手率 = (T日换手率 + T-1日换手率 + ... + T-9日换手率) ÷ 10
10日平均换手率反映近两周的平均交易活跃度,适合中线分析。
20日平均换手率
MA20换手率 = (T日换手率 + T-1日换手率 + ... + T-19日换手率) ÷ 20
20日平均换手率反映近一个月的平均交易活跃度,适合中长线趋势判断。
应用技巧:当短期换手率均线(如MA5)上穿长期换手率均线(如MA20)时,表明交易活跃度正在提升,可能预示着新一轮行情的启动;反之,则可能意味着行情趋于平淡。
2.6 完整计算示例
假设某A股上市公司数据如下:
- 流通股本:5亿股
- 总股本:8亿股
- 当前股价:20元/股
- 某日成交量:3000万股
- 某日成交金额:6亿元
- 流通市值:100亿元
计算过程:
绝对换手率 = 3000万 ÷ 50000万 × 100% = 6.00%
相对换手率 = 3000万 ÷ 80000万 × 100% = 3.75%
金额换手率 = 60000万 ÷ 1000000万 × 100% = 6.00%
若该周五个交易日的成交量分别为:2000万、2500万、3000万、3500万、4000万股:
周换手率 = (2000+2500+3000+3500+4000)万 ÷ 50000万 × 100% = 30.00%
5日平均换手率 = 30.00% ÷ 5 = 6.00%
三、参数动态调整策略
3.1 换手率阈值设定
根据A股市场的长期统计和实践经验,换手率可按以下阈值进行分级:
| 等级 | 换手率范围 | 市场含义 | 操作建议 |
|---|---|---|---|
| 极低换手率 | <1% | 成交极度低迷,流动性差 | 谨慎参与,注意流动性风险 |
| 低换手率 | 1%-2% | 交易清淡,市场关注度低 | 可关注,等待放量信号 |
| 温和换手率 | 2%-3% | 交易正常偏弱 | 中性,结合其他指标判断 |
| 正常换手率 | 3%-7% | 交易活跃度适中 | 正常交易区间 |
| 高换手率 | 7%-15% | 交易活跃,资金关注度高 | 关注方向,警惕风险 |
| 极高换手率 | >15% | 交易异常活跃 | 高度警惕,可能见顶 |
| 异常换手率 | >20% | 极端异常,可能主力对倒 | 规避为主,等待确认 |
特别说明:
- 上述阈值为一般性参考标准,实际应用中需要结合具体股票的市值、板块特征和市场环境进行调整。
- 异常换手率(>20%)在A股中虽然罕见,但在特定场景下会出现,如:新股上市首日、重大利好/利空消息公布、主力资金对倒操作等。
- 持续多日换手率超过15%的股票,往往意味着筹码在快速换手,需要特别关注后续方向。
3.2 不同市值股票的换手率标准
不同市值规模的股票,其换手率特征存在显著差异:
大盘股(市值>500亿元)
大盘股由于流通盘巨大,资金难以在短时间内完成大规模换手,因此换手率普遍较低。
| 等级 | 换手率范围 |
|---|---|
| 低迷 | <0.3% |
| 正常 | 0.3%-1.0% |
| 活跃 | 1.0%-2.0% |
| 高换手 | >2.0% |
典型代表:工商银行、中国石油、贵州茅台等。贵州茅台作为特例,由于其独特的投资属性,换手率长期维持在0.2%-0.5%的极低水平,但价格走势强劲。
中盘股(市值100-500亿元)
中盘股的换手率处于中等水平,是主力资金较为青睐的标的。
| 等级 | 换手率范围 |
|---|---|
| 低迷 | <1% |
| 正常 | 1%-3% |
| 活跃 | 3%-7% |
| 高换手 | >7% |
小盘股(市值<100亿元)
小盘股由于流通盘较小,少量资金即可推动较大换手率。
| 等级 | 换手率范围 |
|---|---|
| 低迷 | <2% |
| 正常 | 2%-5% |
| 活跃 | 5%-10% |
| 高换手 | >10% |
创业板/科创板
创业板和科创板由于涨跌幅限制为20%(主板为10%),投机性更强,换手率普遍高于主板同市值股票。
| 等级 | 换手率范围 |
|---|---|
| 低迷 | <3% |
| 正常 | 3%-8% |
| 活跃 | 8%-15% |
| 高换手 | >15% |
3.3 不同市场环境下的参数调整
牛市环境
在牛市中,市场整体交易活跃,换手率中枢系统性上移:
- 所有等级的阈值可上移30%-50%
- 正常换手率范围调整为5%-10%
- 高换手率阈值从7%上调至10%以上
- 牛市中换手率持续维持高位是趋势健康的表现,不必过度恐慌
熊市环境
在熊市中,市场交易清淡,换手率中枢系统性下移:
- 所有等级的阈值可下移20%-40%
- 正常换手率范围调整为1%-4%
- 低换手率阈值从1%下调至0.5%
- 熊市中的突然放量换手需要高度关注,可能是反弹信号也可能是恐慌性抛售
震荡市环境
在震荡市中,换手率波动较大,建议:
- 使用换手率移动平均(如MA10、MA20)来平滑波动
- 关注换手率突破均线的行为,可能预示方向选择
- 结合价格突破方向综合判断
四、核心交易信号
4.1 低位放量换手
底部区域突然换手率放大
当股票经过较长时间(通常3-6个月或更长)的下跌后,在底部区域出现换手率突然放大的现象,这是一个重要的关注信号。
识别特征:
- 股价处于长期下跌趋势的末端,累计跌幅通常超过30%-50%
- 前期换手率持续低迷(通常低于2%)
- 突然出现换手率放大至前期均值的2-3倍以上
- 放量当日或随后几日,股价不再创新低,甚至出现小幅上涨
- 成交量柱状图明显高出前期平均水平
主力吸筹信号
低位放量换手是主力吸筹的典型特征。主力资金在底部区域通过大量买入来收集筹码,由于买入量大,必然导致换手率显著上升。
确认方法:
- 观察换手率放大后是否持续(持续3-5日以上更为可靠)
- 检查大宗交易数据是否有机构专用席位买入
- 观察龙虎榜数据是否有知名游资或机构席位
- 结合股东人数变化(股东人数减少通常意味着筹码集中)
4.2 高位放量换手
顶部区域换手率急剧放大
当股票经过较大幅度的上涨后,在高位区域出现换手率急剧放大的现象,这是一个危险的预警信号。
识别特征:
- 股价处于长期上涨趋势的高位,累计涨幅通常超过50%-100%
- 前期换手率已经处于较高水平
- 突然出现换手率急剧放大至异常水平(如>15%甚至>20%)
- 股价虽然可能还在创新高,但涨幅明显收窄或出现长上影线
- 当日成交量创出近期甚至历史新高
主力出货信号
高位放量换手是主力出货的典型特征。主力资金在高位区域通过大量卖出来实现获利了结,大量筹码从主力手中转移到了散户手中。
确认方法:
- 换手率放大后股价未能继续上涨,反而开始回落
- 龙虎榜显示机构席位大量卖出
- 股东人数急剧增加
- 后续交易日换手率维持高位但股价持续走低
4.3 换手率与价格关系
换手率与价格走势的组合关系,是判断市场状态的重要工具:
低换手率 + 价格上涨(筹码锁定,看涨)
这是最健康的上涨模式。低换手率意味着持股者惜售,筹码锁定良好,少量买盘即可推动价格上涨。这种情况通常出现在:
- 主力高度控盘的股票
- 具有长期投资价值的优质白马股
- 上涨趋势的中段,市场共识度高
操作建议:持股待涨,趋势未破不轻易离场。
高换手率 + 价格上涨(资金积极,但需警惕)
高换手伴随上涨,说明资金积极入场做多,短期动能强劲。但需要警惕的是,过高的换手率可能意味着多空分歧加大,筹码在快速换手。
操作建议:
- 换手率在5%-10%之间:可适当参与,跟随趋势
- 换手率超过15%:需要高度警惕,考虑逐步减仓
- 连续多日高换手上涨:可能进入冲刺阶段,随时可能见顶
低换手率 + 价格下跌(无量阴跌,看跌)
无量阴跌是最令人担忧的走势之一。低换手率意味着没有主力资金接盘,持股者因绝望而不断以低价卖出,但买盘稀少。这种情况通常出现在:
- 下跌趋势的中后段
- 基本面恶化的股票
- 市场关注度极低的冷门股
操作建议:不宜抄底,等待放量止跌信号。
高换手率 + 价格下跌(恐慌抛售,可能见底)
高换手伴随下跌,说明市场出现恐慌性抛售,大量筹码在低价被抛出。虽然短期看似危险,但这往往是见底的信号之一——恐慌盘涌出意味着最后的卖压被释放。
操作建议:
- 首次出现恐慌性放量下跌:不宜立即抄底,等待企稳确认
- 连续放量下跌后出现缩量企稳:可考虑轻仓试探
- 放量下跌后出现放量上涨(底部反转):可考虑逐步建仓
4.4 换手率拐点
换手率从低位开始上升
当换手率从长期低迷状态开始上升,意味着市场关注度正在提升,资金开始流入。这是行情启动的前兆信号。
识别方法:
- 换手率从1%以下上升至3%以上
- 换手率MA5上穿MA20
- 伴随成交量温和放大
- 股价开始摆脱底部整理区域
操作建议:可作为早期介入信号,结合其他技术指标确认后建仓。
换手率从高位开始下降
当换手率从高位开始下降,意味着市场热情正在消退,资金活跃度降低。
场景一:高位回落(看跌)
- 股价在高位,换手率从15%以上降至5%以下
- 意味着主力出货接近尾声,跟风盘减少
- 后续可能进入阴跌阶段
场景二:中位回落(整理)
- 股价在上涨中途回调,换手率从高位回落至正常水平
- 可能是主力洗盘行为
- 若回调幅度不大且换手率维持在3%以上,后续可能继续上涨
4.5 换手率背离
价格创新高但换手率下降(顶背离)
这是经典的看跌背离信号。价格虽然创出新高,但换手率反而下降,说明推动价格上涨的资金量在减少,上涨动能衰竭。
形成机制:
- 前期大量买入的资金已经获利,开始减少买入
- 新入场资金不足以维持之前的上涨力度
- 价格创新高更多是由于惯性而非新增资金推动
操作建议:考虑逐步减仓,设置止盈位。
价格创新低但换手率上升(底背离)
这是潜在的看涨背离信号。价格虽然创出新低,但换手率反而上升,说明有资金在低位积极承接。
形成机制:
- 恐慌性抛售导致价格创新低
- 但同时有主力资金或价值投资者在低位大量买入
- 抛压正在被新增买盘逐步消化
操作建议:密切关注,等待价格企稳和换手率持续放大后考虑介入。
五、换手率与成交量结合分析
5.1 换手率标准化的意义
成交量是技术分析中最基础最重要的指标之一,但原始成交量存在一个根本性缺陷:不同股票之间的成交量不具有可比性。一家流通盘100亿股的大盘股,日成交5亿股可能只是0.5%的换手率;而一家流通盘1亿股的小盘股,日成交500万股就是5%的换手率。两者的绝对成交量相差100倍,但后者的交易活跃度实际上是前者的10倍。
换手率通过将成交量除以流通股本,实现了标准化处理,使得不同市值、不同板块的股票之间可以进行横向比较。这种标准化对于以下场景尤为重要:
- 选股筛选:在全市场范围内筛选交易活跃的个股
- 行业比较:比较不同行业板块的交易活跃度差异
- 历史对比:比较同一股票在不同时期(流通股本可能发生变化)的交易活跃度
5.2 量比与换手率的关系
量比(Volume Ratio)是另一个常用的成交量指标,其计算公式为:
量比 = 当日即时成交量 ÷ 过去5日同时段平均成交量
量比和换手率的区别与联系:
| 对比维度 | 量比 | 换手率 |
|---|---|---|
| 含义 | 当日与历史同期成交量的比较 | 成交量与流通股本的比率 |
| 参照系 | 自身历史数据 | 流通股本 |
| 时间维度 | 盘中实时指标 | 日/周/月等固定周期 |
| 横向可比性 | 较差 | 较好 |
| 主要用途 | 发现当日异动 | 评估整体活跃度 |
结合使用方法:
- 量比>2 且 换手率>5%:当日放量且整体活跃,可能是行情启动信号
- 量比<0.5 且 换手率<1%:当日缩量且整体低迷,市场关注度极低
- 量比>3 但 换手率<2%:可能是盘中短暂脉冲,持续性存疑
5.3 换手率选股策略
基于换手率的选股策略主要包括以下几种:
策略一:低位放量突破选股
- 筛选条件:股价在60日低点附近(±10%),换手率突然放大至近20日平均的2倍以上
- 逻辑:底部放量可能是主力吸筹信号
- 风险:可能是假突破,需要结合其他指标确认
策略二:温和放量上涨选股
- 筛选条件:股价处于上升趋势,换手率维持在3%-8%之间,MA5换手率>MA20换手率
- 逻辑:适度活跃的换手率支撑价格上涨
- 风险:趋势可能随时反转
策略三:异常换手率监控
- 筛选条件:换手率突然超过15%,且股价未涨停
- 逻辑:发现潜在的主力异动
- 风险:可能是主力对倒出货
六、Python代码实现
6.1 换手率计算函数(支持动态参数和多口径)
import pandas as pd
import numpy as np
def calculate_turnover_rate(volume, float_shares, total_shares=None,
method='absolute'):
"""
计算换手率,支持多种口径
参数:
volume (pd.Series or np.array): 成交量(股)
float_shares (float): 流通股本(股)
total_shares (float): 总股本(股),method='relative'时需要
method (str): 计算口径,'absolute'(绝对换手率)或 'relative'(相对换手率)
返回:
pd.Series: 换手率(百分比)
"""
if method == 'absolute':
denominator = float_shares
elif method == 'relative':
if total_shares is None:
raise ValueError("计算相对换手率需要提供 total_shares 参数")
denominator = total_shares
else:
raise ValueError(f"不支持的 method: {method},请使用 'absolute' 或 'relative'")
turnover_rate = volume / denominator * 100
return turnover_rate
def calculate_turnover_rate_by_amount(trade_amount, float_market_cap):
"""
以金额口径计算换手率(适用于海外市场)
参数:
trade_amount (pd.Series or np.array): 成交金额
float_market_cap (float): 流通市值
返回:
pd.Series: 换手率(百分比)
"""
turnover_rate = trade_amount / float_market_cap * 100
return turnover_rate
6.2 多周期换手率计算
def calculate_multi_period_turnover(df, float_shares, periods=None):
"""
计算多周期换手率
参数:
df (pd.DataFrame): 包含 'volume' 列的DataFrame,需有DatetimeIndex
float_shares (float or pd.Series): 流通股本
periods (list): 需要计算的周期列表,默认为 ['1D', '1W', '1M']
返回:
pd.DataFrame: 包含各周期换手率的DataFrame
"""
if periods is None:
periods = ['1D', '1W', '1M']
result = pd.DataFrame(index=df.index)
# 日换手率
if isinstance(float_shares, pd.Series):
result['daily_turnover'] = df['volume'] / float_shares * 100
else:
result['daily_turnover'] = df['volume'] / float_shares * 100
# 周换手率(滚动5个交易日)
if '1W' in periods:
result['weekly_turnover'] = result['daily_turnover'].rolling(
window=5, min_periods=1).sum()
# 月换手率(滚动22个交易日)
if '1M' in periods:
result['monthly_turnover'] = result['daily_turnover'].rolling(
window=22, min_periods=1).sum()
# 年换手率(滚动250个交易日)
if '1Y' in periods:
result['yearly_turnover'] = result['daily_turnover'].rolling(
window=250, min_periods=1).sum()
return result
def calculate_turnover_ma(daily_turnover, windows=None):
"""
计算换手率移动平均
参数:
daily_turnover (pd.Series): 日换手率序列
windows (list): 移动平均窗口列表
返回:
pd.DataFrame: 包含各窗口移动平均的DataFrame
"""
if windows is None:
windows = [5, 10, 20]
result = pd.DataFrame(index=daily_turnover.index)
result['daily_turnover'] = daily_turnover
for w in windows:
result[f'ma{w}_turnover'] = daily_turnover.rolling(
window=w, min_periods=1).mean()
return result
6.3 换手率信号检测函数
def detect_turnover_signals(df, turnover_col='daily_turnover',
low_threshold=1.0, high_threshold=15.0,
abnormal_threshold=20.0):
"""
检测换手率交易信号
参数:
df (pd.DataFrame): 包含换手率和价格数据的DataFrame
turnover_col (str): 换手率列名
low_threshold (float): 低换手率阈值
high_threshold (float): 高换手率阈值
abnormal_threshold (float): 异常换手率阈值
返回:
pd.DataFrame: 包含信号标记的DataFrame
"""
result = df.copy()
turnover = result[turnover_col]
close = result['close']
# 信号1:低位放量换手(底部吸筹信号)
# 条件:换手率突然放大至20日均值的2倍以上,且股价处于60日低点附近
ma20_turnover = turnover.rolling(window=20, min_periods=1).mean()
price_60d_low = close.rolling(window=60, min_periods=1).min()
result['signal_bottom_volume'] = (
(turnover > ma20_turnover * 2) &
(close < price_60d_low * 1.10)
).astype(int)
# 信号2:高位放量换手(顶部出货信号)
price_60d_high = close.rolling(window=60, min_periods=1).max()
result['signal_top_volume'] = (
(turnover > high_threshold) &
(close > price_60d_high * 0.90)
).astype(int)
# 信号3:异常换手率
result['signal_abnormal'] = (turnover > abnormal_threshold).astype(int)
# 信号4:换手率顶背离(价格创新高,换手率下降)
price_20d_high = close.rolling(window=20, min_periods=1).max()
turnover_20d_high = turnover.rolling(window=20, min_periods=1).max()
result['signal_bearish_divergence'] = (
(close == price_20d_high) &
(turnover < turnover_20d_high * 0.7)
).astype(int)
# 信号5:换手率底背离(价格创新低,换手率上升)
price_20d_low = close.rolling(window=20, min_periods=1).min()
ma5_turnover = turnover.rolling(window=5, min_periods=1).mean()
result['signal_bullish_divergence'] = (
(close == price_20d_low) &
(ma5_turnover > ma20_turnover * 1.3)
).astype(int)
# 信号6:换手率拐点向上
result['signal_turnover_up'] = (
(ma5_turnover > ma20_turnover) &
(ma5_turnover.shift(1) <= ma20_turnover.shift(1))
).astype(int)
# 信号7:换手率拐点向下
result['signal_turnover_down'] = (
(ma5_turnover < ma20_turnover) &
(ma5_turnover.shift(1) >= ma20_turnover.shift(1))
).astype(int)
return result
def classify_turnover_level(turnover_value, market_cap=None, board=None):
"""
根据换手率数值和市场特征进行分级
参数:
turnover_value (float): 换手率值(百分比)
market_cap (float): 市值(亿元),可选
board (str): 板块,'main'/'gem'/'star',可选
返回:
str: 换手率等级
"""
# 根据市值和板块调整阈值
if board == 'gem' or board == 'star':
thresholds = {
'极低': 3, '低': 5, '温和': 8,
'正常': (8, 15), '高': (15, 25), '极高': 25
}
elif market_cap and market_cap > 500:
thresholds = {
'极低': 0.3, '低': 0.5, '温和': 1.0,
'正常': (1.0, 2.0), '高': (2.0, 3.0), '极高': 3.0
}
elif market_cap and market_cap < 100:
thresholds = {
'极低': 2, '低': 3, '温和': 5,
'正常': (5, 10), '高': (10, 20), '极高': 20
}
else:
thresholds = {
'极低': 1, '低': 2, '温和': 3,
'正常': (3, 7), '高': (7, 15), '极高': 15
}
if turnover_value < thresholds['极低']:
return '极低换手率'
elif turnover_value < thresholds['低']:
return '低换手率'
elif turnover_value < thresholds['温和']:
return '温和换手率'
elif turnover_value < thresholds['正常'][1]:
return '正常换手率'
elif turnover_value < thresholds['高'][1]:
return '高换手率'
else:
return '极高换手率'
6.4 换手率选股函数
def turnover_stock_selection(stock_pool, turnover_data, min_turnover=3.0,
max_turnover=15.0, price_change_min=None,
price_change_max=None, volume_ratio_min=None):
"""
基于换手率的选股函数
参数:
stock_pool (list): 股票代码列表
turnover_data (dict): {stock_code: DataFrame} 各股票数据
min_turnover (float): 最低换手率阈值
max_turnover (float): 最高换手率阈值
price_change_min (float): 最低涨跌幅限制
price_change_max (float): 最高涨跌幅限制
volume_ratio_min (float): 最低量比限制
返回:
list: 符合条件的股票代码列表
"""
selected = []
for code in stock_pool:
if code not in turnover_data:
continue
df = turnover_data[code]
if df.empty:
continue
latest = df.iloc[-1]
# 换手率筛选
turnover = latest.get('daily_turnover', 0)
if turnover < min_turnover or turnover > max_turnover:
continue
# 涨跌幅筛选
if price_change_min is not None or price_change_max is not None:
pct_change = latest.get('pct_change', 0)
if price_change_min is not None and pct_change < price_change_min:
continue
if price_change_max is not None and pct_change > price_change_max:
continue
# 量比筛选
if volume_ratio_min is not None:
volume_ratio = latest.get('volume_ratio', 0)
if volume_ratio < volume_ratio_min:
continue
selected.append({
'code': code,
'turnover': turnover,
'close': latest.get('close', 0),
'pct_change': latest.get('pct_change', 0),
'volume_ratio': latest.get('volume_ratio', 0)
})
# 按换手率降序排列
selected.sort(key=lambda x: x['turnover'], reverse=True)
return selected
6.5 回测框架示例
import pandas as pd
import numpy as np
from datetime import datetime, timedelta
class TurnoverBacktest:
"""基于换手率信号的简单回测框架"""
def __init__(self, initial_capital=1000000, commission_rate=0.0003):
self.initial_capital = initial_capital
self.commission_rate = commission_rate
self.trades = []
self.equity_curve = []
def generate_signals(self, df, signal_col='signal_bottom_volume'):
"""
生成交易信号
买入条件:出现底部放量信号
卖出条件:持仓N日后或出现高位放量信号
"""
signals = pd.DataFrame(index=df.index)
signals['signal'] = 0
signals.loc[df[signal_col] == 1, 'signal'] = 1 # 买入信号
# 卖出信号:买入后持有5日自动卖出,或出现高位放量
hold_period = 5
buy_dates = df[df[signal_col] == 1].index
for buy_date in buy_dates:
sell_candidates = []
for i in range(1, hold_period + 1):
try:
next_date = df.index[df.index.get_loc(buy_date) + i]
sell_candidates.append(next_date)
except (IndexError, KeyError):
break
for sell_date in sell_candidates:
if df.loc[sell_date, 'signal_top_volume'] == 1:
signals.loc[sell_date, 'signal'] = -1
break
else:
if sell_candidates:
signals.loc[sell_candidates[-1], 'signal'] = -1
return signals
def run_backtest(self, df, signals):
"""
执行回测
参数:
df (pd.DataFrame): 价格数据
signals (pd.DataFrame): 交易信号
返回:
dict: 回测结果
"""
capital = self.initial_capital
position = 0
entry_price = 0
equity_list = []
for date in df.index:
if date not in signals.index:
equity_list.append({'date': date, 'equity': capital})
continue
price = df.loc[date, 'close']
signal = signals.loc[date, 'signal']
if signal == 1 and position == 0: # 买入
shares = int(capital * 0.95 / price / 100) * 100 # 整手买入
if shares > 0:
cost = shares * price * (1 + self.commission_rate)
capital -= cost
position = shares
entry_price = price
self.trades.append({
'date': date, 'action': 'BUY',
'price': price, 'shares': shares
})
elif signal == -1 and position > 0: # 卖出
revenue = position * price * (1 - self.commission_rate)
capital += revenue
self.trades.append({
'date': date, 'action': 'SELL',
'price': price, 'shares': position,
'pnl': (price - entry_price) / entry_price * 100
})
position = 0
total_equity = capital + position * price
equity_list.append({'date': date, 'equity': total_equity})
equity_df = pd.DataFrame(equity_list)
equity_df.set_index('date', inplace=True)
# 计算回测指标
total_return = (capital - self.initial_capital) / self.initial_capital * 100
winning_trades = [t for t in self.trades if t['action'] == 'SELL' and t['pnl'] > 0]
losing_trades = [t for t in self.trades if t['action'] == 'SELL' and t['pnl'] <= 0]
win_rate = len(winning_trades) / max(len(winning_trades) + len(losing_trades), 1) * 100
return {
'total_return': total_return,
'total_trades': len([t for t in self.trades if t['action'] == 'SELL']),
'win_rate': win_rate,
'equity_curve': equity_df,
'trades': self.trades
}
6.6 可视化代码
import matplotlib.pyplot as plt
import matplotlib.dates as mdates
def plot_turnover_analysis(df, turnover_col='daily_turnover',
ma_windows=[5, 10, 20], figsize=(14, 10)):
"""
换手率分析可视化
参数:
df (pd.DataFrame): 包含价格和换手率数据的DataFrame
turnover_col (str): 换手率列名
ma_windows (list): 移动平均窗口列表
figsize (tuple): 图表大小
"""
fig, axes = plt.subplots(3, 1, figsize=figsize, height_ratios=[2, 1, 1],
sharex=True)
# 子图1:价格走势
axes[0].plot(df.index, df['close'], color='#1E88E5', linewidth=1.2,
label='收盘价')
axes[0].fill_between(df.index, df['close'], alpha=0.1, color='#1E88E5')
axes[0].set_ylabel('价格(元)', fontsize=12)
axes[0].set_title('换手率综合分析', fontsize=14, fontweight='bold')
axes[0].legend(loc='upper left')
axes[0].grid(True, alpha=0.3)
# 子图2:换手率及均线
axes[1].bar(df.index, df[turnover_col], alpha=0.5, color='#90CAF9',
label='日换手率')
colors = ['#FF5722', '#FFC107', '#4CAF50']
for i, w in enumerate(ma_windows):
ma_col = f'ma{w}_turnover'
if ma_col in df.columns:
axes[1].plot(df.index, df[ma_col], color=colors[i],
linewidth=1.2, label=f'MA{w}换手率')
# 添加阈值线
axes[1].axhline(y=1, color='gray', linestyle='--', alpha=0.5, linewidth=0.8)
axes[1].axhline(y=7, color='orange', linestyle='--', alpha=0.5, linewidth=0.8)
axes[1].axhline(y=15, color='red', linestyle='--', alpha=0.5, linewidth=0.8)
axes[1].set_ylabel('换手率(%)', fontsize=12)
axes[1].legend(loc='upper left')
axes[1].grid(True, alpha=0.3)
# 子图3:成交量
axes[2].bar(df.index, df['volume'] / 10000, alpha=0.6,
color='#26A69A', label='成交量(万手)')
axes[2].set_ylabel('成交量(万手)', fontsize=12)
axes[2].set_xlabel('日期', fontsize=12)
axes[2].legend(loc='upper left')
axes[2].grid(True, alpha=0.3)
axes[2].xaxis.set_major_formatter(mdates.DateFormatter('%Y-%m'))
axes[2].xaxis.set_major_locator(mdates.MonthLocator(interval=1))
plt.tight_layout()
plt.savefig('turnover_analysis.png', dpi=150, bbox_inches='tight')
plt.show()
def plot_turnover_price_scatter(df, turnover_col='daily_turnover',
pct_change_col='pct_change', figsize=(10, 8)):
"""
换手率与涨跌幅散点图
参数:
df (pd.DataFrame): 包含换手率和涨跌幅数据的DataFrame
turnover_col (str): 换手率列名
pct_change_col (str): 涨跌幅列名
figsize (tuple): 图表大小
"""
fig, ax = plt.subplots(figsize=figsize)
# 根据涨跌着色
colors = np.where(df[pct_change_col] >= 0, '#EF5350', '#26A69A')
sizes = np.abs(df[pct_change_col]) * 5 + 10
scatter = ax.scatter(df[turnover_col], df[pct_change_col],
c=colors, s=sizes, alpha=0.6, edgecolors='white',
linewidth=0.5)
ax.axhline(y=0, color='gray', linestyle='-', alpha=0.3)
ax.axvline(x=7, color='orange', linestyle='--', alpha=0.5, label='高换手率阈值(7%)')
ax.axvline(x=15, color='red', linestyle='--', alpha=0.5, label='极高换手率阈值(15%)')
ax.set_xlabel('换手率(%)', fontsize=12)
ax.set_ylabel('涨跌幅(%)', fontsize=12)
ax.set_title('换手率与涨跌幅关系散点图', fontsize=14, fontweight='bold')
ax.legend(loc='upper right')
ax.grid(True, alpha=0.3)
plt.tight_layout()
plt.savefig('turnover_price_scatter.png', dpi=150, bbox_inches='tight')
plt.show()
七、实战案例
7.1 A股低位高换手选股案例
案例背景:2024年某A股上市公司(以下简称"A公司"),市值约80亿元,属于小盘股。该股在经历长达8个月的下跌后,累计跌幅达45%,股价从22元跌至12元左右。
换手率变化过程:
| 阶段 | 时间段 | 日均换手率 | 股价区间 | 市场特征 |
|---|---|---|---|---|
| 阴跌期 | 1月-6月 | 0.8%-1.5% | 22→13元 | 持续阴跌,成交低迷 |
| 筑底期 | 7月-8月 | 1.0%-2.0% | 12-13元 | 跌速放缓,开始横盘 |
| 放量期 | 9月初 | 5%-8% | 12-14元 | 换手率突然放大3-5倍 |
| 突破期 | 9月中旬 | 6%-10% | 14-16元 | 放量突破,确认趋势 |
| 上涨期 | 10月-12月 | 4%-7% | 16-20元 | 温和放量上涨 |
分析要点:
- 在阴跌期,换手率长期低于1.5%,表明市场对该股完全失去兴趣。
- 筑底期换手率略有回升,但仍在2%以下,属于地量水平。
- 9月初换手率突然从1.5%飙升至5%以上,放大超过3倍,且股价不再创新低,这是典型的底部放量吸筹信号。
- 9月中旬换手率维持在6%-10%的高位,股价突破前期整理平台,确认上升趋势。
- 上涨期换手率回落至4%-7%的健康水平,说明筹码锁定良好,上涨趋势可持续。
操作策略:在9月初换手率首次放大且股价不创新低时轻仓试探(买入1/3仓位),在放量突破平台时加仓(买入1/3仓位),在上涨趋势确认后持有(保留1/3现金作为后备)。止损位设在放量前的低点下方5%。
7.2 次新股换手率分析案例
案例背景:某创业板新股上市,发行价25元,上市首日涨幅达44%(达到涨停限制),随后进入无涨跌幅限制的5个交易日。
换手率变化过程:
| 交易日 | 收盘价 | 换手率 | 成交量(万股) | 分析 |
|---|---|---|---|---|
| 上市首日 | 36.00 | 68.5% | 6850 | 首日换手极高,筹码大量换手 |
| 第2日 | 42.00 | 45.2% | 4520 | 换手率仍高,多空分歧大 |
| 第3日 | 38.50 | 32.8% | 3280 | 冲高回落,换手率开始下降 |
| 第4日 | 35.00 | 18.5% | 1850 | 继续调整,换手率快速下降 |
| 第5日 | 33.00 | 12.3% | 1230 | 趋于稳定,换手率接近正常 |
| 第10日 | 30.50 | 5.2% | 520 | 筹码逐步沉淀 |
| 第20日 | 28.00 | 3.1% | 310 | 换手率回归正常 |
| 第60日 | 32.00 | 4.5% | 450 | 新一轮行情启动 |
分析要点:
- 次新股上市初期换手率极高是正常现象,因为中签者倾向于上市首日卖出获利了结。
- 首日68.5%的换手率意味着超过2/3的流通筹码换了主人,这是新股特有的现象。
- 随着交易日增加,换手率逐步下降,筹码从短线投机者向中线投资者转移。
- 第60日换手率从低位再次上升至4.5%,且股价企稳回升,可能预示新一轮行情的启动。
操作策略:次新股上市初期(前5个交易日)换手率极高,波动剧烈,不建议普通投资者参与。待换手率稳定在5%以下且股价企稳后,可结合基本面分析考虑介入。当换手率从低位再次上升时,可能是较好的介入时机。
7.3 主力吸筹/出货换手率特征案例
案例背景:某主板上市公司(以下简称"B公司"),市值约200亿元。该股在2024年上半年完成了一轮完整的"主力吸筹-拉升-出货"周期。
阶段一:主力吸筹期(1月-3月)
| 特征 | 具体表现 |
|---|---|
| 股价表现 | 在15-17元区间窄幅震荡,波幅不超过10% |
| 换手率特征 | 日均换手率2%-4%,间歇性出现5%-8%的脉冲 |
| 成交量特征 | 整体缩量,但间歇性出现温和放量 |
| 筹码变化 | 股东人数从8万降至6.5万,筹码趋于集中 |
| K线形态 | 多为小阳小阴线,偶有中阳线 |
分析:吸筹期换手率不高但稳定,主力通过小单持续买入,避免引起市场关注。间歇性的换手率脉冲是主力集中吸筹的表现。
阶段二:拉升期(4月-6月)
| 特征 | 具体表现 |
|---|---|
| 股价表现 | 从17元稳步上涨至28元,涨幅约65% |
| 换手率特征 | 日均换手率4%-7%,呈现"涨时放量、跌时缩量"特征 |
| 成交量特征 | 上涨日成交量明显放大,回调日成交量萎缩 |
| 筹码变化 | 股东人数稳定在6万左右 |
| K线形态 | 阳线多阴线少,阳线实体较大 |
分析:拉升期换手率适中且呈现规律性波动,表明主力控盘良好,上涨趋势健康。"涨放量跌缩量"是典型的健康上涨特征。
阶段三:出货期(7月-8月)
| 特征 | 具体表现 |
|---|---|
| 股价表现 | 在26-30元区间震荡,多次冲高回落 |
| 换手率特征 | 日均换手率急剧上升至8%-15%,多次超过15% |
| 成交量特征 | 成交量持续维持在高位,甚至创出天量 |
| 筹码变化 | 股东人数从6万急剧增至9万,筹码快速分散 |
| K线形态 | 频繁出现长上影线、十字星等见顶信号 |
分析:出货期换手率急剧放大是核心识别特征。主力在高位通过大量对倒交易吸引跟风盘,同时暗中出货。换手率超过15%的交易日往往是主力集中出货的日子。股东人数急剧增加是筹码从主力向散户转移的直接证据。
操作策略:在吸筹期尾声(换手率开始温和放大且股价突破平台)时介入,在拉升期持股不动,在出货期初期(换手率突然急剧放大且出现长上影线)时果断离场。
八、优缺点总结
优点
-
标准化程度高:换手率通过将成交量除以流通股本,消除了股本规模的影响,实现了不同股票之间的横向可比性,这是原始成交量无法做到的。
-
反映市场真实活跃度:换手率直接衡量了市场中股票所有权转移的频率,能够真实反映市场的交易活跃程度和投资者参与意愿。
-
揭示主力行为:异常的换手率变化往往是主力资金进出市场的信号。低位放量吸筹、高位放量出货等经典主力行为模式,都可以通过换手率变化来识别。
-
多维度分析价值:换手率可以与价格、成交量、均线等多个维度结合分析,形成丰富的交易信号体系,适用于不同风格和周期的投资者。
-
计算简单直观:换手率的计算公式简单明了,数据获取方便,不需要复杂的数学模型,适合各类投资者使用。
-
适用范围广泛:换手率不仅适用于个股分析,还可以用于行业板块比较、市场整体活跃度评估、ETF流动性分析等多个层面。
缺点
-
流通股本数据滞后:流通股本会随着限售股解禁、增发、回购等事件发生变化,但数据更新可能存在滞后,导致换手率计算出现偏差。特别是对于频繁发生股本变动的公司,这一问题更为突出。
-
无法区分交易方向:换手率只反映交易活跃程度,无法区分买入和卖出的力量对比。同样10%的换手率,可能是主力在买入,也可能是主力在卖出,需要结合价格走势和其他指标综合判断。
-
对异常交易敏感:大宗交易、大宗减持、转融通出借等非正常交易行为都会影响换手率,可能导致换手率失真。特别是在计算日换手率时,单笔大额交易可能使换手率出现异常跳升。
-
不同口径差异大:绝对换手率、相对换手率、自由流通换手率等不同口径的计算结果差异显著,不同数据平台可能采用不同的计算口径,导致横向比较时需要注意口径一致性。
-
阈值标准不统一:换手率的"高"与"低"因市值、板块、市场环境等因素而异,不存在放之四海而皆准的标准阈值。投资者需要根据具体情况动态调整参数,这增加了使用难度。
-
滞后性:换手率是事后计算的指标,当投资者观察到换手率变化时,市场行情可能已经走了一段。虽然换手率移动平均可以部分缓解这一问题,但无法完全消除滞后性。
-
次新股和特殊品种适用性差:对于刚上市的次新股,由于中签者集中卖出,换手率会异常偏高,传统的换手率分析框架可能失效。对于交易不活跃的冷门股,换手率可能长期处于极低水平,分析价值有限。
适用场景建议
| 场景 | 适用性 | 说明 |
|---|---|---|
| 个股趋势分析 | 高 | 换手率与价格走势结合,判断趋势健康度 |
| 主力行为追踪 | 中高 | 异常换手率可辅助识别主力进出 |
| 选股筛选 | 高 | 通过换手率阈值快速筛选活跃个股 |
| 板块比较 | 中 | 需注意板块内市值差异 |
| 市场整体评估 | 中 | 可用全市场平均换手率衡量市场情绪 |
| 次新股分析 | 低 | 换手率失真,需特殊处理 |
| 量化策略 | 高 | 换手率信号易于量化,适合系统化交易 |
本文档详细介绍了换手率指标的定义、计算方法、参数调整策略、核心交易信号、与其他指标的配合使用方法,以及完整的Python代码实现和实战案例分析。换手率作为技术分析中的基础但核心的指标,其价值在于将成交量标准化,为投资者提供了一个简洁而有效的市场活跃度度量工具。在实际应用中,建议将换手率与价格走势、成交量、均线等多个指标结合使用,以提高分析的准确性和可靠性。
上述内容经供学习参考,股市有风险投资需谨慎