04db423416
- 70 skills with code and documentation - Add .gitignore (ignore __pycache__, output/, temp/, venv/) - Clean up test intermediates and caches
111 lines
3.9 KiB
Python
111 lines
3.9 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Yahoo Finance数据源实现 - 修复编码问题
|
|
提供完整的股票数据查询功能
|
|
"""
|
|
|
|
import requests
|
|
import json
|
|
from datetime import datetime
|
|
import sys
|
|
|
|
# 设置标准输出编码
|
|
sys.stdout.reconfigure(encoding="utf-8")
|
|
|
|
|
|
def query_yahoo_finance_complete(stock_code: str) -> dict:
|
|
"""
|
|
完整的Yahoo Finance查询实现
|
|
支持价格、成交量、市值等完整数据
|
|
"""
|
|
# 标准化股票代码
|
|
if not "." in stock_code:
|
|
if len(stock_code) == 5:
|
|
stock_code = f"{stock_code}.HK"
|
|
elif len(stock_code) == 6:
|
|
if stock_code.startswith(("00", "30")):
|
|
stock_code = f"{stock_code}.SZ"
|
|
else:
|
|
stock_code = f"{stock_code}.SS"
|
|
|
|
try:
|
|
# 获取详细股票信息
|
|
quote_url = f"https://query2.finance.yahoo.com/v10/finance/quoteSummary/{stock_code}?modules=price,summaryDetail,defaultKeyStatistics"
|
|
|
|
headers = {
|
|
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36"
|
|
}
|
|
|
|
response = requests.get(quote_url, headers=headers, timeout=10)
|
|
|
|
if response.status_code != 200:
|
|
return None
|
|
|
|
data = response.json()
|
|
|
|
if "quoteSummary" not in data or "result" not in data["quoteSummary"]:
|
|
return None
|
|
|
|
result = data["quoteSummary"]["result"][0]
|
|
|
|
# 提取价格信息
|
|
price_data = result.get("price", {})
|
|
summary_data = result.get("summaryDetail", {})
|
|
key_stats = result.get("defaultKeyStatistics", {})
|
|
|
|
# 构建完整数据
|
|
stock_info = {
|
|
"source": "yahoo_finance",
|
|
"code": stock_code,
|
|
"name": price_data.get("shortName", ""),
|
|
"price": float(price_data.get("regularMarketPrice", {}).get("raw", 0)),
|
|
"previous_close": float(
|
|
price_data.get("regularMarketPreviousClose", {}).get("raw", 0)
|
|
),
|
|
"open": float(price_data.get("regularMarketOpen", {}).get("raw", 0)),
|
|
"high": float(price_data.get("regularMarketDayHigh", {}).get("raw", 0)),
|
|
"low": float(price_data.get("regularMarketDayLow", {}).get("raw", 0)),
|
|
"volume": int(price_data.get("regularMarketVolume", {}).get("raw", 0)),
|
|
"market_cap": price_data.get("marketCap", {}).get("raw"),
|
|
"pe_ratio": summary_data.get("trailingPE", {}).get("raw"),
|
|
"dividend_yield": summary_data.get("dividendYield", {}).get("raw"),
|
|
"eps": key_stats.get("earningsPerShare", {}).get("raw"),
|
|
"beta": key_stats.get("beta", {}).get("raw"),
|
|
"52_week_high": summary_data.get("fiftyTwoWeekHigh", {}).get("raw"),
|
|
"52_week_low": summary_data.get("fiftyTwoWeekLow", {}).get("raw"),
|
|
"currency": price_data.get("currency", "USD"),
|
|
"exchange": price_data.get("exchangeName", ""),
|
|
"timestamp": datetime.now().isoformat(),
|
|
"success": True,
|
|
}
|
|
|
|
# 过滤掉None值
|
|
for key, value in stock_info.items():
|
|
if value is None:
|
|
stock_info[key] = 0 if isinstance(value, (int, float)) else ""
|
|
|
|
return stock_info
|
|
|
|
except Exception as e:
|
|
print(f"Yahoo Finance query failed for {stock_code}: {e}")
|
|
return None
|
|
|
|
|
|
# 测试函数
|
|
if __name__ == "__main__":
|
|
test_codes = ["00700.HK", "09868.HK", "001309.SZ", "01088.HK"]
|
|
|
|
for code in test_codes:
|
|
print(f"\nTesting {code}...")
|
|
result = query_yahoo_finance_complete(code)
|
|
if result:
|
|
print(f"Success: {result['name']} - {result['price']} {result['currency']}")
|
|
print(f" Volume: {result['volume']:,}")
|
|
print(
|
|
f" Market Cap: {result['market_cap']:,}"
|
|
if result["market_cap"]
|
|
else " Market Cap: N/A"
|
|
)
|
|
else:
|
|
print(f"Failed")
|