今天是第十八天!昨天我們幫機器人注入了「三大法人籌碼面」數據,讓我們的看盤報告具備了技術面與籌碼面的雙重判斷!
但是,不論技術線圖畫得再好看、法人買得多熱烈,「企業有沒有賺錢」 永遠是股價最長遠的基石!在台股市場,每個月 1~10 號都是極其關鍵的「營收公佈期」。當一家公司的月營收創下歷史新高,或是年增率(YoY)大幅暴增時,往往就是股價噴發的起漲點!
今天我們的目標,就是在我們的專案架構中,導入「上市櫃個股月營收數據(MoM 月增率 / YoY 年增率)」抓取與診斷邏輯,打造出具備「基本面營收爆發警示」的全方位 Telegram 看盤小幫手!
步驟一:先釐清邏輯
營收診斷與警報的運作邏輯非常清晰直覺:
接下來,知道邏輯後,我們就可以來寫程式碼了!
步驟二:完整實作程式碼
我們同樣繼續維護我們優雅的模組化架構,要改的是 fetcher.py 和 bot.py!
import pandas as pd
import pandas_ta as ta
import yfinance as yf
def get_stock_data(symbol):
formatted_symbol = symbol.strip().upper()
if not formatted_symbol.endswith('.TW') and not formatted_symbol.endswith('.TWO'):
formatted_symbol += '.TW'
print(f"[INFO] 正在抓取數據、籌碼與基本面營收: {formatted_symbol}...")
# 1. 抓取股價歷史資料
ticker = yf.Ticker(formatted_symbol)
df = ticker.history(period="6mo")
if df.empty and formatted_symbol.endswith('.TW'):
alt_symbol = formatted_symbol.replace('.TW', '.TWO')
ticker = yf.Ticker(alt_symbol)
df = ticker.history(period="6mo")
if not df.empty:
formatted_symbol = alt_symbol
if df.empty:
return None, None, None, None
if isinstance(df.columns, pd.MultiIndex):
df.columns = df.columns.get_level_values(0)
# 技術指標計算
df['MA5'] = df['Close'].rolling(window=5).mean()
df['MA20'] = df['Close'].rolling(window=20).mean()
df['RSI'] = df.ta.rsi(length=14)
macd_df = df.ta.macd(fast=12, slow=26, signal=9)
df['MACD'] = macd_df['MACD_12_26_9']
df['MACD_signal'] = macd_df['MACDs_12_26_9']
df['MACD_hist'] = macd_df['MACDh_12_26_9']
df['Vol_MA5'] = df['Volume'].rolling(window=5).mean()
# 2. 三大法人籌碼模擬數據
chip_data = {
"foreign": 1250,
"investment": 800,
"dealer": -150
}
chip_data["total"] = chip_data["foreign"] + chip_data["investment"] + chip_data["dealer"]
# 3. 最新月營收基本面數據 (單位:千元)
# 實際運作時可連接 FinMind API 或 MOPS 數據
revenue_data = {
"month": "2026-09",
"revenue": 75000000, # 本月營收 750 億
"mom": 8.5, # 月增率 MoM +8.5%
"yoy": 32.4 # 年增率 YoY +32.4%
}
return formatted_symbol, df, chip_data, revenue_data
def generate_report_text(symbol, df, chip_data=None, revenue_data=None):
latest = df.iloc[-1]
prev = df.iloc[-2]
rsi_val = latest['RSI']
latest_vol = latest['Volume']
vol_ma5_val = latest['Vol_MA5']
caption = f"【{symbol} 盤後三維度全方位分析報告】\n"
caption += f"日期:{df.index[-1].strftime('%Y-%m-%d')}\n"
caption += f"收盤價:{latest['Close']:.2f}\n"
caption += f"5MA: {latest['MA5']:.2f} | 20MA: {latest['MA20']:.2f}\n"
caption += f"RSI(14):{rsi_val:.1f}\n"
# 籌碼面區塊
if chip_data:
caption += f"-----------------------------------\n"
caption += f"【三大法人籌碼動向】(單位: 張)\n"
caption += f"外資:{chip_data['foreign']:+d} | 投信:{chip_data['investment']:+d}\n"
caption += f"法人合計:{chip_data['total']:+d}\n"
# 基本面營收區塊
if revenue_data:
caption += f"-----------------------------------\n"
caption += f"【最新月營收報告】({revenue_data['month']})\n"
caption += f"單月營收:{revenue_data['revenue'] / 100000:.2f} 億元\n"
caption += f"MoM (月增率):{revenue_data['mom']:+.1f}%\n"
caption += f"YoY (年增率):{revenue_data['yoy']:+.1f}%\n"
caption += f"-----------------------------------\n"
signals = []
# 基本面訊號判斷
if revenue_data:
if revenue_data['yoy'] >= 30:
signals.append("[基本面] 月營收年增率 (YoY) 突破 30%,營收強勁成長!")
elif revenue_data['yoy'] <= -15:
signals.append("[基本面] 月營收年增率 (YoY) 衰退超過 15%,留意基本面利空!")
# 籌碼面訊號判斷
if chip_data:
if chip_data['foreign'] > 0 and chip_data['investment'] > 0:
signals.append("[籌碼] 外資與投信同買,法人作多力道強勁!")
# 技術面與量能訊號
if prev['MA5'] <= prev['MA20'] and latest['MA5'] > latest['MA20']:
signals.append("[MA] 5MA 向上突破 20MA(黃金交叉)")
if latest_vol > vol_ma5_val * 1.5:
signals.append("[量能] 今日成交量爆發(高於 5 日均量 1.5 倍)!")
if not signals:
caption += "評語:技術面、籌碼面與基本面處於平穩狀態,建議持續觀察。"
else:
caption += "關鍵訊號彙整:\n" + "\n".join(signals)
return caption
解釋一下程式碼吧!
三維度整合(技術面 + 籌碼面 + 基本面):
報告從單一的 K 線圖,升級成「技術面 (MA/RSI/MACD/量能)」、「籌碼面 (三大法人)」與「基本面 (月營收 YoY/MoM)」的三合一報告。
營收單位換算與格式化:
原始營收金額通常很大,我們在輸出時除以 100,000 轉換成習慣閱讀的「億元」單位,搭配 {revenue_data['yoy']:+.1f}% 自動標示正負號,讓資訊更加清晰!
步驟三:執行與測試
在終端機輸入:
python main.py
最後會像這樣!
小結一下:
月營收 YoY 成長率是觀察長線趨勢最重要的指標之一,當看到「YoY > 30% 且 法人同買」時,通常代表公司有實質業績支撐!
今天我們成功將「月營收 YoY / MoM」納入機器人的診斷系統,達成「技術面 + 籌碼面 + 基本面」的全方位三維度分析!