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,91 @@
#!/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 ema(values: list[float], period: int) -> list[float]:
if not values:
return []
k = 2 / (period + 1)
out = [values[0]]
for v in values[1:]:
out.append(v * k + out[-1] * (1 - k))
return out
def macd(closes: list[float]) -> tuple[list[float], list[float], list[float]]:
ema12 = ema(closes, 12)
ema26 = ema(closes, 26)
dif = [a - b for a, b in zip(ema12, ema26)]
dea = ema(dif, 9)
hist = [d - s for d, s in zip(dif, dea)]
return dif, dea, hist
def main() -> None:
symbol = sys.argv[1] if len(sys.argv) > 1 else "00922.TW"
closes = fetch_closes(symbol)
if len(closes) < 35:
print(f"{symbol} 資料不足,無法判斷 MACD至少 35 筆,當前 {len(closes)}")
return
dif, dea, hist = macd(closes)
d0, d1 = dif[-1], dif[-2]
s0, s1 = dea[-1], dea[-2]
h0, h1 = hist[-1], hist[-2]
golden_cross = d1 <= s1 and d0 > s0
death_cross = d1 >= s1 and d0 < s0
low_zone = d0 < 0 and s0 < 0
if golden_cross and low_zone:
signal = "✅ 低位金叉:偏多訊號"
elif golden_cross:
signal = "✅ 金叉:短線轉強"
elif death_cross:
signal = "⚠️ 死叉:短線轉弱"
elif h0 > h1 and h0 > 0:
signal = "📈 多頭延續(柱體擴大)"
elif h0 < h1 and h0 < 0:
signal = "📉 空頭延續(柱體擴大)"
else:
signal = "👀 MACD 震盪中,先觀察"
print(f"{symbol} MACD 摘要")
print(f"- DIF{d0:.4f}")
print(f"- DEA{s0:.4f}")
print(f"- HIST{h0:.4f}")
print(f"- 訊號:{signal}")
if __name__ == "__main__":
main()