restore and rebuild all stock query scripts

Recover 7 existing scripts from remote repo and rebuild 5 missing ones:
- twse-margin-trading.py (融資融券)
- twse-day-trading.py (當沖交易)
- twse-foreign-holdings.py (外資持股)
- yahoo-dividend-browserless.py (股利資訊)
- yahoo-broker-trading-browserless.py (主力券商進出)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-10 10:07:31 +08:00
commit 7d72aed984
16 changed files with 2153 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()