2025年1月18日 星期六

Python 學習筆記 : 技術指標套件 ta 用法 (二)

由於篇幅過長, 因此將 ta 的物件導向 API 用法紀錄在此續篇, 本系列前一篇文章參考 : 



2. ta 的物件導向式 API :      

如前所述, ta 套件的指標類別都分別放在 trend, volatility, volume, momentum, 與 others 等五大指標類型模組下, 使用物件導向 API 時須呼叫指標類別的建構式並傳入價量資料的 DataFrame 以建立一個指標類別, 然後須呼叫其方法才能取得指標數據. 

ta 原生支援 Pandas, 以下測試使用最方便的 yfinance 取得股票之價量資料, 因為 yfinance 就是直接傳回股票價量資料的 DataFrame 且毋須傳遞 API Key. 以台灣五十 (0050) 為例 : 

>>> df=yf.download('0050.TW', start='2024-11-06', end='2025-01-09')   
[*********************100%%**********************]  1 of 1 completed
>>> df.columns     
Index(['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'], dtype='object')

以 OBV 指標為例, 其指標類別為 ta.volume.OnBalanceVolumeIndicator :




呼叫建構式 OnBalanceVolumeIndicator() 時必須傳入 close 與 volume 這兩個必要參數, 它會傳回一個 OnBalanceVolumeIndicator 物件 : 

>>> OBV=ta.volume.OnBalanceVolumeIndicator(close=df['Close'], volume= df['Volume'])   
>>> type(OBV)   
<class 'ta.volume.OnBalanceVolumeIndicator'>   

傳回物件只有一個公開方法 on_balance_volume(), 呼叫它會傳回計算出來的 OBV 指標數據 (型態為 Series 物件) : 

>>> obv=OBV.on_balance_volume()   
>>> obv     
Date
2024-11-06    16706376
2024-11-07    30204928
2024-11-08    43155079
2024-11-11    55519092
2024-11-12    29247005
2024-11-13    20052415
2024-11-14     7905800
2024-11-15    15291381
2024-11-18     1896865
2024-11-19     9515186
2024-11-20     9437186
2024-11-21    -6439431
2024-11-22     1526156
2024-11-25    -6300507
2024-11-26   -17691329
2024-11-27   -31764015
2024-11-28   -44873129
2024-11-29   -36744909
2024-12-02   -26200831
2024-12-03   -16247725
2024-12-04    -9792476
2024-12-05    -2346273
2024-12-06    -9155779
2024-12-09    -4515915
2024-12-10    -8993222
2024-12-11   -15707911
2024-12-12   -10680670
2024-12-13    -6160243
2024-12-16     1183349
2024-12-17    10477578
2024-12-18    17031455
2024-12-19     3986408
2024-12-20    -7136986
2024-12-23     4039080
2024-12-24    12234982
2024-12-25    18141105
2024-12-26    13337544
2024-12-27    20324961
2024-12-30    11647695
2024-12-31     3811161
2025-01-02    -8986541
2025-01-03    -1873170
2025-01-06    22754623
2025-01-07    38698467
2025-01-08    26842750
Name: obv, dtype: int64

此結果與使用指標函式 ta.volume.on_balance_volume() 得到的數據是一樣的. 

接下來計算動能類型的 RSI 指標, 其指標類別為 ta.momentum.RSIIndicator




RSI 為相對強弱指標, 用於衡量價格是在超買或超賣狀態, 從 API 可知必要參數為 close 收盤價 (Series 物件), 備選參數 window 用來設定移動窗口 (預設 14), fillna 設定是否要對 NaN 做填入動作 (預設 False). 呼叫 ta.momentum.RSIIndicator() 並傳入參數建立 RSIIndicator 物件 :

>>> RSI=ta.momentum.RSIIndicator(close=df['Close'])   
>>> type(RSI)   
<class 'ta.momentum.RSIIndicator'>   

RSIIndicator 物件只有一個公開方法 rsi(), 呼叫 rsi() 會傳回計算出來的 RSI 指標數據 :

>>> rsi=RSI.rsi()   
>>> rsi   
Date
2024-11-06          NaN
2024-11-07          NaN
2024-11-08          NaN
2024-11-11          NaN
2024-11-12          NaN
2024-11-13          NaN
2024-11-14          NaN
2024-11-15          NaN
2024-11-18          NaN
2024-11-19          NaN
2024-11-20          NaN
2024-11-21          NaN
2024-11-22          NaN
2024-11-25    45.732159
2024-11-26    39.560536
2024-11-27    34.107863
2024-11-28    33.564358
2024-11-29    35.231532
2024-12-02    48.890462
2024-12-03    54.877909
2024-12-04    57.262711
2024-12-05    59.373997
2024-12-06    57.200326
2024-12-09    57.755502
2024-12-10    53.565209
2024-12-11    48.923488
2024-12-12    54.538551
2024-12-13    54.894578
2024-12-16    56.835996
2024-12-17    59.199976
2024-12-18    59.199976
2024-12-19    50.533601
2024-12-20    45.727610
2024-12-23    57.082949
2024-12-24    58.197052
2024-12-25    59.434195
2024-12-26    58.964392
2024-12-27    60.424311
2024-12-30    56.745051
2024-12-31    50.565547
2025-01-02    46.083754
2025-01-03    51.404401
2025-01-06    63.603546
2025-01-07    66.879390
2025-01-08    59.112553
Name: rsi, dtype: float64

最後利用 mplfinance 套件來繪製 K 線圖與上面的指標, 我寫了一個基於 mplfinance 的 kbar.py 模組來簡化 K 線圖的繪製 :

# kbar.py
import mplfinance as mpf

class KBar():
    def __init__(self, df):
        self.df=df
        self.addplots=[]
    def addplot(self, data, **kwargs):
        plot=mpf.make_addplot(data, **kwargs)
        self.addplots.append(plot)
    def plot(self, embedding=False, **kwargs):
        color=mpf.make_marketcolors(up='red', down='green', inherit=True)   
        font={'font.family': 'Microsoft JhengHei'}   
        style=mpf.make_mpf_style(base_mpf_style='default',
                                 marketcolors=color,
                                 rc=font)
        kwargs['type']='candle'
        kwargs['style']=style
        kwargs['addplot']=self.addplots
        if 'returnfig' in kwargs and kwargs['returnfig'] is True:
            fig, ax=mpf.plot(self.df, **kwargs)
            return fig
        else:
            mpf.plot(self.df, **kwargs)

匯入 kbar 模組並呼叫 kbar.KBar() 建構式建立一個 KBar 物件, 然後把 OBV 與 RSI 指標分別畫在 副圖 2 與副圖 3 (因為成交量固定占用副圖 1) : 

>>> import kbar     
>>> kb=kbar.KBar(df)    
>>> kb.addplot(obv, panel=2, ylabel='OBV')    # 副圖 2
>>> kb.addplot(rsi, panel=3, ylabel='RSI')      # 副圖 3
>>> kb.plot(volume=True, mav=5)  

結果如下 : 





沒有留言 :