市场数据服务接口文档
架构概览
┌─────────────────────────────────────────────────────────────────────────────┐
│ HTTP 客户端 │
│ (浏览器/Postman/其他服务) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ API 路由层 (HTTP) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ /stock/* │ │ /futures/* │ │ /admin/* │ │ /stream (WS) │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 服务层 (Service) │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ StockService │ │FuturesService│ │ AdminService │ │ TestService │ │
│ └──────────────┘ └──────────────┘ └──────────────┘ └──────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 适配器服务层 (Adapter) │
│ ┌──────────────────────────────────┐ │
│ │ AdapterService (单例) │ │
│ │ ┌────────────────────────────┐ │ │
│ │ │ AmazingDataAdapter │ │ │
│ │ │ ┌──────────────────────┐ │ │ │
│ │ │ │ _internal: │ │ │ │
│ │ │ │ InternalDataService │ │ │ │
│ │ │ └──────────────────────┘ │ │ │
│ │ └────────────────────────────┘ │ │
│ └──────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 内部数据服务层 (Internal) │
│ ┌──────────────────┐ ┌──────────────────┐ ┌──────────────────────────┐ │
│ │ _MarketDataInternal│ │ _BaseDataInternal │ │ _InfoDataInternal │ │
│ │ ┌──────────────┐ │ │ ┌──────────────┐ │ │ ┌──────────────────────┐ │ │
│ │ │ query_kline │ │ │ │get_code_list │ │ │ │ get_equity_structure │ │ │
│ │ │query_snapshot│ │ │ │ get_calendar │ │ │ │ get_share_holder │ │ │
│ │ └──────────────┘ │ │ │get_adj_factor│ │ │ │ get_income │ │ │
│ │ │ │ │ get_etf_pcf │ │ │ │ get_balance_sheet │ │ │
│ │ │ │ └──────────────┘ │ │ │ get_cash_flow │ │ │
│ │ │ │ │ │ │ get_margin_* │ │ │
│ │ │ │ │ │ │ get_index_* │ │ │
│ │ │ │ │ │ │ get_fund_share │ │ │
│ └──────────────────┘ └──────────────────┘ │ └──────────────────────┘ │ │
│ └──────────────────────────┘ │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SDK 层 (AmazingData) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │ login │ │BaseData │ │MarketData│ │ InfoData │ │
│ └──────────┘ └──────────┘ └──────────┘ └──────────┘ │
│ (银河证券星耀数智) │
└─────────────────────────────────────────────────────────────────────────────┘
一、对外接口 (HTTP API)
对外接口是提供给外部系统调用的 RESTful API,路径以 /v1 为前缀。
1.1 股票接口
| 接口 |
方法 |
路径 |
说明 |
| 查询股票K线 |
GET |
/v1/stock/klines/{symbol} |
获取指定股票的历史K线数据 |
| 查询股票列表 |
GET |
/v1/stock/symbols |
获取所有股票代码列表 |
| 查询股票基本信息 |
GET |
/v1/stock/basic/{symbol} |
获取股票的基本信息 |
| 批量查询K线 |
POST |
/v1/stock/klines/batch |
批量获取多只股票的K线 |
调用链示例:
GET /v1/stock/klines/000001.SZ
│
▼
routes.py:query_stock_klines()
│
▼
StockService.query_klines()
│
├── 1. 先查数据库 (StockRepository)
│ └── 有数据 → 直接返回
│
└── 2. 无数据 → 从适配器获取
│
▼
AdapterService.get_active_adapter("stock")
│
▼
AmazingDataAdapter.fetch_klines()
│
▼
InternalDataService.market.query_kline()
│
▼
AmazingData.MarketData.query_kline()
1.2 期货接口
| 接口 |
方法 |
路径 |
说明 |
| 查询期货K线 |
GET |
/v1/futures/klines/{symbol} |
获取期货合约K线数据 |
| 查询期货列表 |
GET |
/v1/futures/symbols |
获取所有期货合约列表 |
1.3 管理接口
| 接口 |
方法 |
路径 |
说明 |
| 健康检查 |
GET |
/v1/admin/health |
检查服务健康状态 |
| 数据源状态 |
GET |
/v1/admin/source/status |
查看数据源连接状态 |
| 适配器列表 |
GET |
/v1/admin/adapters |
查看所有适配器配置 |
1.4 测试接口 (Admin)
| 接口 |
方法 |
路径 |
说明 |
| 获取API测试列表 |
GET |
/v1/admin/tests/api |
获取对外接口测试列表 |
| 执行API测试 |
POST |
/v1/admin/tests/api/run |
执行指定的API测试 |
| 获取内部接口测试列表 |
GET |
/v1/admin/tests/internal |
获取对内SDK接口测试列表 |
| 执行内部接口测试 |
POST |
/v1/admin/tests/internal/run |
执行指定的对内接口测试 |
二、对内接口 (Internal SDK 封装层)
对内接口是直接封装 AmazingData SDK 的内部方法,通过 InternalDataService 统一暴露。
2.1 访问路径
# 获取 adapter
adapter = AdapterService.get_active_adapter("stock")
# 访问内部接口
adapter._internal.market.query_kline(...)
adapter._internal.base.get_code_list(...)
adapter._internal.info.get_equity_structure(...)
2.2 接口清单 (23个)
2.2.1 市场数据接口 (_MarketDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 1 |
query_kline() |
查询K线数据 |
MarketData.query_kline() |
| 2 |
query_snapshot() |
查询快照数据 |
MarketData.query_snapshot() |
2.2.2 基础数据接口 (_BaseDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 3 |
get_code_list() |
获取股票代码列表 |
BaseData.get_code_list() |
| 4 |
get_future_code_list() |
获取期货代码列表 |
BaseData.get_future_code_list() |
| 5 |
get_code_info() |
获取代码详细信息 |
BaseData.get_code_info() |
| 6 |
get_calendar() |
获取交易日历 |
BaseData.get_calendar() |
| 7 |
get_adj_factor() |
获取复权因子 |
BaseData.get_adj_factor() |
| 8 |
get_etf_pcf() |
获取ETF申赎数据 |
BaseData.get_etf_pcf() |
2.2.3 股本股东接口 (_InfoDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
特殊处理 |
| 9 |
get_equity_structure() |
获取股本结构 |
InfoData.get_equity_structure() |
- |
| 10 |
get_share_holder() |
获取股东数据 |
InfoData.get_share_holder() |
每次创建新实例 |
| 11 |
get_holder_num() |
获取股东户数 |
InfoData.get_holder_num() |
- |
2.2.4 财务报表接口 (_InfoDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 12 |
get_income() |
获取利润表 |
InfoData.get_income() |
| 13 |
get_balance_sheet() |
获取资产负债表 |
InfoData.get_balance_sheet() |
| 14 |
get_cash_flow() |
获取现金流量表 |
InfoData.get_cash_flow() |
2.2.5 市场状态接口 (_InfoDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 15 |
get_history_stock_status() |
获取历史股票状态 |
InfoData.get_history_stock_status() |
| 16 |
get_margin_summary() |
获取融资融券汇总 |
InfoData.get_margin_summary() |
| 17 |
get_margin_detail() |
获取融资融券明细 |
InfoData.get_margin_detail() |
2.2.6 特色数据接口 (_InfoDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 18 |
get_long_hu_bang() |
获取龙虎榜数据 |
InfoData.get_long_hu_bang() |
| 19 |
get_block_trading() |
获取大宗交易数据 |
InfoData.get_block_trading() |
| 20 |
get_index_constituent() |
获取指数成分股 |
InfoData.get_index_constituent() |
| 21 |
get_index_weight() |
获取指数权重 |
InfoData.get_index_weight() |
2.2.7 基金可转债接口 (_InfoDataInternal)
| 序号 |
方法名 |
说明 |
对应 SDK |
| 22 |
get_fund_share() |
获取基金份额 |
InfoData.get_fund_share() |
| 23 |
get_kzz_issuance() |
获取可转债发行 |
InfoData.get_kzz_issuance() |
三、调用链详解
3.1 完整调用链示例:查询股票K线
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第1层:HTTP 客户端请求 │
│ GET http://localhost:8080/v1/stock/klines/000001.SZ?start=20240101&... │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第2层:API 路由层 (app/api/routes.py) │
│ @router.get("/stock/klines/{symbol}") │
│ def query_stock_klines(symbol, start, end, freq, adjust, db, api_key) │
│ │
│ 职责:参数校验、认证、调用服务层 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第3层:服务层 (app/services/stock_service.py) │
│ class StockService: │
│ def query_klines(self, req: KLineQueryRequest) -> KLineData: │
│ │
│ 职责:业务逻辑、数据聚合、缓存策略 │
│ 步骤: │
│ 1. 先查询数据库 (StockRepository) │
│ 2. 如无数据,调用适配器获取 │
│ 3. 保存到数据库 │
│ 4. 返回格式化数据 │
└─────────────────────────────────────────────────────────────────────────────┘
│ (如无缓存)
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第4层:适配器服务层 (app/services/adapter_service.py) │
│ class AdapterService: # 单例模式 │
│ def get_active_adapter(self, asset_class: str) -> DataSourceAdapter: │
│ │
│ 职责:管理适配器生命周期、连接管理、配置管理 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第5层:适配器实现 (app/adapters/amazingdata_adapter.py) │
│ class AmazingDataAdapter(DataSourceAdapter): │
│ async def fetch_klines(self, symbol, start, end, freq) -> List[KLine] │
│ │
│ 职责:适配器具体实现、数据格式转换、调用内部接口 │
│ │
│ 内部调用: │
│ self._internal.market.query_kline( │
│ code_list=[symbol], │
│ begin_date=int(start), │
│ end_date=int(end), │
│ period=10000 # SDK只支持日线 │
│ ) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第6层:内部数据服务层 (app/adapters/internal_data_service.py) │
│ class _MarketDataInternal: │
│ def query_kline(self, code_list, begin_date, end_date, period): │
│ return self._market_data.query_kline(...) │
│ │
│ 职责:SDK 封装、异常处理、日志记录 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第7层:SDK 层 (AmazingData) │
│ from AmazingData import MarketData │
│ market_data = MarketData(calendar) │
│ market_data.query_kline(code_list, begin_date, end_date, period) │
│ │
│ 职责:与银河证券星耀数智服务器通信 │
└─────────────────────────────────────────────────────────────────────────────┘
3.2 内部接口测试调用链
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第1层:管理后台点击"测试"按钮 │
│ POST /v1/admin/tests/internal/run │
│ Body: { "id": "internal_market_query_kline", "params": {...} } │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第2层:Admin 路由 (app/api/admin_routes.py) │
│ @admin_router.post("/admin/tests/internal/run") │
│ async def run_internal_test(req: APITestRequest, token): │
│ │
│ 职责:获取 adapter、确保连接、调用测试服务 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第3层:测试服务 (app/services/test_service.py) │
│ class TestService: │
│ async def run_internal_test(self, adapter, req: APITestRequest): │
│ │
│ 职责:根据 test_id 分发到对应的内部接口调用 │
│ │
│ 例如 req.id == "internal_market_query_kline": │
│ adapter._internal.market.query_kline(...) │
│ │
│ 例如 req.id == "internal_info_get_share_holder": │
│ adapter._internal.info.get_share_holder(...) # 创建新 InfoData 实例 │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第4层:内部数据服务层 (app/adapters/internal_data_service.py) │
│ │
│ 标准调用流程: │
│ def query_kline(self, ...): │
│ return self._market_data.query_kline(...) │
│ │
│ 特殊处理(get_share_holder): │
│ def get_share_holder(self, ...): │
│ # 创建新的 InfoData 实例以避免 SDK 内部状态问题 │
│ import AmazingData as ad │
│ info_data = ad.InfoData() # <-- 新实例 │
│ return info_data.get_share_holder(...) │
└─────────────────────────────────────────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ 第5层:SDK 层 (AmazingData) │
│ 与银河证券星耀数智服务器通信 │
└─────────────────────────────────────────────────────────────────────────────┘
四、关键代码片段
4.1 内部数据服务初始化
# app/adapters/amazingdata_adapter.py
class AmazingDataAdapter(DataSourceAdapter):
def __init__(self):
self._internal: Optional[InternalDataService] = None
def _do_login(self):
# 初始化 SDK 数据类
self._base_data = self._ad.BaseData()
self._info_data = self._ad.InfoData()
self._calendar = self._base_data.get_calendar()
self._market_data = self._ad.MarketData(self._calendar)
# 初始化内部数据服务层(关键!)
self._internal = InternalDataService(self)
4.2 内部数据服务封装
# app/adapters/internal_data_service.py
class InternalDataService:
"""内部数据服务统一入口"""
def __init__(self, ad):
"""
Args:
ad: AmazingDataAdapter instance with _market_data, _base_data, _info_data
"""
self.market = _MarketDataInternal(ad._market_data)
self.base = _BaseDataInternal(ad._base_data)
self.info = _InfoDataInternal(ad._info_data)
4.3 特殊处理:get_share_holder
# app/adapters/internal_data_service.py
class _InfoDataInternal:
def get_share_holder(self, code_list, local_path, is_local, begin_date=None, end_date=None):
"""获取股东数据"""
try:
# 创建新的 InfoData 实例以避免 SDK 内部状态问题
import AmazingData as ad
info_data = ad.InfoData()
return info_data.get_share_holder(
code_list=code_list,
local_path=local_path,
is_local=is_local,
begin_date=begin_date,
end_date=end_date
)
except Exception as e:
error(f"[_InfoDataInternal] Get share holder failed: {e}")
return {}
五、接口测试清单
5.1 对外接口测试 (18个)
| 分类 |
测试项 |
路径 |
| 股票接口 |
查询股票K线 |
GET /v1/stock/klines/{symbol} |
| 股票接口 |
查询股票列表 |
GET /v1/stock/symbols |
| 期货接口 |
查询期货K线 |
GET /v1/futures/klines/{symbol} |
| 期货接口 |
查询期货列表 |
GET /v1/futures/symbols |
| 管理接口 |
健康检查 |
GET /v1/admin/health |
| ... |
... |
... |
5.2 对内接口测试 (23个)
详见第二节接口清单,每个内部接口都有对应的测试用例。
六、配置说明
6.1 数据源配置 (config.json)
{
"sources": {
"stock": {
"active": "amazingdata",
"list": {
"amazingdata": {
"type": "sdk",
"config": {
"username": "your_username",
"password": "your_password",
"host": "140.206.44.234",
"port": "8600",
"local_path": "./amazing_data_cache/",
"use_local_cache": "true"
}
}
}
}
}
}
七、总结
- 对外接口:HTTP RESTful API,供外部系统调用
- 对内接口:SDK 封装层,通过
adapter._internal 访问
- 调用链:外部请求 → 路由 → 服务 → 适配器服务 → 适配器 → 内部接口 → SDK
- 特殊处理:
get_share_holder 每次创建新的 InfoData 实例以避免 SDK 状态问题
八、数据流向与缓存策略
8.1 数据流向图
┌─────────────────────────────────────────────────────────────────────────────┐
│ 数据流向架构 │
└─────────────────────────────────────────────────────────────────────────────┘
外部请求
│
▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ API │────▶│ Service│────▶│Repository│
│ Layer │ │ Layer │ │ Layer │
└────┬────┘ └────┬────┘ └────┬────┘
│ │ │
│ │ ▼
│ │ ┌─────────┐
│ │ │ MySQL │
│ │ │ Database│
│ │ └────┬────┘
│ │ │
│ ▼ │
│ ┌─────────┐ │
│ │ Adapter │ │
│ │ Service │ │
│ └────┬────┘ │
│ │ │
▼ ▼ ▼
┌─────────────────────────────────────────┐
│ AmazingDataAdapter │
│ ┌─────────────────────────────────┐ │
│ │ InternalDataService │ │
│ │ ┌─────────┐ ┌─────────┐ │ │
│ │ │ _Market │ │ _Base │ ... │ │
│ │ │ _Data │ │ _Data │ │ │
│ │ └────┬────┘ └────┬────┘ │ │
│ └───────┼───────────┼────────────┘ │
└──────────┼───────────┼─────────────────┘
│ │
▼ ▼
┌─────────────────────────────────────────┐
│ AmazingData SDK │
│ MarketData BaseData InfoData │
└─────────────────────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 银河证券星耀数智服务器 │
└─────────────────────────────────────────┘
8.2 缓存策略
# 数据获取优先级
1. 内存缓存 (Redis) - 最高优先级,实时数据
2. 数据库 (MySQL) - 持久化存储,历史数据
3. SDK 实时获取 - 兜底方案,网络请求
缓存规则:
| 数据类型 |
缓存位置 |
缓存时间 |
更新策略 |
| K线数据 |
MySQL + Redis |
永久 + 5分钟 |
懒加载 |
| 股票列表 |
MySQL |
永久 |
每日同步 |
| 实时行情 |
Redis |
1分钟 |
实时推送 |
| 财务数据 |
MySQL |
永久 |
季度更新 |
九、错误处理机制
9.1 错误处理层级
┌─────────────────────────────────────────────────────────────────────────────┐
│ 错误处理流程 │
└─────────────────────────────────────────────────────────────────────────────┘
SDK 错误
│
▼
┌─────────────────┐
│ Internal Layer │ 捕获异常,记录日志,返回默认值
│ try/except │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Adapter Layer │ 转换数据格式,处理空值
│ │
└────────┬────────┘
│
▼
┌─────────────────┐
│ Service Layer │ 业务逻辑判断,降级策略
│ │
└────────┬────────┘
│
▼
┌─────────────────┐
│ API Layer │ 包装错误响应,HTTP 状态码
│ │
└────────┬────────┘
│
▼
客户端收到错误响应
9.2 错误码定义
| 错误码 |
说明 |
处理方式 |
| 0 |
成功 |
- |
| 400 |
请求参数错误 |
检查参数格式 |
| 401 |
未授权 |
检查 API Key |
| 404 |
数据不存在 |
尝试从 SDK 获取 |
| 500 |
服务器内部错误 |
查看日志,联系管理员 |
| 503 |
数据源不可用 |
检查适配器连接状态 |
9.3 内部接口错误处理示例
# app/adapters/internal_data_service.py
class _MarketDataInternal:
def query_kline(self, code_list, begin_date, end_date, period):
"""查询K线数据 - 带错误处理"""
try:
return self._market_data.query_kline(
code_list=code_list,
begin_date=begin_date,
end_date=end_date,
period=period
)
except Exception as e:
# 记录详细错误日志
error(f"[_MarketDataInternal] Query kline failed: {e}")
error(f" Params: code_list={code_list}, period={period}")
# 返回空结果而非抛出异常,保证服务可用性
return {}
十、WebSocket 实时数据接口
10.1 WebSocket 连接
ws://localhost:8080/v1/stream
10.2 消息类型
| 消息类型 |
方向 |
说明 |
| subscribe |
C→S |
订阅标的 |
| unsubscribe |
C→S |
取消订阅 |
| tick |
S→C |
实时 tick 数据 |
| kline |
S→C |
实时 K线数据 |
| error |
S→C |
错误通知 |
10.3 订阅示例
// 客户端订阅
const ws = new WebSocket('ws://localhost:8080/v1/stream');
ws.onopen = () => {
// 订阅股票
ws.send(JSON.stringify({
action: 'subscribe',
symbols: ['000001.SZ', '000002.SZ']
}));
};
ws.onmessage = (event) => {
const data = JSON.parse(event.data);
console.log('收到数据:', data);
};
10.4 WebSocket 调用链
客户端订阅
│
▼
WebSocket Endpoint
│
▼
StreamService
│
▼
AdapterService.get_adapter("stock")
│
▼
AmazingDataAdapter.subscribe_tick(symbols, callback)
│
▼
AmazingData.MarketData.subscribe(...) # SDK 订阅
│
▼
数据推送回调
│
▼
WebSocket 发送给客户端
十一、数据同步机制
11.1 同步任务类型
┌─────────────────────────────────────────────────────────────────────────────┐
│ 数据同步架构 │
└─────────────────────────────────────────────────────────────────────────────┘
┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐
│ 股票K线同步 │ │ 期货K线同步 │ │ 股票列表同步│ │ 财务数据同步│
└──────┬──────┘ └──────┬──────┘ └──────┬──────┘ └──────┬──────┘
│ │ │ │
└────────────────┴────────────────┴────────────────┘
│
▼
┌─────────────────┐
│ Sync Service │
└────────┬────────┘
│
┌────────────┼────────────┐
▼ ▼ ▼
┌─────────┐ ┌─────────┐ ┌─────────┐
│ Daily │ │ Weekly │ │ Manual │
│ Sync │ │ Sync │ │ Sync │
└─────────┘ └─────────┘ └─────────┘
11.2 同步接口
| 接口 |
方法 |
路径 |
说明 |
| 手动同步 |
POST |
/v1/admin/data/sync |
触发指定类型的数据同步 |
11.3 同步调用链
POST /v1/admin/data/sync
│
▼
AdminService.sync_data(sync_type)
│
├── sync_type = "base" → 同步基础K线
├── sync_type = "quote" → 同步行情指标
├── sync_type = "finance" → 同步财务数据
└── sync_type = "full" → 全量同步
│
▼
AmazingDataAdapter.fetch_stock_basic_info()
│
▼
InternalDataService.base.get_code_list()
InternalDataService.base.get_code_info()
InternalDataService.info.get_equity_structure()
│
▼
保存到 MySQL
十二、数据库表结构
12.1 表清单
| 表名 |
说明 |
数据来源 |
stock_symbols |
股票基础信息 |
SDK BaseData |
stock_klines_1d_base |
股票日线基础数据 |
SDK MarketData |
stock_klines_1d_quote |
股票日线行情指标 |
SDK MarketData |
stock_klines_1d_finance |
股票日线财务数据 |
SDK InfoData |
futures_klines_1d_base |
期货日线基础数据 |
SDK MarketData |
futures_klines_1d_quote |
期货日线行情指标 |
SDK MarketData |
realtime_quotes |
实时行情数据 |
SDK MarketData |
sync_tasks |
同步任务记录 |
系统生成 |
12.2 分表策略
stock_klines_*
├── stock_klines_1d_base # 日线基础K线 (OHLCV)
├── stock_klines_1d_quote # 日线行情指标 (均线、MACD等)
├── stock_klines_1d_finance # 日线财务数据 (市值、PE等)
├── stock_klines_1m_base # 分钟线基础数据
└── stock_klines_5m_base # 5分钟线基础数据
十三、部署与运维
13.1 启动流程
# 1. 启动服务
python -m uvicorn app.main:app --host 0.0.0.0 --port 8080
# 2. 服务初始化流程
main.py
│
├── 加载配置 (config.json)
│
├── 初始化数据库连接
│
├── 初始化 Redis 连接
│
└── 启动 FastAPI 服务
│
└── 首次请求时懒加载适配器
13.2 适配器连接流程
首次请求
│
▼
AdapterService.get_active_adapter("stock")
│
├── 检查 active_adapters 缓存
│ ├── 存在且已连接 → 直接返回
│ └── 不存在或断开 → 创建新连接
│
▼
AmazingDataAdapter.connect(config)
│
├── 登录 SDK
│ AmazingData.login(username, password, host, port)
│
├── 初始化数据类
│ BaseData(), InfoData(), MarketData()
│
└── 初始化 InternalDataService
│ self._internal = InternalDataService(self)
│
▼
保存到 active_adapters 缓存
13.3 健康检查
# 健康检查接口
GET /v1/admin/health
# 响应示例
{
"code": 0,
"message": "success",
"data": {
"status": "healthy",
"database": "connected",
"redis": "connected",
"adapters": {
"amazingdata": "connected"
}
}
}
十四、开发指南
14.1 新增对外接口
# 1. 在 routes.py 添加路由
@router.get("/stock/new_endpoint/{param}")
def new_endpoint(param: str, db: Session = Depends(get_db)):
service = StockService(db)
return service.new_method(param)
# 2. 在 service 实现业务逻辑
class StockService:
def new_method(self, param):
# 业务逻辑
return result
# 3. 如需 SDK 数据,在 adapter 添加方法
class AmazingDataAdapter:
async def fetch_new_data(self, param):
return self._internal.xxx.method(param)
14.2 新增对内接口
# 1. 在 internal_data_service.py 添加方法
class _InfoDataInternal:
def new_internal_method(self, param):
try:
return self._info_data.sdk_method(param)
except Exception as e:
error(f"[_InfoDataInternal] new method failed: {e}")
return default_value
# 2. 在 test_service.py 添加测试用例
APITestCase(
id="internal_info_new_method",
name="SDK: new_method",
description="...",
method="INTERNAL",
path="AmazingDataAdapter._internal.info.new_internal_method"
)
14.3 调用关系速查
需要调用 SDK 的接口:
↓
adapter._internal.{category}.{method}
category 可选值:
- market: 市场数据 (K线、快照)
- base: 基础数据 (代码列表、日历、复权因子)
- info: 信息数据 (财务、股本、融资融券等)
十五、附录
15.1 SDK Period 参数对照表
| 周期 |
SDK 参数值 |
说明 |
| 日线 |
10000 |
仅支持此值 |
| 1分钟 |
- |
SDK 不支持 |
| 5分钟 |
- |
SDK 不支持 |
注意:当前 SDK 版本 query_kline 仅支持 period=10000(日线),其他值会导致 'NoneType' object cannot be interpreted as an integer 错误。
15.2 文件结构
app/
├── api/
│ ├── routes.py # 对外接口路由
│ └── admin_routes.py # 管理后台路由
├── services/
│ ├── stock_service.py # 股票业务服务
│ ├── futures_service.py # 期货业务服务
│ ├── adapter_service.py # 适配器管理服务
│ └── test_service.py # 测试服务
├── adapters/
│ ├── amazingdata_adapter.py # 星耀数智适配器
│ ├── internal_data_service.py # 内部数据服务层
│ └── base.py # 适配器基类
├── models/ # 数据模型
├── repositories/ # 数据访问层
└── core/ # 核心工具
15.3 关键配置项
| 配置项 |
说明 |
默认值 |
sources.stock.active |
当前激活的股票数据源 |
amazingdata |
sources.stock.list.amazingdata.config.local_path |
本地缓存路径 |
./amazing_data_cache/ |
sources.stock.list.amazingdata.config.use_local_cache |
是否使用本地缓存 |
true |
文档版本: 1.0
最后更新: 2026-03-15
适用版本: Python Market Data Service