Overlap:HMA(赫尔移动平均线)技术指标详解
一、HMA的定义
HMA(Hull Moving Average,赫尔移动平均线) 是由澳大利亚数学家、交易员艾伦·赫尔(Alan Hull)于2005年开发的一种高级移动平均线指标。该指标旨在解决传统移动平均线(如SMA、EMA)面临的核心矛盾:平滑性与滞后性之间的权衡。
核心设计理念
传统移动平均线面临一个无法回避的困境:使用较短的时间周期可以获得更快的响应速度,但曲线不够平滑,容易产生假信号;使用较长的时间周期可以获得更平滑的曲线,但滞后性严重,信号出现时行情往往已经走了一大截。
赫尔通过创新的数学处理方法,将加权移动平均线(WMA)与平方根周期相结合,创造出了一条既能快速响应价格变化、又能保持曲线平滑的移动平均线。该指标一经推出便在交易界获得了广泛认可,被认为是移动平均线家族中的重大突破。
HMA的核心特征
| 特征 | 说明 |
|---|---|
| 核心优势 | 极大减少滞后,同时保持曲线平滑 |
| 理论基础 | 加权移动平均 + 价格序列偏移处理 + 平方根周期平滑 |
| 指标类型 | 趋势跟踪/重叠指标 |
| 开发者 | Alan Hull(2005年) |
| 计算周期 | 可调,常见参数为9、14、20、50、200等 |
| 与传统MA的关系 | HMA是WMA的嵌套组合,非传统EMA/SMA |
HMA与传统移动平均线的对比
| 对比维度 | HMA | EMA | SMA |
|---|---|---|---|
| 滞后程度 | 极低 | 中等 | 高 |
| 平滑程度 | 高 | 中等 | 最高 |
| 对价格变化的响应 | 快 | 中等 | 慢 |
| 计算复杂度 | 较高(嵌套WMA) | 低 | 最低 |
| 趋势捕捉能力 | 强,适合趋势跟踪 | 中等 | 一般 |
| 适用场景 | 趋势识别、入场时机、动态止损 | 通用趋势跟踪 | 长期趋势判断 |
二、HMA的计算方法
1. 核心计算公式
HMA的计算过程包含三个主要步骤,使用加权移动平均线(WMA)作为基础构件:
第一步:计算两个基础WMA
设周期参数为 nn(例如 n=20n=20n=20),首先计算两个WMA:
WMA1=WMA(Price,n/2)
\mathrm{WMA}_1 = \mathrm{WMA}(\mathrm{Price}, n/2)
WMA1=WMA(Price,n/2)
WMA2=WMA(Price,n) \mathrm{WMA}_2 = \mathrm{WMA}(\mathrm{Price}, n) WMA2=WMA(Price,n)
其中 WMA(Price,n)\mathrm{WMA}(\mathrm{Price}, n)WMA(Price,n) 表示对价格序列计算周期为 nnn 的加权移动平均。
第二步:计算中间差值序列
将两个WMA进行组合,得到一个中间序列:
Intermediate=2×WMA1−WMA2
\mathrm{Intermediate} = 2 \times \mathrm{WMA}_1 - \mathrm{WMA}_2
Intermediate=2×WMA1−WMA2
这个步骤通过用较短周期WMA(响应更快)减去较长周期WMA(更平滑),极大地消除了滞后。
第三步:最终平滑
对中间序列应用周期为 n\sqrt{n}n 的 WMA 平滑,得到最终的 HMA 值:
HMA=WMA(Intermediate,n) \mathrm{HMA} = \mathrm{WMA}(\mathrm{Intermediate}, \sqrt{n}) HMA=WMA(Intermediate,n)
2. 加权移动平均(WMA)的计算
由于HMA的计算依赖于WMA,需要先明确WMA的计算方式。WMA赋予近期价格更高的权重,权重呈线性递减:
对于周期 nnn 的价格序列 P1,P2,...,PnP_1, P_2, ..., P_nP1,P2,...,Pn (PnP_nPn 为最新价格),WMA\mathrm{WMA}WMA 的计算公式为:
WMAn=n×Pn+(n−1)×Pn−1+...+1×P1n+(n−1)+...+1 \mathrm{WMA}_n = \frac{n \times P_n + (n-1) \times P_{n-1} + ... + 1 \times P_1}{n + (n-1) + ... + 1} WMAn=n+(n−1)+...+1n×Pn+(n−1)×Pn−1+...+1×P1
分母为权重和:
∑i=1ni=n(n+1)2 \sum_{i=1}^{n} i = \frac{n(n+1)}{2} i=1∑ni=2n(n+1)
因此:
WMAn=∑i=1ni×Pin(n+1)2 \mathrm{WMA}_n = \frac{\sum_{i=1}^{n} i \times P_i}{\frac{n(n+1)}{2}} WMAn=2n(n+1)∑i=1ni×Pi
3. 非整数周期的处理
由于 n/2n/2n/2 和 n\sqrt{n}n 的计算结果可能不是整数,实际应用中通常采用四舍五入取整 5。例如:
- 当 n=14n=14n=14 时,n/2=7n/2=7n/2=7,20≈3.74→\sqrt{20} \approx 3.74 \rightarrow20≈3.74→ 取整为 4
- 当 n=20n=20n=20 时,n/2=10n/2=10n/2=10,20≈4.47→\sqrt{20} \approx 4.47 \rightarrow20≈4.47→ 取整为 4
- 当 n=50n=50n=50 时,n/2=25n/2=25n/2=25,50≈7.07→\sqrt{50} \approx 7.07 \rightarrow50≈7.07→ 取整为 7
4. 完整计算示例
假设使用 n=10n=10n=10 周期,最近10个收盘价如下,演示HMA的计算过程:
| 位置(i) | 收盘价§ | 权重 |
|---|---|---|
| 1(最旧) | 100 | 1 |
| 2 | 102 | 2 |
| 3 | 101 | 3 |
| 4 | 103 | 4 |
| 5 | 105 | 5 |
| 6 | 107 | 6 |
| 7 | 106 | 7 |
| 8 | 108 | 8 |
| 9 | 110 | 9 |
| 10(最新) | 112 | 10 |
第一步:计算WMA₁(周期 n/2 = 5)
取最近5个价格(位置6-10):[107, 106, 108, 110, 112]
权重:[5, 4, 3, 2, 1](权重和=15)
加权和 = 107×5 + 106×4 + 108×3 + 110×2 + 112×1 = 535 + 424 + 324 + 220 + 112 = 1615
WMA₁ = 1615 / 15 = 107.67
第二步:计算WMA₂(周期 n = 10)
使用全部10个价格,权重[10,9,8,7,6,5,4,3,2,1](权重和=55)
加权和 = 100×1 + 102×2 + 101×3 + 103×4 + 105×5 + 107×6 + 106×7 + 108×8 + 110×9 + 112×10 ?
注意顺序:WMA计算时,最新价格应乘以最大权重。更清晰地列出:
| 位置 | 价格 | 权重(从最新倒序) | 加权值 |
|---|---|---|---|
| 10(最新) | 112 | 10 | 1120 |
| 9 | 110 | 9 | 990 |
| 8 | 108 | 8 | 864 |
| 7 | 106 | 7 | 742 |
| 6 | 107 | 6 | 642 |
| 5 | 105 | 5 | 525 |
| 4 | 103 | 4 | 412 |
| 3 | 101 | 3 | 303 |
| 2 | 102 | 2 | 204 |
| 1(最旧) | 100 | 1 | 100 |
加权和 = 1120+990+864+742+642+525+412+303+204+100 = 5902
WMA₂ = 5902 / 55 ≈ 107.31
第三步:计算中间值
Intermediate = 2 × WMA₁ - WMA₂ = 2 × 107.67 - 107.31 = 215.34 - 107.31 = 108.03
第四步:最终WMA平滑(周期 √10 ≈ 3.16 → 取整为 3)
取最近3个Intermediate值进行3周期WMA平滑,假设前两个周期中间值为[107.50, 107.80, 108.03]:
权重:[3, 2, 1](权重和=6)
加权和 = 107.50×1 + 107.80×2 + 108.03×3 = 107.50 + 215.60 + 324.09 = 647.19
HMA = 647.19 / 6 ≈ 107.87
5. 参数说明
| 参数 | 默认值 | 说明 | 适用场景 |
|---|---|---|---|
| length | 10 | HMA计算周期 | 控制指标的灵敏度和平滑度 |
| offset | 0 | 结果偏移周期数 | 用于将指标线向前或向后平移 |
周期参数选择指南:
| 周期范围 | 适用场景 | 特点 |
|---|---|---|
| 9-14 | 短线/日内交易 | 灵敏度高,响应快,适合捕捉短期波动 |
| 20-50 | 波段交易 | 灵敏度与平滑度平衡,适合中期趋势跟踪 |
| 50-100 | 中长线趋势 | 平滑度好,适合识别主要趋势方向 |
| 100+ | 长期趋势分析 | 极度平滑,仅用于确认长期多空方向 |
三、HMA的使用方法
1. 趋势识别——最基础用法
HMA的方向是判断市场趋势的最直观依据:
| HMA状态 | 趋势含义 | 操作倾向 |
|---|---|---|
| HMA线向上运行 | 上升趋势,买方力量主导 | 以做多为主,寻找买入机会 |
| HMA线向下运行 | 下降趋势,卖方力量主导 | 以做空为主,寻找卖出机会 |
| HMA线走平 | 趋势可能减弱或进入盘整 | 观望,等待方向明确 |
独特优势:相比传统移动平均线,HMA的拐点出现得更早、更明显。由于滞后极小,HMA方向转变几乎与价格反转同步,能够帮助交易者更早识别趋势变化。
2. 价格穿越信号
价格与HMA的穿越关系是最简单的入场/出场信号:
| 信号类型 | 触发条件 | 含义 | 操作建议 |
|---|---|---|---|
| 买入信号 | 价格从下方向上穿越HMA线 | 短期价格强于趋势线,可能启动上涨 | 考虑建立多头仓位 |
| 卖出信号 | 价格从上方向下穿越HMA线 | 短期价格弱于趋势线,可能启动下跌 | 考虑平仓或建立空头 |
信号增强条件:
- 穿越发生时HMA线方向与穿越方向一致(即上升趋势中的上穿)
- 穿越时成交量放大
- 穿越发生在关键支撑/阻力位附近
3. 拐点交易策略——HMA的核心用法
HMA的创造者艾伦·赫尔明确建议:使用HMA时,应关注其转折点而非交叉信号。因为HMA的滞后已大幅减少,均线交叉策略在该指标上的效果不佳。
HMA拐点识别方法:
| 信号类型 | 识别方法 | 操作建议 |
|---|---|---|
| 上升趋势确认 | HMA从下降转为上升(出现低点后开始上行) | 多头入场或加仓 |
| 下降趋势确认 | HMA从上升转为下降(出现高点后开始下行) | 空头入场或平多 |
| 趋势延续确认 | HMA持续沿同一方向运行 | 顺势持仓 |
赫尔的原话:“由于赫尔移动平均线的滞后已经大幅减少,依赖两条不同周期的HMA产生交叉信号的方法效果不佳。相反,关注HMA本身的转折点——当它从下行转为上行时买入,从上行转为下行时卖出”。
4. 动态支撑与阻力
HMA线因其紧贴价格走势的特性,可以作为动态的支撑/阻力参考:
| 趋势方向 | HMA角色 | 使用方法 |
|---|---|---|
| 上升趋势 | 动态支撑 | 价格回调至HMA附近获得支撑时,是加仓或入场机会 |
| 下降趋势 | 动态阻力 | 价格反弹至HMA附近遇阻回落时,是做空或减仓机会 |
5. 多时间框架分析
利用不同周期的HMA可以构建多时间框架分析系统:
| 周期组合 | 分析方法 | 信号含义 |
|---|---|---|
| 短期HMA(如9) + 长期HMA(如50) | 短期HMA上穿长期HMA | 短期动能强于长期,上升趋势确认 |
| 短期HMA下穿长期HMA | 短期动能弱于长期,下降趋势确认 |
注意:由于HMA本身已极大减少滞后,其交叉信号比传统均线交叉更及时,但也可能产生更多假信号,建议与其他指标确认。
6. 与其他指标的配合策略
HMA不应单独使用,建议与其他技术指标配合:
| 配合指标 | 策略逻辑 | 效果 |
|---|---|---|
| RSI | 用RSI确认超买超卖状态 | HMA方向 + RSI极值 = 高概率反转信号 |
| MACD | 趋势方向双重确认 | HMA与MACD同时发出信号时可靠性更高 |
| 成交量 | 验证突破有效性 | HMA穿越伴随放量时可信度更高 |
| 布林带 | 价格边界确认 | HMA方向与价格突破布林带边界同步时信号更强 |
7. 作为动态止损工具
HMA因其紧贴价格走势的特性,非常适合用作动态止损线:
| 仓位方向 | 止损设置方法 |
|---|---|
| 多头持仓 | 将止损设置在HMA线下方一定距离,随着HMA上升逐步上移止损 |
| 空头持仓 | 将止损设置在HMA线上方一定距离,随着HMA下降逐步下移止损 |
8. 参数优化建议
HMA的周期参数选择对交易效果有显著影响:
| 交易风格 | 推荐周期 | 原因 |
|---|---|---|
| 短线/日内交易 | 9-14 | 灵敏度高,能快速捕捉短期波动 |
| 波段交易 | 20-50 | 平衡灵敏度与稳定性,适合中期持仓 |
| 趋势跟踪 | 50-100 | 平滑度好,过滤短期噪音,专注主要趋势 |
| 极高波动市场 | 20-30(配合较大参数) | 降低灵敏度,减少假信号 |
9. 注意事项与局限性
使用HMA前需了解以下要点:
| 局限性 | 说明 |
|---|---|
| 仍为滞后指标 | HMA虽极大减少了滞后,但仍基于历史数据计算,无法预测未来 |
| 低波动期可能产生假信号 | 在横盘整理或低波动市场中,HMA可能频繁转向产生假信号 |
| 参数选择敏感 | 不同周期参数会显著影响HMA的灵敏度,需要根据品种和交易周期优化 |
| 计算复杂度较高 | 涉及嵌套WMA和平方根周期计算,手动计算较复杂 |
| 不能单独使用 | 建议与其他技术指标配合使用,构建完整交易系统 |
适用场景总结:
| 市场环境 | 适用性 | 说明 |
|---|---|---|
| 强趋势行情 | 最佳适用 | 趋势中HMA表现优异,方向明确 |
| 震荡行情 | 慎用 | 可能频繁产生假信号 |
| 高波动市场 | 适用 | 可选用稍长周期过滤噪音 |
| 短线交易 | 适用 | 灵敏度高,响应快 |
四、使用pandas_ta计算HMA(附示例代码)
1. pandas_ta中的HMA函数
pandas_ta库内置了HMA指标的完整实现,函数位于overlap模块中。该实现完全遵循艾伦·赫尔的原始算法。
2. 函数完整参数
pandas_ta.overlap.hma(close, length=None, offset=None, **kwargs)
参数详解:
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
close | pd.Series | 必需 | 收盘价序列 |
length | int | 10 | HMA计算周期(原始参数) |
offset | int | 0 | 结果偏移周期数 |
fillna | (可选) | — | 填充NaN值的方式 |
fill_method | (可选) | — | 填充方法类型 |
返回值:pd.Series——HMA值序列。
计算流程(源码逻辑):
# 核心计算步骤
half_length = int(length / 2) # 周期的一半
sqrt_length = int(sqrt(length)) # 周期的平方根(取整)
wmaf = wma(close, half_length) # 计算短周期WMA
wmas = wma(close, length) # 计算长周期WMA
hma = wma(2 * wmaf - wmas, sqrt_length) # 计算中间值WMA,得到HMA
3. 示例代码
import pandas as pd
import pandas_ta as ta
import numpy as np
import matplotlib.pyplot as plt
from math import sqrt
# ========== 第一步:准备数据 ==========
np.random.seed(42)
dates = pd.date_range(start='2022-01-01', end='2024-12-31', freq='D')
n = len(dates)
# 生成带趋势和周期波动的价格序列
trend = np.linspace(0, 45, n)
cycle = np.sin(np.linspace(0, 6 * np.pi, n)) * 15
noise = np.random.randn(n) * 3
price_series = 100 + trend + cycle + noise
# 添加趋势变化区间
price_series = price_series.astype(float)
for i in range(300, 450):
price_series[i] = price_series[300] + (i-300) * 0.2 # 强势上涨段
for i in range(450, 600):
price_series[i] = price_series[450] - (i-450) * 0.15 # 强势下跌段
for i in range(600, 750):
price_series[i] = price_series[600] + np.random.randn() * 0.8 # 盘整段
df = pd.DataFrame(index=dates[:n])
df['close'] = price_series[:n]
df['high'] = df['close'] + np.abs(np.random.randn(n)) * 2 + 1
df['low'] = df['close'] - np.abs(np.random.randn(n)) * 2 - 1
df['volume'] = np.random.randint(1000000, 25000000, n)
print("=" * 60)
print("数据预览:")
print(df.head())
print("\n" + "=" * 60 + "\n")
# ========== 第二步:计算HMA(基础用法) ==========
# 使用默认参数 length=10
df['HMA_10'] = ta.hma(df['close'])
print("HMA计算结果(最近10行):")
print(df[['close', 'HMA_10']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第三步:手动验证HMA计算 ==========
def manual_wma(series, length):
"""手动计算加权移动平均(WMA)"""
weights = np.arange(1, length + 1)
wma = series.rolling(window=length).apply(
lambda x: np.sum(weights * x) / weights.sum(), raw=True
)
return wma
def manual_hma(close, length=10):
"""手动计算HMA验证pandas_ta结果"""
# 计算基础WMA
half_length = max(1, int(length / 2))
sqrt_length = max(1, int(sqrt(length)))
wma_half = manual_wma(close, half_length)
wma_full = manual_wma(close, length)
# 计算中间值并最终平滑
intermediate = 2 * wma_half - wma_full
hma = manual_wma(intermediate, sqrt_length)
return hma
df['HMA_manual'] = manual_hma(df['close'])
# 验证一致性
diff = (df['HMA_10'] - df['HMA_manual']).abs().max()
print(f"pandas_ta与手动计算的最大差异:{diff:.10f}")
print("\n" + "=" * 60 + "\n")
# ========== 第四步:不同周期参数对比 ==========
# 短线参数 (9)
df['HMA_9'] = ta.hma(df['close'], length=9)
# 标准参数 (14)
df['HMA_14'] = ta.hma(df['close'], length=14)
# 中长线参数 (20)
df['HMA_20'] = ta.hma(df['close'], length=20)
# 长线参数 (50)
df['HMA_50'] = ta.hma(df['close'], length=50)
print("不同周期HMA对比(最近5行):")
print(df[['close', 'HMA_9', 'HMA_14', 'HMA_20', 'HMA_50']].tail())
print("\n" + "=" * 60 + "\n")
# ========== 第五步:计算传统均线进行对比 ==========
df['SMA_14'] = ta.sma(df['close'], length=14)
df['EMA_14'] = ta.ema(df['close'], length=14)
print("HMA vs SMA vs EMA 对比(最近10行):")
print(df[['close', 'HMA_14', 'SMA_14', 'EMA_14']].tail(10))
print("\n" + "=" * 60 + "\n")
# ========== 第六步:价格穿越信号 ==========
df['price_above_hma'] = df['close'] > df['HMA_14']
df['cross_above'] = (df['price_above_hma'] == True) & (df['price_above_hma'].shift(1) == False)
df['cross_below'] = (df['price_above_hma'] == False) & (df['price_above_hma'].shift(1) == True)
df['signal'] = ''
df.loc[df['cross_above'], 'signal'] = '买入(价格上穿HMA)'
df.loc[df['cross_below'], 'signal'] = '卖出(价格下穿HMA)'
print("价格穿越HMA信号统计:")
print(f"买入信号数量:{df['cross_above'].sum()}")
print(f"卖出信号数量:{df['cross_below'].sum()}")
print("\n最近15个穿越信号:")
signals = df[df['signal'] != ''].tail(15)
if not signals.empty:
print(signals[['close', 'HMA_14', 'signal']])
print("\n" + "=" * 60 + "\n")
# ========== 第七步:HMA拐点检测 ==========
# 识别HMA方向变化点
hma_diff = df['HMA_14'].diff()
df['hma_turning_up'] = (hma_diff > 0) & (hma_diff.shift(1) <= 0)
df['hma_turning_down'] = (hma_diff < 0) & (hma_diff.shift(1) >= 0)
df['turn_signal'] = ''
df.loc[df['hma_turning_up'], 'turn_signal'] = 'HMA拐头向上(买入信号)'
df.loc[df['hma_turning_down'], 'turn_signal'] = 'HMA拐头向下(卖出信号)'
print("HMA拐点信号统计:")
print(f"拐头向上(买入)数量:{df['hma_turning_up'].sum()}")
print(f"拐头向下(卖出)数量:{df['hma_turning_down'].sum()}")
print("\n最近15个拐点信号:")
turn_signals = df[df['turn_signal'] != ''].tail(15)
if not turn_signals.empty:
print(turn_signals[['close', 'HMA_14', 'turn_signal']])
print("\n" + "=" * 60 + "\n")
# ========== 第八步:策略回测(价格穿越策略 vs 拐点策略) ==========
# 策略1:价格穿越HMA策略
df['position_cross'] = 0
in_position_cross = False
for i in range(1, len(df)):
if not in_position_cross and df['cross_above'].iloc[i]:
df.loc[df.index[i], 'position_cross'] = 1
in_position_cross = True
elif in_position_cross and df['cross_below'].iloc[i]:
df.loc[df.index[i], 'position_cross'] = 0
in_position_cross = False
else:
df.loc[df.index[i], 'position_cross'] = df['position_cross'].iloc[i-1]
# 策略2:HMA拐点策略
df['position_turn'] = 0
in_position_turn = False
for i in range(1, len(df)):
if not in_position_turn and df['hma_turning_up'].iloc[i]:
df.loc[df.index[i], 'position_turn'] = 1
in_position_turn = True
elif in_position_turn and df['hma_turning_down'].iloc[i]:
df.loc[df.index[i], 'position_turn'] = 0
in_position_turn = False
else:
df.loc[df.index[i], 'position_turn'] = df['position_turn'].iloc[i-1]
# 计算收益
df['returns'] = df['close'].pct_change()
df['strategy_cross_returns'] = df['position_cross'].shift(1) * df['returns']
df['strategy_turn_returns'] = df['position_turn'].shift(1) * df['returns']
total_return_buyhold = (1 + df['returns']).prod() - 1
total_return_cross = (1 + df['strategy_cross_returns']).prod() - 1
total_return_turn = (1 + df['strategy_turn_returns']).prod() - 1
print("=" * 60)
print("策略绩效统计(HMA策略回测):")
print(f"买入持有策略总收益率:{total_return_buyhold:.2%}")
print(f"HMA穿越策略总收益率:{total_return_cross:.2%}")
print(f"HMA拐点策略总收益率:{total_return_turn:.2%}")
print("\n注意:此为简化回测,仅供参考")
print("=" * 60 + "\n")
# ========== 第九步:可视化 ==========
plt.figure(figsize=(14, 12))
# 子图1:价格与HMA对比
plt.subplot(2, 1, 1)
plt.plot(df.index[-150:], df['close'][-150:], label='Close Price',
linewidth=1.2, color='black')
plt.plot(df.index[-150:], df['HMA_14'][-150:], label='HMA (14) - 赫尔移动平均线',
linewidth=1.5, color='blue')
plt.plot(df.index[-150:], df['SMA_14'][-150:], label='SMA (14) - 传统',
linewidth=1, color='orange', alpha=0.7, linestyle='--')
plt.plot(df.index[-150:], df['EMA_14'][-150:], label='EMA (14)',
linewidth=1, color='green', alpha=0.7, linestyle=':')
plt.title('HMA vs SMA vs EMA 对比 (Last 150 days)', fontsize=14)
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
# 子图2:不同周期HMA对比
plt.subplot(2, 1, 2)
plt.plot(df.index[-150:], df['close'][-150:], label='Close Price',
linewidth=1, alpha=0.5, color='black')
plt.plot(df.index[-150:], df['HMA_9'][-150:], label='HMA (9) - 短线',
linewidth=1, alpha=0.7)
plt.plot(df.index[-150:], df['HMA_14'][-150:], label='HMA (14) - 标准',
linewidth=1.5, color='blue')
plt.plot(df.index[-150:], df['HMA_20'][-150:], label='HMA (20) - 中线',
linewidth=1.5, color='green')
plt.plot(df.index[-150:], df['HMA_50'][-150:], label='HMA (50) - 长线',
linewidth=1.5, color='purple')
# 标记穿越信号
buy_signals = df[df['cross_above']]
sell_signals = df[df['cross_below']]
plt.scatter(buy_signals.index[-25:], buy_signals['close'][-25:],
color='green', marker='^', s=60, label='买入信号(价格上穿)', alpha=0.8)
plt.scatter(sell_signals.index[-25:], sell_signals['close'][-25:],
color='red', marker='v', s=60, label='卖出信号(价格下穿)', alpha=0.8)
plt.title('HMA:不同周期对比与穿越信号', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend(loc='upper left')
plt.grid(True, alpha=0.3)
plt.tight_layout()
plt.show()
# ========== 第十步:不同周期平滑效果对比图 ==========
plt.figure(figsize=(14, 6))
plt.plot(df.index[-150:], df['close'][-150:], label='Close Price',
linewidth=1, alpha=0.4, color='black')
plt.plot(df.index[-150:], df['HMA_9'][-150:], label='HMA (9) - 敏感',
linewidth=1, alpha=0.8)
plt.plot(df.index[-150:], df['HMA_20'][-150:], label='HMA (20) - 平衡',
linewidth=1.5, color='blue')
plt.plot(df.index[-150:], df['HMA_50'][-150:], label='HMA (50) - 平滑',
linewidth=1.5, color='green')
plt.title('HMA:不同周期灵敏度对比 (9, 20, 50)', fontsize=14)
plt.xlabel('Date')
plt.ylabel('Price')
plt.legend()
plt.grid(True, alpha=0.3)
plt.show()
# ========== 第十一步:数据清洗提示 ==========
nan_count = df['HMA_14'].isna().sum()
print(f"\nHMA初始NaN数量:{nan_count}")
print("原因:HMA需要至少length个周期的数据才能完成WMA计算")
print("处理建议:df_clean = df.iloc[14:].copy()")
print("\n" + "=" * 60)
print("HMA使用提示:")
print("1. HMA是移动平均线的重大改进,极大减少了滞后")
print("2. 上升HMA表示上升趋势,下降HMA表示下降趋势")
print("3. 价格上穿HMA是买入信号,下穿是卖出信号")
print("4. HMA拐点(方向变化)是最核心的交易信号(艾伦·赫尔推荐)")
print("5. 短线交易建议用9-14周期,趋势跟踪建议用50-100周期")
print("6. 建议与RSI、MACD等指标配合使用,提高信号可靠性")
print("7. 低波动期HMA可能产生假信号,建议结合市场环境判断")
print("=" * 60)
5. 关键注意事项
周期参数的选择:HMA的周期参数length决定了指标的灵敏度。周期越小(如9),HMA越贴近价格,反应越灵敏,适合短线交易;周期越大(如50),HMA越平滑,适合识别长期趋势方向。
非整数周期的处理:在计算length/2和sqrt(length)时,pandas_ta使用int()进行取整处理。这是标准做法,与各交易平台保持一致。
与传统均线的对比优势:从上面的可视化结果可以明显看出,HMA相比SMA和EMA,在保持平滑的同时,对价格变化的响应更快,趋势转折点出现得更早。
五、总结
HMA(赫尔移动平均线)是移动平均线家族中的一项重大创新,其核心价值与定位如下:
| 维度 | 特点 |
|---|---|
| 核心创新 | 嵌套加权移动平均 + 平方根周期平滑 |
| 三大核心信号 | 价格穿越、HMA方向、HMA拐点 |
| 默认参数 | length=10 |
| 最佳应用场景 | 趋势跟踪、入场时机判断、动态止损 |
| 与传统MA关系 | HMA ≈ EMA的响应速度 + SMA的平滑度 |
| 主要局限 | 低波动期假信号、仍需配合其他指标使用 |
实战使用三原则:
- 方向优先,穿越确认:HMA的方向是趋势判断的首要依据,价格穿越HMA可作为入场时机参考。上升趋势中只考虑做多,下降趋势中只考虑做空
- 拐点是最核心信号:根据艾伦·赫尔的建议,HMA的转折点(从下行转上行/从上行转下行)是最可靠的交易信号,应优先于价格穿越信号使用
- 长短周期配合:短周期HMA(9-14)用于捕捉入场时机,长周期HMA(50-200)用于确认主趋势方向。当两者方向一致时,信号可靠性最高
最后提醒:HMA的最大价值在于它用数学方法解决了移动平均线“平滑”与“灵敏”之间的矛盾。它是少数能够在实战中让交易者“鱼与熊掌兼得”的工具——既保留了趋势跟踪的平滑性,又几乎消除了传统均线的滞后。然而,HMA不是完美无缺的,在横盘震荡市场中同样可能产生假信号。因此,建议将HMA与其他技术指标(如RSI、MACD)和成交量分析结合使用,构建完整的交易决策系统。无论使用何种指标,都需结合市场具体环境进行综合判断。

194

被折叠的 条评论
为什么被折叠?



