# stock-backend **Repository Path**: lventou/stock-backend ## Basic Information - **Project Name**: stock-backend - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: master - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 0 - **Created**: 2025-04-02 - **Last Updated**: 2025-12-29 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # Stock Analysis API 基于 FastAPI 的股票数据接口服务 ## 目录结构 stock-backend/ # 项目根目录 📦 data/ ← 数据获取与清洗脚本 📦 features/ ← 特征工程 📦 strategy/ ← 多个策略模块 📦 trade/ ← 下单与风控 📦 monitor/ ← 日志与告警 📦 configs/ ← 参数配置 main.py ← 项目入口,调度运行 ### 启动 安裝poetry ```shell (Invoke-WebRequest -Uri https://install.python-poetry.org -UseBasicParsing).Content | python - ``` ```shell poetry install ``` ### 要做 "sqlalchemy (>=2.0.41,<3.0.0)", "pydantic (>=2.11.5,<3.0.0)" 看下怎么处理orm和pydantic参数校验,以及接口类型需要处理,看怎么结合最优雅 swagger也要先配置好 明白了,你这个 router 文件现在比较长,混合了 接口定义、数据转换、业务逻辑、第三方库调用。优化思路就是 拆分职责(单一职责原则),让每一层都清晰、可复用,也更容易测试。下面我帮你梳理。 1️⃣ 按职责拆分 通常可以拆成三层: 层 文件/位置 内容 路由层(API Router) modules/akshare/router.py 仅负责接口声明、参数校验(FastAPI Query / Body / Path)、调用服务层 服务层(Service / 业务逻辑) modules/akshare/service.py 负责处理业务逻辑:调用 akshare 获取数据、处理 DataFrame、返回统一结构(dict / Pydantic model) 数据模型层(Schema / Response / Request) modules/akshare/schemas/ Pydantic 模型定义:请求参数(Request)、返回结果(Response)、统一返回结构(BaseResponse) 好处: 路由层清爽,只管接收参数和返回结果 服务层可单独测试,未来改数据源(比如用 tushare)不改路由 schema 层统一管理,和业务逻辑解耦 2️⃣ 如何抽方法 ① 公共工具方法 你现在有: def timestamp_to_date(timestamp: Optional[int]) -> str ✅ 建议抽到工具文件: modules/akshare/utils.py 方便多个接口复用。 ② Service 层封装 比如历史数据: async def get_history(symbol: str, period: str, start_date: int, end_date: Optional[int], adjust: str): start_date = timestamp_to_date(start_date) end_date = timestamp_to_date(end_date) df = ak.stock_zh_a_hist( symbol=symbol, period=period, adjust=adjust, start_date=start_date, end_date=end_date, timeout=10, ) data = df.to_dict(orient="records") return [ HistoryResponse( time=item["日期"], symbol=item["股票代码"], open=item["开盘"], close=item["收盘"], high=item["最高"], low=item["最低"], volume=item["成交量"], turnover=item["成交额"], amplitude=item["振幅"], changePercent=item["涨跌幅"], changeAmount=item["涨跌额"], turnoverRate=item["换手率"], ) for item in data ] 路由层就只调用: @router.get("/history", summary="历史数据", response_model=BaseResponse[List[HistoryResponse]]) async def history_trading(symbol: str = Query(...), ...): stock = await akshare_service.get_history(symbol, period, start_date, end_date, adjust) return BaseResponse.success(stock) ③ Realtime / Quote 也一样 realtime_trading → service.get_realtime(symbol) quote_trading → service.get_quote(symbol) 路由层不要管 DataFrame 的转换、时间戳转换等细节。 3️⃣ utils.py 可以放什么 时间转换:timestamp_to_date DataFrame 转 Pydantic Model 的通用函数 字段重命名 / 清理函数 4️⃣ schema 层整理 modules/akshare/schemas/ ├── request.py # 接口入参的 Pydantic model(如果有复杂对象) ├── response.py # 接口返回对象 HistoryResponse / RealtimeResponse / QuoteResponse 保持 纯数据结构,不要放业务逻辑 路由层只用来声明 response_model=BaseResponse[List[HistoryResponse]] 5️⃣ 路由层可以更简洁 优化前: 长达 200+ 行 有数据处理、打印、DataFrame 转 dict、字段映射 优化后: @router.get("/history", response_model=BaseResponse[List[HistoryResponse]]) async def history_trading(...): stock = await akshare_service.get_history(...) return BaseResponse.success(stock) ✅ 变成几行就够了 6️⃣ 其他优化点 复用字段映射 Quote 接口里你现在循环再转 dict,可以做一个 映射表,直接用循环生成对象。 避免重复写 30+ 行 temp_dict.get(...)。 统一异常处理 akshare 可能抛异常,service 层统一捕获,并返回 BaseResponse.error(...) 超时 / 重试机制 akshare 网络请求可以加 timeout 和简单重试,避免接口卡死。 日志 打印不要用 print,用 logging 模块,更专业。 ✅ 总结 文件结构优化示例 modules/akshare/ ├── __init__.py ├── router.py # 只管接口、参数、调用 service ├── service.py # 业务逻辑,DataFrame -> Response ├── utils.py # 工具函数 └── schemas/ ├── __init__.py ├── request.py └── response.py 这样路由文件可以从 200+ 行缩到 30~40 行,逻辑更清晰。 如果你需要,我可以帮你 把你的 router 代码改造成优化后的版本,直接拆好 service + utils + schema。 你希望我帮你改吗?