#!/usr/bin/env python3 # -*- coding: utf-8 -*- from __future__ import annotations import json import sys import urllib.parse import urllib.request def fetch_closes(symbol: str, range_: str = "6mo", interval: str = "1d") -> list[float]: base = f"https://query1.finance.yahoo.com/v8/finance/chart/{symbol}" params = {"range": range_, "interval": interval} url = f"{base}?{urllib.parse.urlencode(params)}" req = urllib.request.Request(url, headers={"User-Agent": "Mozilla/5.0"}) with urllib.request.urlopen(req, timeout=30) as resp: data = json.loads(resp.read().decode("utf-8", errors="replace")) result = data.get("chart", {}).get("result", []) if not result: return [] quote = result[0].get("indicators", {}).get("quote", []) if not quote: return [] closes = quote[0].get("close", []) return [float(x) for x in closes if x is not None] def sma(values: list[float], window: int) -> float: return sum(values[-window:]) / window def main() -> None: symbol = sys.argv[1] if len(sys.argv) > 1 else "00922.TW" closes = fetch_closes(symbol) if len(closes) < 60: print(f"{symbol} 資料不足:至少需要 60 筆日收盤,當前 {len(closes)}") return price = closes[-1] ma5 = sma(closes, 5) ma10 = sma(closes, 10) ma20 = sma(closes, 20) ma60 = sma(closes, 60) bias20 = ((price - ma20) / ma20) * 100 print(f"{symbol} 均線摘要") print(f"- 收盤:{price:.2f}") print(f"- MA5 :{ma5:.2f}") print(f"- MA10:{ma10:.2f}") print(f"- MA20:{ma20:.2f}") print(f"- MA60:{ma60:.2f}") print(f"- 20日乖離:{bias20:.2f}%") # 簡單判讀 trend = [] if price > ma20: trend.append("站上月線") else: trend.append("跌破月線") if ma20 > ma60: trend.append("中期偏多") else: trend.append("中期偏弱") if ma5 > ma20: trend.append("短線強於月線") else: trend.append("短線弱於月線") print(f"- 判讀:{'/'.join(trend)}") if __name__ == "__main__": main()