在前一篇關於 ta 套件的測試中曾經以布林傑通道為例繪製其上限, 中線, 與下限, 可否在上下限之間填色以強調通道的收歛與發散情況呢? 可以的, 只要利用 plot() 函式的 fill_between 參數即可, 本系列文章索引參考 :
首先從 Yahoo Finance 下載 0050 近半年來的價量資料 :
>>> import yfinance as yf
>>> df=yf.download('0050.TW', start='2024-08-20', end='2025-01-20')
[*********************100%%**********************] 1 of 1 completed
然後用 ta 套件計算布林傑通道指標, 在 ta 官網搜尋 'bollinger' 即可找到其指標類別 ta.volatility.BollingerBands :
可見 ta 的布林傑指標類別預設滑動窗口是 20, 上下限之標準差預設為 2, 呼叫其建構式 ta.volatility.BollingerBands() 並傳入必要參數收盤價的 Series 物件即可建立 BollingerBands 指標物件 :
>>> import ta
>>> BB=ta.volatility.BollingerBands(df['Close'])
>>> type(BB)
<class 'ta.volatility.BollingerBands'>
呼叫 BollingerBands 指標物件的 bollinger_mavg(), bollinger_hband(), 與 bollinger_lband() 方法會分別傳回布林傑中線, 與上下限之 Series 物件 :
>>> bbm=BB.bollinger_mavg() # 中線
>>> bbh=BB.bollinger_hband() # 上限
>>> bbl=BB.bollinger_lband() # 下限
>>> type(bbm)
<class 'pandas.core.series.Series'>
>>> type(bbh)
<class 'pandas.core.series.Series'>
>>> type(bbl)
<class 'pandas.core.series.Series'>
>>> bbm
Date
2024-08-20 NaN
2024-08-21 NaN
2024-08-22 NaN
2024-08-23 NaN
2024-08-26 NaN
...
2025-01-13 197.592500
2025-01-14 197.567500
2025-01-15 197.417500
2025-01-16 197.465000
2025-01-17 197.560001
Name: mavg, Length: 103, dtype: float64
>>> bbh
Date
2024-08-20 NaN
2024-08-21 NaN
2024-08-22 NaN
2024-08-23 NaN
2024-08-26 NaN
...
2025-01-13 203.157323
2025-01-14 203.163324
2025-01-15 203.212691
2025-01-16 203.264575
2025-01-17 203.216108
Name: hband, Length: 103, dtype: float64
>>> bbl
Date
2024-08-20 NaN
2024-08-21 NaN
2024-08-22 NaN
2024-08-23 NaN
2024-08-26 NaN
...
2025-01-13 192.027678
2025-01-14 191.971676
2025-01-15 191.622309
2025-01-16 191.665426
2025-01-17 191.903893
Name: lband, Length: 103, dtype: float64
這樣就可以用 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 類別的建構函式並傳入價量 df 建立 KBar 物件 :
>>> import kbar
>>> kb=kbar.KBar(df)
>>> kb.addplot(bbh, color='red', width=1) # 上限疊圖
>>> kb.addplot(bbm, color='blue', width=1) # 中線疊圖
>>> kb.addplot(bbl, color='green', width=1) # 下限疊圖
>>> kb.plot(volume=True)
結果如下 :
接下來便是要在布林傑通道的上下限曲線之間填色, mplfinance 套件的 plot() 函式有一個 fill_between 參數可以用來在指定的 Y 軸區間填色, 用法參考 mplfinance 教學文件 :
fill_between 參數值為一個字典 (單區間填色) 或字典串列 (多區間填色), 字典中可用的鍵摘要說明如下表 :
key (鍵) 名稱 | 說明 |
y1 | 第一條資料線的 Y 軸數值, 可以是與主圖索引等長對齊的 list 或一維 ndarray |
y2 | 第二條資料線的 Y 軸數值, 可以是與主圖索引等長對齊的 list 或一維 ndarray |
where | 決定在哪些 X 軸區域填充顏色的布林值 Series 或 ndarray, 預設填充整個區域 |
color | 指定要填充的顏色, 格式例如 'cyan' 或 '#00FFFF' |
alpha | 指定填充顏色的不透明度 (0~1), 預設為 0.5 |
interpolate | 是否在資料之間內插以使邊界平滑 : True 或 False (預設) |
先在 K 線圖上新增布林傑上下限與中線疊圖 :
>>> import kbar
>>> kb=kbar.KBar(df)
>>> kb.addplot(bbh, color='red', width=1) # 上限疊圖
>>> kb.addplot(bbm, color='blue', width=1) # 中線疊圖
>>> kb.addplot(bbl, color='green', width=1) # 下限疊圖
然後建立一個填色字典 :
>>> fill_between=dict(y1=bbl.values, y2=bbh.values, color='cyan', alpha=0.3)
這裡 y1 與 y2 參數都是用 values 屬性從 bbl (下限) 與 bbh (上限) 這兩個 Series 物件中取出的一維 ndarray 陣列 :
>>> bbl.values
array([ nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, 170.12689033,
170.23572968, 170.28583699, 170.20918148, 170.08403056,
169.81666464, 169.25048449, 168.61944645, 168.16900744,
168.14925903, 168.15729205, 168.20390841, 169.19939766,
170.27416137, 170.95175947, 172.13770519, 173.60905758,
175.1146881 , 175.86193223, 176.77859139, 177.31671369,
178.45402917, 179.47429228, 180.35475564, 181.30589677,
181.99071414, 182.36593703, 182.54719321, 182.79797247,
183.86675428, 185.35692943, 187.1846761 , 187.98999251,
189.12906253, 189.84455446, 190.01109833, 190.23275395,
189.96888795, 189.63812581, 189.51609843, 188.84458977,
188.72614331, 188.50619393, 187.92008835, 187.85801194,
187.80223999, 187.4549489 , 186.69404511, 185.91857966,
185.41537725, 185.35391702, 185.35463013, 185.34540622,
185.42701563, 185.77766063, 186.19018768, 186.17159865,
186.1747256 , 186.24260036, 186.23718512, 186.4806345 ,
186.43269043, 186.50360361, 186.97686189, 186.94599184,
187.0024802 , 187.40804458, 188.53739771, 190.08511692,
191.92075606, 192.61908143, 192.78440713, 192.60245912,
192.58255969, 192.01177644, 191.21332298, 191.31273806,
191.90515682, 192.16284683, 192.02767806, 191.97167638,
191.62230933, 191.6654256 , 191.9038928 ])
>>> bbh.values
array([ nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, nan,
nan, nan, nan, 186.35311303,
185.65427429, 185.43916606, 185.67582066, 186.03097188,
186.6733378 , 187.96951825, 189.2305566 , 190.520995 ,
190.80074249, 191.06770947, 191.37609342, 192.07060356,
192.49083955, 193.23824145, 194.06229481, 194.58594211,
195.53531037, 196.25806593, 196.83140769, 198.228286 ,
199.11097022, 199.80570803, 200.28024497, 200.48410415,
200.93928616, 201.39406358, 201.4328071 , 201.47202875,
201.05824724, 200.50307118, 199.68032329, 199.58000719,
199.46093686, 199.74544493, 200.27390228, 200.22224635,
200.12111296, 200.2518751 , 200.27890279, 200.10541023,
199.64385638, 199.27880516, 199.19991134, 199.08698775,
198.73776093, 198.46505232, 198.78595672, 199.06142217,
199.23962458, 199.17608481, 199.24037261, 199.27459652,
199.09798742, 198.42234243, 197.69981476, 197.77840441,
197.79027684, 198.13740147, 198.4378164 , 198.83936825,
199.37231293, 199.86640066, 199.89814116, 199.88401151,
200.31752255, 200.70695786, 200.70760351, 200.30488399,
199.63424424, 199.54591948, 199.52559348, 199.5675421 ,
199.53744153, 200.74822417, 202.38667702, 202.96226194,
202.98484409, 203.1121547 , 203.15732255, 203.16332423,
203.21269128, 203.2645747 , 203.21610842])
然後將此填色字典傳給 plot() 函式的 fill_between 參數即可 :
>>> kb.plot(volume=True, fill_between=fill_between)
結果如下 :
沒有留言 :
張貼留言