From 7c794cb342c92a0edafb6e9c882d372452b47b95 Mon Sep 17 00:00:00 2001 From: cirry <812852553@qq.com> Date: Sun, 16 Aug 2026 00:47:13 +0800 Subject: [PATCH] =?UTF-8?q?=E7=9C=8B=E8=82=A1=E5=8A=9F=E8=83=BD=E6=9B=B4?= =?UTF-8?q?=E6=96=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- backend/app/api.py | 16 ++++++++++++++++ backend/app/config.py | 1 + backend/app/schemas.py | 29 +++++++++++++++++++++++++++++ backend_run.log | 3 +++ frontend/src/api/client.ts | 8 ++++++++ frontend/src/api/types.ts | 28 ++++++++++++++++++++++++++++ frontend/src/views/HomeView.vue | 6 +++++- 7 files changed, 90 insertions(+), 1 deletion(-) diff --git a/backend/app/api.py b/backend/app/api.py index c523bd3..fb1d58c 100644 --- a/backend/app/api.py +++ b/backend/app/api.py @@ -3,6 +3,7 @@ GET /api/health 健康检查 GET /api/candles/{sym} 取 K 线(支持 1d/1w/1M/1y 周期,日线为基底聚合) GET /api/stocks 全市场股票列表(基本信息 + 最新行情 + 缓存条数) + GET /api/market/overview 主页大盘总览(A 股/港美指数 + 两市市值成交统计) POST /api/backtest 跑回测,返回 K线+指标+买卖点+净值+绩效 POST /api/screener/run 智能选股:自然语言 -> 条件 -> 全市场筛选 POST /api/screener/sync 启动全市场数据同步(后台任务) @@ -28,6 +29,7 @@ from .backtest.strategies import build_strategy from .config import settings from .data import fetcher, repository from .data.aggregation import bars_per_year, resample_bars +from .data.market_overview import MarketOverviewError, fetch_overview from .data.symbols import plain_code from .db import get_session from .domain import Bar @@ -52,6 +54,7 @@ from .schemas import ( EventBacktestRequest, EventBacktestResponse, IndicatorOut, + MarketOverviewResponse, MetricsOut, PreferencesOut, PreferencesUpdate, @@ -319,6 +322,19 @@ async def stock_facets(session: AsyncSession = Depends(get_session)) -> StockFac return resp +@router.get("/market/overview", response_model=MarketOverviewResponse) +async def get_market_overview() -> MarketOverviewResponse: + """主页大盘总览:A 股 + 港美指数最近收盘(含迷你走势),沪深两市市值/成交统计。 + + 收盘口径(token 无实时权限),展示时标注交易日;部分来源失败不影响其余。 + """ + try: + data = await fetch_overview() + except MarketOverviewError as e: + raise HTTPException(status_code=503, detail=str(e)) from e + return MarketOverviewResponse(**data) + + @router.post("/backtest", response_model=BacktestResponse) async def backtest( req: BacktestRequest, diff --git a/backend/app/config.py b/backend/app/config.py index fcc04df..b5e0203 100644 --- a/backend/app/config.py +++ b/backend/app/config.py @@ -30,6 +30,7 @@ class Settings(BaseSettings): redis_url: str = "" stocks_cache_ttl: int = 300 # 股票列表缓存秒数(行情列允许最多滞后这么多秒) facets_cache_ttl: int = 3600 # 行业/地域筛选项缓存秒数(stock_basic 很少变) + market_overview_ttl: int = 300 # 主页大盘总览缓存秒数(收盘口径数据,无需更勤) # ---- LLM(智能选股的自然语言解析;DeepSeek,OpenAI 兼容协议,可换任意兼容网关)---- llm_base_url: str = "https://api.deepseek.com" diff --git a/backend/app/schemas.py b/backend/app/schemas.py index b241bf7..9e6ee1c 100644 --- a/backend/app/schemas.py +++ b/backend/app/schemas.py @@ -373,3 +373,32 @@ class TradesImportResponse(BaseModel): class TradesClearResponse(BaseModel): deleted: int + + +# ---------- 大盘总览(主页) ---------- +class IndexQuoteOut(BaseModel): + code: str # 000001.SH / HKTECH / DJI + name: str # 上证指数 / 恒生科技 / 道琼斯 + region: str # cn | hk | us(前端分组展示) + close: float | None = None + change: float | None = None + pct_chg: float | None = None + trade_date: date | None = None # 最近交易日(收盘口径) + spark: list[float] = [] # 近 N 日收盘(旧 -> 新),迷你走势用 + spark_dates: list[str] = [] # 与 spark 对齐的交易日(YYYYMMDD),hover 提示用 + + +class MarketStatsOut(BaseModel): + """沪深两市汇总(daily_info:沪 SH_A + 深 SZ_MARKET,亿元)。""" + trade_date: date | None = None + total_mv: float | None = None # 总市值(亿元) + float_mv: float | None = None # 流通市值(亿元) + amount: float | None = None # 两市成交额(亿元) + turnover: float | None = None # 换手率 %(沪市口径) + + +class MarketOverviewResponse(BaseModel): + updated_at: datetime + indexes: list[IndexQuoteOut] = [] + stats: MarketStatsOut | None = None + errors: list[str] = [] # 部分来源失败的说明(透明但不阻塞展示) diff --git a/backend_run.log b/backend_run.log index d4233a4..f8fae8e 100644 --- a/backend_run.log +++ b/backend_run.log @@ -691,3 +691,6 @@ INFO: 127.0.0.1:52455 - "GET /api/watchlist HTTP/1.1" 200 OK INFO: 127.0.0.1:52453 - "GET /api/trades?ts_code=000001.SZ HTTP/1.1" 200 OK INFO: 127.0.0.1:52454 - "GET /api/screener/preview/000001.SZ?limit=500&adjust=qfq&timeframe=1d HTTP/1.1" 200 OK INFO: 127.0.0.1:52465 - "GET /api/screener/preview/000001.SZ?limit=800&adjust=qfq&timeframe=1d&end=2024-07-24 HTTP/1.1" 200 OK +WARNING: WatchFiles detected changes in 'app\data\market_overview.py'. Reloading... + INFO: 127.0.0.1:53348 - "GET /api/auth/me HTTP/1.1" 200 OK +INFO: 127.0.0.1:53466 - "GET /api/preferences HTTP/1.1" 200 OK diff --git a/frontend/src/api/client.ts b/frontend/src/api/client.ts index 3b3a7ff..a7abb05 100644 --- a/frontend/src/api/client.ts +++ b/frontend/src/api/client.ts @@ -7,6 +7,7 @@ import type { EventBacktestResponse, LoginRequest, LoginResponse, + MarketOverview, PreviewResponse, ScreenerQueryItem, ScreenerRunRequest, @@ -160,6 +161,13 @@ export async function getStockPreview( return (await res.json()) as PreviewResponse; } +// ---------- 大盘总览(主页) ---------- +export async function getMarketOverview(): Promise { + const res = await apiFetch('/api/market/overview'); + if (!res.ok) throw new ApiError(await readError(res, '获取大盘行情失败'), res.status); + return (await res.json()) as MarketOverview; +} + export async function getStocks(params: { search?: string; market?: string; diff --git a/frontend/src/api/types.ts b/frontend/src/api/types.ts index d41ae76..ceaf395 100644 --- a/frontend/src/api/types.ts +++ b/frontend/src/api/types.ts @@ -347,3 +347,31 @@ export interface EventBacktestResponse { trades: EventTrade[]; total: number; } + +// ---------- 大盘总览(主页) ---------- +export interface IndexQuote { + code: string; // 000001.SH / HKTECH / DJI + name: string; // 上证指数 / 恒生科技 / 道琼斯 + region: 'cn' | 'hk' | 'us'; + close: number | null; + change: number | null; + pct_chg: number | null; + trade_date: string | null; // 最近交易日(ISO) + spark: number[]; // 近 N 日收盘(旧 -> 新) + spark_dates: string[]; // 与 spark 对齐的交易日(YYYYMMDD) +} + +export interface MarketStats { + trade_date: string | null; + total_mv: number | null; // 沪深总市值(亿元) + float_mv: number | null; // 沪深流通市值(亿元) + amount: number | null; // 两市成交额(亿元) + turnover: number | null; // 换手率 %(沪市口径) +} + +export interface MarketOverview { + updated_at: string; + indexes: IndexQuote[]; + stats: MarketStats | null; + errors: string[]; +} diff --git a/frontend/src/views/HomeView.vue b/frontend/src/views/HomeView.vue index f12bfd6..13484a9 100644 --- a/frontend/src/views/HomeView.vue +++ b/frontend/src/views/HomeView.vue @@ -1,7 +1,9 @@