iT邦幫忙

2026 iThome 鐵人賽

DAY 10
0

今天是第十天!這意味著前面九天 Telegram 股市分析 Bot 已經完成了核心基礎設施(資料抓取、技術指標計算、K 線繪圖、多型態 Telegram 訊息發送)。今天我們要為機器人進行「功能擴充與排程自動化」,讓它成為真正能每天幫你自動盯盤、發送報告的機器人!
今天要做兩大升級,所以在升級前還是要確認終端機前面有沒有(venv)。

寫到這裡,可能會有人發現,欸?怎麼都只有台積電(2330),那這個小機器人也太爛了吧!要看其他企業的都不行,所以今天第一部分升級就是,我們要讓他可以同時看其他企業的,並不是單一。下面是我們今天要升級的兩大部分。

  • 支援自訂自選股清單(多檔股票巡檢):不只看 2330 台積電,還能一次分析多檔股票(例如:2330, 2317, 2454, 0050)。
  • 加入定時自動執行(Windows排程 / Cron):設定好時間(例如每日盤後 14:00),電腦會自動跑腳本發訊息,完全不需要手動按 python main.py!

步驟一:升級腳本(支援多股巡檢與優化 Telegram 訊息格式)
既然要寫多股版本,那我們的程式碼又要再做修改了。下面是這次的程式碼!
記得一定要換成自己的 Chat ID 和 TOKEN!

import os
import pandas as pd
import yfinance as yf
import mplfinance as mpf
import urllib.request
import time

# 1. 通訊金鑰與設定
TOKEN = "你的_BOT_TOKEN"
CHAT_ID = "你的_CHAT_ID"

# 想要追蹤的股票清單 (可自行增加或修改)
STOCK_LIST = [
    {"symbol": "2330.TW", "name": "台積電"},
    {"symbol": "2317.TW", "name": "鴻海"},
    {"symbol": "2454.TW", "name": "聯發科"},
    {"symbol": "0050.TW", "name": "元大台灣50"}
]

# 發送圖片到 Telegram 的函式
def send_telegram_photo(token, chat_id, photo_path, caption_text):
    url = f"https://api.telegram.org/bot{token}/sendPhoto"
    boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'

    if not os.path.exists(photo_path):
        print(f" 找不到圖片檔案: {photo_path}")
        return False

    with open(photo_path, 'rb') as f:
        photo_data = f.read()

    parts = [
        f'--{boundary}\r\nContent-Disposition: form-data; name="chat_id"\r\n\r\n{chat_id}\r\n'.encode('utf-8'),
        f'--{boundary}\r\nContent-Disposition: form-data; name="caption"\r\n\r\n{caption_text}\r\n'.encode('utf-8'),
        f'--{boundary}\r\nContent-Disposition: form-data; name="photo"; filename="{os.path.basename(photo_path)}"\r\nContent-Type: image/png\r\n\r\n'.encode('utf-8') + photo_data + b'\r\n',
        f'--{boundary}--\r\n'.encode('utf-8')
    ]

    payload = b''.join(parts)
    headers = {'Content-Type': f'multipart/form-data; boundary={boundary}'}

    try:
        req = urllib.request.Request(url, data=payload, headers=headers)
        with urllib.request.urlopen(req) as response:
            return True
    except Exception as e:
        print(f" Telegram 發送失敗:{e}")
        return False

# 分析單檔股票並繪圖發送
def process_stock(symbol, name):
    print(f"\n 正在分析:{name} ({symbol})...")
    
    # 抓取 6 個月資料
    df = yf.download(symbol, period="6mo", progress=False)

    if df.empty:
        print(f" 無法取得 {symbol} 資料,略過。")
        return

    # 清理多層索引
    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()

    # 取最近 60 天畫圖
    df_plot = df.tail(60).copy()
    img_filename = f"{symbol.replace('.', '_')}_chart.png"

    ap = [
        mpf.make_addplot(df_plot['MA5'], color='orange', width=1.5),
        mpf.make_addplot(df_plot['MA20'], color='blue', width=1.5)
    ]

    mpf.plot(
        df_plot,
        type='candle',
        volume=True,
        addplot=ap,
        title=f"{name} ({symbol}) 60-Day K-Line",
        savefig=img_filename
    )

    # 判斷交叉訊號
    latest = df.iloc[-1]
    prev = df.iloc[-2]

    caption = f" 【{name} ({symbol}) 盤後速報】\n"
    caption += f" 日期:{df.index[-1].strftime('%Y-%m-%d')}\n"
    caption += f" 收盤價:{latest['Close']:.2f}\n"

    if prev['MA5'] <= prev['MA20'] and latest['MA5'] > latest['MA20']:
        caption += " 訊號:【黃金交叉】5MA 向上突破 20MA,多頭轉強!"
    elif prev['MA5'] >= prev['MA20'] and latest['MA5'] < latest['MA20']:
        caption += " 訊號:【死亡交叉】5MA 向下跌破 20MA,注意風險!"
    else:
        caption += "橫盤整理中,尚未出現重大交叉訊號。"

    # 發送訊息
    success = send_telegram_photo(TOKEN, CHAT_ID, img_filename, caption)
    if success:
        print(f" {name} 報告已成功發送至 Telegram!")
    
    # 刪除暫存圖檔
    if os.path.exists(img_filename):
        os.remove(img_filename)

# 主流程
if __name__ == "__main__":
    print(" 開始執行全自動股市盤後掃描...")
    for item in STOCK_LIST:
        process_stock(item["symbol"], item["name"])
        time.sleep(1) # 避開 API 請求過快
    print("\n 所有股票巡檢完畢!")

步驟二:設定 Windows 自動排程(每天台股盤後自動執行)
如果你跟我一樣是Windows,跟著我就可以完成設定喔!

  1. 鍵盤按下 Win + R,輸入 taskschd.msc 並按 Enter 打開「工作排程器」。
  2. 點擊右側的 「建立基本工作...」 (Create Basic Task)。
  3. 名稱 輸入:Stock Bot Daily Scan,點擊「下一步」。
  4. 觸發器 選擇:每天,點擊「下一步」。
  5. 時間 設定為:每天下午 14:30(台股 13:30 收盤後資料更新完畢的時間)。
  6. 動作選擇:啟動程式,點擊「下一步」。
  7. 設定詳細資料:
    程式或指令碼:填入你虛擬環境中的 Python 路徑(例如:C:\Users\nitas\OneDrive\桌面\stock-bot\venv\Scripts\python.exe)
  8. 新增引數(選填):輸入 main.py
  9. 開始於(選填):填入專案資料夾完整路徑(例如:C:\Users\nitas\OneDrive\桌面\stock-bot)
    點擊「完成」即可!
    步驟三:執行與結果測試
    完成上述之後,在終端機內輸入:
python main.py

大概會長下面這樣~
https://ithelp.ithome.com.tw/upload/images/20260924/20184215g8MjVP2BFJ.jpg
小結一下,今天我們直接把這個台股 Telegram Bot 的戰力拉滿!不僅順利搞定了字元編碼(ASCII Error)的小麻煩,還把原本只能看單一股票的腳本,一口氣升級成「多股自動巡檢系統」!
現在我們的機器人已經能夠:
多股巡檢:一次掃描台積電、鴻海、聯發科、0050 等自選股清單。
自動圖表與訊號:自動計算 5MA/20MA 均線,抓出黃金交叉/死亡交叉,並產出漂亮的 60 天 K 線圖。
無縫發送:直接推播圖片加中文分析到 Telegram 手機端。
全自動定時執行:掛上排程器後,每天盤後自動幫你盯盤發報告,真正解放雙手!


上一篇
Day 09:視覺化升級 — 讓 Telegram 機器人直接傳送 K 線圖到手機!
下一篇
Day 11:升級雙重技術指標(RSI + MACD)與指標背離提醒
系列文
30 天打造專屬盯盤機器人:資料爬取、策略指標到 Telegram/LINE 推播 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言