|
|
|
|
|
# 期货K线接口修复报告
|
|
|
|
|
|
|
|
|
|
|
|
## 问题描述
|
|
|
|
|
|
|
|
|
|
|
|
期货K线接口 `/v1/futures/klines/{symbol}` 返回的 `items` 为空列表。
|
|
|
|
|
|
|
|
|
|
|
|
## 根本原因
|
|
|
|
|
|
|
|
|
|
|
|
代码中**硬编码**了使用 `amazingdata` 适配器,但配置文件中配置的是 `custom` 适配器。导致:
|
|
|
|
|
|
|
|
|
|
|
|
1. 配置文件中 `sources.futures.active = "custom"`
|
|
|
|
|
|
2. 但代码中尝试连接 `amazingdata` 适配器
|
|
|
|
|
|
3. `_connect_adapter` 方法中尝试从 `file_config.sources.stock.list["amazingdata"]` 获取配置
|
|
|
|
|
|
4. 配置中不存在 `amazingdata`,导致 `KeyError: 'amazingdata'`
|
|
|
|
|
|
5. 异常被捕获后返回空列表
|
|
|
|
|
|
|
|
|
|
|
|
## 修复内容
|
|
|
|
|
|
|
|
|
|
|
|
### 1. 修复硬编码适配器名称
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
- `app/services/futures_service.py`
|
|
|
|
|
|
- `app/services/stock_service.py`
|
|
|
|
|
|
|
|
|
|
|
|
**修改内容:**
|
|
|
|
|
|
将以下代码:
|
|
|
|
|
|
```python
|
|
|
|
|
|
if not adapter:
|
|
|
|
|
|
loop.run_until_complete(adapter_service._connect_adapter("amazingdata"))
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
改为:
|
|
|
|
|
|
```python
|
|
|
|
|
|
if not adapter:
|
|
|
|
|
|
# 从配置获取当前激活的适配器名称
|
|
|
|
|
|
from app.core.config import get_config
|
|
|
|
|
|
config = get_config()
|
|
|
|
|
|
active_source = config.sources.futures.active # 或 config.sources.stock.active
|
|
|
|
|
|
|
|
|
|
|
|
info(f"Connecting to configured adapter: {active_source}")
|
|
|
|
|
|
loop.run_until_complete(adapter_service._connect_adapter(active_source))
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 2. 修复适配器配置获取逻辑
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
- `app/services/adapter_service.py`
|
|
|
|
|
|
|
|
|
|
|
|
**修改内容:**
|
|
|
|
|
|
将以下代码:
|
|
|
|
|
|
```python
|
|
|
|
|
|
if name == "amazingdata":
|
|
|
|
|
|
source_info = file_config.sources.stock.list["amazingdata"]
|
|
|
|
|
|
adapter_config = dict(source_info.config) if source_info else {}
|
|
|
|
|
|
else:
|
|
|
|
|
|
adapter_config = self.configs[name].get("config", {})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
改为:
|
|
|
|
|
|
```python
|
|
|
|
|
|
# 尝试从配置文件中获取适配器配置
|
|
|
|
|
|
adapter_config = None
|
|
|
|
|
|
|
|
|
|
|
|
# 1. 首先检查 stock 配置
|
|
|
|
|
|
if name in file_config.sources.stock.list:
|
|
|
|
|
|
source_info = file_config.sources.stock.list[name]
|
|
|
|
|
|
adapter_config = dict(source_info.config) if source_info else {}
|
|
|
|
|
|
|
|
|
|
|
|
# 2. 然后检查 futures 配置
|
|
|
|
|
|
elif name in file_config.sources.futures.list:
|
|
|
|
|
|
source_info = file_config.sources.futures.list[name]
|
|
|
|
|
|
adapter_config = dict(source_info.config) if source_info else {}
|
|
|
|
|
|
|
|
|
|
|
|
# 3. 使用默认配置
|
|
|
|
|
|
else:
|
|
|
|
|
|
adapter_config = self.configs[name].get("config", {})
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
### 3. 修复期货仓库的频率映射
|
|
|
|
|
|
|
|
|
|
|
|
**修改文件:**
|
|
|
|
|
|
- `app/repositories/futures_repository.py`
|
|
|
|
|
|
|
|
|
|
|
|
**修改内容:**
|
|
|
|
|
|
添加了对其他频率的映射(虽然数据库只支持1分钟和日线,但避免KeyError):
|
|
|
|
|
|
```python
|
|
|
|
|
|
def _get_kline_model(self, freq: Frequency):
|
|
|
|
|
|
mapping = {
|
|
|
|
|
|
Frequency.FREQ_1M: FuturesKLine1M,
|
|
|
|
|
|
Frequency.FREQ_1D: FuturesKLine1D,
|
|
|
|
|
|
Frequency.FREQ_5M: FuturesKLine1D, # 默认使用日线
|
|
|
|
|
|
Frequency.FREQ_15M: FuturesKLine1D,
|
|
|
|
|
|
Frequency.FREQ_30M: FuturesKLine1D,
|
|
|
|
|
|
Frequency.FREQ_60M: FuturesKLine1D,
|
|
|
|
|
|
Frequency.FREQ_1W: FuturesKLine1D,
|
|
|
|
|
|
Frequency.FREQ_1MONTH: FuturesKLine1D,
|
|
|
|
|
|
}
|
|
|
|
|
|
return mapping.get(freq, FuturesKLine1D)
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
## 当前状态
|
|
|
|
|
|
|
|
|
|
|
|
API现在可以正常返回响应:
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"code": 0,
|
|
|
|
|
|
"message": "success",
|
|
|
|
|
|
"data": {
|
|
|
|
|
|
"symbol": "CU2504.SHFE",
|
|
|
|
|
|
"name": null,
|
|
|
|
|
|
"freq": "1d",
|
|
|
|
|
|
"adjust": "",
|
|
|
|
|
|
"count": 0,
|
|
|
|
|
|
"items": []
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
`items` 为空是因为:
|
|
|
|
|
|
1. 数据库中没有数据
|
|
|
|
|
|
2. 配置的 `custom` 适配器未注册(只注册了 `amazingdata`)
|
|
|
|
|
|
|
|
|
|
|
|
## 使用建议
|
|
|
|
|
|
|
|
|
|
|
|
要使接口返回实际数据,需要:
|
|
|
|
|
|
|
|
|
|
|
|
1. **配置 AmazingData 适配器:**
|
|
|
|
|
|
修改 `config.json`:
|
|
|
|
|
|
```json
|
|
|
|
|
|
{
|
|
|
|
|
|
"sources": {
|
|
|
|
|
|
"futures": {
|
|
|
|
|
|
"active": "amazingdata",
|
|
|
|
|
|
"list": {
|
|
|
|
|
|
"amazingdata": {
|
|
|
|
|
|
"type": "sdk",
|
|
|
|
|
|
"config": {
|
|
|
|
|
|
"username": "your_username",
|
|
|
|
|
|
"password": "your_password",
|
|
|
|
|
|
"host": "your_host",
|
|
|
|
|
|
"port": "8600"
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
2. **安装 AmazingData SDK:**
|
|
|
|
|
|
```bash
|
|
|
|
|
|
pip install AmazingData tgw
|
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
|
|
3. **或者注册自定义适配器:**
|
|
|
|
|
|
在 `AdapterService._register_builtin_adapters()` 中添加:
|
|
|
|
|
|
```python
|
|
|
|
|
|
self.register_adapter("custom", lambda: YourCustomAdapter())
|
|
|
|
|
|
```
|