赫爾移動平均線(Hull Moving Average,簡稱HMA)是一種技術指標,于2005年由Alan Hull開發。它是一種移動平均線,利用加權計算來減少滯后并提高準確性。
HMA對價格變動非常敏感,同時最大程度地減少短期波動可能產生的噪音。它通過使用加權計算來強調更近期的價格,同時平滑數據。
計算HMA的公式涉及三個步驟。首先,使用價格數據計算加權移動平均線。然后,使用第一步的結果計算第二個加權移動平均線。最后,使用第二步的結果計算第三個加權移動平均線。最終計算的結果就是移動赫爾平均線。
WMA_1 =一段時期內價格的加權移動平均值(WMA) /2
WMA_2 =價格在一段時間內的WMA
HMA_non_smooth = 2 * WMA_1 - WMA_2
HMA = HMA_non_smooth的WMA除以根號(周期)
在下面的文章中,我們將介紹如何使用Python實現HMA。本文將對計算WMA的兩種方法進行詳細比較。然后介紹它在時間序列建模中的作用。
Python實現HMA
方法1:將WMA計算為按時期加權的移動平均價格:
defhma(period):
wma_1=df['Adj Close'].rolling(period//2).apply(lambdax: \\
np.sum(x*np.arange(1, period//2+1)) /np.sum(np.arange(1, period//2+1)), raw=True)
wma_2=df['Adj Close'].rolling(period).apply(lambdax: \\
np.sum(x*np.arange(1, period+1)) /np.sum(np.arange(1, period+1)), raw=True)
diff=2*wma_1-wma_2
hma=diff.rolling(int(np.sqrt(period))).mean()
returnhma
period=20
df['hma'] =hma(period)
df['sma_20days'] =df['Adj Close'].rolling(period).mean()
figsize= (10,6)
df[['Adj Close','hma','sma_20days']].plot(figsize=figsize)
plt.title('Hull Moving Average {0} days'.format(period))
plt.show()
如圖所示,HMA比通常的SMA反應更快:
還可以嘗試更短的時間框架,看看HMA與價格曲線的關系有多密切。
df['hma_short']=hma(14)
df['hma_long']=hma(30)
figsize= (12,6)
df[['Adj Close','hma_short','hma_long']].plot(figsize=figsize)
plt.title('Hull Moving Average')
plt.show()
方法2,使用體量計算加權平均值:
defhma_volume(period):
wma_1=df['nominal'].rolling(period//2).sum()/df['Volume'].rolling(period//2).sum()
wma_2=df['nominal'].rolling(period).sum()/df['Volume'].rolling(period).sum()
diff=2*wma_1-wma_2
hma=diff.rolling(int(np.sqrt(period))).mean()
returnhma
df['nominal'] =df['Adj Close'] *df['Volume']
period=20
df['hma_volume']=hma_volume(period)
figsize=(12,8)
fig, (ax0,ax1) =plt.subplots(nrows=2, sharex=True, subplot_kw=dict(frameon=True),figsize=figsize)
df[['Adj Close','hma_volume','hma']].plot(ax=ax0)
ax0.set_title('HMA Volume vs HMA period')
df[['Volume']].plot(ax=ax1)
ax1.set_title('Hull Moving Average')
plt.show()
體量的HMA比第一種方法計算的HMA稍滯后:
策略的回溯測試
為了回測每種策略(方法1和2),我們將計算一個短期和一個長期的HMA:
當短線超過長線時,可以觸發買入指令。當短線低于長線時,就會觸發賣出指令。
然后我們計算每個信號產生的pnl。
方法1:
#SIGNAL
df['hma_short']=hma(20)
df['hma_long']=hma(30)
df['signal'] =np.where(df['hma_short'] >df['hma_long'],1,-1)
#RETURN
df['signal_shifted']=df['signal'].shift()
## Calculate the returns on the days we trigger a signal
df['returns'] =df['Adj Close'].pct_change()
## Calculate the strategy returns
df['strategy_returns'] =df['signal_shifted'] *df['returns']
## Calculate the cumulative returns
df1=df.dropna()
df1['cumulative_returns'] = (1+df1['strategy_returns']).cumprod()
#PLOT
figsize=(12,8)
fig, (ax0,ax1) =plt.subplots(nrows=2, sharex=True, subplot_kw=dict(frameon=True),figsize=figsize)
df[['Adj Close','hma_long','hma_short']].plot(ax=ax0)
ax0.set_title("HMA: Short vs Long")
df[['signal']].plot(ax=ax1,style='-.',alpha=0.4)
ax1.legend()
ax1.set_title("HMA - Signals")
plt.show()
df1['cumulative_returns'].plot(figsize=(10,4))
plt.title("Cumulative Return")
plt.show()
你可以看到每次產生的信號都有一條交叉線:
在數據集的整個時間段內產生的總體回報是正的,即使在某些時期它是負的:
回報率:
df1['cumulative_returns'].tail()[-1]
#1.0229750801053696
方法2:
#SIGNAL
df['hma_volume_short']=hma_volume(20)
df['hma_volume_long']=hma_volume(30)
df['signal'] =np.where(df['hma_volume_short'] >df['hma_volume_long'],1,-1)
#RETURN
df['returns'] =df['Adj Close'].pct_change()
## Calculate the strategy returns
df['strategy_returns'] =df['signal'].shift() *df['returns']
## Calculate the cumulative returns
df2=df.dropna()
df2['cumulative_returns_volume'] = (1+df2['strategy_returns']).cumprod()
# PLOT
figsize=(12,8)
fig, (ax0,ax1) =plt.subplots(nrows=2, sharex=True, subplot_kw=dict(frameon=True),figsize=figsize)
df[['Adj Close','hma_volume_short','hma_volume_long']].plot(ax=ax0)
df[['signal']].plot(ax=ax1,style='-.',alpha=0.4)
ax0.set_title("HMA - Volume: Short vs Long")
ax1.legend()
plt.title("HMA - Signals")
plt.show()
figs= (10,4)
df2['cumulative_returns_volume'].plot(figsize=figs)
plt.title("Cumulative Return")
plt.show()
看起來比第一種方法中的HMA更平滑,可以觸發的信號更少(在我們的例子中只有1個):
這種策略產生的回報不是很好:0.75(0.775-1?-24%)
df2['cumulative_returns_volume'].tail()[-1]
#0.7555329108482581
我們來比較兩種策略的信號:
df['signal'] =np.where(df['hma_short'] >df['hma_long'],1,-1)
df['signal_volume'] =np.where(df['hma_volume_short'] >df['hma_volume_long'],1,-1)
figsize=(12,8)
df[['signal','signal_volume']].plot(figsize=figsize)
plt.show()
空頭頭寸的信號比多頭頭寸更多:
所以僅使用HMA還不足以產生有利可圖的策略。我們可以使用相對強弱指數(RSI)和隨機指數(Stochastic Oscillator等其他指標來確認交易信號。但是對于時間序列來說,HMA是一個很好的特征工程的方法。
HMA信號的一些解釋
交叉信號:當價格越過HMA上方時,可以解釋為看漲信號,當價格越過HMA下方時,可以解釋為看空信號。它也可以觸發買入和賣出信號,正如我們之前已經看到的。(上圖點1)。
趨勢跟蹤信號:HMA也可用于識別趨勢并生成趨勢跟蹤信號。當HMA傾斜向上時,它表示上升趨勢,當它傾斜向下時,它表示下降趨勢(上圖點2)。
反轉信號:當價格從下方接近HMA時,看漲反轉趨勢可能在不久的將來發生(上圖點3)。
HMA在時間序列建模的作用
HMA在時間序列建模中的作用主要是作為一個平滑濾波器,可以在一定程度上減少噪聲并提高時間序列預測的準確性。在時間序列建模中,經常需要對數據進行平滑處理,以消除異常值和噪聲,同時保留趨勢和季節性變化的信號。HMA是一種有效的平滑濾波器,它通過加權平均的方式來計算平均值,并對較早的數據施加更大的權重,從而可以更準確地捕捉趨勢性信號。
除了作為一個平滑濾波器,HMA還可以作為一個特征提取器來提取時間序列中的特征,并用于建立預測模型。例如,可以使用HMA計算時間序列中的趨勢和季節性變化,并將其作為輸入特征用于構建ARIMA、VAR或LSTM等預測模型。
總結
HMA不僅在交易中有廣泛的應用,也是一種有用的時間序列分析工具。HMA作為一種移動平均線,可以減少時間序列中的噪聲和突發性變化,從而更準確地捕捉數據的趨勢性和周期性變化。在時間序列分析中,HMA通常用于平滑處理數據,以提高預測的準確性。在實際應用中,HMA常常與其他技術指標和時間序列分析方法相結合,在各種數據分析和預測任務中獲取更好的預測結果。
-
濾波器
+關注
關注
161文章
7795瀏覽量
177996 -
SMA
+關注
關注
4文章
175瀏覽量
24812 -
HMA
+關注
關注
0文章
4瀏覽量
8448 -
python
+關注
關注
56文章
4792瀏覽量
84628
發布評論請先 登錄
相關推薦
評論