feat: 暴露fuyao SDK全部A股接口 + AI分析轮次上限提至30

This commit is contained in:
Sakurasan
2026-09-01 17:04:38 +08:00
parent 8b43b57bb2
commit 86429f43c2
3 changed files with 145 additions and 4 deletions
+119 -1
View File
@@ -7,6 +7,7 @@
上游错误转 HTTPException,密钥永不出现在响应中。
"""
from datetime import datetime
from fastapi import APIRouter, Query, HTTPException
from fastapi.responses import JSONResponse
from services import fuyao_client
@@ -80,6 +81,16 @@ async def v2_prices_historical(
return JSONResponse({"data": items, "count": len(items)}, headers=_NO_CACHE_HEADERS)
@router.get("/corporate-actions/adjustment-factors", summary="v2 复权因子事件流")
async def v2_adjustment_factors(
thscode: str = Query(..., description="标的 thscode,单只"),
from_date: str = Query(None, description="起始日 yyyy-MM-dd"),
to_date: str = Query(None, description="截止日 yyyy-MM-dd"),
):
data = await _guard(fuyao_client.corp_actions_adjustment_factors(thscode, from_date, to_date))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/calendar/trading-days", summary="v2 近一年交易日序列")
async def v2_calendar():
items = await _guard(fuyao_client.calendar_trading_days())
@@ -162,4 +173,111 @@ async def v2_index_prices_historical(
end: int = Query(..., description="结束时间,毫秒 Unix 时间戳"),
):
items = await _guard(fuyao_client.index_prices_historical(thscode, start, end))
return JSONResponse({"data": items, "count": len(items)}, headers=_NO_CACHE_HEADERS)
return JSONResponse({"data": items, "count": len(items)}, headers=_NO_CACHE_HEADERS)
# ---------------------------------------------------------------
# 特殊数据(涨停/跌停/炸板/连板/热股/龙虎/异动/飙升)
# ---------------------------------------------------------------
@router.get("/special/limit-up-pool", summary="v2 涨停池")
async def v2_limit_up_pool(
date: str = Query(None, description="日期 yyyy-MM-dd"),
page: int = Query(1, ge=1),
size: int = Query(50, ge=1, le=200),
sort_field: str = Query("seal_money", description="排序字段"),
sort_dir: str = Query("desc", description="asc/desc"),
):
date_ms = int(datetime.strptime(date, "%Y-%m-%d").timestamp() * 1000) if date else None
data = await _guard(fuyao_client.limit_up_pool(date_ms, page, size, sort_field, sort_dir))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/limit-down-pool", summary="v2 跌停池")
async def v2_limit_down_pool(
date: str = Query(None, description="日期 yyyy-MM-dd"),
page: int = Query(1, ge=1),
size: int = Query(50, ge=1, le=200),
sort_field: str = Query("last_limit_time"),
sort_dir: str = Query("desc"),
):
date_ms = int(datetime.strptime(date, "%Y-%m-%d").timestamp() * 1000) if date else None
data = await _guard(fuyao_client.limit_down_pool(date_ms, page, size, sort_field, sort_dir))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/limit-break-pool", summary="v2 炸板池")
async def v2_limit_break_pool(
date: str = Query(None, description="日期 yyyy-MM-dd"),
page: int = Query(1, ge=1),
size: int = Query(50, ge=1, le=200),
sort_field: str = Query("price_change_ratio_pct"),
sort_dir: str = Query("desc"),
):
date_ms = int(datetime.strptime(date, "%Y-%m-%d").timestamp() * 1000) if date else None
data = await _guard(fuyao_client.limit_break_pool(date_ms, page, size, sort_field, sort_dir))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/limit-up-ladder", summary="v2 连板梯队")
async def v2_limit_up_ladder():
data = await _guard(fuyao_client.limit_up_ladder())
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/hot-stock-list", summary="v2 热股榜")
async def v2_hot_stock_list(
period: str = Query("day", description="day/week/month"),
):
data = await _guard(fuyao_client.hot_stock_list(period))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/hot-stock-history", summary="v2 热股榜历史")
async def v2_hot_stock_history(date: str = Query(..., description="日期 yyyy-MM-dd")):
data = await _guard(fuyao_client.hot_stock_list_history(date))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/hot-stock-rank-trend", summary="v2 热股排名趋势")
async def v2_hot_stock_rank_trend(
thscode: str = Query(..., description="标的 thscode"),
start_date: str = Query(..., description="起始日期 yyyy-MM-dd"),
end_date: str = Query(..., description="结束日期 yyyy-MM-dd"),
):
data = await _guard(fuyao_client.hot_stock_rank_trend(thscode, start_date, end_date))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/dragon-tiger-list", summary="v2 龙虎榜")
async def v2_dragon_tiger_list(
board_type: str = Query("all", description="all/sh/sz"),
date: str = Query(None, description="日期 yyyy-MM-dd"),
):
data = await _guard(fuyao_client.dragon_tiger_list(board_type, date))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/anomaly-list", summary="v2 异动分析列表")
async def v2_anomaly_list(
tag_codes: str = Query(None, description="逗号分隔异动类型编码"),
):
codes = [c.strip() for c in tag_codes.split(",") if c.strip()] if tag_codes else None
data = await _guard(fuyao_client.anomaly_analysis_list(codes))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/anomaly-stock", summary="v2 个股异动明细")
async def v2_anomaly_stock(
thscodes: str = Query(..., description="逗号分隔 thscode,最多50只"),
):
data = await _guard(fuyao_client.anomaly_analysis_stock(thscodes))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)
@router.get("/special/skyrocket-list", summary="v2 飙升榜")
async def v2_skyrocket_list(
period: str = Query("day", description="day/week/month"),
):
data = await _guard(fuyao_client.skyrocket_list(period))
return JSONResponse({"data": data}, headers=_NO_CACHE_HEADERS)