概覽
預測資產(chǎn)價格變動一直是一個廣泛研究的領(lǐng)域,旨在開發(fā)能夠“準確”捕捉這些資產(chǎn)價格變動的 alpha 生成交易策略。 考慮到大多數(shù)資產(chǎn)價格的隨機性,根據(jù)定義,它本質(zhì)上是隨機的。 因此,這個想法側(cè)重于執(zhí)行某種分析,以一定程度的信心捕捉這種隨機元素的運動。 在用于預測這一走勢的眾多方法中,技術(shù)指標已經(jīng)存在了相當長的一段時間(據(jù)報道自 1800 年代以來一直在使用)作為形成潛在走勢觀點的方法之一。
在算法交易普及之前,技術(shù)指標主要由交易者使用,他們會在交易屏幕上查看這些指標以做出買入/賣出決定。 盡管這仍然非常普遍,但技術(shù)分析已經(jīng)進入自動交易,因為機器學習和其他統(tǒng)計工具能夠在短時間內(nèi)分析這些數(shù)據(jù),并且計算機的計算能力可以進行數(shù)十年的回溯測試 數(shù)據(jù)的。
盡管本文不贊成或反對使用技術(shù)分析,但以下技術(shù)指標可用于執(zhí)行各種回溯測試并就其預測能力提出意見。
技術(shù)指標
本文將重點介紹專業(yè)人士和學者廣泛使用的技術(shù)指標的綜合列表,以及我認為對自動交易最有利的技術(shù)指標。 指標列表如下:
1. 簡單移動平均線(快和慢)
2.平均真實范圍
3.平均方向指數(shù)(快和慢)
4. 隨機震蕩指標(快和慢)
5. 相對強度指數(shù)(快慢)
6. 移動平均收斂發(fā)散
7.布林帶
8.變化率
數(shù)據(jù)
使用 pandas datareader for Yahoo finance 數(shù)據(jù)庫,我提取了從 1990 年 1 月到今天的每日 Apple 和 Netflix 股票數(shù)據(jù)。 大多數(shù)指標是使用收盤價而不是本文中的調(diào)整收盤價創(chuàng)建的。
由于技術(shù)指標在短期內(nèi)效果最好,我將分別使用 5 天和 15 天作為我的快信號和慢信號。 然而,這可能會根據(jù)投資期限而改變。 以下指標可通過單個參數(shù)更改自定義為任何持續(xù)時間。
#importing variables
import pandas as pd
import numpy as np
import datetime as dt
import pandas_datareader as pdr
import seaborn as sns
import matplotlib.pyplot as plt
#extracting data from Yahoo Finance API
tickers = ['AAPL','NFLX']
all_data = pd.DataFrame()
test_data = pd.DataFrame()
no_data = []
for i in tickers:
try:
test_data = pdr.get_data_yahoo(i, start = dt.datetime(1990,1,1), end = dt.date.today())
test_data['symbol'] = i
all_data = all_data.append(test_data)
except:
no_data.append(i)
#Creating Return column
all_data['return'] = all_data.groupby('symbol')['Close'].pct_change()
簡單移動平均線 (SMA)
簡單移動平均線是最常見的技術(shù)指標之一。 SMA 計算給定時間間隔內(nèi)的平均價格,并用于確定股票的趨勢。 如上定義,我將創(chuàng)建一個慢速 SMA (SMA_15) 和一個快速 SMA (SMA_5)。 要為機器學習算法提供已經(jīng)設(shè)計好的因素,還可以使用 (SMA_15/SMA_5) 或 (SMA_15 - SMA_5) 作為一個因素來捕捉這兩個移動平均線之間的關(guān)系。
all_data['SMA_5'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.rolling(window = 5).mean())
all_data['SMA_15'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.rolling(window = 15).mean())
all_data['SMA_ratio'] = all_data['SMA_15'] / all_data['SMA_5']
#Plotting
start = dt.datetime.strptime('2019-01-01', '%Y-%m-%d')
end = dt.datetime.strptime('2019-12-31', '%Y-%m-%d')
sns.set()
fig = plt.figure(facecolor = 'white', figsize = (20,10))
ax0 = plt.subplot2grid((6,4), (1,0), rowspan=4, colspan=4)
ax0.plot(all_data[all_data.symbol=='AAPL'].loc[start:end,['Close','SMA_5','SMA_15']])
ax0.set_facecolor('ghostwhite')
ax0.legend(['Close','SMA_5','SMA_15'],ncol=3, loc = 'upper left', fontsize = 15)
plt.title("Apple Stock Price, Slow and Fast Moving Average", fontsize = 20)
ax1 = plt.subplot2grid((6,4), (5,0), rowspan=1, colspan=4, sharex = ax0)
ax1.plot(all_data[all_data.symbol=='AAPL'].loc[start:end,['SMA_ratio']], color = 'blue')
ax1.legend(['SMA_Ratio'],ncol=3, loc = 'upper left', fontsize = 12)
ax1.set_facecolor('silver')
plt.subplots_adjust(left=.09, bottom=.09, right=1, top=.95, wspace=.20, hspace=0)
plt.show()
簡單移動平均交易量
與價格的簡單移動平均線類似,成交量的簡單移動平均線提供了對股票顯示信號強度的洞察力。
all_data['SMA5_Volume'] = all_data.groupby('symbol')['Volume'].transform(lambda x: x.rolling(window = 5).mean())
all_data['SMA15_Volume'] = all_data.groupby('symbol')['Volume'].transform(lambda x: x.rolling(window = 15).mean())
all_data['SMA_Volume_Ratio'] = all_data['SMA5_Volume']/all_data['SMA15_Volume']
Wilder的平滑
在繼續(xù)下一個指標之前,我想提一下通常與其他指標一起使用的另一種平滑或移動平均線。 雖然 SMA 很常見,但它包含了對過去每個值給予同等權(quán)重的偏見。 為了解決這個問題,Wells Wilder 引入了一種新版本的平滑處理,它更加重視最近發(fā)生的事件。 我們將對以下大部分指標使用 Wilder 平滑,下面是通??捎糜讷@得此平滑的函數(shù)。
def Wilder(data, periods):
start = np.where(~np.isnan(data))[0][0] #Check if nans present in beginning
Wilder = np.array([np.nan]*len(data))
Wilder[start+periods-1] = data[start:(start+periods)].mean() #Simple Moving Average
for i in range(start+periods,len(data)):
Wilder[i] = (Wilder[i-1]*(periods-1) + data[i])/periods #Wilder Smoothing
return(Wilder)
平均真實范圍 (ATR)
平均真實范圍是一種常用的技術(shù)指標,用于衡量市場的波動性,以真實范圍的移動平均值來衡量。 公司較高的 ATR 意味著股票的波動性較高。 然而,ATR 主要用于確定何時退出或進入交易,而不是確定交易股票的方向。
如上所述,慢速 ATR 代表 5 天移動平均線,快速 ATR 代表 15 天移動平均線。
真實范圍定義為以下最大值:
a. 高- 低
b. 絕對值(高- 前一收盤)
c. 絕對值(低- 前一收盤)
all_data['prev_close'] = all_data.groupby('symbol')['Close'].shift(1)
all_data['TR'] = np.maximum((all_data['High'] - all_data['Low']),
np.maximum(abs(all_data['High'] - all_data['prev_close']),
abs(all_data['prev_close'] - all_data['Low'])))
for i in all_data['symbol'].unique():
TR_data = all_data[all_data.symbol == i].copy()
all_data.loc[all_data.symbol==i,'ATR_5'] = Wilder(TR_data['TR'], 5)
all_data.loc[all_data.symbol==i,'ATR_15'] = Wilder(TR_data['TR'], 15)
all_data['ATR_Ratio'] = all_data[ATR_5'] / all_data[ATR_15']
平均方向指數(shù) (ADX)
平均方向指數(shù)由 Wilder 開發(fā),用于評估股票價格趨勢的強度。 它的兩個主要組成部分 +DI 和 -DI 有助于確定趨勢的方向。 一般來說,ADX在25以上表示趨勢強,ADX小于20表示趨勢弱。 ADX 的計算相當復雜,需要一定的步驟。
我也會計算 5 天和 15 天的 ADX。
all_data['prev_high'] = all_data.groupby('symbol')['High'].shift(1)
all_data['prev_low'] = all_data.groupby('symbol')['Low'].shift(1)
all_data['+DM'] = np.where(~np.isnan(all_data.prev_high),
np.where((all_data['High'] > all_data['prev_high']) &
(((all_data['High'] - all_data['prev_high']) > (all_data['prev_low'] - all_data['Low']))),
all_data['High'] - all_data['prev_high'],
0),np.nan)
all_data['-DM'] = np.where(~np.isnan(all_data.prev_low),
np.where((all_data['prev_low'] > all_data['Low']) &
(((all_data['prev_low'] - all_data['Low']) > (all_data['High'] - all_data['prev_high']))),
all_data['prev_low'] - all_data['Low'],
0),np.nan)
for i in all_data['symbol'].unique():
ADX_data = all_data[all_data.symbol == i].copy()
all_data.loc[all_data.symbol==i,'+DM_5'] = Wilder(ADX_data['+DM'], 5)
all_data.loc[all_data.symbol==i,'-DM_5'] = Wilder(ADX_data['-DM'], 5)
all_data.loc[all_data.symbol==i,'+DM_15'] = Wilder(ADX_data['+DM'], 15)
all_data.loc[all_data.symbol==i,'-DM_15'] = Wilder(ADX_data['-DM'], 15)
all_data['+DI_5'] = (all_data['+DM_5']/all_data['ATR_5'])*100
all_data['-DI_5'] = (all_data['-DM_5']/all_data['ATR_5'])*100
all_data['+DI_15'] = (all_data['+DM_15']/all_data['ATR_15'])*100
all_data['-DI_15'] = (all_data['-DM_15']/all_data['ATR_15'])*100
all_data['DX_5'] = (np.round(abs(all_data['+DI_5'] - all_data['-DI_5'])/(all_data['+DI_5'] + all_data['-DI_5']) * 100))
all_data['DX_15'] = (np.round(abs(all_data['+DI_15'] - all_data['-DI_15'])/(all_data['+DI_15'] + all_data['-DI_15']) * 100))
for i in all_data['symbol'].unique():
ADX_data = all_data[all_data.symbol == i].copy()
all_data.loc[all_data.symbol==i,'ADX_5'] = Wilder(ADX_data['DX_5'], 5)
all_data.loc[all_data.symbol==i,'ADX_15'] = Wilder(ADX_data['DX_15'], 15)
隨機震蕩指標
隨機震蕩指標是一種動量指標,旨在識別超買和超賣證券,通常用于技術(shù)分析。
all_data['Lowest_5D'] = all_data.groupby('symbol')['Low'].transform(lambda x: x.rolling(window = 5).min())
all_data['High_5D'] = all_data.groupby('symbol')['High'].transform(lambda x: x.rolling(window = 5).max())
all_data['Lowest_15D'] = all_data.groupby('symbol')['Low'].transform(lambda x: x.rolling(window = 15).min())
all_data['High_15D'] = all_data.groupby('symbol')['High'].transform(lambda x: x.rolling(window = 15).max())
all_data['Stochastic_5'] = ((all_data['Close'] - all_data['Lowest_5D'])/(all_data['High_5D'] - all_data['Lowest_5D']))*100
all_data['Stochastic_15'] = ((all_data['Close'] - all_data['Lowest_15D'])/(all_data['High_15D'] - all_data['Lowest_15D']))*100
all_data['Stochastic_%D_5'] = all_data['Stochastic_5'].rolling(window = 5).mean()
all_data['Stochastic_%D_15'] = all_data['Stochastic_5'].rolling(window = 15).mean()
all_data['Stochastic_Ratio'] = all_data['Stochastic_%D_5']/all_data['Stochastic_%D_15']
相對強度指數(shù) (RSI)
RSI 是最常見的動量指標之一,旨在量化價格變化和這種變化的速度。
all_data['Diff'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.diff())
all_data['Up'] = all_data['Diff']
all_data.loc[(all_data['Up']<0), 'Up'] = 0
all_data['Down'] = all_data['Diff']
all_data.loc[(all_data['Down']>0), 'Down'] = 0
all_data['Down'] = abs(all_data['Down'])
all_data['avg_5up'] = all_data.groupby('symbol')['Up'].transform(lambda x: x.rolling(window=5).mean())
all_data['avg_5down'] = all_data.groupby('symbol')['Down'].transform(lambda x: x.rolling(window=5).mean())
all_data['avg_15up'] = all_data.groupby('symbol')['Up'].transform(lambda x: x.rolling(window=15).mean())
all_data['avg_15down'] = all_data.groupby('symbol')['Down'].transform(lambda x: x.rolling(window=15).mean())
all_data['RS_5'] = all_data['avg_5up'] / all_data['avg_5down']
all_data['RS_15'] = all_data['avg_15up'] / all_data['avg_15down']
all_data['RSI_5'] = 100 - (100/(1+all_data['RS_5']))
all_data['RSI_15'] = 100 - (100/(1+all_data['RS_15']))
all_data['RSI_ratio'] = all_data['RSI_5']/all_data['RSI_15']
移動平均收斂發(fā)散 (MACD)
MACD 使用兩條指數(shù)移動平均線,并根據(jù)它們的收斂或發(fā)散創(chuàng)建趨勢分析。 雖然最常用的 MACD 慢速和快速信號分別基于 26 天和 12 天,但為了與其他指標保持一致,我使用了 15 天和 5 天。
all_data['5Ewm'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.ewm(span=5, adjust=False).mean())
all_data['15Ewm'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.ewm(span=15, adjust=False).mean())
all_data['MACD'] = all_data['15Ewm'] - all_data['5Ewm']
布林帶
布林帶捕捉股票的波動性,用于識別超買和超賣股票。 布林帶由三個主要元素組成:簡單的移動平均線、高于移動平均線 2 個標準差的上限和低于移動平均線 2 個標準差的下限。
all_data['15MA'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.rolling(window=15).mean())
all_data['SD'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.rolling(window=15).std())
all_data['upperband'] = all_data['15MA'] + 2*all_data['SD']
all_data['lowerband'] = all_data['15MA'] - 2*all_data['SD']
變化率
變化率是一個動量指標,它解釋了相對于之前價格固定時期的價格動量。
all_data['RC'] = all_data.groupby('symbol')['Close'].transform(lambda x: x.pct_change(periods = 15))
結(jié)論
這些技術(shù)指標在捕獲的時間范圍內(nèi)是高度可定制的,同時允許各種有助于創(chuàng)建更好模型的特征工程。 這些值可以直接適合機器學習模型,也可以形成更大模型的因子子集。
還有許多其他指標可以考慮,即使不是很重要。 本文中列出的指標絕不是詳盡的指標列表,而是我在模型中使用的指標列表。
在我的下一篇文章中,我將解釋這些指標在機器學習模型中的實施,并深入探討創(chuàng)建和仔細回測策略。
請在下方留下您的意見和建議。
聯(lián)系客服