2025年1月8日 星期三

Python 學習筆記 : 技術指標套件 Ta-Lib 用法

Ta-Lib 是一套基於 K 線理論所建構的開放原始碼技術指標 (Technical Indicatiors) 函式庫, 最早是由 Mario Fortier 於 1999 年創建, 包含 158 種價量技術指標與模式識別的函式與類別, 為金融分析, 量化投資, 與演算法交易等領域提供了高效的技術分析功能. 原始碼使用 C++ 開發, 但被包裝成跨平台工具, 支援 Python, Java, 與 .NET 等程式語言介面, 參考官網介紹 :


Ta-Lib 原始碼託管於 GitHub :


Ta-Lib 採用 BSD 授權, 開發者可免費將其整合到開源或商業專案中. 

Ta-Lib 的 Python API 教學文件參考 : 


參考書籍如下 :

# Python 網頁程式交易 App 實作 (博碩, 2018, 林萍珍) 第 15 章


一. 安裝 Ta-Lib 套件 : 

Ta-Lib 無法直接用 pip install 從 PyPi 網站下載安裝, Windows 系統須根據 Python 版本至 GitHub 下載 whl 檔後用 pip install 安裝 :


而 Linux 系統須先下載舊版 (v0.4.0) 原始碼用 make 進行編譯后, 再用 pip install 安裝倒最新版的 Ta-Lib, 參考 : 

安裝好 Ta-Lib 後即可匯入使用, 但其套件名稱為小寫的 talib :

>>> import talib    

檢視版本 : 

>>> talib.__version__   
'0.4.28'   


二. 取得股票盤後資料 :    

有許多管道可取得股票價量資料, 例如 : 
  1. 撰寫網頁爬蟲自證交所網站下載  (台股)
  2. 使用 twstock 套件 (台股)
  3. 使用 yfinance API (全球)
  4. 使用 FinMind API (全球)
  5. 使用 FinLab API  (全球)
  6. 使用券商 API (全球)
由於證交所為了避免主機負荷過重, 會對頻繁的爬取動作採取鎖 IP 的反爬蟲限制, 所以最好是使用 API 較能穩定取得資料 (其實 twstock 也是爬蟲), 其中以 yfinance 最方便, 只要安裝好套件即可下載全球股票資料, 不需要 API token 驗證. 

不過, 從 API 取得的 OHLCV 價量資料欄位名稱必須做些調整才能餵給 Ta-Lib 計算指標數值, 例如從 yfinance 取得的 OHLCV 盤後資料, 其欄位名稱為首字母大寫的 Open, High, Low, Close, Volume, 可用下面的串列生成式更改以符合 Ta-Lib 要求 : 

df.columns=[column.lower() for column in df.columns]  

參考 :


而從 FinMind 取得的資料則是 close, open 欄位符合要求, 但它的最高價使用 max, 最低價使用 min, 成交量使用 Trading_Volume, 可用 DataFrame 物件的 rename() 方法傳入一個字典來修改 :

df=df.rename(columns={'max': 'High', 'min': 'Low', 'Trading_Volume': 'volume'})

參考 :


至於 FinLab, 由於其 API 與眾不同,  其 OHLCV 價量資料是要個別取得後組合為一個包含全市場的 DataFrame, 在組合過程中即可設定 OHLCV 的欄位名稱以符合 Ta-Lib 要求, 作法參考 : 



三. Ta-Lib 的兩種用法 :    

Ta-Lib 提供函數式 (functional) 與物件導向式 (object-oriented) 兩種 API 介面, 以物件導向用法較好用, 因為它可直接傳入的 DataFrame 價量資料; 而函數式用法的傳入參數為 Numpy 的 ndarray 陣列 (一維), 因此若原始價量資料是 DataFrame, 還必須依指標不同將公式需要的 OHLCV 個別抓出來丟給指標函式去計算指標數值. 


1. Ta-Lib 的函數式用法 :  

採用函數式用法時可直接匯入整個 talib 套件 :

import talib

所有指標的函式都放在 talib 命名空間下 (指標函式名稱均為大寫), 呼叫這些指標函式並傳入價量資料的一維 Numpy 浮點數陣列就會傳回指標數值 (也是一維陣列), 例如 :

sma=talib.SMA(data)
rsi=talib.RSI(data)

注意, 傳入參數 data 是一維 Numpy 浮點數陣列. 也可以從 talib 匯入要用的指標函式, 例如 :

from talib import SMA, RSI

sma=SMA(data)
rsi=RSI(data)

參考官網說明 :


Ta-Lib 提供 158 種技術指標函式, 呼叫 talib.get_functions() 函式會傳回這些指標函式名稱組成的串列 : 

>>> indicators=talib.get_functions()  
>>> indicators 
['HT_DCPERIOD', 'HT_DCPHASE', 'HT_PHASOR', 'HT_SINE', 'HT_TRENDMODE', 'ADD', 'DIV', 'MAX', 'MAXINDEX', 'MIN', 'MININDEX', 'MINMAX', 'MINMAXINDEX', 'MULT', 'SUB', 'SUM', 'ACOS', 'ASIN', 'ATAN', 'CEIL', 'COS', 'COSH', 'EXP', 'FLOOR', 'LN', 'LOG10', 'SIN', 'SINH', 'SQRT', 'TAN', 'TANH', 'ADX', 'ADXR', 'APO', 'AROON', 'AROONOSC', 'BOP', 'CCI', 'CMO', 'DX', 'MACD', 'MACDEXT', 'MACDFIX', 'MFI', 'MINUS_DI', 'MINUS_DM', 'MOM', 'PLUS_DI', 'PLUS_DM', 'PPO', 'ROC', 'ROCP', 'ROCR', 'ROCR100', 'RSI', 'STOCH', 'STOCHF', 'STOCHRSI', 'TRIX', 'ULTOSC', 'WILLR', 'BBANDS', 'DEMA', 'EMA', 'HT_TRENDLINE', 'KAMA', 'MA', 'MAMA', 'MAVP', 'MIDPOINT', 'MIDPRICE', 'SAR', 'SAREXT', 'SMA', 'T3', 'TEMA', 'TRIMA', 'WMA', 'CDL2CROWS', 'CDL3BLACKCROWS', 'CDL3INSIDE', 'CDL3LINESTRIKE', 'CDL3OUTSIDE', 'CDL3STARSINSOUTH', 'CDL3WHITESOLDIERS', 'CDLABANDONEDBABY', 'CDLADVANCEBLOCK', 'CDLBELTHOLD', 'CDLBREAKAWAY', 'CDLCLOSINGMARUBOZU', 'CDLCONCEALBABYSWALL', 'CDLCOUNTERATTACK', 'CDLDARKCLOUDCOVER', 'CDLDOJI', 'CDLDOJISTAR', 'CDLDRAGONFLYDOJI', 'CDLENGULFING', 'CDLEVENINGDOJISTAR', 'CDLEVENINGSTAR', 'CDLGAPSIDESIDEWHITE', 'CDLGRAVESTONEDOJI', 'CDLHAMMER', 'CDLHANGINGMAN', 'CDLHARAMI', 'CDLHARAMICROSS', 'CDLHIGHWAVE', 'CDLHIKKAKE', 'CDLHIKKAKEMOD', 'CDLHOMINGPIGEON', 'CDLIDENTICAL3CROWS', 'CDLINNECK', 'CDLINVERTEDHAMMER', 'CDLKICKING', 'CDLKICKINGBYLENGTH', 'CDLLADDERBOTTOM', 'CDLLONGLEGGEDDOJI', 'CDLLONGLINE', 'CDLMARUBOZU', 'CDLMATCHINGLOW', 'CDLMATHOLD', 'CDLMORNINGDOJISTAR', 'CDLMORNINGSTAR', 'CDLONNECK', 'CDLPIERCING', 'CDLRICKSHAWMAN', 'CDLRISEFALL3METHODS', 'CDLSEPARATINGLINES', 'CDLSHOOTINGSTAR', 'CDLSHORTLINE', 'CDLSPINNINGTOP', 'CDLSTALLEDPATTERN', 'CDLSTICKSANDWICH', 'CDLTAKURI', 'CDLTASUKIGAP', 'CDLTHRUSTING', 'CDLTRISTAR', 'CDLUNIQUE3RIVER', 'CDLUPSIDEGAP2CROWS', 'CDLXSIDEGAP3METHODS', 'AVGPRICE', 'MEDPRICE', 'TYPPRICE', 'WCLPRICE', 'BETA', 'CORREL', 'LINEARREG', 'LINEARREG_ANGLE', 'LINEARREG_INTERCEPT', 'LINEARREG_SLOPE', 'STDDEV', 'TSF', 'VAR', 'ATR', 'NATR', 'TRANGE', 'AD', 'ADOSC', 'OBV']

呼叫 len() 來計算指標數量 :

>>> len(talib.get_functions())  
158  

Ta-Lib 所提供的 158 種技術指標可區分為如下七大類 :
  1. 重疊研究 (overlap studies) : 例如 SMA, EMA, 布林通道等
  2. 動量指標 (momentum indicators) : 例如 RSI, KD, MACD, DMI, ADX, WILLR 等
  3. 量能指標 (volume indicators) : 例如 AD, OBV, 
  4. 波動指標 (volatility indicators) : 例如 ATR, NATR 等
  5. 價格轉換 (price transform) : 例如 MEDPRICE, TYPPRICE 等
  6. 週期指標 (cycle indicators) : 例如 HT_DCPERIOD, HT_DCPHASE 等
  7. 型態識別 (pattern recognition) : 例如 CDLDOJISTAR, CDLHARAMI 等
這些指標函式的說明文件參考官網 : 


下面利用 yfinance 取得台股 0050 盤後價量資料來展示 Ta-Lib 指標的函數式用法 : 

>>> import yfinance as yf   
>>> df=yf.download('0050.TW', start='2024-11-06', end='2025-01-06')    
[*********************100%%**********************]  1 of 1 completed

檢視首尾 5 筆資料 : 

>>> df.head()   
                  Open        High  ...   Adj Close    Volume
Date                                ...                      
2024-11-06  194.050003  198.050003  ...  195.199997  16706376
2024-11-07  194.899994  198.050003  ...  197.449997  13498552
2024-11-08  199.399994  200.000000  ...  199.000000  12950151
2024-11-11  198.850006  199.100006  ...  199.100006  12364013
2024-11-12  195.199997  195.850006  ...  194.000000  26272087

[5 rows x 6 columns]

>>> df.tail()  
                  Open        High  ...   Adj Close    Volume
Date                                ...                      
2024-12-27  197.600006  199.050003  ...  198.899994   6987417
2024-12-30  198.149994  198.649994  ...  197.800003   8677266
2024-12-31  196.699997  196.899994  ...  195.750000   7836534
2025-01-02  195.649994  195.649994  ...  194.050003  12797702
2025-01-03  196.000000  196.949997  ...  196.000000   7113371

[5 rows x 6 columns]

然後依據指標函式的要求傳入所需的價量資料參數以計算指標數值. 每一種指標需要傳入的必要參數不一樣, 有的指標公式只用到收盤價, 有的需要成交量, 也有的開高低收量都要. 可以用 help() 檢視函式的介面, 例如移動均價指標 SMA : 

>>> help(talib.SMA)    
Help on function SMA in module talib._ta_lib:

SMA(real, timeperiod=-2147483648)
    SMA(real[, timeperiod=?])
    
    Simple Moving Average (Overlap Studies)
    
    Inputs:
        real: (any ndarray)
    Parameters:
        timeperiod: 30
    Outputs:
        real

可見 SMA() 有一個浮點數的必要參數 (real, 這裡是指收盤價), 與一個預設值為 30 的關鍵字參數 timeperiod, 從 DataFrame 中抽取 Close 欄位傳給 SMA() 即可計算 SMA 指標 :

>>> sma=talib.SMA(df['Close'].values)   
>>> sma 
array([         nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan,          nan,          nan,          nan,
                nan, 193.36000112, 193.42333476, 193.32166799,
       193.10833486, 193.04666799, 193.17333476, 193.36166789,
       193.60333455, 193.82166748, 194.09333445, 194.21000112,
       194.29666799, 194.51833445])

因預設為計算 30 天移動均價, 因此前面有 30 個 nan, 第 31 個才會有指標值. 也可以指定 timeperiod 參數, 例如 5 日移動均價 :

>>> sma5=talib.SMA(df['Close'].values, timeperiod=5)   
>>> sma5   
array([         nan,          nan,          nan,          nan,
       196.95      , 196.46000061, 195.17000122, 193.84000244,
       191.95      , 191.6       , 191.33999939, 191.01000061,
       191.15      , 191.69000244, 191.21000366, 190.34000549,
       189.83000488, 188.67000427, 188.54000244, 189.43000183,
       191.1       , 193.03999939, 194.73999939, 195.6       ,
       195.66000061, 195.15      , 194.87999878, 194.78999939,
       194.81000061, 195.31000061, 196.15000305, 196.00000305,
       195.46000366, 195.69000244, 195.83000183, 196.08999939,
       196.86000061, 198.11999817, 198.22999878, 197.81999817,
       196.95      , 196.5       ])

檢視另一個指標 OBV (能量潮) :

>>> help(talib.OBV)    
Help on function OBV in module talib._ta_lib:

OBV(real, volume)
    OBV(real, volume)
    
    On Balance Volume (Volume Indicators)
    
    Inputs:
        real: (any ndarray)
        prices: ['volume']
    Outputs:
        real

此指標需要兩個必要參數 real (收盤價) 與 prices (成交量), 沒有關鍵字參數 (無 parameters 項目), 因為 OBV 公式是固定計算前後日的價量變化. 但注意從 yfinance 下載的 Volume 欄位值是 int 整數陣列, 必須轉成浮點數才可以傳入 OBV() 計算指標值, 否則會出現錯誤 :

>>> import numpy as np   
>>> volume=df['Volume'].values.astype(np.float64)   
>>> obv=talib.OBV(df['Close'].values, volume)   
>>> obv   
array([ 16706376.,  30204928.,  43155079.,  55519092.,  29247005.,
        20052415.,   7905800.,  15291381.,   1896865.,   9515186.,
         9437186.,  -6439431.,   1526156.,  -6300507., -17691329.,
       -31764015., -44873129., -36744909., -26200831., -16247725.,
        -9792476.,  -2346273.,  -9155779.,  -4515915.,  -8993222.,
       -15707911., -10680670.,  -6160243.,   1183349.,  10477578.,
        10477578.,  -2567469., -13690863.,  -2514797.,   5681105.,
        11587228.,   6783667.,  13771084.,   5093818.,  -2742716.,
       -15540418.,  -8427047.])  

注意, 計算指標不需要日期時間欄位, 因為它計算的對象是序列資料本身, 與時間單位無關 (可以自行設定 index). 

接下來可以用 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 embedding:
            fig, ax=mpf.plot(self.df, returnfig=True, **kwargs)
            return fig
        else:
            mpf.plot(self.df, **kwargs)

mplfinace 套件根據傳入的 OHLCV 價量資料繪製 K 線圖與副圖, 與 Ta-Lib 的價量欄位名稱全小寫不同的是, 它要求是首字母須大寫, 而 yfinance 下載的盤後資料剛好符合要求, 因此可以直接使用, 毋須調整欄位名稱. 

首先匯入上面自訂的 kbar 模組 : 

>>> import kbar   

然後呼叫 kbar.KBar() 建構式並傳入價量資料建立一個 KBar 物件, 呼叫其 plot() 方法即可繪製 K 線圖 :

>>> kb=kbar.KBar(df)   
>>> kb.plot()   

這樣就會畫出單純的 K 線圖了 :




KBar 物件的 plot() 方法其實就是呼叫 mplfinance 的 plot() 函式來繪圖, 但在 kbar.py 模組中, data, type, style, 與 add_plot 參數已經被設定好了, 但其於參數仍可傳入 KBar 物件的 plot() 方法中, 摘要如下表 :


 plot() 方法參數 說明
 volume 是否顯示成交量 (布林值), 預設 False
 title 設定圖形標題
 tight_layout 是否以緊緻方式排版 (布林值), 預設 False
 mav 設定均線日期, 可以是整數 (單天期均線) 或整數串列 (多天期均線)
 figratio 圖形寬高尺寸比例, 可用 tuple (寬, 高) 或 list [寬, 高], 預設 (8, 5.75), 單位為吋
 figscale 圖形縮放比率 (在 figration 尺寸基礎上進行縮放)
 returnfig 是否傳回 Figure 物件 (布林值), 預設 False
 show_nontrading 是否顯示非交易日, True/False (預設)
 xrotation X 軸標籤旋轉角度 (預設 45)
 block 是否直接繪圖 (布林值), 預設 True. 若設為 False 須用 plt.show() 繪圖
 savefig 設定欲儲存之圖檔檔名 (支援 jpg, png, pdf, 與 svg)


我們可以在 K 線圖底下繪製指標疊圖, 只要呼叫 KBar 物件的 addplot() 方法並傳入要繪製的指標序列 (ndarray 或 Series 物件皆可) 與副圖的 panel 編號即可 (副圖從 1 開始起算, 0 是保留給疊圖用的), 例如將 sma5 疊在 K 線圖上 (pannel=0); 把 OBV 指標畫在副圖 (pannel=1) :

>>> kb.addplot(sma5, panel=0)   
>>> kb.addplot(obv, panel=1, ylabel='OBV')     
>>> kb.plot()   

結果如下 : 




KBar 物件的 addplot() 方法其實是呼叫 mplfinance 的 make_addplot() 函式來添加副圖的, 它的所有參數都可以傳入 addplot() 方法中, 摘要如下表 :


 addplot() 方法參數 說明
 panel 繪圖框編號 (0~9, 0 為疊圖, 1~9 為副圖, 但 1 為內建成交量副圖)
 color 線條顏色
 marker 資料點標記符號, 例如 'o' 為圓點, 's' 為方點 
 ylabel Y 軸標籤 (字串)
 ylim Y 軸座標範圍 (串列)
 width 線條寬度 (px)


如果有多個指標要畫在 K 線圖下方, 只要呼叫 addplot() 並指定 pannel 編號即可, 例如添加 MFI 指標, 呼叫 talib.MFI () 需要傳入 high, low, close, 與 volume 四個必要參數 :

>>> high=df['High'].values   
>>> low=df['Low'].values     
>>> close=df['Close'].values    
>>> volume=df['Volume'].values.astype(np.float64)     
>>> mfi=talib.MFI(high, low, close, volume)    
>>> mfi    
array([        nan,         nan,         nan,         nan,         nan,
               nan,         nan,         nan,         nan,         nan,
               nan,         nan,         nan,         nan, 36.52278116,
       27.84390884, 19.48269033, 25.2474845 , 35.8421018 , 42.9185449 ,
       49.65502982, 49.74023035, 52.22997413, 51.11938324, 49.33400714,
       53.01754778, 51.85624257, 46.39775973, 54.85881271, 66.14822568,
       70.16098537, 59.0320236 , 48.67628014, 49.3305763 , 50.22018197,
       43.80847539, 49.3688432 , 50.54106715, 48.55150349, 48.01651452,
       40.67040565, 45.67233937])

呼叫 addplot() 將 MFI 指標畫在 pannel=2 : 

>>> kb.addplot(mfi, panel=2, ylabel='MFI')    
>>> kb.plot()    

結果如下 :




呼叫 plot() 方法時也可以傳入 volume=True 參數開啟成交量疊圖顯示, 但它預設會占用 pannel=1, 這時指標疊圖就要從 2 起算, 否則會跟成交量疊在一起. 

其次, sma 指標其實不需要特別用 Ta-lib 來計算後去疊圖, mplfinance 的 plot() 函式本身就提供一個 mav 參數來設定指定天期的移動平均數, mav 可以是單一整數或整數串列, 例如 mav=3 表示在 K 線圖上疊一個 3 日 SMA 指標線, mav=[3, 5] 表示疊兩條移動平均線.  

總結來說, 從上面測試可知, 函數式 API 用起來較為麻煩, 除了必須先去查詢指標函式需要傳入那些價量數據外 (一維 Numpy 陣列), 還必須確認它們的資料型態是浮點數. 


2. Ta-Lib 的物件導向用法 :  

Ta-Lib 的物件導向 API 支援直接傳入 DataFrame 價量資料, 只要 OHLCV 欄位名稱是全小寫的 open, high, low, close, volume 即可. 

例如從 yfinance 取得盤後資料 : 

>>> import yfinance as yf   
>>> df=yf.download('0050.TW', start='2024-11-06', end='2025-01-06')    
[*********************100%%**********************]  1 of 1 completed

檢視欄位名稱 :

>>> df.columns    
Index(['Open', 'High', 'Low', 'Close', 'Adj Close', 'Volume'], dtype='object')

這不符 Ta-Lib 對 OHLCV 欄位名稱全小寫的要求, 可用下面的串列生成式修改 :

>>> df.columns=[column.lower() for column in df.columns]     
>>> df.columns      
Index(['open', 'high', 'low', 'close', 'adj close', 'volume'], dtype='object')

這樣就可以計算技術指標了. 

Ta-Lib 的物件導向 API 將所有指標做成類別放在 abstract 模組下 (但如果用 dir(talib) 檢視 Ta-Lib 套件的成員會找不到 abstract, 因為開發者將其隱藏起來避免它被公開存取), 可透過 abstract 直接匯入指標類別, 例如 :

from talib.abstract import SMA, RSI, OBV, MFI

然後呼叫指標類別的建構式並傳入 OHLCV 價量資料的 DataFrame 來計算指標, 結果會傳回一個 Pandas Series 物件 : 

sma=SMA(df)
rsi=RSI(df)
obv=OBV(df)
mfi=MFI(df)

也可以匯入整個 abstract 模組 : 

import talib.abstract as abstract 

然後透過它來取得個別指標類別 : 

sma=abstract.SMA(df)
rsi=abstract.RSI(df)
obv=abstract.OBV(df)
mfi=abstract.MFI(df)

呼叫 print() 印出這些類別會顯示計算該指標所需要的輸入參數以及其預設值 :

>>> print(abstract.SMA)   
SMA([input_arrays], [timeperiod=30])

Simple Moving Average (Overlap Studies)

Inputs:
    price: (any ndarray)
Parameters:
    timeperiod: 30
Outputs:
    real
>>> print(abstract.RSI)   
RSI([input_arrays], [timeperiod=14])

Relative Strength Index (Momentum Indicators)

Inputs:
    price: (any ndarray)
Parameters:
    timeperiod: 14
Outputs:
    real
>>> print(abstract.OBV)   
OBV([input_arrays])

On Balance Volume (Volume Indicators)

Inputs:
    price: (any ndarray)
    prices: ['volume']
Outputs:
    real
>>> print(abstract.MFI)   
MFI([input_arrays], [timeperiod=14])

Money Flow Index (Momentum Indicators)

Inputs:
    prices: ['high', 'low', 'close', 'volume']
Parameters:
    timeperiod: 14    
Outputs:
    real

可見有些指標有 timeperiod 參數 (有移動平均的都有, 呼叫建構式時可以傳入 timeperiod 參數指定之), 有些則沒有 (例如 OBV). 

以下使用第一種方式以預設天期參數計算 SMA, RSI, OBV, 與 MFI 指標 :

>>> from talib.abstract import SMA, RSI, OBV, MFI   
>>> sma=SMA(df)    
>>> rsi=RSI(df)   
>>> obv=OBV(df)    
>>> mfi=MFI(df)   

可見使用物件導向 API 非常方便, 直接將欄位名稱符合要求之 DataFrame 傳給建構式即可. 尤其是計算 MFI 指標時不用像上面函數式 API 那樣要先將成交量轉成浮點數, MFI 類別會自動處理. 

檢視傳回值的資料型態都是 Pandas 的 Series 物件 : 

>>> type(sma)   
<class 'pandas.core.series.Series'>   
>>> type(rsi)   
<class 'pandas.core.series.Series'>   
>>> type(obv)   
<class 'pandas.core.series.Series'>   
>>> type(mfi)   
<class 'pandas.core.series.Series'>  

檢視其中的 MFI 指標 : 

>>> mfi   
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          NaN
2024-11-26    36.522781
2024-11-27    27.843909
2024-11-28    19.482690
2024-11-29    25.247484
2024-12-02    35.842102
2024-12-03    42.918545
2024-12-04    49.655030
2024-12-05    49.740230
2024-12-06    52.229974
2024-12-09    51.119383
2024-12-10    49.334007
2024-12-11    53.017548
2024-12-12    51.856243
2024-12-13    46.397760
2024-12-16    54.858813
2024-12-17    66.148226
2024-12-18    70.160985
2024-12-19    59.032024
2024-12-20    48.676280
2024-12-23    49.330576
2024-12-24    50.220182
2024-12-25    43.808475
2024-12-26    49.368843
2024-12-27    50.541067
2024-12-30    48.551503
2024-12-31    48.016515
2025-01-02    40.670406
2025-01-03    45.672339
dtype: float64

接著繪製 K 線圖 : 

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

此處因為傳入 volume=True, 成交量副圖預設會占用 pannel=1 副圖, 所以 RSI, OBV, 與 MFI 指標非別指派 pannel 為 2, 3, 4; 而 mav=5 表示要在 K 線圖上繪製 5 日移動平均線疊圖, 它會使用 pannel=0, 結果如下 :




可見物件導向 API 比較簡單好用. 不過要注意的是在使用 mplfinance 繪製指標副圖時必須先確定指標數據要有值, 如果全為 NaN (這在天期參數 timeperiod 比資料長度還長時就會傳回全部 NaN 的 Series 物件) 則在繪製副圖時會出現 ValueError, 故呼叫 addplot() 前要先檢查是否指標值為全部 NaN :

if not rsi.isna().all():  # 確保 RSI 有值
    kb.addplot(rsi, panel=2, ylabel='RSI')
if not obv.isna().all():  # 確保 OBV 有值
    kb.addplot(obv, panel=3, ylabel='OBV')
if not mfi.isna().all():  # 確保 MFI 有值
    kb.addplot(mfi, panel=4, ylabel='MFI')

這樣就可避免出現錯誤. 

沒有留言:

張貼留言