fix: 增加获取主力合约接口

master
Lxy 3 months ago
parent 955f22cd75
commit 1c145453f4

@ -324,6 +324,75 @@ class TqSdkAdapter(BaseDataAdapter):
print(f"获取所有品种列表失败:{e}") print(f"获取所有品种列表失败:{e}")
return self._get_mock_all_symbols() return self._get_mock_all_symbols()
def get_main_contracts(self) -> Dict[str, str]:
"""获取主力合约
Returns:
Dict[str, str]: 品种代码到主力合约代码的映射
"""
try:
if TQSDK_AVAILABLE and self.api:
# 使用TQSDK的query_quotes方法获取主力合约
main_contracts = {}
# 尝试获取不同类别的主力合约
for ins_class in ['FUTURE']:
try:
# 查询主力合约
quotes = self.api.query_quotes(ins_class=ins_class)
# 等待数据准备就绪
import time
start_time = time.time()
timeout = 5 # 5秒超时
while True:
if quotes:
break
if time.time() - start_time > timeout:
print("获取主力合约数据超时")
break
time.sleep(0.1)
# 处理获取到的主力合约
for quote in quotes:
try:
# 获取合约信息
contract_info = self.api.get_quote(quote)
self.api.wait_update()
if hasattr(contract_info, 'underlying_symbol') and hasattr(contract_info, 'instrument_id'):
underlying_symbol = contract_info.underlying_symbol
instrument_id = contract_info.instrument_id
main_contracts[underlying_symbol] = instrument_id
except Exception as e:
print(f"处理主力合约 {quote} 失败:{e}")
except Exception as e:
print(f"获取 {ins_class} 类别的主力合约失败:{e}")
print(f"获取到主力合约:{main_contracts}")
return main_contracts
else:
# 返回模拟数据
print("无法获取真实主力合约数据,使用模拟数据")
return self._get_mock_main_contracts()
except Exception as e:
print(f"获取主力合约失败:{e}")
return self._get_mock_main_contracts()
def _get_mock_main_contracts(self) -> Dict[str, str]:
"""获取模拟主力合约数据"""
# 模拟主力合约数据
mock_main_contracts = {
'AU': 'AU2603', # 黄金
'AG': 'AG2603', # 白银
'CU': 'CU2603', # 铜
'NI': 'NI2603', # 镍
'SN': 'SN2603' # 锡
}
print(f"使用模拟主力合约数据: {mock_main_contracts}")
return mock_main_contracts
def _get_mock_all_symbols(self) -> List[str]: def _get_mock_all_symbols(self) -> List[str]:
"""获取模拟品种列表""" """获取模拟品种列表"""
# 返回exchange_map中映射的所有品种 # 返回exchange_map中映射的所有品种

@ -434,6 +434,36 @@ class DataFetcher:
{'symbol': 'ZN2603', 'product': 'ZN', 'product_name': '', 'exchange': 'SHFE', 'month': '2603'} {'symbol': 'ZN2603', 'product': 'ZN', 'product_name': '', 'exchange': 'SHFE', 'month': '2603'}
] ]
def get_main_contracts(self) -> Dict[str, str]:
"""获取主力合约
Returns:
Dict[str, str]: 品种代码到主力合约代码的映射
"""
try:
# 使用适配器的get_main_contracts方法
result = self.adapter.get_main_contracts()
if result:
return result
else:
# 如果适配器返回空,使用模拟数据
print("使用模拟主力合约数据")
return self._get_mock_main_contracts()
except Exception as e:
print(f"获取主力合约失败:{e}")
return self._get_mock_main_contracts()
def _get_mock_main_contracts(self) -> Dict[str, str]:
"""获取模拟主力合约数据"""
# 模拟主力合约数据
return {
'AU': 'AU2603', # 黄金
'AG': 'AG2603', # 白银
'CU': 'CU2603', # 铜
'NI': 'NI2603', # 镍
'SN': 'SN2603' # 锡
}
# 导入numpy # 导入numpy
import numpy as np import numpy as np

@ -46,6 +46,28 @@ def get_contracts():
except Exception as e: except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500 return jsonify({'status': 'error', 'message': str(e)}), 500
# 主力合约获取接口
@app.route('/api/main-contracts', methods=['GET'])
def get_main_contracts():
try:
print("正在获取主力合约数据...")
main_contracts = data_fetcher.get_main_contracts()
print(f"获取到主力合约:{main_contracts}")
# 转换为主力合约列表格式,包含品种名称
main_contracts_list = []
for product, contract in main_contracts.items():
product_name = data_fetcher.get_product_name_cn(product)
main_contracts_list.append({
'product': product,
'product_name': product_name,
'main_contract': contract
})
return jsonify({'status': 'success', 'data': main_contracts_list})
except Exception as e:
return jsonify({'status': 'error', 'message': str(e)}), 500
# K线数据获取接口 # K线数据获取接口
@app.route('/api/kline', methods=['GET']) @app.route('/api/kline', methods=['GET'])
def get_kline(): def get_kline():

@ -73,6 +73,62 @@
7. 处理数据并返回给客户端 7. 处理数据并返回给客户端
8. 如果TQSDK失败自动切换到测试数据源 8. 如果TQSDK失败自动切换到测试数据源
## 主力合约获取
### 核心流程
1. **主力合约获取机制**
- 系统通过TQSDK的`query_quotes()`方法获取主力合约数据
- 支持实盘数据和模拟数据两种模式
- 实现了异常处理和超时机制,确保获取过程稳定
2. **数据处理**
- 从TQSDK获取主力合约列表
- 提取品种代码和对应的主力合约代码
- 转换为主力合约映射表,便于查询
3. **API接口**
- 提供`/api/main-contracts`接口,返回主力合约数据
- 接口返回格式包含品种代码、品种名称和主力合约代码
### 代码位置
- **TQSDK适配器**`backend/service_implementation/qihuo_analyzer/data/api_adapters/tqsdk_adapter.py`
- 实现了`get_main_contracts()`方法使用TQSDK获取主力合约数据
- 提供了模拟数据作为fallback
- **数据获取器**`backend/service_implementation/qihuo_analyzer/data/data_fetcher.py`
- 实现了`get_main_contracts()`方法,作为适配器方法的包装
- 提供了统一的主力合约获取接口
- **API服务**`backend/service_implementation/service/app.py`
- 添加了`/api/main-contracts`接口,返回主力合约数据
- 处理数据格式转换和错误处理
### 使用方法
1. **通过API接口获取**
```
GET http://localhost:5000/api/main-contracts
```
2. **在代码中获取**
```python
from qihuo_analyzer.data.data_fetcher import DataFetcher
data_fetcher = DataFetcher()
data_fetcher.connect()
main_contracts = data_fetcher.get_main_contracts()
print(main_contracts) # 输出:{'AU': 'AU2603', 'AG': 'AG2603', ...}
```
### 技术实现细节
- **TQSDK接口**:使用`query_quotes(ins_class='FUTURE')`获取主力合约数据
- **数据处理**:通过`get_quote()`获取合约详细信息,提取`underlying_symbol`和`instrument_id`
- **异常处理**:实现了多层异常捕获,确保系统稳定性
- **模拟数据**当TQSDK不可用时使用预定义的模拟数据
## 技术特点 ## 技术特点
1. **工厂模式**:使用工厂模式管理数据源实例,提高代码可维护性 1. **工厂模式**:使用工厂模式管理数据源实例,提高代码可维护性
@ -80,3 +136,4 @@
3. **容错机制**:实现了数据源故障自动切换,提高系统可靠性 3. **容错机制**:实现了数据源故障自动切换,提高系统可靠性
4. **配置驱动**:数据源配置通过配置文件管理,便于运维和部署 4. **配置驱动**:数据源配置通过配置文件管理,便于运维和部署
5. **模块化设计**将数据获取逻辑与API接口分离提高代码可读性 5. **模块化设计**将数据获取逻辑与API接口分离提高代码可读性
6. **主力合约支持**:实现了主力合约的自动获取和管理,方便用户快速访问主要交易合约
Loading…
Cancel
Save