windows-desktop: C端基线(Windows 本地实时分析器 + 采集器 bug 修复)

This commit is contained in:
lookt
2026-09-15 20:04:13 +08:00
commit 2c72de1dba
23 changed files with 2308 additions and 0 deletions
+83
View File
@@ -0,0 +1,83 @@
"""
龙虎榜采集器
主方案:AkShare stock_lhb_detail_daily_sina(已实测可用,含上榜原因)
备选:东财 datacenter 接口(报表名不确定,暂时注释备用)
"""
import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).parent.parent.parent))
import akshare as ak
import pandas as pd
from datetime import datetime, timedelta
from src.storage.db import upsert_df, upsert_log, get_last_fetch
def fetch_lhb_date(trade_date: str) -> pd.DataFrame:
"""
获取单日龙虎榜
trade_date: "YYYY-MM-DD""YYYYMMDD"
"""
# 统一为 YYYYMMDD 格式
ds = trade_date.replace("-", "")
try:
df = ak.stock_lhb_detail_daily_sina(date=ds)
except Exception as e:
print(f" [WARN] LHB Sina failed for {trade_date}: {e}")
return pd.DataFrame()
if df is None or df.empty:
return pd.DataFrame()
# Sina 返回列(实测):序号, 股票代码, 股票名称, 收盘价, 涨跌幅, 成交额, 成交额, 上榜原因
# 编码问题导致中文列名显示乱码,用位置索引映射
# 0=序号, 1=代码, 2=名称, 3=收盘, 4=涨跌幅, 5=成交额, 6=??? 7=上榜原因
df.columns = ["no", "ts_code", "name", "close", "pct_change", "amount", "amount2", "reason"]
df["trade_date"] = trade_date.replace("-", "")
# 格式化为 YYYY-MM-DD
df["trade_date"] = pd.to_datetime(df["trade_date"]).dt.strftime("%Y-%m-%d")
# 保留有用字段
keep = ["trade_date", "ts_code", "name", "close", "pct_change", "amount", "reason"]
df = df[[c for c in keep if c in df.columns]]
return df
def fetch_lhb_range(start_date: str, end_date: str = None) -> pd.DataFrame:
"""抓取日期区间的龙虎榜(逐日)"""
end_date = end_date or datetime.today().strftime("%Y-%m-%d")
all_days = []
cur = datetime.strptime(start_date.replace("-", ""), "%Y%m%d")
end = datetime.strptime(end_date.replace("-", ""), "%Y%m%d")
while cur <= end:
ds = cur.strftime("%Y-%m-%d")
df = fetch_lhb_date(ds)
if df is not None and not df.empty:
all_days.append(df)
cur += timedelta(days=1)
if all_days:
return pd.concat(all_days, ignore_index=True)
return pd.DataFrame()
def incremental_lhb(source: str = "lhb_daily") -> pd.DataFrame:
"""增量采集:只抓上次之后的新交易日"""
last = get_last_fetch(source)
start = last.get("last_date") or (datetime.today() - timedelta(days=7)).strftime("%Y-%m-%d")
end = datetime.today().strftime("%Y-%m-%d")
df = fetch_lhb_range(start, end)
if df is not None and not df.empty:
upsert_df(df, "lhb_daily")
upsert_log(source, param="", last_date=end)
return df
if __name__ == "__main__":
import fire
fire.Fire({
"date": lambda d: upsert_df(fetch_lhb_date(d), "lhb_daily"),
"range": lambda s, e=None: upsert_df(fetch_lhb_range(s, e), "lhb_daily"),
"incr": lambda: incremental_lhb(),
})