feat: AI分析第三档——海外期货章节、报告分卡片渲染、红绿着色、期号;LLM改流式+分段生成绕开网关120s超时

This commit is contained in:
Sakurasan
2026-09-02 13:17:49 +08:00
parent 311b9f0d7e
commit 1d46ad7a08
8 changed files with 358 additions and 120 deletions
+67
View File
@@ -86,6 +86,73 @@ async def _fetch_flow_boards(client: httpx.AsyncClient, fs: str, po: int, pz: in
return boards
_GLOBAL_INDICES = "100.NDX,100.DJIA,100.SPX,100.HSI,100.N225,100.FTSE"
_FUT_MARKETS = ("m:8", "m:113", "m:142", "m:114", "m:115") # 中金所/上期所/上期能源/大商所/郑商所
async def fetch_global_markets() -> dict | None:
"""海外主要指数 + 国内期货主力合约;失败返回 None"""
try:
async with httpx.AsyncClient(timeout=_TIMEOUT, headers={"User-Agent": _UA}) as client:
overseas, futures = await asyncio.gather(
_fetch_overseas_indices(client),
_fetch_futures_main(client),
)
if not overseas and not futures:
return None
return {"overseas": overseas, "futures": futures}
except Exception:
return None
async def _fetch_overseas_indices(client: httpx.AsyncClient) -> list[dict]:
resp = await client.get(
"https://push2delay.eastmoney.com/api/qt/ulist.np/get",
params={"secids": _GLOBAL_INDICES, "fields": "f12,f14,f2,f3", "fltt": 2, "invt": 2},
)
resp.raise_for_status()
diff = (resp.json().get("data") or {}).get("diff") or []
return [
{"name": d.get("f14", ""), "price": d.get("f2"), "changePct": d.get("f3")}
for d in diff
]
async def _fetch_futures_main(client: httpx.AsyncClient) -> list[dict]:
"""国内期货主力合约(名称含"主连/主力合约"),按成交额降序取前12"""
import re
results: list[dict] = []
for fs in _FUT_MARKETS:
try:
resp = await client.get(
"https://push2delay.eastmoney.com/api/qt/clist/get",
params={"fid": "f6", "po": 1, "pz": 200, "pn": 1, "np": 1,
"fltt": 2, "invt": 2, "fs": fs, "fields": "f12,f14,f2,f3,f6"},
)
resp.raise_for_status()
diff = (resp.json().get("data") or {}).get("diff") or []
except Exception:
continue
for d in diff:
name = d.get("f14") or ""
if "主连" not in name and "主力合约" not in name:
continue
if "次主连" in name: # 次主力合约,排除
continue
amount = d.get("f6")
if not isinstance(amount, (int, float)):
continue
results.append({
"name": re.sub(r"(主连|主力合约)$", "", name),
"price": d.get("f2"),
"changePct": d.get("f3"),
"amountYi": round(amount / 1e8, 1),
})
results.sort(key=lambda x: -x["amountYi"])
return results[:12]
async def fetch_sector_fund_flow() -> dict | None:
"""板块主力资金流排行:行业净流入/净流出 TOP6 + 概念净流入 TOP6;失败返回 None"""
try: