這個程式碼:
-
安全地抓取股票資料
-
檢查型態,避免 Series/DataFrame 錯誤
-
計算移動平均與量能異常
-
畫出柱狀圖 + 折線 + 異常點
-
適合當作 量能分析模板
===========================================================
import yfinance as yf
import matplotlib.pyplot as plt
import pandas as pd
# 1️⃣ 選股票
ticker = "2330.TW"
data = yf.download(ticker, period="3mo", interval="1d", auto_adjust=True)
# 2️⃣ 型態檢查
print("資料型態檢查:")
print(f"data type: {type(data)}") # DataFrame
print(f"Volume type: {type(data['Volume'])}") # Series
print("欄位名稱:", data.columns)
print("Index 型態:", type(data.index))
# 3️⃣ 取成交量,確保是 Series
if isinstance(data['Volume'], pd.Series):
volume = data['Volume']
else:
volume = data['Volume'].squeeze() # 轉成 Series
# 4️⃣ 計算移動平均量能
volume_ma5 = volume.rolling(window=5).mean()
volume_ma20 = volume.rolling(window=20).mean()
# 5️⃣ 計算量能異常
volume_mean = volume.mean()
volume_std = volume.std()
high_volume_flag = volume > (volume_mean + 2*volume_std)
# 6️⃣ 畫圖(安全處理 index)
x_labels = [d.strftime('%Y-%m-%d') for d in data.index]
plt.figure(figsize=(12,6))
plt.bar(x_labels, volume.values, color='skyblue', label='成交量')
plt.plot(x_labels, volume_ma5.values, color='red', label='5日平均量')
plt.plot(x_labels, volume_ma20.values, color='green', label='20日平均量')
plt.scatter(
[x_labels[i] for i, flag in enumerate(high_volume_flag) if flag],
[volume.values[i] for i, flag in enumerate(high_volume_flag) if flag],
color='orange', label='量能異常', zorder=5
)
plt.xticks(rotation=45)
plt.legend()
plt.title(f'{ticker} 成交量與移動平均 (安全模板)')
plt.tight_layout()
plt.show()
======================================================
🔹 特點
-
型態檢查 → 避免 Series/DataFrame 不匹配錯誤
-
index 安全處理 →
strftime轉成字串,Matplotlib bar 不出錯 -
計算量能指標 → 5 日 / 20 日平均、異常量能點
-
一條龍流程 → 從抓資料到畫圖,小實驗可直接使用
=====================================================
程式碼 逐行拆解、解釋用途與作用:
-
引入套件
-
yfinance:抓取股票資料的 API -
matplotlib.pyplot:繪圖套件,用來畫折線圖、柱狀圖等 -
pandas:資料處理套件,用來操作 DataFrame、Series
-
-
ticker:股票代號,這裡是台積電(2330.TW) -
yf.download(...):-
period="3mo"→ 下載過去 3 個月資料 -
interval="1d"→ 每日資料 -
auto_adjust=True→ 自動調整股價(考慮除權息),方便分析
-
-
回傳結果:
data是一個 DataFrame,包含欄位:Open, High, Low, Close, Adj Close, Volume
-
檢查資料型態,避免之後計算或畫圖時發生 Series/DataFrame 錯誤
-
.columns→ 取得欄位名稱 -
.index→ 取得索引型態(通常是 DatetimeIndex)
-
data['Volume']可能是 Series 或 DataFrame(單欄時偶爾會有差異) -
isinstance判斷型態,確保volume最終是 Series,方便做.rolling()、算平均等操作
-
rolling(window=5)→ 計算 5 日移動平均 -
.mean()→ 計算平均 -
5 日平均量與 20 日平均量,用來觀察量能趨勢
-
volume_mean→ 成交量平均值 -
volume_std→ 成交量標準差 -
high_volume_flag→ 標記「量能異常」的布林值 (True/False)-
條件:成交量大於平均 + 2 倍標準差 → 異常放大量
-
-
將 DatetimeIndex 轉成 字串日期,方便 matplotlib 畫圖
-
避免直接用
DatetimeIndex某些版本 matplotlib 會出現錯誤
-
plt.figure(figsize=(12,6))→ 設定圖表大小 -
plt.bar(...)→ 畫成交量柱狀圖 -
plt.plot(...)→ 畫移動平均折線圖 -
.values→ 確保資料是 numpy array,避免 Series 與索引不對應
-
plt.scatter→ 畫量能異常點 -
[x_labels[i] for i, flag in enumerate(high_volume_flag) if flag]-
取布林值為 True 的日期
-
-
[volume.values[i] for i, flag in enumerate(high_volume_flag) if flag]-
取對應成交量
-
-
zorder=5→ 讓異常點疊在其他圖表之上
-
plt.xticks(rotation=45)→ X 軸文字旋轉,避免重疊 -
plt.legend()→ 顯示圖例 -
plt.title(...)→ 設定標題 -
plt.tight_layout()→ 調整邊距,避免標題或 X 軸文字被截掉 -
plt.show()→ 顯示圖表

沒有留言:
張貼留言