|
|
|
|
|
# 统一行情数据服务 - Python实现
|
|
|
|
|
|
|
|
|
|
|
|
Python版本的统一行情数据服务,所有接口和功能与Go版本保持一致。
|
|
|
|
|
|
|
|
|
|
|
|
## 特性
|
|
|
|
|
|
|
|
|
|
|
|
- **多周期K线支持**:1m/5m/15m/30m/60m/1d/1w/1month
|
|
|
|
|
|
- **股票复权支持**:前复权(qfq)/后复权(hfq)
|
|
|
|
|
|
- **数据源热切换**:支持Wind、Tushare等多个数据源动态切换
|
|
|
|
|
|
- **双轨设计**:股票和期货接口独立,数据存储隔离
|
|
|
|
|
|
- **WebSocket实时订阅**:支持实时行情推送
|
|
|
|
|
|
- **数据质量监控**:自动检测数据缺失并告警
|
|
|
|
|
|
- **交易日历**:支持查询股票和期货的交易日历
|
|
|
|
|
|
- **期货合约查询**:根据品种获取可交易合约列表
|
|
|
|
|
|
|
|
|
|
|
|
## 技术栈
|
|
|
|
|
|
|
|
|
|
|
|
- **语言**: Python 3.10+
|
|
|
|
|
|
- **Web框架**: FastAPI
|
|
|
|
|
|
- **WebSocket**: FastAPI原生WebSocket + python-socketio
|
|
|
|
|
|
- **数据库**: PostgreSQL 15+ (SQLAlchemy ORM)
|
|
|
|
|
|
- **数据源**: Tushare (首期支持)
|
|
|
|
|
|
|
|
|
|
|
|
## 项目结构
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
|
|
python_market_data_service/
|
|
|
|
|
|
├── app/
|
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
|
│ ├── main.py # 主程序入口
|
|
|
|
|
|
│ ├── api/ # API路由
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── routes.py # 主要API路由
|
|
|
|
|
|
│ │ └── admin_routes.py # 管理后台路由
|
|
|
|
|
|
│ ├── core/ # 核心模块
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── config.py # 配置管理
|
|
|
|
|
|
│ │ ├── errors.py # 错误定义
|
|
|
|
|
|
│ │ └── logger.py # 日志工具
|
|
|
|
|
|
│ ├── models/ # 数据模型
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── types.py # 基础类型
|
|
|
|
|
|
│ │ └── admin_types.py # 管理后台类型
|
|
|
|
|
|
│ ├── repositories/ # 数据访问层
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── database.py # 数据库连接
|
|
|
|
|
|
│ │ ├── models.py # 数据库模型
|
|
|
|
|
|
│ │ ├── stock_repository.py
|
|
|
|
|
|
│ │ └── futures_repository.py
|
|
|
|
|
|
│ ├── services/ # 业务逻辑层
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── stock_service.py
|
|
|
|
|
|
│ │ ├── futures_service.py
|
|
|
|
|
|
│ │ ├── admin_service.py
|
|
|
|
|
|
│ │ ├── config_service.py
|
|
|
|
|
|
│ │ ├── adapter_service.py
|
|
|
|
|
|
│ │ └── test_service.py
|
|
|
|
|
|
│ ├── adapters/ # 数据源适配器
|
|
|
|
|
|
│ │ ├── __init__.py
|
|
|
|
|
|
│ │ ├── base.py # 适配器基类
|
|
|
|
|
|
│ │ └── tushare_adapter.py
|
|
|
|
|
|
│ └── websocket/ # WebSocket服务
|
|
|
|
|
|
│ ├── __init__.py
|
|
|
|
|
|
│ └── server.py
|
|
|
|
|
|
├── scripts/
|
|
|
|
|
|
│ └── sync_data.py # 数据同步工具
|
|
|
|
|
|
├── tests/ # 测试文件
|
|
|
|
|
|
├── requirements.txt # 依赖列表
|
|
|
|
|
|
├── pyproject.toml # 项目配置
|
|
|
|
|
|
└── README.md # 本文件
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 快速开始
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 环境准备
|
|
|
|
|
|
|
|
|
|
|
|
- Python 3.10+
|
|
|
|
|
|
- PostgreSQL 15+
|
|
|
|
|
|
- Tushare Token (从 [Tushare官网](https://tushare.pro) 获取)
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 安装依赖
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 创建虚拟环境
|
|
|
|
|
|
python -m venv venv
|
|
|
|
|
|
|
|
|
|
|
|
# 激活虚拟环境
|
|
|
|
|
|
# Windows:
|
|
|
|
|
|
venv\Scripts\activate
|
|
|
|
|
|
# Linux/Mac:
|
|
|
|
|
|
source venv/bin/activate
|
|
|
|
|
|
|
|
|
|
|
|
# 安装依赖
|
|
|
|
|
|
pip install -r requirements.txt
|
|
|
|
|
|
|
|
|
|
|
|
# 安装Tushare(需单独安装)
|
|
|
|
|
|
pip install tushare
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 配置环境变量
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# Windows PowerShell
|
|
|
|
|
|
$env:TUSHARE_TOKEN="your_tushare_token"
|
|
|
|
|
|
$env:DATABASE_URL="postgresql://user:password@localhost:5432/marketdata"
|
|
|
|
|
|
|
|
|
|
|
|
# Linux/Mac
|
|
|
|
|
|
export TUSHARE_TOKEN="your_tushare_token"
|
|
|
|
|
|
export DATABASE_URL="postgresql://user:password@localhost:5432/marketdata"
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 4. 初始化数据库
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 创建数据库(使用psql或pgAdmin)
|
|
|
|
|
|
createdb marketdata
|
|
|
|
|
|
|
|
|
|
|
|
# 启动服务时会自动创建表结构
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 5. 启动服务
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 开发模式
|
|
|
|
|
|
python -m app.main
|
|
|
|
|
|
|
|
|
|
|
|
# 或使用uvicorn
|
|
|
|
|
|
uvicorn app.main:app --reload --port 8080
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
服务将启动在 `http://localhost:8080`
|
|
|
|
|
|
|
|
|
|
|
|
- API文档: `http://localhost:8080/docs`
|
|
|
|
|
|
- 管理后台: `http://localhost:8080/admin`
|
|
|
|
|
|
|
|
|
|
|
|
### 6. 同步基础数据
|
|
|
|
|
|
|
|
|
|
|
|
```bash
|
|
|
|
|
|
# 同步股票列表
|
|
|
|
|
|
python scripts/sync_data.py --type stocks
|
|
|
|
|
|
|
|
|
|
|
|
# 同步期货列表
|
|
|
|
|
|
python scripts/sync_data.py --type futures
|
|
|
|
|
|
|
|
|
|
|
|
# 同步交易日历
|
|
|
|
|
|
python scripts/sync_data.py --type calendar --start 20240101 --end 20241231
|
|
|
|
|
|
|
|
|
|
|
|
# 同步K线数据
|
|
|
|
|
|
python scripts/sync_data.py --type klines --symbol 000001.SZ --start 20240301 --end 20240307 --freq 1d
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## API接口
|
|
|
|
|
|
|
|
|
|
|
|
### 股票接口
|
|
|
|
|
|
|
|
|
|
|
|
| 接口 | 方法 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `/v1/stock/klines/:symbol` | GET | 查询K线数据 |
|
|
|
|
|
|
| `/v1/stock/symbols` | GET | 查询标的列表 |
|
|
|
|
|
|
| `/v1/stock/klines/batch` | POST | 批量查询K线 |
|
|
|
|
|
|
| `/v1/stock/trading-dates` | GET | 获取交易日历 |
|
|
|
|
|
|
|
|
|
|
|
|
### 期货接口
|
|
|
|
|
|
|
|
|
|
|
|
| 接口 | 方法 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `/v1/futures/klines/:symbol` | GET | 查询K线数据 |
|
|
|
|
|
|
| `/v1/futures/symbols` | GET | 查询标的列表 |
|
|
|
|
|
|
| `/v1/futures/klines/batch` | POST | 批量查询K线 |
|
|
|
|
|
|
| `/v1/futures/continuous/:underlying` | GET | 查询主力连续合约(预留) |
|
|
|
|
|
|
| `/v1/futures/trading-dates` | GET | 获取交易日历 |
|
|
|
|
|
|
| `/v1/futures/contracts` | GET | 获取品种合约列表 |
|
|
|
|
|
|
|
|
|
|
|
|
### 管理接口
|
|
|
|
|
|
|
|
|
|
|
|
| 接口 | 方法 | 说明 |
|
|
|
|
|
|
|------|------|------|
|
|
|
|
|
|
| `/v1/admin/source/status` | GET | 获取数据源状态 |
|
|
|
|
|
|
| `/v1/admin/source/switch` | POST | 切换数据源 |
|
|
|
|
|
|
| `/v1/admin/backfill` | POST | 历史数据补录 |
|
|
|
|
|
|
| `/v1/admin/health` | GET | 健康检查 |
|
|
|
|
|
|
|
|
|
|
|
|
### 管理后台
|
|
|
|
|
|
|
|
|
|
|
|
服务启动后,访问 `http://localhost:8080/admin` 进入管理后台。
|
|
|
|
|
|
|
|
|
|
|
|
### WebSocket实时订阅
|
|
|
|
|
|
|
|
|
|
|
|
**连接地址**: `ws://localhost:8080/v1/stream`
|
|
|
|
|
|
|
|
|
|
|
|
**认证**: 连接时在Header中传递 `X-API-Key`
|
|
|
|
|
|
|
|
|
|
|
|
**客户端消息**:
|
|
|
|
|
|
```json
|
|
|
|
|
|
// 订阅
|
|
|
|
|
|
{
|
|
|
|
|
|
"action": "subscribe",
|
|
|
|
|
|
"symbols": ["000001.SZ", "CU2504.SHFE"]
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 取消订阅
|
|
|
|
|
|
{
|
|
|
|
|
|
"action": "unsubscribe",
|
|
|
|
|
|
"symbols": ["000001.SZ"]
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**服务器消息**:
|
|
|
|
|
|
```json
|
|
|
|
|
|
// 订阅确认
|
|
|
|
|
|
{
|
|
|
|
|
|
"type": "ack",
|
|
|
|
|
|
"action": "subscribe",
|
|
|
|
|
|
"symbols": ["000001.SZ", "CU2504.SHFE"],
|
|
|
|
|
|
"ts": "2025-03-07T12:30:00Z"
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// 心跳
|
|
|
|
|
|
{
|
|
|
|
|
|
"type": "heartbeat",
|
|
|
|
|
|
"ts": "2025-03-07T12:30:30Z"
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
**限制**: 单连接最大订阅100个标的
|
|
|
|
|
|
|
|
|
|
|
|
## 与Go版本的主要区别
|
|
|
|
|
|
|
|
|
|
|
|
1. **Web框架**: Gin -> FastAPI
|
|
|
|
|
|
2. **ORM**: 原生SQL -> SQLAlchemy
|
|
|
|
|
|
3. **WebSocket**: Gorilla -> FastAPI原生
|
|
|
|
|
|
4. **配置**: 文件+环境变量 -> Pydantic Settings
|
|
|
|
|
|
5. **API文档**: 自动生成Swagger/ReDoc
|
|
|
|
|
|
|
|
|
|
|
|
## License
|
|
|
|
|
|
|
|
|
|
|
|
MIT
|