实现 sidecar 模块

This commit is contained in:
cheney
2026-06-23 10:37:31 +08:00
parent ca5dd30eed
commit 31d28d8683
20 changed files with 1434 additions and 0 deletions
+243
View File
@@ -0,0 +1,243 @@
# sidecar 对外接口说明
## 1. 模块定位
sidecar 是本项目的 Python 行情数据侧车模块,对外提供统一的数据获取与 DuckDB 缓存接口。调用方可以选择直接调用 Python 服务类,也可以通过 FastAPI HTTP 接口访问。
## 2. Python 服务接口
### 2.1 创建默认服务
```python
from sidecar.config import load_config
from sidecar.service import create_default_service
service = create_default_service(load_config())
```
#### 输入
无业务输入;配置从环境变量读取:
| 环境变量 | 类型 | 默认值 | 说明 |
|---|---:|---|---|
| `TORTOISE_DUCKDB_PATH` | string | `data/tortoise.duckdb` | DuckDB 数据库文件路径 |
| `TORTOISE_SNAPSHOT_TTL_SECONDS` | int | `15` | 行情快照缓存秒数 |
| `TORTOISE_REQUEST_TIMEOUT_SECONDS` | int | `8` | 腾讯财经 HTTP 请求超时秒数 |
#### 输出
返回 `UnifiedDataService` 实例。
### 2.2 `get_kline`
```python
bars = service.get_kline("600000", period="day", limit=120, refresh=False)
```
#### 输入
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---:|---|---|
| `symbol` | string | 是 | - | 股票代码,支持 `600000`、`sh600000`、`SZ000001` 等格式 |
| `period` | string | 否 | `day` | K 线周期,支持 `day/week/month/1m/5m/15m/30m/60m` |
| `limit` | int | 否 | `800` | 最大返回条数 |
| `refresh` | bool | 否 | `False` | 是否跳过缓存强制刷新 |
#### 输出
返回 `list[KlineBar]`,按交易日期升序排列。
| 字段 | 类型 | 说明 |
|---|---|---|
| `symbol` | string | 标准化股票代码,例如 `sh600000` |
| `period` | string | K 线周期 |
| `trade_date` | date | 交易日期 |
| `open` | float/null | 开盘价 |
| `high` | float/null | 最高价 |
| `low` | float/null | 最低价 |
| `close` | float/null | 收盘价 |
| `volume` | float/null | 成交量 |
| `amount` | float/null | 成交额 |
| `source` | string | 数据源,当前为 `mootdx` |
### 2.3 `get_snapshot`
```python
snapshot = service.get_snapshot("600000", refresh=False)
```
#### 输入
| 参数 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---:|---|---|
| `symbol` | string | 是 | - | 股票代码,支持 `600000`、`sh600000`、`SZ000001` 等格式 |
| `refresh` | bool | 否 | `False` | 是否跳过 TTL 缓存强制刷新 |
#### 输出
返回 `Snapshot`。
| 字段 | 类型 | 说明 |
|---|---|---|
| `symbol` | string | 标准化股票代码 |
| `name` | string/null | 股票名称 |
| `trade_time` | datetime/null | 行情时间 |
| `price` | float/null | 最新价 |
| `previous_close` | float/null | 昨收价 |
| `open` | float/null | 开盘价 |
| `high` | float/null | 最高价 |
| `low` | float/null | 最低价 |
| `volume` | float/null | 成交量 |
| `amount` | float/null | 成交额 |
| `change` | float/null | 涨跌额 |
| `change_percent` | float/null | 涨跌幅百分比 |
| `turnover_rate` | float/null | 换手率 |
| `pe_ttm` | float/null | 滚动市盈率 |
| `pe_static` | float/null | 静态市盈率 |
| `pb` | float/null | 市净率 |
| `market_cap` | float/null | 总市值 |
| `float_market_cap` | float/null | 流通市值 |
| `limit_up` | float/null | 涨停价 |
| `limit_down` | float/null | 跌停价 |
| `source` | string | 实际命中的数据源,通常为 `tencent` 或 `mootdx` |
## 3. HTTP 接口
启动命令:
```bash
uvicorn sidecar.api:app --host 127.0.0.1 --port 8765
```
### 3.1 健康检查
```http
GET /health
```
#### 输入
无。
#### 输出
```json
{
"status": "ok"
}
```
### 3.2 获取 K 线
```http
GET /kline/{symbol}?period=day&limit=800&refresh=false
```
#### 输入
| 参数 | 位置 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---:|---|---|
| `symbol` | path | string | 是 | - | 股票代码 |
| `period` | query | string | 否 | `day` | K 线周期 |
| `limit` | query | int | 否 | `800` | 返回条数,范围 `1..800` |
| `refresh` | query | bool | 否 | `false` | 是否强制刷新 |
#### 输出
```json
{
"data": [
{
"symbol": "sh600000",
"period": "day",
"trade_date": "2026-06-23",
"open": 10.0,
"high": 10.5,
"low": 9.8,
"close": 10.2,
"volume": 1000000.0,
"amount": 10200000.0,
"source": "mootdx"
}
]
}
```
### 3.3 获取行情快照
```http
GET /snapshot/{symbol}?refresh=false
```
#### 输入
| 参数 | 位置 | 类型 | 必填 | 默认值 | 说明 |
|---|---|---|---:|---|---|
| `symbol` | path | string | 是 | - | 股票代码 |
| `refresh` | query | bool | 否 | `false` | 是否强制刷新 |
#### 输出
```json
{
"data": {
"symbol": "sh600000",
"name": "浦发银行",
"trade_time": "2026-06-23T15:00:00",
"price": 10.5,
"previous_close": 10.0,
"open": 10.1,
"high": 10.6,
"low": 9.9,
"volume": 1000000.0,
"amount": 10500000.0,
"change": 0.5,
"change_percent": 5.0,
"turnover_rate": 1.2,
"pe_ttm": 6.7,
"pe_static": 7.8,
"pb": 0.66,
"market_cap": 1000.0,
"float_market_cap": 800.0,
"limit_up": 11.0,
"limit_down": 9.0,
"source": "tencent"
}
}
```
## 4. 缓存行为
- K 线缓存表:`md.kline_bars`,主键为 `symbol + period + trade_date`。
- 快照缓存表:`md.snapshots`,主键为 `symbol`,使用 `expires_at` 控制 TTL。
- `refresh=false` 时优先使用缓存;`refresh=true` 时跳过缓存并重新拉取。
- 快照数据源按顺序降级:腾讯财经失败后回退 mootdx。
## 5. 注意事项
- 当前 K 线底层依赖 mootdx,第一次连接可能触发 mootdx 自动测速。
- 腾讯财经 PB 字段使用索引 `46`,索引 `43` 是振幅,不可作为 PB 使用。
- 策略模块建议只依赖本文件描述的统一接口,不直接依赖 mootdx 或腾讯财经字段。
## 6. 真实数据源测试
默认单元测试不访问外网。需要验证 mootdx 与腾讯财经真实接口时,先安装依赖,再显式开启环境变量:
```bash
pip install -e .[test]
RUN_REAL_MARKET_TESTS=1 pytest tests/test_real_sources.py -vv
```
Windows PowerShell 示例:
```powershell
$env:RUN_REAL_MARKET_TESTS = "1"
python -m pytest tests/test_real_sources.py -vv
```
真实测试用例:
- `3-1`:腾讯财经真实快照接口返回有效价格。
- `3-2`:mootdx 真实 K 线接口返回至少一条日线。
- `3-3`:统一服务使用真实数据源写入并读取 DuckDB 缓存。