# data **Repository Path**: quant-seminar/data ## Basic Information - **Project Name**: data - **Description**: No description available - **Primary Language**: Unknown - **License**: Not specified - **Default Branch**: dev - **Homepage**: None - **GVP Project**: No ## Statistics - **Stars**: 0 - **Forks**: 1 - **Created**: 2026-04-04 - **Last Updated**: 2026-05-24 ## Categories & Tags **Categories**: Uncategorized **Tags**: None ## README # data `data` 是 Seminar 项目的数据基座服务,负责日频股票数据的采集、存储和查询。服务对外提供 FastAPI 接口,底层使用 Tushare 获取数据,使用 DolphinDB 存储统一的因子长表,并支持通过结构化 JSON 动态构造派生因子。 线上部署地址: - 服务根地址:https://data.realhuhu.com/ ## 功能概览 - 定时更新:服务启动后注册每日 19:00 的数据更新任务。 - 手动更新:通过 `/stock/daily/update` 触发后台更新任务。 - 数据查询:通过 `/stock/daily/query` 查询指定股票、日期区间和因子。 - 派生因子:支持用 `Derivative` JSON 构造时序、截面、TA-Lib 和嵌套表达式。 - 因子预处理:支持调用 DolphinDB `factorBacktest::preprocess` 做去极值、标准化和中性化。 ## 服务结构 ```text data |-- main.py # FastAPI 入口和定时任务 |-- config.py # 环境变量配置 |-- core | |-- database/session.py # DolphinDB 连接和建表 | |-- routers/stock_daily/view.py # 日频数据 API | |-- routers/stock_daily/derive.py | |-- routers/stock_daily/preprocess.py | |-- workers/stock_daily/base.py # 数据更新 worker 框架 | |-- workers/stock_daily/volume_price.py | |-- workers/stock_daily/financial.py | |-- operators # 派生因子 DSL | `-- utils # Tushare、查询、限流、日志工具 `-- pyproject.toml ``` ## 数据模型 DolphinDB 中的日频股票数据统一存储为长表: | 字段 | 类型 | 说明 | | --- | --- | --- | | `time` | `TIMESTAMP` | 数据日期或公告日期 | | `code` | `SYMBOL` | 股票代码,例如 `000001.SZ` | | `factor` | `SYMBOL` | 因子名,例如 `close_hfq` | | `value` | `DOUBLE` | 因子值 | 查询时服务会根据 `time/code/factor` 过滤数据,并 pivot 成宽表用于派生因子计算。 ## 配置 服务会加载当前目录和上级目录中的 `.env`: ```env PROD=true DOLPHIN_HOST=dolphindb DOLPHIN_PORT=8848 DOLPHIN_USERNAME=admin DOLPHIN_PASSWORD=123456 DOLPHIN_DAILY_DB=... DOLPHIN_DAILY_STOCK_TB=... TUSHARE_TOKEN=... ``` 在主项目中可通过 `docker-compose.yml` 启动,默认映射: | 服务 | 容器端口 | 主机端口 | | --- | --- | --- | | `seminar-data` | `8000` | `8800` | ## 启动 本地开发: ```bash uv sync uvicorn main:app --host 127.0.0.1 --port 8000 --reload ``` 通过主项目 Docker Compose: ```bash docker compose up --build seminar-data ``` ## API ### GET `/stock/daily/metadata` 返回当前服务支持的股票代码、基础因子列表和因子构造说明。 响应结构: ```json { "code": 100, "msg": "OK", "data": { "codes": ["000001.SZ"], "factors": ["open", "close_hfq"], "instruct": "..." } } ``` 其中 `instruct` 是给调用方或大模型使用的派生因子构造规范。 ### POST `/stock/daily/query` 查询日频因子数据,返回 parquet 二进制文件。 请求体: ```json { "start_date": "2024-01-01", "end_date": "2024-12-31", "codes": ["000001.SZ", "600000.SH"], "factors": ["close_hfq", "vol", "CLOSE_MA20"], "derive_factors": {}, "preprocess": [] } ``` 字段说明: | 字段 | 说明 | | --- | --- | | `start_date` | 开始日期,格式 `YYYY-MM-DD` | | `end_date` | 结束日期,格式 `YYYY-MM-DD` | | `codes` | 股票代码列表 | | `factors` | 输出因子列表,可包含基础因子、内置派生因子和负号因子 | | `derive_factors` | 用户自定义派生因子,类型为 `dict[str, Derivative]` | | `preprocess` | 需要预处理的输出因子名列表 | 负号因子示例: ```json { "factors": ["-pe_ttm", "roe"] } ``` 服务会查询 `pe_ttm`,返回列名为 `-pe_ttm` 的取反结果。 ### POST `/stock/daily/update` 启动后台数据更新任务。服务通过进程内锁保证同一时间只有一个 worker 运行。 响应示例: ```json { "code": 100, "msg": "已启动后台更新任务" } ``` ## 派生因子 DSL `derive_factors` 使用结构化 JSON 描述计算图。核心模型如下: ```python Col = Union[str, "Derivative", int, float, bool] class Derivative(BaseModel): type: Literal["TS", "CS"] = "TS" op: str fields: dict params: dict = {} ``` `type` 决定分组方式: | 类型 | 分组 | 适用场景 | | --- | --- | --- | | `TS` | 按 `code` 分组 | 均线、滚动统计、滞后项、技术指标 | | `CS` | 按 `time` 分组 | 截面排名、z-score、残差、中性化 | `op` 格式为 `group.operation`,例如: - `unary.rolling` - `binary.div` - `multiary.add` - `talib.RSI` - `nullary.weekday` ### 示例:20 日均线 ```json { "MA20": { "type": "TS", "op": "unary.rolling", "fields": { "col": "close_hfq" }, "params": { "window": 20, "agg": "mean" } } } ``` ### 示例:5 日收益率 ```json { "RET_5D": { "type": "TS", "op": "unary.pct_change", "fields": { "col": "close_hfq" }, "params": { "periods": 5 } } } ``` ### 示例:截面百分位排名 ```json { "PB_RANK": { "type": "CS", "op": "unary.rank_pct", "fields": { "col": "pb" }, "params": {} } } ``` ### 示例:嵌套因子 先计算每日成交量截面排名,再对排名做 5 日均值: ```json { "VOL_RANK_MA5": { "type": "TS", "op": "unary.rolling", "fields": { "col": { "type": "CS", "op": "unary.rank_pct", "fields": { "col": "vol" }, "params": {} } }, "params": { "window": 5, "agg": "mean" } } } ``` 完整 DSL 说明以 `/stock/daily/metadata` 返回的 `instruct` 为准。 ## 数据更新流程 日频数据更新由 `DailyStockWorker` 统一调度: 1. 根据 DolphinDB 中已有数据获取每个 `code/factor` 的最近日期。 2. 每个 handler 根据最近日期增量调用 Tushare。 3. 将宽表结果转换为 `time/code/factor/value` 长表。 4. 分批写入 DolphinDB。 当前注册的数据来源包括: - `volume_price.py`:基础日线、前复权、后复权、每日指标。 - `financial.py`:资产负债表、利润表、现金流量表、财务指标,以及季度和 TTM 字段。 ## 注意事项 - 价格类技术指标优先使用后复权字段,例如 `close_hfq`、`open_hfq`、`high_hfq`、`low_hfq`。 - 利润表和现金流量表字段优先使用 TTM 字段,例如 `revenue_ttm`。 - 使用截面操作时必须显式声明 `"type": "CS"`。 - `Derivative` 只能出现在 `fields` 中,`params` 中应只放常量、列表或普通字典。 - `preprocess` 会额外依赖 `circ_mv`,用于市值和行业中性化。