feat: AI日报核心股追踪章节增加连续上榜股票(近3日+)
This commit is contained in:
@@ -90,6 +90,77 @@ async def active_core_stocks(days: int = Query(10, ge=1, le=30, description="交
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.get("/consecutive", summary="连续上榜的核心股")
|
||||
async def consecutive_core_stocks(min_days: int = Query(3, ge=2, le=10, description="最小连续天数")):
|
||||
from datetime import date as date_cls
|
||||
conn = get_connection()
|
||||
try:
|
||||
# 最近30个有数据的交易日
|
||||
rows = conn.execute(
|
||||
"SELECT DISTINCT trade_date FROM daily_core_stocks ORDER BY trade_date DESC LIMIT 30"
|
||||
).fetchall()
|
||||
all_dates = [r["trade_date"] for r in reversed(rows)]
|
||||
|
||||
if not all_dates:
|
||||
return JSONResponse({"stocks": []}, headers=_NO_CACHE_HEADERS)
|
||||
|
||||
# 查询所有上榜记录
|
||||
placeholders = ",".join("?" * len(all_dates))
|
||||
rows = conn.execute(
|
||||
f"""SELECT trade_date, stock_code, stock_name, f3, cover_count
|
||||
FROM daily_core_stocks
|
||||
WHERE trade_date IN ({placeholders})
|
||||
ORDER BY stock_code, trade_date""",
|
||||
all_dates,
|
||||
).fetchall()
|
||||
|
||||
# 按股票分组,记录上榜日期
|
||||
stock_dates: dict[str, dict] = {}
|
||||
for r in rows:
|
||||
code = r["stock_code"]
|
||||
s = stock_dates.setdefault(code, {
|
||||
"stockCode": code,
|
||||
"stockName": r["stock_name"],
|
||||
"dates": [],
|
||||
"dailyGains": {},
|
||||
})
|
||||
s["dates"].append(r["trade_date"])
|
||||
s["dailyGains"][r["trade_date"]] = r["f3"]
|
||||
|
||||
# 计算连续上榜天数(从最新交易日往回数)
|
||||
results = []
|
||||
for code, s in stock_dates.items():
|
||||
dates_list = sorted(s["dates"])
|
||||
consecutive = 0
|
||||
last_n = []
|
||||
for i in range(len(dates_list) - 1, -1, -1):
|
||||
if i == len(dates_list) - 1:
|
||||
consecutive = 1
|
||||
last_n.append(dates_list[i])
|
||||
else:
|
||||
prev_idx = all_dates.index(dates_list[i + 1]) if dates_list[i + 1] in all_dates else -1
|
||||
curr_idx = all_dates.index(dates_list[i]) if dates_list[i] in all_dates else -1
|
||||
if prev_idx - curr_idx <= 2:
|
||||
consecutive += 1
|
||||
last_n.append(dates_list[i])
|
||||
else:
|
||||
break
|
||||
|
||||
if consecutive >= min_days:
|
||||
results.append({
|
||||
"stockCode": code,
|
||||
"stockName": s["stockName"],
|
||||
"consecutiveDays": consecutive,
|
||||
"recentDates": last_n,
|
||||
"dailyGains": {d: s["dailyGains"].get(d) for d in last_n},
|
||||
})
|
||||
|
||||
results.sort(key=lambda x: -x["consecutiveDays"])
|
||||
return JSONResponse({"stocks": results}, headers=_NO_CACHE_HEADERS)
|
||||
finally:
|
||||
conn.close()
|
||||
|
||||
|
||||
@router.get("/history", summary="指定交易日核心股(含所属题材)")
|
||||
async def core_stock_history(date: str = Query(..., description="交易日 YYYY-MM-DD")):
|
||||
conn = get_connection()
|
||||
|
||||
Reference in New Issue
Block a user