mirror of
https://ghfast.top/https://github.com/aeroxw/tick-stock-panel.git
synced 2026-09-12 16:44:15 +08:00
- CONTRIBUTING §4 新增「能力路由矩阵契约」: 注册表单一权威、usable 统一 门控、能力层中立原则、独立路由禁特殊值(same_as_daily 已下线)、 分时/depth5 边界注记 - custom-data-source: 除权因子接入示例移除 same_as_daily - plugin-development: manifest 字段表补 homepage 可选字段
337 lines
9.3 KiB
Markdown
337 lines
9.3 KiB
Markdown
# 自定义数据源接入
|
||
|
||
本项目默认使用 TickFlow。自定义数据源是一个可选扩展: 外部 HTTP 服务负责取数和整理, 本项目只把返回结果映射成内部标准字段, 然后复用现有存储、指标、enriched、策略和前端展示逻辑。
|
||
|
||
## 支持范围
|
||
|
||
当前自定义源支持五类数据:
|
||
|
||
| 数据集 | 配置名 | 说明 |
|
||
| --- | --- | --- |
|
||
| 日K | `daily` | 批量返回一组股票在指定区间内的日K |
|
||
| 除权因子 | `adj_factor` | 批量返回一组股票的复权因子 |
|
||
| 实时行情 | `realtime` | 返回全市场快照,用于盘中 enriched 增量计算 |
|
||
| 分钟K | `minute` | 返回 1m 分钟K(需映射出 symbol / datetime / OHLC / 量额) |
|
||
| 财务数据 | `financial` | 一个配置覆盖全部财务表,请求时把表名作为参数传给上游;字段由数据源决定,仅需映射出 symbol |
|
||
|
||
深度盘口(depth5)暂无数据集契约,仍由 TickFlow 提供。
|
||
|
||
## 配置位置
|
||
|
||
把 YAML 放到运行数据目录下:
|
||
|
||
```text
|
||
data/data_sources/*.yaml
|
||
```
|
||
|
||
Dev 模式下,默认位置是项目根目录的 `data/`;Docker 部署中,项目的 `data/` 会挂载为容器内的 `/app/data`。可通过 `DATA_DIR` 覆盖。
|
||
|
||
修改 YAML 后可在「设置 -> 数据源」点击「重新加载」,或调用:
|
||
|
||
```bash
|
||
curl -X POST http://127.0.0.1:3018/api/settings/data-sources/reload
|
||
```
|
||
|
||
## 最小 YAML
|
||
|
||
```yaml
|
||
name: mock_source
|
||
display_name: "Mock 自定义数据源"
|
||
auth:
|
||
type: none
|
||
|
||
datasets:
|
||
daily:
|
||
url: http://127.0.0.1:3021/daily
|
||
method: POST
|
||
batch: 100
|
||
rpm: 200
|
||
response_path: data
|
||
field_map:
|
||
ts_code: symbol
|
||
trade_date: date
|
||
open: open
|
||
high: high
|
||
low: low
|
||
close: close
|
||
vol: volume
|
||
amt: amount
|
||
transforms:
|
||
date: "parse_date(value, '%Y-%m-%d')"
|
||
|
||
adj_factor:
|
||
url: http://127.0.0.1:3021/adj_factor
|
||
method: POST
|
||
batch: 100
|
||
rpm: 200
|
||
response_path: data
|
||
field_map:
|
||
ts_code: symbol
|
||
trade_date: trade_date
|
||
factor: ex_factor
|
||
transforms:
|
||
trade_date: "parse_date(value, '%Y-%m-%d')"
|
||
|
||
realtime:
|
||
url: http://127.0.0.1:3021/realtime
|
||
method: GET
|
||
rpm: 60
|
||
response_path: data
|
||
field_map:
|
||
ts_code: symbol
|
||
name: name
|
||
last: last_price
|
||
pre_close: prev_close
|
||
open: open
|
||
high: high
|
||
low: low
|
||
vol: volume
|
||
amt: amount
|
||
pct: change_pct
|
||
amount_change: change_amount
|
||
amplitude: amplitude
|
||
turnover: turnover_rate
|
||
```
|
||
|
||
## 字段契约
|
||
|
||
### daily 必填
|
||
|
||
| 内部字段 | 含义 |
|
||
| --- | --- |
|
||
| `symbol` | 标准代码,如 `000001.SZ` |
|
||
| `date` | 交易日 |
|
||
| `open` / `high` / `low` / `close` | 不复权 OHLC |
|
||
| `volume` | 成交量 |
|
||
| `amount` | 成交额 |
|
||
|
||
### adj_factor 必填
|
||
|
||
| 内部字段 | 含义 |
|
||
| --- | --- |
|
||
| `symbol` | 标准代码 |
|
||
| `trade_date` | 除权日期 |
|
||
| `ex_factor` | 复权因子 |
|
||
|
||
### realtime 必填
|
||
|
||
| 内部字段 | 含义 |
|
||
| --- | --- |
|
||
| `symbol` | 标准代码 |
|
||
| `last_price` | 最新价 |
|
||
| `prev_close` | 昨收 |
|
||
| `open` / `high` / `low` | 当日 OHLC |
|
||
| `volume` | 成交量 |
|
||
|
||
建议实时接口额外提供 `amount`、`change_pct`、`change_amount`、`amplitude`、`turnover_rate`、`name`。缺失时部分字段会由 pipeline 回算,但精度取决于可用输入。
|
||
|
||
`change_pct`、`amplitude`、`turnover_rate` 统一使用小数制,例如 `0.0366` 表示 `3.66%`。百分制单位必须在 realtime 数据集上**显式声明**,不做数值猜测(数值无法区分两种单位:`0.05` 既可能是 0.05% 也可能是 5%):
|
||
|
||
```yaml
|
||
datasets:
|
||
realtime:
|
||
url: https://api.example.com/snapshot
|
||
pct_unit: percent # 接口返回 3.66 表示 3.66%;小数制源声明 decimal 或省略
|
||
```
|
||
|
||
处理规则:
|
||
|
||
| 声明 | 行为 |
|
||
| --- | --- |
|
||
| `pct_unit: percent` | `change_pct` / `amplitude` / `turnover_rate` 无条件 `/100` |
|
||
| `pct_unit: decimal` | 三列原样透传 |
|
||
| 未声明 | `change_pct` 按截面中位数归一(A 股涨跌停 30% 上限使两种单位物理可分);`amplitude` / `turnover_rate` **置 `None`** 交由 pipeline 按价格与股本口径重算,并记录 WARNING |
|
||
| 列已配置 `transforms` | 视为用户已接管该列单位,原样透传 |
|
||
|
||
## 请求约定
|
||
|
||
- `daily` / `adj_factor` 会按 `batch` 切分 symbols。
|
||
- POST 请求会发送 JSON body: `symbols`、`start_time`、`end_time`。
|
||
- GET 请求会发送 query 参数: `symbols=000001.SZ,600000.SH`。
|
||
- `realtime` 必须是全市场快照接口,不支持逐个 symbol 拉实时行情。
|
||
|
||
可通过这些字段改参数名:
|
||
|
||
```yaml
|
||
symbols_param: symbols
|
||
start_param: start_time
|
||
end_param: end_time
|
||
```
|
||
|
||
分钟数据源如果需要区分资产类型或周期,可继续配置:
|
||
|
||
```yaml
|
||
asset_type_param: asset_type
|
||
freq_param: period
|
||
```
|
||
|
||
配置后,分钟请求会分别传入 `stock` / `etf` / `index` 和 `1m`;留空时不向上游发送这两个参数,以兼容已有数据源。
|
||
|
||
### 请求超时
|
||
|
||
每个数据集可单独配置请求超时(秒),默认 30:
|
||
|
||
```yaml
|
||
timeout: 60
|
||
```
|
||
|
||
留空或省略时用默认 30 秒,可配置范围为大于 0 且不超过 300 秒;该值对数据同步与「试拉测试」均生效。在设置页编辑数据源时可在「超时」输入框修改(与 批量 / RPM / 响应路径 同行)。「试拉测试」直接使用当前表单内容,新建数据源或尚未保存的修改也可测试。
|
||
|
||
## 鉴权
|
||
|
||
支持三种简单鉴权:
|
||
|
||
```yaml
|
||
auth:
|
||
type: bearer
|
||
token_env: MY_DATA_TOKEN
|
||
```
|
||
|
||
```yaml
|
||
auth:
|
||
type: header
|
||
header: X-Token
|
||
token_env: MY_DATA_TOKEN
|
||
```
|
||
|
||
```yaml
|
||
auth:
|
||
type: query
|
||
param: token
|
||
token_env: MY_DATA_TOKEN
|
||
```
|
||
|
||
Token 可以放在系统环境变量或项目 `.env` 中。
|
||
|
||
## 联调流程
|
||
|
||
1. 启动 mock 数据源:
|
||
|
||
```bash
|
||
cd docs/examples/custom-data-source
|
||
python mock_server.py
|
||
```
|
||
|
||
2. 复制示例配置:
|
||
|
||
```bash
|
||
mkdir -p data/data_sources
|
||
cp docs/examples/custom-data-source/mock_source.yaml data/data_sources/mock_source.yaml
|
||
```
|
||
|
||
3. 在「设置 -> 数据源」点击「重新加载」。
|
||
|
||
4. 使用「试拉测试」选择 `mock_source` 和 `daily` / `adj_factor` / `realtime`。
|
||
|
||
5. 保存数据源选择:
|
||
|
||
- 日K: `mock_source`
|
||
- 除权因子: `mock_source` (或保持默认 `tickflow`)
|
||
- 实时行情: `mock_source`
|
||
|
||
6. 触发同步或开启实时行情。
|
||
|
||
## 常见错误
|
||
|
||
| 现象 | 处理 |
|
||
| --- | --- |
|
||
| 列表里没有 custom 源 | 检查 YAML 是否放在 `data/data_sources/` 并点击重新加载 |
|
||
| errors 提示 missing mapped fields | `field_map` 没映射到必填内部字段 |
|
||
| 试拉 rows 为 0 | 检查 `response_path` 是否指向数组 |
|
||
| 日期列全为空 | 检查 `parse_date` 的格式是否和返回值一致 |
|
||
| 实时行情没刷新 | 确认实时数据源已保存为 custom,且返回全市场快照 |
|
||
|
||
## 用 AI 生成映射配置
|
||
|
||
如果你的数据源 API 文档比较复杂,可以把 API 文档和返回示例丢给 AI,让它帮你生成 `field_map` 和 YAML 配置。
|
||
|
||
### 操作步骤
|
||
|
||
1. 从你的数据源获取 API 文档(接口地址、请求方式、返回字段说明)
|
||
2. 试拉一次,拿到返回的 JSON 示例
|
||
3. 把下面的 prompt 模板 + API 文档 + JSON 示例一起发给 AI
|
||
4. 把 AI 生成的 YAML 贴到 `data/data_sources/xxx.yaml`
|
||
5. 在设置页点「重新加载」,再「试拉测试」验证
|
||
|
||
### Prompt 模板
|
||
|
||
复制以下内容发给 AI(替换方括号部分):
|
||
|
||
```text
|
||
我在配置一个自定义数据源接入股票面板。请根据我的 API 文档和返回示例,生成 YAML 配置。
|
||
|
||
要求:
|
||
1. 输出标准 YAML 配置,包含 name / display_name / auth / datasets
|
||
2. 每个数据集的 field_map 把我的接口字段名映射到内部字段名
|
||
3. 日期类字段如果格式不是 YYYY-MM-DD, 加上 transforms 里的 parse_date
|
||
4. 只配置我能提供的接口, 不存在的数据集不要写
|
||
|
||
内部字段对照表:
|
||
|
||
日K (daily):
|
||
symbol = 股票代码, 格式 000001.SZ / 600000.SH
|
||
date = 交易日期
|
||
open / high / low / close = OHLC
|
||
volume = 成交量
|
||
amount = 成交额
|
||
|
||
除权因子 (adj_factor):
|
||
symbol = 股票代码
|
||
trade_date = 除权日期
|
||
ex_factor = 复权因子
|
||
|
||
实时行情 (realtime):
|
||
symbol = 股票代码
|
||
last_price = 最新价
|
||
prev_close = 昨收价
|
||
open / high / low = 当日 OHLC
|
||
volume = 成交量
|
||
amount = 成交额
|
||
change_pct = 涨跌幅 (小数, 0.0366 = 3.66%)
|
||
change_amount = 涨跌额
|
||
amplitude = 振幅 (小数, 0.024 = 2.4%)
|
||
turnover_rate = 换手率 (小数, 0.05 = 5%)
|
||
# 上游若返回百分数值 (3.66 表示 3.66%), 在 realtime 数据集声明 pct_unit: percent,
|
||
# 不要依赖数值自动识别; 逐列转换也可用 transforms: turnover_rate: "value / 100"
|
||
|
||
分钟K (minute):
|
||
symbol = 股票代码
|
||
datetime = 时间戳 (YYYY-MM-DD HH:MM:SS)
|
||
open / high / low / close = OHLC
|
||
volume = 成交量
|
||
amount = 成交额
|
||
|
||
=== 我的 API 文档 ===
|
||
[把你的接口文档贴这里: URL / 请求方式 / 参数 / 返回字段说明]
|
||
|
||
=== 返回 JSON 示例 ===
|
||
[把试拉的 JSON 返回贴这里]
|
||
```
|
||
|
||
AI 会输出类似这样的结果:
|
||
|
||
```yaml
|
||
name: my_source
|
||
display_name: "我的数据源"
|
||
auth:
|
||
type: bearer
|
||
token_env: MY_API_TOKEN
|
||
|
||
datasets:
|
||
daily:
|
||
url: https://api.example.com/kline
|
||
method: POST
|
||
batch: 100
|
||
rpm: 200
|
||
response_path: data.list
|
||
field_map:
|
||
ts_code: symbol
|
||
trade_date: date
|
||
open: open
|
||
vol: volume
|
||
transforms:
|
||
date: "parse_date(value, '%Y%m%d')"
|
||
```
|
||
|
||
把这段 YAML 保存为 `data/data_sources/my_source.yaml`,然后在设置页重新加载即可。
|