iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Software Development

30 天打造專屬盯盤機器人:資料爬取、策略指標到 Telegram/LINE 推播系列 第 9 篇

Day 09:視覺化升級 — 讓 Telegram 機器人直接傳送 K 線圖到手機!

  • 分享至 

  • xImage
  •  

今天是第九天!前面八天我們已經在不知不覺中做了好多東西耶,昨天我們已經能收到文字警報了,但看股票如果能「看圖」,視覺上會直觀非常多。
Telegram API 不只支援傳送純文字,還支援傳送圖片。今天我們就來學習如何用 Python 把本地端產生的 kline.png 圖片,自動打包上傳到 Telegram!

步驟一:解釋程式碼邏輯

  • 發送文字(Day 07/08):使用的是 sendMessage 介面,資料是純文字。
  • 發送圖片(Day 09):使用的是 sendPhoto 介面,資料需要用「檔案表單(multipart/form-data)」的方式打包。

如果用 Python 內建的 urllib 來寫 sendPhoto 檔案上傳,需要手動寫非常複雜的表單標頭(Header)編碼。
為了維持程式碼的簡潔與新手友好的原則,今天我們要引入一個 Python 界的熱門第三方套件——requests!
還是老樣子,記得在終端機前面檢查有沒有(venv)。
步驟二:安裝第三方套件 requests
requests 是 Python 最經典的網路請求工具,處理檔案上傳只需要短短幾行程式碼。
接下來,請在 VS Code 終端機輸入以下命令安裝:

pip install requests

會長下面這樣!
https://ithelp.ithome.com.tw/upload/images/20260923/20184215V9f4C8tahz.png

步驟三:撰寫「繪圖與多媒體發送」完整程式碼
今天我們會用到 Telegram 的 sendPhoto API,用來發送 local 儲存好的圖片檔案。
請打開 main.py,照著下面的完整程式碼寫(記得把 Token 和 Chat ID 換成你自己的喔!):

import pandas as pd
import yfinance as yf
import mplfinance as mpf
import urllib.request
import urllib.parse
import json

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

# 2. 抓取股票資料
print(" 正在下載股票資料並繪製 K 線圖...")
df = yf.download("2330.TW", period="6mo")

# 防呆檢查
if df.empty:
    print(" 錯誤:無法下載股票資料,請檢查網路或股票代碼!")
    exit()

# 清理 yfinance 多層索引
if isinstance(df.columns, pd.MultiIndex):
    df.columns = df.columns.get_level_values(0)

# 計算 5MA 與 20MA
df['MA5'] = df['Close'].rolling(window=5).mean()
df['MA20'] = df['Close'].rolling(window=20).mean()

# 取最近 60 天的資料來畫圖
df_plot = df.tail(60).copy()

# 3. 設定 K 線圖樣式並存檔
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="2330.TW 60-Day K-Line Chart",
    savefig='stock_chart.png'
)
print(" K 線圖已順利繪製並存檔為 stock_chart.png!")

# 4. 判斷最新一天訊號作為圖片文字說明 (Caption)
latest = df.iloc[-1]
prev = df.iloc[-2]

caption_text = f" 【2330 台積電 最新盤後分析】\n"
caption_text += f" 日期:{df.index[-1].strftime('%Y-%m-%d')}\n"
caption_text += f" 收盤價:{latest['Close']:.2f}\n"

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

# 5. 發送圖片與說明文字給 Telegram (修正編碼問題的版本)
print(" 正在發送圖片到 Telegram...")
url = f"https://api.telegram.org/bot{TOKEN}/sendPhoto"

boundary = '----WebKitFormBoundary7MA4YWxkTrZu0gW'

# 讀取圖片檔案
with open('stock_chart.png', 'rb') as f:
    photo_data = f.read()

# 嚴格將所有欄位轉為 bytes 並使用 utf-8 編碼
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="stock_chart.png"\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:
        print(" 成功發送 K 線圖與分析訊息到 Telegram!")
except Exception as e:
    print(f" 發送失敗,錯誤訊息:{e}")

步驟四:執行程式與成果確認

python main.py

最後長這樣!
https://ithelp.ithome.com.tw/upload/images/20260923/201842157MSyAGCF1a.jpg
小結一下:
今天我們不僅學會了用 mplfinance 畫出專業的台股 K 線圖,還打通了發送圖片與多媒體訊息到 Telegram 的管道!
現在我們的機器人已經有模有樣了,但每次都要自己手動按 python main.py 還是有點麻煩。
明天就是第十天的最後總結與升級預告!我們要把這整套工具佈署成自動化腳本,讓它每天台股開盤/收盤時自動發送最新盤後圖表與訊號到你手機,真正實現「打造個人專屬台股自動看盤小幫手」!


上一篇
Day 08:功能大合體 — 將黃金交叉看盤訊號自動推送到 Telegram 手機!
下一篇
Day 10 : 打造【全自動多股追蹤 Telegram Bot】
系列文
30 天打造專屬盯盤機器人:資料爬取、策略指標到 Telegram/LINE 推播 共 11 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言