You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
149 lines
5.4 KiB
149 lines
5.4 KiB
# 内部接口层文档
|
|
|
|
## 架构设计
|
|
|
|
```
|
|
对外接口 (AmazingDataAdapter)
|
|
│
|
|
├── 内部接口层 (InternalDataService)
|
|
│ ├── _MarketDataInternal (市场数据)
|
|
│ ├── _BaseDataInternal (基础数据)
|
|
│ └── _InfoDataInternal (信息数据)
|
|
│
|
|
└── AmazingData SDK
|
|
├── _market_data
|
|
├── _base_data
|
|
└── _info_data
|
|
```
|
|
|
|
## 设计原则
|
|
|
|
1. **对外接口不直接调用 SDK** - 所有 SDK 调用都通过内部接口层
|
|
2. **统一错误处理** - 内部接口层统一处理 SDK 异常
|
|
3. **日志记录** - 内部接口层统一记录调用日志
|
|
4. **便于测试** - 可以 mock 内部接口进行单元测试
|
|
|
|
## 内部接口类
|
|
|
|
### _MarketDataInternal
|
|
|
|
封装 `_market_data` SDK 对象的方法:
|
|
|
|
| 方法 | SDK 方法 | 说明 |
|
|
|------|----------|------|
|
|
| `login()` | `_market_data.login()` | 登录 |
|
|
| `is_login()` | `_market_data.is_login()` | 检查登录状态 |
|
|
| `query_kline()` | `_market_data.query_kline()` | 查询K线 |
|
|
| `query_snapshot()` | `_market_data.query_snapshot()` | 查询快照 |
|
|
|
|
### _BaseDataInternal
|
|
|
|
封装 `_base_data` SDK 对象的方法:
|
|
|
|
| 方法 | SDK 方法 | 说明 |
|
|
|------|----------|------|
|
|
| `get_code_list()` | `_base_data.get_code_list()` | 获取股票代码列表 |
|
|
| `get_future_code_list()` | `_base_data.get_future_code_list()` | 获取期货代码列表 |
|
|
| `get_code_info()` | `_base_data.get_code_info()` | 获取代码信息 |
|
|
| `get_calendar()` | `_base_data.get_calendar()` | 获取交易日历 |
|
|
| `get_adj_factor()` | `_base_data.get_adj_factor()` | 获取复权因子 |
|
|
| `get_backward_factor()` | `_base_data.get_backward_factor()` | 获取后复权因子 |
|
|
| `get_etf_pcf()` | `_base_data.get_etf_pcf()` | 获取ETF申赎数据 |
|
|
| `get_hist_code_list()` | `_base_data.get_hist_code_list()` | 获取历史代码列表 |
|
|
|
|
### _InfoDataInternal
|
|
|
|
封装 `_info_data` SDK 对象的方法:
|
|
|
|
| 方法 | SDK 方法 | 说明 |
|
|
|------|----------|------|
|
|
| `get_equity_structure()` | `_info_data.get_equity_structure()` | 股本结构 |
|
|
| `get_share_holder()` | `_info_data.get_share_holder()` | 股东数据 |
|
|
| `get_holder_num()` | `_info_data.get_holder_num()` | 股东户数 |
|
|
| `get_income()` | `_info_data.get_income()` | 利润表 |
|
|
| `get_balance_sheet()` | `_info_data.get_balance_sheet()` | 资产负债表 |
|
|
| `get_cash_flow()` | `_info_data.get_cash_flow()` | 现金流量表 |
|
|
| `get_profit_express()` | `_info_data.get_profit_express()` | 业绩预告 |
|
|
| `get_profit_notice()` | `_info_data.get_profit_notice()` | 业绩快报 |
|
|
| `get_margin_summary()` | `_info_data.get_margin_summary()` | 融资融券汇总 |
|
|
| `get_margin_detail()` | `_info_data.get_margin_detail()` | 融资融券明细 |
|
|
| `get_long_hu_bang()` | `_info_data.get_long_hu_bang()` | 龙虎榜 |
|
|
| `get_block_trading()` | `_info_data.get_block_trading()` | 大宗交易 |
|
|
| `get_index_constituent()` | `_info_data.get_index_constituent()` | 指数成分股 |
|
|
| `get_index_weight()` | `_info_data.get_index_weight()` | 指数权重 |
|
|
| `get_fund_share()` | `_info_data.get_fund_share()` | 基金份额 |
|
|
| `get_kzz_issuance()` | `_info_data.get_kzz_issuance()` | 可转债发行 |
|
|
| `get_history_stock_status()` | `_info_data.get_history_stock_status()` | 历史股票状态(涨停/跌停/ST/停牌) |
|
|
|
|
## 使用方式
|
|
|
|
### 在 AmazingDataAdapter 中
|
|
|
|
```python
|
|
class AmazingDataAdapter(DataSourceAdapter):
|
|
def __init__(self):
|
|
# ... 其他初始化 ...
|
|
self._internal: Optional[InternalDataService] = None
|
|
|
|
async def connect(self, config: dict) -> None:
|
|
# ... 登录和初始化 SDK ...
|
|
|
|
# 初始化内部数据服务层
|
|
self._internal = InternalDataService(self)
|
|
|
|
def _fetch_klines_sync(self, ...):
|
|
# 使用内部接口,而不是直接调用 SDK
|
|
kline_dict = self._internal.market.query_kline(...)
|
|
code_info = self._internal.base.get_code_info(...)
|
|
equity = self._internal.info.get_equity_structure(...)
|
|
```
|
|
|
|
### 错误处理
|
|
|
|
内部接口统一处理 SDK 异常,返回空数据或默认值:
|
|
|
|
```python
|
|
class _BaseDataInternal:
|
|
def get_code_info(self, security_type: str) -> pd.DataFrame:
|
|
try:
|
|
return self._base_data.get_code_info(security_type=security_type)
|
|
except Exception as e:
|
|
error(f"[_BaseDataInternal] Get code info failed: {e}")
|
|
return pd.DataFrame() # 返回空数据而不是抛出异常
|
|
```
|
|
|
|
## 文件结构
|
|
|
|
```
|
|
app/adapters/
|
|
├── __init__.py
|
|
├── base.py # 适配器基类
|
|
├── amazingdata_adapter.py # 对外适配器(使用内部接口)
|
|
└── internal_data_service.py # 内部接口层
|
|
```
|
|
|
|
## 迁移说明
|
|
|
|
### 之前的调用方式(已废弃)
|
|
```python
|
|
# 直接调用 SDK
|
|
code_info = self._base_data.get_code_info(security_type=...)
|
|
kline = self._market_data.query_kline(...)
|
|
equity = self._info_data.get_equity_structure(...)
|
|
```
|
|
|
|
### 现在的调用方式
|
|
```python
|
|
# 通过内部接口调用
|
|
code_info = self._internal.base.get_code_info(security_type=...)
|
|
kline = self._internal.market.query_kline(...)
|
|
equity = self._internal.info.get_equity_structure(...)
|
|
```
|
|
|
|
## 优势
|
|
|
|
1. **解耦** - 对外接口与 SDK 解耦,便于更换数据源
|
|
2. **可测试性** - 可以 mock 内部接口进行单元测试
|
|
3. **错误处理** - 统一的错误处理和日志记录
|
|
4. **扩展性** - 可以在内部接口层添加缓存、限流等功能
|