Initial commit: stocks-query skill

Add scripts for querying Taiwan stock market data via Yahoo Finance:
- Individual stock quotes (price, OHLC, volume, bid/ask)
- Three major institutional investors (foreign, trust, dealer)
- Technical indicators (RSI14, ATR14, KD, Bollinger Bands, MACD, MA)
- ETF holdings analysis (top 10, industry distribution, asset allocation)
- TAIEX weighted index market summary

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-26 18:10:52 +08:00
commit 48eba04300
10 changed files with 1324 additions and 0 deletions

View File

@@ -0,0 +1,82 @@
#!/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()