iT邦幫忙

2023 iThome 鐵人賽

DAY 22
0
AI & Data

用Python程式進行股票技術分析系列 第 22

Day22 其他的技術指標(1)

  • 分享至 

  • xImage
  •  

技術分析有主要指標與次要(輔助、次)指標。主要指標包含移動平均線、KD指標與MACD指標等,今明兩天會介紹幾種次要指標。

峰谷(線)指標

ZigZag指標本意為蜿蜒,中文多稱為峰谷線(波峰、波谷),或是峰谷指標。對於不會判斷轉折的人,提供客觀的幫助,可以簡易的判斷K線圖的轉折。指標需要定義一參考點,通常是收盤價,當日高或低點,第二個參數是百分比值。當價格扭轉了指定的百分比,把參考點連接點,就可以形成轉折線。參數可以設定0.1-10%,通用參數設定值為5%;且短期訊號太過敏感,容易不準。
參考XQ全球贏家手冊,看盤軟體的峰谷線指標 (ZigZag指標)之計算公式於下:

ZigZag= n 期價格移動平均(系統預設為5 天,可於設定指標設定計算天數)。
若n 期最高價的移動平均>n 期收盤價移動平均*(1+0.05)則上述價格取用最高價的移動平均。反之,若n 期最低價的移動平均*(1-0.05) 則上述價格取用最低價的移動平均,其餘則選用收盤價的移動平均。

程式實作:繪製峰谷線指標

這個指標目前只能透過看盤軟體取得。首先在看盤軟體主圖中加入ZigZag指標(預設參數為:扭轉條件為5,計算方式為百分比,計算基準為收盤價);之後匯出成Excel檔,然後透過pandas套件讀取Excel檔後存進DataFrame資料結構。程式碼如下所示:

##### 使用2022年3月11日到2023年7月12日之日線圖資料 #####

# 載入從「好神通PLUS」輸出的Excel檔
df = pd.read_excel('Day22(1).xlsx')

# 保存K線的基本資訊(開、高、低、收、量)
df_k_line = df.drop(columns=['SMA5','SMA10','SMA20','SMA60','SMA120','SMA240','ZIGZAG_5%','MA5','MA10'])

# 保存價的移動平均線
df_sma = df.drop(columns=['開盤價','最高價','最低價','收盤價','ZIGZAG_5%','成交量','MA5','MA10'])

# 保存峰谷線
df_zigzag = df.drop(columns=['開盤價','最高價','最低價','收盤價','SMA5','SMA10','SMA20','SMA60','SMA120','SMA240','成交量','MA5','MA10'])

# 將K線的Columns的名稱由中文改為英文
df_k_line = df_k_line.rename(columns={'時間':'Date','開盤價':'Open','最高價':'High','最低價':'Low','收盤價':'Close','成交量':'Volume'})

# 將價的移動平均線的Columns的名稱由中文改為英文
df_sma = df_sma.rename(columns={'時間':'Date'})

# 將峰谷線的Columns的名稱由中文改為英文
df_zigzag = df_zigzag.rename(columns={'時間':'Date'})

# 將K線的Date設為Index
df_k_line.set_index(df_k_line['Date'],inplace=True)
df_k_line = df_k_line.drop(columns=['Date'])

# 將價的移動平均線的Date設為Index
df_sma.set_index(df_sma['Date'],inplace=True)
df_sma = df_sma.drop(columns=['Date'])

再將峰谷線指標繪製於K線圖上,程式碼如下所示:

# 取得ZigZag轉折點
df_zigzag = df_zigzag.dropna()
print(df_zigzag)

# 設定K線格式
mc = mpf.make_marketcolors(up='xkcd:light red', down='xkcd:almost black', inherit=True)
s  = mpf.make_mpf_style(base_mpf_style='yahoo', marketcolors=mc)

# 設定轉折線
seq_of_seq_of_points = [] 
for _current in range(0,len(df_zigzag)) :
    _next = _current + 1
    if _next < len(df_zigzag) :
        seq_of_seq_of_points.append([(df_zigzag.iloc[_current]['Date'],df_zigzag.iloc[_current]['ZIGZAG_5%']),(df_zigzag.iloc[_next]['Date'],df_zigzag.iloc[_next]['ZIGZAG_5%'])])
    else :
        break
        
# 設定移動平均線
added_plots={
    "SMA5": mpf.make_addplot(df_sma['SMA5'],width=0.8,color='xkcd:violet')
            }

# 繪出K線圖
kwargs = dict(type='candle', style=s, figratio=(19,10), addplot=list(added_plots.values()),alines=dict(alines=seq_of_seq_of_points, linewidths=1, colors='xkcd:azure', alpha=0.6))
mpf.plot(df_k_line,**kwargs)

程式執行結果如下所示:
Imgur
而在Day10有談到「尋找方向變化點」函式,其中的mode參數設為close時就會有峰谷線指標的功能。使用尋找方向變化點函式進行峰谷線指標的程式碼如下所示:

import myutils

# 尋找方向變化點:方向變化點已經整併進myutils套件中(不用重複貼程式碼到這邊)
_,_,max_min = myutils.FindingDirectionalChangePoints(df_k_line,mode='close')
print(max_min)

# 設定K線格式
mc = mpf.make_marketcolors(up='xkcd:light red', down='xkcd:almost black', inherit=True)
s  = mpf.make_mpf_style(base_mpf_style='yahoo', marketcolors=mc)

# 設定轉折線
seq_of_seq_of_points = []
for _current in range(0,len(max_min)) :
    _next = _current + 1
    if _next < len(max_min) :
        seq_of_seq_of_points.append([(max_min.iloc[_current]['Date'],max_min.iloc[_current]['Price']),(max_min.iloc[_next]['Date'],max_min.iloc[_next]['Price'])])
    else :
        break
        
# 設定移動平均線
added_plots={
    "SMA5": mpf.make_addplot(df_sma['SMA5'],width=0.8,color='xkcd:violet')
            }

# 繪出K線圖
kwargs = dict(type='candle', style=s, figratio=(19,10), addplot=list(added_plots.values()),alines=dict(alines=seq_of_seq_of_points, linewidths=1, colors='xkcd:azure', alpha=0.6))
mpf.plot(df_k_line,**kwargs)

程式執行結果如下所示:
Imgur
進行與看盤軟體的ZigZag指標的數值比對,發現除最後兩三筆會有差異外;其於數值相同。比對結果如下圖所示:
Imgur

趨向指標(Directional Movement Index)

趨向指標(Directional Movement Index)簡稱為DMI指標,對新手而言,DMI指標是一套在理論與實際應用上,都相當複雜的技術指標。DMI指標主要的用途在於做趨勢成立的判斷,因此是屬於較為長期交易的技術指標,且DMI指標為趨勢指標,是觀察大波段行情的好工具。DMI指標可以做為買的工具(不過反應較慢),但不適合做為賣的工具。DMI指標包含+DI值、–DI值,+DI 代表多頭,–DI 代表空頭;另外還有一個ADX值:ADX值本身不具備多空特性,而是跟隨+DI值、–DI值來辨識多空,且ADX值為趨勢動量指標,在漲勢或跌勢明顯的階段,ADX線會逐漸增加,代表上漲或下跌的力量已經增強。ADX線上升角度較強且大於20以上時,表示中長期漲勢或跌勢更加確定,突破30/40以上則將大漲或大跌一段;ADX值接近50時就有反轉壓力 (ADX值在大型股過40、小型股過50要很警戒)。

程式實作:繪製與計算趨向指標

在看盤軟體新增DMI指標於副圖後將該頁面匯出成Excel檔案,然後透過pandas套件讀取Excel檔後存進DataFrame資料結構。程式碼如下所示:

##### 使用2016年12月20日到2017年6月27日之日線圖資料 #####

# 載入從「好神通PLUS」輸出的Excel檔
df = pd.read_excel('Day22(2).xlsx')

# 保存K線的基本資訊(開、高、低、收、量)
df_k_line = df.drop(columns=['SMA5','SMA10','SMA20','SMA60','SMA120','SMA240','MA5','MA10','+DI14','-DI14','ADX14'])

# 保存價的移動平均線
df_sma = df.drop(columns=['開盤價','最高價','最低價','收盤價','成交量','MA5','MA10','+DI14','-DI14','ADX14']) 

# 保存DMI指標
df_dmi = df.drop(columns=['開盤價','最高價','最低價','收盤價','成交量','SMA5','SMA10','SMA20','SMA60','SMA120','SMA240','MA5','MA10']) 

# 將K線的Columns的名稱由中文改為英文
df_k_line = df_k_line.rename(columns={'時間':'Date','開盤價':'Open','最高價':'High','最低價':'Low','收盤價':'Close','成交量':'Volume'})

# 將價的移動平均線的Columns的名稱由中文改為英文
df_sma = df_sma.rename(columns={'時間':'Date'})

# 將DMI指標的Columns的名稱由中文改為英文
df_dmi = df_dmi.rename(columns={'時間':'Date'})

# 將K線的Date設為Index
df_k_line.set_index(df_k_line['Date'],inplace=True)
df_k_line = df_k_line.drop(columns=['Date'])

# 將價的移動平均線的Date設為Index
df_sma.set_index(df_sma['Date'],inplace=True)
df_sma = df_sma.drop(columns=['Date'])

# 將DMI指標的Date設為Index
df_dmi.set_index(df_dmi['Date'],inplace=True)
df_dmi = df_dmi.drop(columns=['Date'])

再將DMI指標繪製於副圖上,程式碼如下所示:

# 設定K線格式
mc = mpf.make_marketcolors(up='xkcd:light red', down='xkcd:almost black', inherit=True)
s  = mpf.make_mpf_style(base_mpf_style='yahoo', marketcolors=mc)

# 設定移動平均線與DMI指標
added_plots={
    "SMA5": mpf.make_addplot(df_sma['SMA5'],width=0.4,color='xkcd:maroon'),
    "SMA10": mpf.make_addplot(df_sma['SMA10'],width=0.4,color='xkcd:cyan'),
    "SMA20": mpf.make_addplot(df_sma['SMA20'],width=0.4,color='xkcd:violet'),
    "SMA60": mpf.make_addplot(df_sma['SMA60'],width=0.4,color='xkcd:salmon'),
    "SMA120": mpf.make_addplot(df_sma['SMA120'],width=0.4,color='xkcd:blue grey'),
    "SMA240": mpf.make_addplot(df_sma['SMA240'],width=0.4,color='xkcd:sky blue'),
    'DI+': mpf.make_addplot(df_dmi['+DI14'],width=0.8,panel=1,secondary_y=False,color='xkcd:red'),
    'DI-': mpf.make_addplot(df_dmi['-DI14'],width=0.8,panel=1,secondary_y=False,color='xkcd:light blue'),
    'ADX': mpf.make_addplot(df_dmi['ADX14'],width=0.8,panel=1,color='xkcd:blue')
            }

# 繪出K線圖
kwargs = dict(type='candle', style=s, figratio=(19,10), addplot=list(added_plots.values()), datetime_format='%Y-%m-%d')
mpf.plot(df_k_line,**kwargs)

程式執行結果如下所示:
Imgur
當然也可以用talib套件來計算DMI指標,但要分別呼叫PLUS_DI函式計算DI+值,呼叫MINUS_DI函式計算DI-值;以及呼叫ADX函式計算ADX值。程式碼如下所示:

from talib.abstract import *

# 當使用talib Abstract API時,DataFrame欄位名稱需為小寫
# 請參考書籍:Python:量化交易 Ta-Lib 技術指標 139個活用技巧
df_k_line_talib = df_k_line.copy()
df_k_line_talib.columns=[ i.lower() for i in df_k_line_talib.columns]

talib_plus_di = PLUS_DI( df_k_line_talib, timeperiod=14)
talib_minus_di = MINUS_DI( df_k_line_talib, timeperiod=14)
talib_adx = ADX( df_k_line_talib, timeperiod=14)

程式執行結果如下所示:
Imgur
完整的程式碼請參照「第二十二天:其他的技術指標(1).ipynb」。


上一篇
Day21 葛蘭碧八大法則
下一篇
Day23 其他的技術指標(2)
系列文
用Python程式進行股票技術分析30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言