今天是第十五天!前幾天我們完成了一連串的大工程:從第九天繪製精美 K 線圖、第十一天計算 RSI/MACD 技術指標、第十二天加入籌碼量能監控、第十三天實現 Telegram /stock 即時互動點播,到昨天完成漂亮的專案模組化重構!
但現在我們的機器人還有一個小小的遺憾:要嘛是你手動傳指令 /stock 它才動,要嘛是你得親自跑去電腦前執行程式。真正的「全自動看盤小幫手」,應該要能在每天台股盤後(例如下午 2:00),自己時間一到就自動起床、掃描自選股清單,並把最新的分析報告推送到你的手機!
今天我們的目標,就是在模組化後的專案結構中,導入 Python 強大的排程套件 APScheduler,打造出真正的「全自動定時推播服務」!
步驟一:先釐清邏輯
自動排程的邏輯非常簡單直覺:
pip install apscheduler
步驟三:改寫實作程式碼
我們只需要更新 config.py、在 bot.py 加入自動掃描函式,並在 main.py 把排程器啟動起來即可!
1. config.py(加入 CHATID 與設定時間)
# config.py
# 1. Telegram 設定
TOKEN = "你的_BOT_TOKEN"
CHAT_ID = "你的_CHAT_ID"
# 2. 排程時間設定 (每天下午 14:00 觸發)
SCHEDULE_HOUR = 14
SCHEDULE_MINUTE = 0
# 3. 預設自選股清單
DEFAULT_STOCKS = [
{"symbol": "2330.TW", "name": "台積電"},
{"symbol": "2317.TW", "name": "鴻海"},
{"symbol": "2454.TW", "name": "聯發科"},
{"symbol": "0050.TW", "name": "元大台灣50"}
]
2. bot.py(新增定時全自動巡檢函式)
在原本的 bot.py 底部,加入主動推播的 scheduled_job 處理邏輯:
# bot.py (請在原本檔案內容下方新增以下程式碼)
import time
from config import CHAT_ID, DEFAULT_STOCKS
# 排程自動觸發的巡檢任務
async def scheduled_job(context: ContextTypes.DEFAULT_TYPE):
print("[INFO] 觸發定時排程,開始執行全自動盤後巡檢...")
for item in DEFAULT_STOCKS:
raw_symbol = item["symbol"]
stock_name = item["name"]
# 1. 抓取資料
symbol, df = get_stock_data(raw_symbol)
if df is None:
print(f"[WARNING] 找不到 {stock_name} ({raw_symbol}) 資料,略過。")
continue
# 2. 畫圖與產生文字
img_path = create_stock_chart(symbol, df)
caption_text = f"【{stock_name} 盤後自動巡檢報告】\n" + generate_report_text(symbol, df)
# 3. 主動發送至 Telegram 頻道/個人對話框
try:
with open(img_path, 'rb') as photo:
await context.bot.send_photo(chat_id=CHAT_ID, photo=photo, caption=caption_text)
print(f"[SUCCESS] {stock_name} 盤後報告已發送!")
except Exception as e:
print(f"[ERROR] 發送 {stock_name} 失敗: {e}")
# 4. 清理暫存檔
if os.path.exists(img_path):
os.remove(img_path)
time.sleep(1)
print("[FINISH] 本次定時巡檢任務完成!")
3. main.py
# main.py
from telegram.ext import ApplicationBuilder
from apscheduler.schedulers.asyncio import AsyncIOScheduler
from apscheduler.triggers.cron import CronTrigger
from config import TOKEN, SCHEDULE_HOUR, SCHEDULE_MINUTE
from bot import setup_handlers, scheduled_job
if __name__ == "__main__":
print("[START] 機器人與自動排程系統啟動中...")
# 1. 初始化 Telegram Bot Application
app = ApplicationBuilder().token(TOKEN).build()
# 2. 註冊指令處理器 (/start, /stock)
setup_handlers(app)
# 3. 初始化並設定 APScheduler 自動排程
scheduler = AsyncIOScheduler()
# 設定每週一至週五 下午 14:00 自動執行 scheduled_job
scheduler.add_job(
scheduled_job,
trigger=CronTrigger(day_of_week="mon-fri", hour=SCHEDULE_HOUR, minute=SCHEDULE_MINUTE),
args=[app]
)
scheduler.start()
print(f"[INFO] 排程設定完成:每週一至週五 {SCHEDULE_HOUR:02d}:{SCHEDULE_MINUTE:02d} 自動推播。")
# 4. 開始持續監聽
app.run_polling()
解釋一下程式碼吧!
主動推播的 context.bot.send_photo():
先前互動點播使用的是 update.message.reply_photo(),那是「被動回覆」;而這次在排程任務中,我們改用 context.bot.send_photo(chat_id=CHAT_ID, ...),直接指定 CHAT_ID 進行「主動推播」!
CronTrigger(精準時間觸發):
我們使用 CronTrigger(day_of_week="mon-fri", hour=14, minute=0),這代表只在「週一到週五的 14:00」觸發,自動避開週末休市的時間,非常智慧又省資源!
步驟四:執行程式
在終端機輸入:
pythom main.py
最後會長下面這樣!