fix: deploy scripts/ files properly (correct directory)

This commit is contained in:
知微
2026-07-01 23:00:28 +08:00
parent b2822cec15
commit ec285669c4
13 changed files with 3537 additions and 51 deletions
+67 -31
View File
@@ -6,14 +6,39 @@
API: push2his.eastmoney.com 个股资金流日线
"""
import json, os, sys, time
import json, os, sys, time, urllib.request
from datetime import datetime
from urllib.request import urlopen
from urllib.request import urlopen, Request
from concurrent.futures import ThreadPoolExecutor, as_completed
from threading import Semaphore
DATA_DIR = "/home/hmo/web-dashboard/data"
DECISIONS_PATH = f"{DATA_DIR}/decisions.json"
CACHE_PATH = f"{DATA_DIR}/capital_flow_cache.json"
UA = "Mozilla/5.0"
# 限速器:最多5个并发,每请求后强制间隔0.3s
RATE_LIMIT = Semaphore(5)
MIN_INTERVAL = 0.3
_last_req = 0
def _rate_limited_request(url):
"""带速率限制的HTTP GET,用Semaphore控制并发数"""
global _last_req
with RATE_LIMIT:
elapsed = time.time() - _last_req
if elapsed < MIN_INTERVAL:
time.sleep(MIN_INTERVAL - elapsed)
proxy_handler = urllib.request.ProxyHandler({})
opener = urllib.request.build_opener(proxy_handler)
req = Request(url, headers={"User-Agent": UA, "Referer": "https://data.eastmoney.com/"})
try:
resp = opener.open(req, timeout=8)
_last_req = time.time()
return json.loads(resp.read().decode("utf-8"))
except Exception:
return None
# eastmoney secid: 1=上海 0=深圳
def secid(code):
code = str(code).strip()
@@ -22,30 +47,28 @@ def secid(code):
return f"0.{code}"
def fetch_flow(code, days=5):
"""拉取个股近N日资金流"""
"""拉取个股近N日资金流(带限速+代理绕过)"""
sid = secid(code)
url = f"http://push2his.eastmoney.com/api/qt/stock/fflow/daykline/get?secid={sid}&fields1=f1,f2,f3,f7&fields2=f51,f52,f53,f54,f55,f56,f57&lmt={days}"
try:
resp = urlopen(url, timeout=5)
data = json.loads(resp.read().decode("utf-8"))
klines = data.get("data", {}).get("klines", [])
if not klines:
return None
result = []
for k in klines:
p = k.split(",")
if len(p) >= 7:
result.append({
"date": p[0],
"main_net": float(p[1]), # 主力净流入(元)
"super_large": float(p[2]), # 超大单净流入(元)
"large": float(p[3]), # 大单净流入(元)
"medium": float(p[4]), # 中单净流入(元)
"small": float(p[5]), # 小单净流入(元)
})
return result
except Exception as e:
data = _rate_limited_request(url)
if not data:
return None
klines = data.get("data", {}).get("klines", [])
if not klines:
return None
result = []
for k in klines:
p = k.split(",")
if len(p) >= 7:
result.append({
"date": p[0],
"main_net": float(p[1]), # 主力净流入(元)
"super_large": float(p[2]), # 超大单净流入(元)
"large": float(p[3]), # 大单净流入(元)
"medium": float(p[4]), # 中单净流入(元)
"small": float(p[5]), # 小单净流入(元)
})
return result
def fetch_flow_intraday(code):
"""拉取当日分时资金流(用于盘中判断)"""
@@ -119,27 +142,40 @@ def main():
codes.add(c)
except:
pass
all_flows = {}
for code in sorted(codes):
# 并行抓取:ThreadPoolExecutor + 内置限速器(Semaphore 5 + 0.3s间隔)
code_list = sorted(codes)
if not code_list:
print("[capital_flow] 无代码需要采集")
return
def fetch_one(code):
flow = fetch_flow(code, days=5)
if flow:
analysis = analyze_flow(flow)
all_flows[code] = {
return (code, {
"updated_at": datetime.now().strftime("%Y-%m-%d %H:%M"),
"flow": flow,
"analysis": analysis,
}
time.sleep(0.3) # API限流
})
return (code, None)
with ThreadPoolExecutor(max_workers=5) as pool:
futures = {pool.submit(fetch_one, c): c for c in code_list}
for f in as_completed(futures):
code, result = f.result()
if result:
all_flows[code] = result
# 写缓存
cache = {
"updated_at": datetime.now().strftime("%Y-%m-%d %H:%M"),
"stocks": all_flows,
}
json.dump(cache, open(CACHE_PATH, "w"), indent=2, ensure_ascii=False)
print(f"[capital_flow] {len(all_flows)}只更新完成")
print(f"[capital_flow] {len(all_flows)}/{len(code_list)}只更新完成")
if __name__ == "__main__":
main()