feat(data): 财务数据加载与清洗模块

新增 FinancialLoader 类,提供:
- 财务数据加载与清洗(保留合并报表,按 update_flag 去重)
- 支持 as-of join 拼接行情数据(无未来函数)
- 自动识别财务表并配置 asof_backward 拼接模式
This commit is contained in:
2026-03-04 23:35:20 +08:00
parent 620696c842
commit 3b42093100
12 changed files with 695 additions and 379 deletions

View File

@@ -1,795 +0,0 @@
# ProStock 数据接口封装规范
## 1. 概述
本文档定义了新增 Tushare API 接口封装的标准规范。所有非特殊接口必须遵循此规范,确保:
- 代码风格统一
- 自动 sync 支持
- 增量更新逻辑一致
- 减少存储写入压力
- 类型安全(强制类型提示)
### 1.1 技术栈
- **存储层**: DuckDB高性能嵌入式 OLAP 数据库)
- **数据格式**: Pandas DataFrame / Polars DataFrame
- **速率限制**: 令牌桶算法TokenBucketRateLimiter
- **并发**: ThreadPoolExecutor 多线程
- **类型系统**: Python 3.10+ 类型提示
### 1.2 自动化支持
项目提供 `prostock-api-interface` Skill 来自动化接口封装流程。在 `api.md` 中定义接口后,调用该 Skill 可自动生成:
- 数据模块文件(`src/data/api_wrappers/api_{data_type}.py`
- 数据库表管理配置
- 测试文件(`tests/test_{data_type}.py`
## 2. 接口分类
### 2.1 特殊接口(不参与统一 sync
以下接口有独立的同步逻辑,不参与自动 sync 机制:
| 接口类型 | 文件名 | 说明 |
|---------|--------|------|
| 交易日历 | `api_trade_cal.py` | 全局数据,按日期范围获取,使用 HDF5 缓存 |
| 股票基础信息 | `api_stock_basic.py` | 一次性全量获取CSV 存储 |
| 辅助数据 | `api_industry`, `api_concept` | 低频更新,独立管理 |
### 2.2 标准接口(必须遵循本规范)
所有按股票或按日期获取的因子数据、行情数据、财务数据等,必须遵循本规范:
- 按日期获取:**优先选择**,支持全市场批量获取
- 按股票获取:仅当 API 不支持按日期获取时使用
## 3. 文件结构要求
### 3.1 文件命名
```
api_{data_type}.py
```
- 示例:`api_daily.py``api_moneyflow.py``api_limit_list.py`
- **必须**以 `api_` 前缀开头
- 使用小写字母和下划线
### 3.2 文件位置
所有接口文件必须位于 `src/data/api_wrappers/` 目录下。
### 3.3 导出要求
新接口必须在 `src/data/api_wrappers/__init__.py` 中导出:
```python
from src.data.api_wrappers.api_{data_type} import get_{data_type}
__all__ = [
# ... 其他导出 ...
"get_{data_type}",
]
```
## 4. 接口设计规范
### 4.1 数据获取函数签名要求
函数必须返回 `pd.DataFrame`,参数必须包含以下之一:
#### 4.1.1 按日期获取的接口(优先)
适用于:涨跌停、龙虎榜、筹码分布、每日指标等。
**函数签名要求**
```python
def get_{data_type}(
trade_date: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
ts_code: Optional[str] = None,
# 其他可选参数...
) -> pd.DataFrame:
```
**要求**
- 优先使用 `trade_date` 获取单日全市场数据
- 支持 `start_date + end_date` 获取区间数据
- `ts_code` 作为可选过滤参数
- **性能优势**: 单日全市场数据一次 API 调用即可完成
#### 4.1.2 按股票获取的接口
适用于:日线行情、资金流向等。
**函数签名要求**
```python
def get_{data_type}(
ts_code: str,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
# 其他可选参数...
) -> pd.DataFrame:
```
**要求**
- `ts_code` 为必选参数
- 需要遍历所有股票获取全市场数据
### 4.2 文档字符串要求
函数必须包含 **Google 风格**的完整文档字符串,包含:
```python
def get_{data_type}(...) -> pd.DataFrame:
"""Fetch {数据描述} from Tushare.
This interface retrieves {详细描述}.
Args:
ts_code: Stock code (e.g., '000001.SZ', '600000.SH')
trade_date: Specific trade date (YYYYMMDD format)
start_date: Start date (YYYYMMDD format)
end_date: End date (YYYYMMDD format)
# 其他参数...
Returns:
pd.DataFrame with columns:
- ts_code: Stock code
- trade_date: Trade date (YYYYMMDD)
- {其他字段}: {字段描述}
Example:
>>> # Get single date data for all stocks
>>> data = get_{data_type}(trade_date='20240101')
>>>
>>> # Get date range data
>>> data = get_{data_type}(start_date='20240101', end_date='20240131')
>>>
>>> # Get specific stock data
>>> data = get_{data_type}(ts_code='000001.SZ', trade_date='20240101')
"""
```
### 4.3 日期格式要求
- 所有日期参数使用 **YYYYMMDD** 字符串格式
- 统一使用 `trade_date` 作为日期字段名
- 如果 API 返回其他日期字段名(如 `date``end_date`),必须在返回前重命名为 `trade_date`
```python
if "date" in data.columns:
data = data.rename(columns={"date": "trade_date"})
```
### 4.4 股票代码要求
- 统一使用 `ts_code` 作为股票代码字段名
- 格式:`{code}.{exchange}`,如 `000001.SZ``600000.SH`
- 确保返回的 DataFrame 包含 `ts_code`
### 4.5 字段名规范(重要)
**必须使用 Tushare API 返回的原始字段名,禁止进行不必要的重命名。**
这是为了确保:
- 代码可读性:使用 API 文档中的标准字段名
- 维护简单性:避免因字段名映射导致的混淆和错误
- 数据一致性:数据库字段名与 API 返回字段名保持一致
**禁止做法**(以下代码是不允许的):
```python
# 错误:将 Tushare 的原始字段名改为自定义名称
column_mapping = {
"turnover_rate": "tor", # 不要这样做
"volume_ratio": "vr", # 不要这样做
}
data = data.rename(columns=column_mapping)
```
**正确做法**(直接使用原始字段名):
```python
# 正确:保留 Tushare 返回的原始字段名
# Tushare 返回 'turnover_rate',就直接使用 'turnover_rate'
# Tushare 返回 'volume_ratio',就直接使用 'volume_ratio'
# 表结构定义应使用原始字段名
TABLE_SCHEMA = {
"ts_code": "VARCHAR(16) NOT NULL",
"trade_date": "DATE NOT NULL",
"turnover_rate": "DOUBLE", # 使用原始字段名
"volume_ratio": "DOUBLE", # 使用原始字段名
# ... 其他字段
}
```
**例外情况**(允许重命名):
- 日期字段:如果 API 返回 `date`,应重命名为 `trade_date` 以符合项目规范
- 必须重命名的情况:如果两个不同 API 返回相同含义但不同名称的字段,需要统一命名
**教训**(真实案例):
`api_pro_bar.py` 早期版本将 `turnover_rate` 重命名为 `tor``volume_ratio` 重命名为 `vr`
导致:
1. 代码与 Tushare 文档不一致,增加学习成本
2. 数据库字段名与 API 字段名不一致,造成混淆
3. 需要额外的数据迁移脚本修复历史数据
### 4.6 令牌桶限速要求
所有 API 调用必须通过 `TushareClient`,自动满足令牌桶限速要求。
#### 4.6.1 基本用法(单线程场景)
```python
from src.data.client import TushareClient
def get_{data_type}(...) -> pd.DataFrame:
client = TushareClient()
# Build parameters
params = {}
if trade_date:
params["trade_date"] = trade_date
if ts_code:
params["ts_code"] = ts_code
# ...
# Fetch data (rate limiting handled automatically)
data = client.query("{api_name}", **params)
return data
```
**注意**: `TushareClient` 自动处理:
- 令牌桶速率限制
- API 重试逻辑(指数退避)
- 配置加载
#### 4.6.2 多线程/并发场景(重要)
**问题**: 多线程并发调用时,如果每个线程创建独立的 `TushareClient` 实例,每个实例会有独立的限流器,导致实际并发请求数 = 线程数 × 单个限流器速率,**限流失效**。
**解决方案**: 数据获取函数必须接受可选的 `client` 参数Sync 类传递共享的客户端实例。
**数据获取函数签名**(必须支持 client 参数):
```python
from src.data.client import TushareClient
from typing import Optional
def get_{data_type}(
ts_code: str,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
client: Optional[TushareClient] = None, # 新增:可选客户端参数
) -> pd.DataFrame:
"""Fetch {数据描述} from Tushare.
Args:
ts_code: Stock code
start_date: Start date (YYYYMMDD)
end_date: End date (YYYYMMDD)
client: Optional TushareClient instance for shared rate limiting.
If None, creates a new client. For concurrent sync operations,
pass a shared client to ensure proper rate limiting.
Returns:
pd.DataFrame with data
"""
client = client or TushareClient() # 如果没有提供则创建新实例
params = {"ts_code": ts_code}
if start_date:
params["start_date"] = start_date
if end_date:
params["end_date"] = end_date
data = client.query("{api_name}", **params)
return data
```
**Sync 类实现**(必须传递共享 client
```python
from concurrent.futures import ThreadPoolExecutor
from src.data.client import TushareClient
from src.data.storage import ThreadSafeStorage
class {DataType}Sync:
def __init__(self, max_workers: Optional[int] = None):
self.storage = ThreadSafeStorage()
self.client = TushareClient() # 共享客户端实例
self.max_workers = max_workers or 10
def sync_single_stock(
self,
ts_code: str,
start_date: str,
end_date: str,
) -> pd.DataFrame:
"""同步单只股票的数据。"""
# 传递共享 client 以确保多线程下的限流生效
data = get_{data_type}(
ts_code=ts_code,
start_date=start_date,
end_date=end_date,
client=self.client, # 关键:传递共享客户端
)
return data
def sync_all(self, ...):
# 使用 ThreadPoolExecutor 并发执行
with ThreadPoolExecutor(max_workers=self.max_workers) as executor:
# 所有线程共享 self.client限流器正常工作
...
```
**关键规则**:
1. 所有按股票获取的接口必须接受 `client: Optional[TushareClient] = None` 参数
2. Sync 类在 `__init__` 中创建 `self.client = TushareClient()`
3. Sync 类的同步方法必须将 `self.client` 传递给数据获取函数
4. 数据获取函数使用 `client = client or TushareClient()` 模式
所有 API 调用必须通过 `TushareClient`,自动满足令牌桶限速要求:
```python
from src.data.client import TushareClient
def get_{data_type}(...) -> pd.DataFrame:
client = TushareClient()
# Build parameters
params = {}
if trade_date:
params["trade_date"] = trade_date
if ts_code:
params["ts_code"] = ts_code
# ...
# Fetch data (rate limiting handled automatically)
data = client.query("{api_name}", **params)
return data
```
**注意**: `TushareClient` 自动处理:
- 令牌桶速率限制
- API 重试逻辑(指数退避)
- 配置加载
## 5. DuckDB 存储规范
### 5.0 强制落库要求(关键)
**所有封装的 API 接口必须将数据落库到 DuckDB。**
这是数据同步的核心原则,确保:
- 数据持久化:避免重复调用 API节省 token
- 增量更新:基于本地数据状态进行智能同步
- 数据一致性:所有数据都有统一的存储和访问方式
- 离线可用:数据可以在没有网络的情况下查询
**落库检查清单**
- [ ]`storage.py``_init_db()` 方法中创建对应的表
- [ ] 表结构必须包含 `ts_code``trade_date` 作为主键
- [ ] 实现 `sync_{data_type}()` 函数,使用 `Storage``ThreadSafeStorage` 保存数据
- [ ] 确保同步逻辑正确处理增量更新
**反例警示**`api_pro_bar.py` 早期版本虽然实现了 `sync_pro_bar()` 函数,但忘记在 `storage.py` 中创建 `pro_bar` 表,导致同步的数据无法落库,造成 token 浪费和数据丢失。
### 5.1 存储架构
### 5.1 存储架构
项目使用 **DuckDB** 作为持久化存储:
- **单例模式**: `Storage` 类确保单一数据库连接
- **线程安全**: `ThreadSafeStorage` 提供并发写入支持
- **UPSERT 支持**: `INSERT OR REPLACE` 自动处理重复数据
- **查询下推**: WHERE 条件在数据库层过滤
### 5.2 表结构设计
每个数据类型对应一个 DuckDB 表:
```sql
CREATE TABLE {data_type} (
ts_code VARCHAR(16) NOT NULL,
trade_date DATE NOT NULL,
# ...
PRIMARY KEY (ts_code, trade_date)
);
CREATE INDEX idx_{data_type}_date_code ON {data_type}(trade_date, ts_code);
```
**主键要求**:
- 必须包含 `ts_code``trade_date`
- 使用 UPSERT 确保幂等性
### 5.3 存储写入策略
**批量写入模式**(推荐用于多线程场景):
```python
from src.data.storage import ThreadSafeStorage
def sync_{data_type}(self, ...):
storage = ThreadSafeStorage()
# 收集数据到队列(不立即写入)
for data_chunk in data_generator:
storage.queue_save("{data_type}", data_chunk)
# 批量写入所有数据
storage.flush()
```
**直接写入模式**(适用于简单场景):
```python
from src.data.storage import Storage
storage = Storage()
storage.save("{data_type}", data, mode="append")
```
### 5.4 数据类型映射
标准字段类型映射(`DEFAULT_TYPE_MAPPING`
```python
DEFAULT_TYPE_MAPPING = {
"ts_code": "VARCHAR(16)",
"trade_date": "DATE",
"open": "DOUBLE",
"high": "DOUBLE",
"low": "DOUBLE",
"close": "DOUBLE",
"vol": "DOUBLE",
"amount": "DOUBLE",
# ... 其他字段
}
```
## 6. Sync 集成规范
### 6.1 使用 db_manager 进行同步
项目使用 `db_manager` 模块提供高级同步功能:
```python
from src.data.db_manager import SyncManager, ensure_table
def sync_{data_type}(force_full: bool = False) -> pd.DataFrame:
"""Sync {数据描述} to DuckDB."""
manager = SyncManager()
# 确保表存在
ensure_table("{data_type}", schema={
"ts_code": "VARCHAR(16)",
"trade_date": "DATE",
# ... 其他字段
})
# 执行同步
result = manager.sync(
table_name="{data_type}",
fetch_func=get_{data_type},
start_date=start_date,
end_date=end_date,
force_full=force_full,
)
return result
```
### 6.2 增量更新逻辑
`SyncManager` 自动处理增量更新:
1. **检查本地最新日期**: 从 DuckDB 获取 `MAX(trade_date)`
2. **获取交易日历**: 从 `api_trade_cal` 获取交易日范围
3. **计算需要同步的日期**: 本地最新日期 + 1 到最新交易日
4. **批量获取数据**: 按日期或按股票获取
5. **批量写入**: 使用 `ThreadSafeStorage` 队列写入
### 6.3 便捷函数
每个接口必须提供顶层便捷函数:
```python
def sync_{data_type}(force_full: bool = False) -> pd.DataFrame:
"""Sync {数据描述} to local storage.
Args:
force_full: If True, force full reload from 20180101
Returns:
DataFrame with synced data
"""
# Implementation...
```
## 7. 代码模板
### 7.1 按日期获取接口模板
```python
"""{数据描述} interface.
Fetch {数据描述} data from Tushare.
"""
import pandas as pd
from typing import Optional
from src.data.client import TushareClient
def get_{data_type}(
trade_date: Optional[str] = None,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
ts_code: Optional[str] = None,
) -> pd.DataFrame:
"""Fetch {数据描述} from Tushare.
This interface retrieves {详细描述}.
Args:
trade_date: Specific trade date (YYYYMMDD format)
start_date: Start date (YYYYMMDD format)
end_date: End date (YYYYMMDD format)
ts_code: Stock code filter (optional)
Returns:
pd.DataFrame with columns:
- ts_code: Stock code
- trade_date: Trade date (YYYYMMDD)
- {字段1}: {描述}
- {字段2}: {描述}
Example:
>>> # Get all stocks for a single date
>>> data = get_{data_type}(trade_date='20240101')
>>>
>>> # Get date range data
>>> data = get_{data_type}(start_date='20240101', end_date='20240131')
"""
client = TushareClient()
# Build parameters
params = {}
if trade_date:
params["trade_date"] = trade_date
if start_date:
params["start_date"] = start_date
if end_date:
params["end_date"] = end_date
if ts_code:
params["ts_code"] = ts_code
# Fetch data
data = client.query("{tushare_api_name}", **params)
# Rename date column if needed
if "date" in data.columns:
data = data.rename(columns={"date": "trade_date"})
return data
```
### 7.2 按股票获取接口模板
```python
"""{数据描述} interface.
Fetch {数据描述} data from Tushare (per stock).
"""
import pandas as pd
from typing import Optional
from src.data.client import TushareClient
def get_{data_type}(
ts_code: str,
start_date: Optional[str] = None,
end_date: Optional[str] = None,
) -> pd.DataFrame:
"""Fetch {数据描述} for a specific stock.
Args:
ts_code: Stock code (e.g., '000001.SZ')
start_date: Start date (YYYYMMDD format)
end_date: End date (YYYYMMDD format)
Returns:
pd.DataFrame with {数据描述} data
"""
client = TushareClient()
params = {"ts_code": ts_code}
if start_date:
params["start_date"] = start_date
if end_date:
params["end_date"] = end_date
data = client.query("{tushare_api_name}", **params)
return data
```
### 7.3 Sync 函数模板
```python
from src.data.db_manager import SyncManager, ensure_table
from src.data.api_wrappers import get_{data_type}
def sync_{data_type}(force_full: bool = False) -> pd.DataFrame:
"""Sync {数据描述} to local DuckDB storage.
Args:
force_full: If True, force full reload from 20180101
Returns:
DataFrame with synced data
"""
manager = SyncManager()
# Ensure table exists with proper schema
ensure_table("{data_type}", schema={
"ts_code": "VARCHAR(16)",
"trade_date": "DATE",
# Add other fields...
})
# Perform sync
result = manager.sync(
table_name="{data_type}",
fetch_func=get_{data_type},
force_full=force_full,
)
return result
```
## 8. 测试规范
### 8.1 测试文件要求
必须创建对应的测试文件:`tests/test_{data_type}.py`
### 8.2 测试覆盖要求
```python
import pytest
import pandas as pd
from unittest.mock import patch, MagicMock
from src.data.api_wrappers.api_{data_type} import get_{data_type}
class Test{DataType}:
"""Test suite for {data_type} API wrapper."""
@patch("src.data.api_wrappers.api_{data_type}.TushareClient")
def test_get_by_date(self, mock_client_class):
"""Test fetching data by date."""
# Setup mock
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.query.return_value = pd.DataFrame({
"ts_code": ["000001.SZ"],
"trade_date": ["20240101"],
# ... other columns
})
# Test
result = get_{data_type}(trade_date="20240101")
# Assert
assert not result.empty
assert "ts_code" in result.columns
assert "trade_date" in result.columns
mock_client.query.assert_called_once()
@patch("src.data.api_wrappers.api_{data_type}.TushareClient")
def test_get_by_stock(self, mock_client_class):
"""Test fetching data by stock code."""
# Similar setup...
pass
@patch("src.data.api_wrappers.api_{data_type}.TushareClient")
def test_empty_response(self, mock_client_class):
"""Test handling empty response."""
mock_client = MagicMock()
mock_client_class.return_value = mock_client
mock_client.query.return_value = pd.DataFrame()
result = get_{data_type}(trade_date="20240101")
assert result.empty
```
### 8.3 Mock 规范
- 在导入位置打补丁:`patch('src.data.api_wrappers.api_{data_type}.TushareClient')`
- 测试正常和异常情况
- 验证参数传递正确
## 9. 使用 Skill 自动生成
### 9.1 准备工作
1.`api.md` 中定义接口信息,包含:
- 接口名称和描述
- 输入参数(名称、类型、必选、描述)
- 输出参数(名称、类型、描述)
### 9.2 调用 Skill
告知 Claude 要封装的接口名称:
> "帮我封装 {data_type} 接口"
> "为 {data_type} 接口生成代码"
### 9.3 自动生成内容
Skill 会自动:
1. 解析 `api.md` 中的接口定义
2. 生成 `src/data/api_wrappers/api_{data_type}.py`
3. 更新 `src/data/api_wrappers/__init__.py` 导出
4. 生成 `tests/test_{data_type}.py` 测试文件
5. 提供 `sync_{data_type}()` 函数模板
## 10. 检查清单
### 10.1 文件结构
- [ ] 文件位于 `src/data/api_wrappers/api_{data_type}.py`
- [ ] 已更新 `src/data/api_wrappers/__init__.py` 导出公共接口
- [ ] 已创建 `tests/test_{data_type}.py` 测试文件
### 10.2 接口实现
- [ ] 数据获取函数使用 `TushareClient`
- [ ] 函数包含完整的 Google 风格文档字符串
- [ ] 日期参数使用 `YYYYMMDD` 格式
- [ ] 返回的 DataFrame 包含 `ts_code``trade_date` 字段
- [ ] 优先实现按日期获取的接口(如果 API 支持)
- [ ] 参数传递前检查是否为 None
### 10.3 存储集成
- [ ] 使用 `Storage``ThreadSafeStorage` 进行数据存储
- [ ] 表结构包含 `ts_code``trade_date` 作为主键
- [ ] 使用 UPSERT 模式(`INSERT OR REPLACE`
- [ ] 多线程场景使用 `queue_save()` + `flush()` 模式
### 10.4 Sync 集成
- [ ] 使用 `db_manager` 模块进行同步管理
- [ ] 实现 `sync_{data_type}()` 便捷函数
- [ ] 支持 `force_full` 参数
- [ ] 增量更新逻辑正确
### 10.5 测试
- [ ] 已编写单元测试
- [ ] 已 mock `TushareClient`
- [ ] 测试覆盖按日期和按股票获取
- [ ] 测试覆盖正常和异常情况
## 11. 示例参考
### 11.1 完整示例api_daily.py
参见 `src/data/api_wrappers/api_daily.py` - 按股票获取日线数据的完整实现。
### 11.2 完整示例api_trade_cal.py
参见 `src/data/api_wrappers/api_trade_cal.py` - 特殊接口(交易日历)的实现,包含 HDF5 缓存逻辑。
### 11.3 完整示例api_stock_basic.py
参见 `src/data/api_wrappers/api_stock_basic.py` - 特殊接口(股票基础信息)的实现,包含 CSV 存储逻辑。
---
**最后更新**: 2026-02-23
**版本**: v2.0 - 更新 DuckDB 存储规范,添加 Skill 自动化说明

View File

@@ -1,621 +0,0 @@
1、通用行情接口https://tushare.pro/document/2?doc_id=109能够获取的字段参考https://tushare.pro/document/2?doc_id=27要求保存A股日线行情中所有输出字段和tor换手率 vr量比
ts_code str Y 证券代码,不支持多值输入,多值输入获取结果会有重复记录
start_date str N 开始日期 (日线格式YYYYMMDD提取分钟数据请用2019-09-01 09:00:00这种格式)
end_date str N 结束日期 (日线格式YYYYMMDD)
asset str Y 资产类别E股票 I沪深指数 C数字货币 FT期货 FD基金 O期权 CB可转债v1.2.39默认E
adj str N 复权类型(只针对股票)None未复权 qfq前复权 hfq后复权 , 默认None目前只支持日线复权同时复权机制是根据设定的end_date参数动态复权采用分红再投模式具体请参考常见问题列表里的说明。
freq str Y 数据频度 :支持分钟(min)/日(D)/周(W)/月(M)K线其中1min表示1分钟类推1/5/15/30/60分钟 默认D。对于分钟数据有600积分用户可以试用请求2次正式权限可以参考权限列表说明 ,使用方法请参考股票分钟使用方法。
ma list N 均线支持任意合理int数值。注均线是动态计算要设置一定时间范围才能获得相应的均线比如5日均线开始和结束日期参数跨度必须要超过5日。目前只支持单一个股票提取均线即需要输入ts_code参数。e.g: ma_5表示5日均价ma_v_5表示5日均量
factors list N 股票因子asset='E'有效)支持 tor换手率 vr量比
adjfactor str N 复权因子在复权数据时如果此参数为True返回的数据中则带复权因子默认为False。 该功能从1.2.33版本开始生效
输出指标
具体输出的数据指标可参考各行情具体指标:
股票Dailyhttps://tushare.pro/document/2?doc_id=27
基金Dailyhttps://tushare.pro/document/2?doc_id=127
期货Dailyhttps://tushare.pro/document/2?doc_id=138
期权Dailyhttps://tushare.pro/document/2?doc_id=159
指数Dailyhttps://tushare.pro/document/2?doc_id=95
A股日线行情
接口daily可以通过数据工具调试和查看数据
数据说明交易日每天15点16点之间入库。本接口是未复权行情停牌期间不提供数据
调取说明基础积分每分钟内可调取500次每次6000条数据一次请求相当于提取一个股票23年历史
描述:获取股票行情数据,或通过通用行情接口获取数据,包含了前后复权数据
输入参数
名称 类型 必选 描述
ts_code str N 股票代码(支持多个股票同时提取,逗号分隔)
trade_date str N 交易日期YYYYMMDD
start_date str N 开始日期(YYYYMMDD)
end_date str N 结束日期(YYYYMMDD)
日期都填YYYYMMDD格式比如20181010
输出参数
名称 类型 描述
ts_code str 股票代码
trade_date str 交易日期
open float 开盘价
high float 最高价
low float 最低价
close float 收盘价
pre_close float 昨收价【除权价】
change float 涨跌额
pct_chg float 涨跌幅 【基于除权后的昨收计算的涨跌幅:(今收-除权昨收)/除权昨收 】
vol float 成交量 (手)
amount float 成交额 (千元)
接口用例
#取000001的前复权行情
df = ts.pro_bar(ts_code='000001.SZ', adj='qfq', start_date='20180101', end_date='20181011')
ts_code trade_date open high low close \
trade_date
20181011 000001.SZ 20181011 1085.71 1097.59 1047.90 1065.19
20181010 000001.SZ 20181010 1138.65 1151.61 1121.36 1128.92
20181009 000001.SZ 20181009 1130.00 1155.93 1122.44 1140.81
20181008 000001.SZ 20181008 1155.93 1165.65 1128.92 1128.92
20180928 000001.SZ 20180928 1164.57 1217.51 1164.57 1193.74
#取上证指数行情数据
df = ts.pro_bar(ts_code='000001.SH', asset='I', start_date='20180101', end_date='20181011')
In [10]: df.head()
Out[10]:
ts_code trade_date close open high low \
0 000001.SH 20181011 2583.4575 2643.0740 2661.2859 2560.3164
1 000001.SH 20181010 2725.8367 2723.7242 2743.5480 2703.0626
2 000001.SH 20181009 2721.0130 2713.7319 2734.3142 2711.1971
3 000001.SH 20181008 2716.5104 2768.2075 2771.9384 2710.1781
4 000001.SH 20180928 2821.3501 2794.2644 2821.7553 2791.8363
pre_close change pct_chg vol amount
0 2725.8367 -142.3792 -5.2233 197150702.0 170057762.5
1 2721.0130 4.8237 0.1773 113485736.0 111312455.3
2 2716.5104 4.5026 0.1657 116771899.0 110292457.8
3 2821.3501 -104.8397 -3.7159 149501388.0 141531551.8
4 2791.7748 29.5753 1.0594 134290456.0 125369989.4
#均线
df = ts.pro_bar(ts_code='000001.SZ', start_date='20180101', end_date='20181011', ma=[5, 20, 50])
Tushare pro_bar接口的均价和均量数据是动态计算想要获取某个时间段的均线必须要设置start_date日期大于最大均线的日期数然后自行截取想要日期段。例如想要获取20190801开始的3日均线必须设置start_date='20190729'然后剔除20190801之前的日期记录。
#换手率tor量比vr
df = ts.pro_bar(ts_code='000001.SZ', start_date='20180101', end_date='20181011', factors=['tor', 'vr'])
- 基础信息https://tushare.pro/document/2?doc_id=25
接口stock_basic可以通过数据工具调试和查看数据
描述:获取基础信息数据,包括股票代码、名称、上市日期、退市日期等
权限2000积分起。此接口是基础信息调取一次就可以拉取完建议保存倒本地存储后使用
输入参数
名称 类型 必选 描述
ts_code str N TS股票代码
name str N 名称
market str N 市场类别 (主板/创业板/科创板/CDR/北交所)
list_status str N 上市状态 L上市 D退市 P暂停上市 G过会未交易默认是L
exchange str N 交易所 SSE上交所 SZSE深交所 BSE北交所
is_hs str N 是否沪深港通标的N否 H沪股通 S深股通
输出参数
名称 类型 默认显示 描述
ts_code str Y TS代码
symbol str Y 股票代码
name str Y 股票名称
area str Y 地域
industry str Y 所属行业
fullname str N 股票全称
enname str N 英文全称
cnspell str Y 拼音缩写
market str Y 市场类型(主板/创业板/科创板/CDR
exchange str N 交易所代码
curr_type str N 交易货币
list_status str N 上市状态 L上市 D退市 G过会未交易 P暂停上市
list_date str Y 上市日期
delist_date str N 退市日期
is_hs str N 是否沪深港通标的N否 H沪股通 S深股通
act_name str Y 实控人名称
act_ent_type str Y 实控人企业性质
说明旧版上的PE/PB/股本等字段,请在行情接口“每日指标”中获取。
交易日历
接口trade_cal可以通过数据工具调试和查看数据。
描述:获取各大交易所交易日历数据,默认提取的是上交所
积分需2000积分
输入参数
名称 类型 必选 描述
exchange str N 交易所 SSE上交所,SZSE深交所,CFFEX 中金所,SHFE 上期所,CZCE 郑商所,DCE 大商所,INE 上能源
start_date str N 开始日期 格式YYYYMMDD 下同)
end_date str N 结束日期
is_open str N 是否交易 '0'休市 '1'交易
输出参数
名称 类型 默认显示 描述
exchange str Y 交易所 SSE上交所 SZSE深交所
cal_date str Y 日历日期
is_open str Y 是否交易 0休市 1交易
pretrade_date str Y 上一个交易日
接口示例
pro = ts.pro_api()
df = pro.trade_cal(exchange='', start_date='20180101', end_date='20181231')
或者
df = pro.query('trade_cal', start_date='20180101', end_date='20181231')
数据样例
exchange cal_date is_open
0 SSE 20180101 0
1 SSE 20180102 1
2 SSE 20180103 1
3 SSE 20180104 1
4 SSE 20180105 1
5 SSE 20180106 0
6 SSE 20180107 0
7 SSE 20180108 1
8 SSE 20180109 1
9 SSE 20180110 1
10 SSE 20180111 1
11 SSE 20180112 1
12 SSE 20180113 0
13 SSE 20180114 0
14 SSE 20180115 1
15 SSE 20180116 1
16 SSE 20180117 1
17 SSE 20180118 1
18 SSE 20180119 1
19 SSE 20180120 0
20 SSE 20180121 0
每日指标
接口daily_basic可以通过数据工具调试和查看数据。
更新时间交易日每日15点17点之间
描述获取全部股票每日重要的基本面指标可用于选股分析、报表展示等。单次请求最大返回6000条数据可按日线循环提取全部历史。
积分至少2000积分才可以调取5000积分无总量限制具体请参阅积分获取办法
输入参数
名称 类型 必选 描述
ts_code str Y 股票代码(二选一)
trade_date str N 交易日期 (二选一)
start_date str N 开始日期(YYYYMMDD)
end_date str N 结束日期(YYYYMMDD)
日期都填YYYYMMDD格式比如20181010
输出参数
名称 类型 描述
ts_code str TS股票代码
trade_date str 交易日期
close float 当日收盘价
turnover_rate float 换手率(%
turnover_rate_f float 换手率(自由流通股)
volume_ratio float 量比
pe float 市盈率(总市值/净利润, 亏损的PE为空
pe_ttm float 市盈率TTM亏损的PE为空
pb float 市净率(总市值/净资产)
ps float 市销率
ps_ttm float 市销率TTM
dv_ratio float 股息率 %
dv_ttm float 股息率TTM%
total_share float 总股本 (万股)
float_share float 流通股本 (万股)
free_share float 自由流通股本 (万)
total_mv float 总市值 (万元)
circ_mv float 流通市值(万元)
接口用法
pro = ts.pro_api()
df = pro.daily_basic(ts_code='', trade_date='20180726', fields='ts_code,trade_date,turnover_rate,volume_ratio,pe,pb')
或者
df = pro.query('daily_basic', ts_code='', trade_date='20180726',fields='ts_code,trade_date,turnover_rate,volume_ratio,pe,pb')
数据样例
ts_code trade_date turnover_rate volume_ratio pe pb
0 600230.SH 20180726 2.4584 0.72 8.6928 3.7203
1 600237.SH 20180726 1.4737 0.88 166.4001 1.8868
2 002465.SZ 20180726 0.7489 0.72 71.8943 2.6391
3 300732.SZ 20180726 6.7083 0.77 21.8101 3.2513
4 600007.SH 20180726 0.0381 0.61 23.7696 2.3774
5 300068.SZ 20180726 1.4583 0.52 27.8166 1.7549
6 300552.SZ 20180726 2.0728 0.95 56.8004 2.9279
7 601369.SH 20180726 0.2088 0.95 44.1163 1.8001
8 002518.SZ 20180726 0.5814 0.76 15.1004 2.5626
9 002913.SZ 20180726 12.1096 1.03 33.1279 2.9217
10 601818.SH 20180726 0.1893 0.86 6.3064 0.7209
11 600926.SH 20180726 0.6065 0.46 9.1772 0.9808
12 002166.SZ 20180726 0.7582 0.82 16.9868 3.3452
13 600841.SH 20180726 0.3754 1.02 66.2647 2.2302
14 300634.SZ 20180726 23.1127 1.26 120.3053 14.3168
15 300126.SZ 20180726 1.2304 1.11 348.4306 1.5171
16 300718.SZ 20180726 17.6612 0.92 32.0239 3.8661
17 000708.SZ 20180726 0.5575 0.70 10.3674 1.0276
18 002626.SZ 20180726 0.6187 0.83 22.7580 4.2446
19 600816.SH 20180726 0.6745 0.65 11.0778 3.2214
股票曾用名
接口namechange
描述:历史名称变更记录
输入参数
名称 类型 必选 描述
ts_code str N TS代码
start_date str N 公告开始日期
end_date str N 公告结束日期
输出参数
名称 类型 默认输出 描述
ts_code str Y TS代码
name str Y 证券名称
start_date str Y 开始日期
end_date str Y 结束日期
ann_date str Y 公告日期
change_reason str Y 变更原因
接口示例
pro = ts.pro_api()
df = pro.namechange(ts_code='600848.SH', fields='ts_code,name,start_date,end_date,change_reason')
数据样例
ts_code name start_date end_date change_reason
0 600848.SH 上海临港 20151118 None 改名
1 600848.SH 自仪股份 20070514 20151117 撤销ST
2 600848.SH ST自仪 20061026 20070513 完成股改
3 600848.SH SST自仪 20061009 20061025 未股改加S
4 600848.SH ST自仪 20010508 20061008 ST
5 600848.SH 自仪股份 19940324 20010507 其他
股票历史列表(历史每天股票列表)
接口bak_basic
描述获取备用基础列表数据从2016年开始
限量单次最大7000条可以根据日期参数循环获取历史正式权限需要5000积分。
输入参数
名称 类型 必选 描述
trade_date str N 交易日期
ts_code str N 股票代码
输出参数
名称 类型 默认显示 描述
trade_date str Y 交易日期
ts_code str Y TS股票代码
name str Y 股票名称
industry str Y 行业
area str Y 地域
pe float Y 市盈率(动)
float_share float Y 流通股本(亿)
total_share float Y 总股本(亿)
total_assets float Y 总资产(亿)
liquid_assets float Y 流动资产(亿)
fixed_assets float Y 固定资产(亿)
reserved float Y 公积金
reserved_pershare float Y 每股公积金
eps float Y 每股收益
bvps float Y 每股净资产
pb float Y 市净率
list_date str Y 上市日期
undp float Y 未分配利润
per_undp float Y 每股未分配利润
rev_yoy float Y 收入同比(%
profit_yoy float Y 利润同比(%
gpr float Y 毛利率(%
npr float Y 净利润率(%
holder_num int Y 股东人数
接口示例
pro = ts.pro_api()
df = pro.bak_basic(trade_date='20211012', fields='trade_date,ts_code,name,industry,pe')
数据样例
trade_date ts_code name industry pe
0 20211012 300605.SZ 恒锋信息 软件服务 56.4400
1 20211012 301017.SZ 漱玉平民 医药商业 58.7600
2 20211012 300755.SZ 华致酒行 其他商业 23.0000
3 20211012 300255.SZ 常山药业 生物制药 24.9900
4 20211012 688378.SH 奥来德 专用机械 24.9600
... ... ... ... ... ...
4529 20211012 688257.SH 新锐股份 机械基件 0.0000
4530 20211012 688255.SH 凯尔达 机械基件 0.0000
4531 20211012 688211.SH 中科微至 专用机械 0.0000
4532 20211012 605567.SH 春雪食品 食品 0.0000
4533 20211012 605566.SH 福莱蒽特 染料涂料 0.0000
通用行情接口
接口名称pro_bar本接口是集成开发接口部分指标是现用现算
更新时间股票和指数通常在15点17点之间数字货币实时更新具体请参考各接口文档明细。
描述目前整合了股票未复权、前复权、后复权、指数、数字货币、ETF基金、期货、期权的行情数据未来还将整合包括外汇在内的所有交易行情数据同时提供分钟数据。不同数据对应不同的积分要求具体请参阅每类数据的文档说明。
其它由于本接口是集成接口在SDK层做了一些逻辑处理目前暂时没法用http的方式调取通用行情接口。用户可以访问Tushare的Github查看源代码完成类似功能。
输入参数
名称 类型 必选 描述
ts_code str Y 证券代码,不支持多值输入,多值输入获取结果会有重复记录
start_date str N 开始日期 (日线格式YYYYMMDD提取分钟数据请用2019-09-01 09:00:00这种格式)
end_date str N 结束日期 (日线格式YYYYMMDD)
asset str Y 资产类别E股票 I沪深指数 C数字货币 FT期货 FD基金 O期权 CB可转债v1.2.39默认E
adj str N 复权类型(只针对股票)None未复权 qfq前复权 hfq后复权 , 默认None目前只支持日线复权同时复权机制是根据设定的end_date参数动态复权采用分红再投模式具体请参考常见问题列表里的说明。
freq str Y 数据频度 :支持分钟(min)/日(D)/周(W)/月(M)K线其中1min表示1分钟类推1/5/15/30/60分钟 默认D。对于分钟数据有600积分用户可以试用请求2次正式权限可以参考权限列表说明 ,使用方法请参考股票分钟使用方法。
ma list N 均线支持任意合理int数值。注均线是动态计算要设置一定时间范围才能获得相应的均线比如5日均线开始和结束日期参数跨度必须要超过5日。目前只支持单一个股票提取均线即需要输入ts_code参数。e.g: ma_5表示5日均价ma_v_5表示5日均量
factors list N 股票因子asset='E'有效)支持 tor换手率 vr量比
adjfactor str N 复权因子在复权数据时如果此参数为True返回的数据中则带复权因子默认为False。 该功能从1.2.33版本开始生效
输出指标
具体输出的数据指标可参考各行情具体指标:
股票Dailyhttps://tushare.pro/document/2?doc_id=27
内容如下A股日线行情
接口daily可以通过数据工具调试和查看数据
数据说明交易日每天15点16点之间入库。本接口是未复权行情停牌期间不提供数据
调取说明基础积分每分钟内可调取500次每次6000条数据一次请求相当于提取一个股票23年历史
描述:获取股票行情数据,或通过通用行情接口获取数据,包含了前后复权数据
输入参数
名称 类型 必选 描述
ts_code str N 股票代码(支持多个股票同时提取,逗号分隔)
trade_date str N 交易日期YYYYMMDD
start_date str N 开始日期(YYYYMMDD)
end_date str N 结束日期(YYYYMMDD)
日期都填YYYYMMDD格式比如20181010
输出参数
名称 类型 描述
ts_code str 股票代码
trade_date str 交易日期
open float 开盘价
high float 最高价
low float 最低价
close float 收盘价
pre_close float 昨收价【除权价】
change float 涨跌额
pct_chg float 涨跌幅 【基于除权后的昨收计算的涨跌幅:(今收-除权昨收)/除权昨收 】
vol float 成交量 (手)
amount float 成交额 (千元)
接口示例
pro = ts.pro_api()
df = pro.daily(ts_code='000001.SZ', start_date='20180701', end_date='20180718')
#多个股票
df = pro.daily(ts_code='000001.SZ,600000.SH', start_date='20180701', end_date='20180718')
或者
df = pro.query('daily', ts_code='000001.SZ', start_date='20180701', end_date='20180718')
也可以通过日期取历史某一天的全部历史
df = pro.daily(trade_date='20180810')
数据样例
ts_code trade_date open high low close pre_close change pct_chg vol amount
0 000001.SZ 20180718 8.75 8.85 8.69 8.70 8.72 -0.02 -0.23 525152.77 460697.377
1 000001.SZ 20180717 8.74 8.75 8.66 8.72 8.73 -0.01 -0.11 375356.33 326396.994
2 000001.SZ 20180716 8.85 8.90 8.69 8.73 8.88 -0.15 -1.69 689845.58 603427.713
3 000001.SZ 20180713 8.92 8.94 8.82 8.88 8.88 0.00 0.00 603378.21 535401.175
4 000001.SZ 20180712 8.60 8.97 8.58 8.88 8.64 0.24 2.78 1140492.31 1008658.828
5 000001.SZ 20180711 8.76 8.83 8.68 8.78 8.98 -0.20 -2.23 851296.70 744765.824
6 000001.SZ 20180710 9.02 9.02 8.89 8.98 9.03 -0.05 -0.55 896862.02 803038.965
7 000001.SZ 20180709 8.69 9.03 8.68 9.03 8.66 0.37 4.27 1409954.60 1255007.609
8 000001.SZ 20180706 8.61 8.78 8.45 8.66 8.60 0.06 0.70 988282.69 852071.526
9 000001.SZ 20180705 8.62 8.73 8.55 8.60 8.61 -0.01 -0.12 835768.77 722169.579
基金Dailyhttps://tushare.pro/document/2?doc_id=127
期货Dailyhttps://tushare.pro/document/2?doc_id=138
期权Dailyhttps://tushare.pro/document/2?doc_id=159
指数Dailyhttps://tushare.pro/document/2?doc_id=95
接口用例
#取000001的前复权行情
df = ts.pro_bar(ts_code='000001.SZ', adj='qfq', start_date='20180101', end_date='20181011')
ts_code trade_date open high low close \
trade_date
20181011 000001.SZ 20181011 1085.71 1097.59 1047.90 1065.19
20181010 000001.SZ 20181010 1138.65 1151.61 1121.36 1128.92
20181009 000001.SZ 20181009 1130.00 1155.93 1122.44 1140.81
20181008 000001.SZ 20181008 1155.93 1165.65 1128.92 1128.92
20180928 000001.SZ 20180928 1164.57 1217.51 1164.57 1193.74
#取上证指数行情数据
df = ts.pro_bar(ts_code='000001.SH', asset='I', start_date='20180101', end_date='20181011')
In [10]: df.head()
Out[10]:
ts_code trade_date close open high low \
0 000001.SH 20181011 2583.4575 2643.0740 2661.2859 2560.3164
1 000001.SH 20181010 2725.8367 2723.7242 2743.5480 2703.0626
2 000001.SH 20181009 2721.0130 2713.7319 2734.3142 2711.1971
3 000001.SH 20181008 2716.5104 2768.2075 2771.9384 2710.1781
4 000001.SH 20180928 2821.3501 2794.2644 2821.7553 2791.8363
pre_close change pct_chg vol amount
0 2725.8367 -142.3792 -5.2233 197150702.0 170057762.5
1 2721.0130 4.8237 0.1773 113485736.0 111312455.3
2 2716.5104 4.5026 0.1657 116771899.0 110292457.8
3 2821.3501 -104.8397 -3.7159 149501388.0 141531551.8
4 2791.7748 29.5753 1.0594 134290456.0 125369989.4
#均线
df = ts.pro_bar(ts_code='000001.SZ', start_date='20180101', end_date='20181011', ma=[5, 20, 50])
Tushare pro_bar接口的均价和均量数据是动态计算想要获取某个时间段的均线必须要设置start_date日期大于最大均线的日期数然后自行截取想要日期段。例如想要获取20190801开始的3日均线必须设置start_date='20190729'然后剔除20190801之前的日期记录。
#换手率tor量比vr
df = ts.pro_bar(ts_code='000001.SZ', start_date='20180101', end_date='20181011', factors=['tor', 'vr'])
说明
对于pro_api参数如果在一开始就通过 ts.set_token('xxxx') 设置过token的情况这个参数就不是必需的。
例如:
df = ts.pro_bar(ts_code='000001.SH', asset='I', start_date='20180101', end_date='20181011')
每日指标
接口daily_basic可以通过数据工具调试和查看数据。
更新时间交易日每日15点17点之间
描述获取全部股票每日重要的基本面指标可用于选股分析、报表展示等。单次请求最大返回6000条数据可按日线循环提取全部历史。
积分至少2000积分才可以调取5000积分无总量限制具体请参阅积分获取办法
输入参数
名称 类型 必选 描述
ts_code str Y 股票代码(二选一)
trade_date str N 交易日期 (二选一)
start_date str N 开始日期(YYYYMMDD)
end_date str N 结束日期(YYYYMMDD)
日期都填YYYYMMDD格式比如20181010
输出参数
名称 类型 描述
ts_code str TS股票代码
trade_date str 交易日期
close float 当日收盘价
turnover_rate float 换手率(%
turnover_rate_f float 换手率(自由流通股)
volume_ratio float 量比
pe float 市盈率(总市值/净利润, 亏损的PE为空
pe_ttm float 市盈率TTM亏损的PE为空
pb float 市净率(总市值/净资产)
ps float 市销率
ps_ttm float 市销率TTM
dv_ratio float 股息率 %
dv_ttm float 股息率TTM%
total_share float 总股本 (万股)
float_share float 流通股本 (万股)
free_share float 自由流通股本 (万)
total_mv float 总市值 (万元)
circ_mv float 流通市值(万元)
接口用法
pro = ts.pro_api()
df = pro.daily_basic(ts_code='', trade_date='20180726', fields='ts_code,trade_date,turnover_rate,volume_ratio,pe,pb')
或者
df = pro.query('daily_basic', ts_code='', trade_date='20180726',fields='ts_code,trade_date,turnover_rate,volume_ratio,pe,pb')
数据样例
ts_code trade_date turnover_rate volume_ratio pe pb
0 600230.SH 20180726 2.4584 0.72 8.6928 3.7203
1 600237.SH 20180726 1.4737 0.88 166.4001 1.8868
2 002465.SZ 20180726 0.7489 0.72 71.8943 2.6391
3 300732.SZ 20180726 6.7083 0.77 21.8101 3.2513
4 600007.SH 20180726 0.0381 0.61 23.7696 2.3774
5 300068.SZ 20180726 1.4583 0.52 27.8166 1.7549
6 300552.SZ 20180726 2.0728 0.95 56.8004 2.9279
7 601369.SH 20180726 0.2088 0.95 44.1163 1.8001
8 002518.SZ 20180726 0.5814 0.76 15.1004 2.5626
9 002913.SZ 20180726 12.1096 1.03 33.1279 2.9217
10 601818.SH 20180726 0.1893 0.86 6.3064 0.7209
11 600926.SH 20180726 0.6065 0.46 9.1772 0.9808
12 002166.SZ 20180726 0.7582 0.82 16.9868 3.3452
13 600841.SH 20180726 0.3754 1.02 66.2647 2.2302
14 300634.SZ 20180726 23.1127 1.26 120.3053 14.3168
15 300126.SZ 20180726 1.2304 1.11 348.4306 1.5171
16 300718.SZ 20180726 17.6612 0.92 32.0239 3.8661
17 000708.SZ 20180726 0.5575 0.70 10.3674 1.0276
18 002626.SZ 20180726 0.6187 0.83 22.7580 4.2446
19 600816.SH 20180726 0.6745 0.65 11.0778 3.2214
ST股票列表
接口stock_st可以通过数据工具调试和查看数据。
描述获取ST股票列表可根据交易日期获取历史上每天的ST列表
权限3000积分起
提示每天上午9:20更新单次请求最大返回1000行数据可循环提取,本接口数据从20160101开始,太早历史无法补齐
输入参数
名称 类型 必选 描述
ts_code str N 股票代码
trade_date str N 交易日期格式YYYYMMDD下同
start_date str N 开始时间
end_date str N 结束时间
输出参数
名称 类型 默认显示 描述
ts_code str Y 股票代码
name str Y 股票名称
trade_date str Y 交易日期
type str Y 类型
type_name str Y 类型名称
接口用法
pro = ts.pro_api()
#获取20250813日所有的ST股票
df = pro.stock_st(trade_date='20250813')
数据样例
ts_code name trade_date type type_name
0 300313.SZ *ST天山 20250813 ST 风险警示板
1 605081.SH *ST太和 20250813 ST 风险警示板
2 300391.SZ *ST长药 20250813 ST 风险警示板
3 300343.SZ ST联创 20250813 ST 风险警示板
4 300044.SZ ST赛为 20250813 ST 风险警示板
.. ... ... ... ... ...
170 300175.SZ ST朗源 20250813 ST 风险警示板
171 603721.SH *ST天择 20250813 ST 风险警示板
172 600289.SH ST信通 20250813 ST 风险警示板
173 000929.SZ *ST兰黄 20250813 ST 风险警示板
174 000638.SZ *ST万方 20250813 ST 风险警示板

View File

@@ -1,145 +0,0 @@
利润表
接口income可以通过数据工具调试和查看数据。
描述:获取上市公司财务利润表数据
积分用户需要至少2000积分才可以调取具体请参阅积分获取办法
提示当前接口只能按单只股票获取其历史数据如果需要获取某一季度全部上市公司数据请使用income_vip接口参数一致需积攒5000积分。
输入参数
名称 类型 必选 描述
ts_code str Y 股票代码
ann_date str N 公告日期YYYYMMDD格式下同
f_ann_date str N 实际公告日期
start_date str N 公告日开始日期
end_date str N 公告日结束日期
period str N 报告期(每个季度最后一天的日期比如20171231表示年报20170630半年报20170930三季报)
report_type str N 报告类型,参考文档最下方说明
comp_type str N 公司类型1一般工商业2银行3保险4证券
输出参数
名称 类型 默认显示 描述
ts_code str Y TS代码
ann_date str Y 公告日期
f_ann_date str Y 实际公告日期
end_date str Y 报告期
report_type str Y 报告类型 见底部表
comp_type str Y 公司类型(1一般工商业2银行3保险4证券)
end_type str Y 报告期类型
basic_eps float Y 基本每股收益
diluted_eps float Y 稀释每股收益
total_revenue float Y 营业总收入
revenue float Y 营业收入
int_income float Y 利息收入
prem_earned float Y 已赚保费
comm_income float Y 手续费及佣金收入
n_commis_income float Y 手续费及佣金净收入
n_oth_income float Y 其他经营净收益
n_oth_b_income float Y 加:其他业务净收益
prem_income float Y 保险业务收入
out_prem float Y 减:分出保费
une_prem_reser float Y 提取未到期责任准备金
reins_income float Y 其中:分保费收入
n_sec_tb_income float Y 代理买卖证券业务净收入
n_sec_uw_income float Y 证券承销业务净收入
n_asset_mg_income float Y 受托客户资产管理业务净收入
oth_b_income float Y 其他业务收入
fv_value_chg_gain float Y 加:公允价值变动净收益
invest_income float Y 加:投资净收益
ass_invest_income float Y 其中:对联营企业和合营企业的投资收益
forex_gain float Y 加:汇兑净收益
total_cogs float Y 营业总成本
oper_cost float Y 减:营业成本
int_exp float Y 减:利息支出
comm_exp float Y 减:手续费及佣金支出
biz_tax_surchg float Y 减:营业税金及附加
sell_exp float Y 减:销售费用
admin_exp float Y 减:管理费用
fin_exp float Y 减:财务费用
assets_impair_loss float Y 减:资产减值损失
prem_refund float Y 退保金
compens_payout float Y 赔付总支出
reser_insur_liab float Y 提取保险责任准备金
div_payt float Y 保户红利支出
reins_exp float Y 分保费用
oper_exp float Y 营业支出
compens_payout_refu float Y 减:摊回赔付支出
insur_reser_refu float Y 减:摊回保险责任准备金
reins_cost_refund float Y 减:摊回分保费用
other_bus_cost float Y 其他业务成本
operate_profit float Y 营业利润
non_oper_income float Y 加:营业外收入
non_oper_exp float Y 减:营业外支出
nca_disploss float Y 其中:减:非流动资产处置净损失
total_profit float Y 利润总额
income_tax float Y 所得税费用
n_income float Y 净利润(含少数股东损益)
n_income_attr_p float Y 净利润(不含少数股东损益)
minority_gain float Y 少数股东损益
oth_compr_income float Y 其他综合收益
t_compr_income float Y 综合收益总额
compr_inc_attr_p float Y 归属于母公司(或股东)的综合收益总额
compr_inc_attr_m_s float Y 归属于少数股东的综合收益总额
ebit float Y 息税前利润
ebitda float Y 息税折旧摊销前利润
insurance_exp float Y 保险业务支出
undist_profit float Y 年初未分配利润
distable_profit float Y 可分配利润
rd_exp float Y 研发费用
fin_exp_int_exp float Y 财务费用:利息费用
fin_exp_int_inc float Y 财务费用:利息收入
transfer_surplus_rese float Y 盈余公积转入
transfer_housing_imprest float Y 住房周转金转入
transfer_oth float Y 其他转入
adj_lossgain float Y 调整以前年度损益
withdra_legal_surplus float Y 提取法定盈余公积
withdra_legal_pubfund float Y 提取法定公益金
withdra_biz_devfund float Y 提取企业发展基金
withdra_rese_fund float Y 提取储备基金
withdra_oth_ersu float Y 提取任意盈余公积金
workers_welfare float Y 职工奖金福利
distr_profit_shrhder float Y 可供股东分配的利润
prfshare_payable_dvd float Y 应付优先股股利
comshare_payable_dvd float Y 应付普通股股利
capit_comstock_div float Y 转作股本的普通股股利
net_after_nr_lp_correct float N 扣除非经常性损益后的净利润(更正前)
credit_impa_loss float N 信用减值损失
net_expo_hedging_benefits float N 净敞口套期收益
oth_impair_loss_assets float N 其他资产减值损失
total_opcost float N 营业总成本(二)
amodcost_fin_assets float N 以摊余成本计量的金融资产终止确认收益
oth_income float N 其他收益
asset_disp_income float N 资产处置收益
continued_net_profit float N 持续经营净利润
end_net_profit float N 终止经营净利润
update_flag str Y 更新标识
接口使用说明
pro = ts.pro_api()
df = pro.income(ts_code='600000.SH', start_date='20180101', end_date='20180730', fields='ts_code,ann_date,f_ann_date,end_date,report_type,comp_type,basic_eps,diluted_eps')
获取某一季度全部股票数据
df = pro.income_vip(period='20181231',fields='ts_code,ann_date,f_ann_date,end_date,report_type,comp_type,basic_eps,diluted_eps')
数据样例
ts_code ann_date f_ann_date end_date report_type comp_type basic_eps diluted_eps \
0 600000.SH 20180428 20180428 20180331 1 2 0.46 0.46
1 600000.SH 20180428 20180428 20180331 1 2 0.46 0.46
2 600000.SH 20180428 20180428 20171231 1 2 1.84 1.84
主要报表类型说明
代码 | 类型 | 说明
---- | ----- | ---- |
1 | 合并报表 | 上市公司最新报表(默认)
2 | 单季合并 | 单一季度的合并报表
3 | 调整单季合并表 | 调整后的单季合并报表(如果有)
4 | 调整合并报表 | 本年度公布上年同期的财务报表数据,报告期为上年度
5 | 调整前合并报表 | 数据发生变更,将原数据进行保留,即调整前的原数据
6 | 母公司报表 | 该公司母公司的财务报表数据
7 | 母公司单季表 | 母公司的单季度表
8 | 母公司调整单季表 | 母公司调整后的单季表
9 | 母公司调整表 | 该公司母公司的本年度公布上年同期的财务报表数据
10 | 母公司调整前报表 | 母公司调整之前的原始财务报表数据
11 | 母公司调整前合并报表 | 母公司调整之前合并报表原数据
12 | 母公司调整前报表 | 母公司报表发生变更前保留的原数据

View File

@@ -0,0 +1,181 @@
"""财务数据加载与清洗模块。
提供财务数据的加载、清洗和与行情数据拼接功能。
"""
from datetime import datetime, timedelta
from typing import Optional, List
import polars as pl
from src.data.storage import Storage
class FinancialLoader:
"""财务数据加载器。
负责财务数据的清洗、去重,以及与行情数据的 as-of join。
Attributes:
storage: DuckDB 存储实例
"""
def __init__(self):
self.storage = Storage()
def load_financial_data(
self,
table_name: str,
columns: List[str],
start_date: str,
end_date: str,
ts_code: Optional[str] = None,
) -> pl.DataFrame:
"""加载并清洗财务数据。
数据清洗流程:
1. 仅保留 report_type == '1'(合并报表)
2. 按 (ts_code, f_ann_date) 分组,按 update_flag 降序去重
3. 转换为 Date 类型,按 ts_code 和 f_ann_date 排序
Args:
table_name: 财务表名(如 'financial_income'
columns: 需要的字段列表(必须包含核心字段)
start_date: 数据开始日期YYYYMMDD
end_date: 数据结束日期YYYYMMDD
ts_code: 可选,单个股票代码过滤
Returns:
清洗后的 Polars DataFrame已排序f_ann_date 为 pl.Date 类型
"""
# 确保包含必要字段
required_cols = {"ts_code", "f_ann_date", "report_type", "update_flag"}
query_cols = list(set(columns) | required_cols)
# 从数据库加载原始数据
df = self._load_from_db(table_name, query_cols, start_date, end_date, ts_code)
if df.is_empty():
return df
# 步骤1: 仅保留合并报表 (report_type 可能是字符串或整数)
df = df.filter(pl.col("report_type") == 1)
# 步骤2: 按 update_flag 降序排列后去重
df = df.with_columns(
[pl.col("update_flag").cast(pl.Int32).alias("update_flag_int")]
)
# 排序ts_code, f_ann_date 升序update_flag 降序
df = df.sort(
["ts_code", "f_ann_date", "update_flag_int"],
descending=[False, False, True],
)
# 去重:保留每个 (ts_code, f_ann_date) 的第一条update_flag 最高的)
df = df.unique(subset=["ts_code", "f_ann_date"], keep="first")
# 移除临时列
df = df.drop("update_flag_int")
# 步骤3: 确保 f_ann_date 是 Date 类型并排序
# 数据库返回的必须是 Date 类型,如果不是则报错
if df["f_ann_date"].dtype != pl.Date:
raise TypeError(
f"f_ann_date 必须是 Date 类型,实际类型为 {df['f_ann_date'].dtype}. "
f"请检查数据库表结构,确保日期字段为 DATE 类型。"
)
# 最终排序join_asof 要求)
df = df.sort(["ts_code", "f_ann_date"])
return df
def merge_financial_with_price(
self,
df_price: pl.DataFrame,
df_financial: pl.DataFrame,
financial_cols: List[str],
) -> pl.DataFrame:
"""将财务数据拼接到行情数据。
使用 join_asof 向后匹配:对于每个交易日,找到最近的历史公告数据。
注意:输入的 df_price 的 trade_date 必须是 pl.Date 类型且已排序。
Args:
df_price: 行情数据 DataFrame必须包含 ts_code, trade_dateDate 类型)
df_financial: 财务数据 DataFrame已通过 load_financial_data 清洗Date 类型)
financial_cols: 需要从财务表保留的字段列表
Returns:
拼接后的 DataFrametrade_date 仍为 Date 类型)
"""
if df_financial.is_empty():
# 财务数据为空,返回行情数据(财务列为空)
for col in financial_cols:
if col not in df_price.columns:
df_price = df_price.with_columns([pl.lit(None).alias(col)])
return df_price
# 执行 asof join: 向后寻找最近的历史数据
# strategy='backward': 对于每个 trade_date找 f_ann_date <= trade_date 的最新记录
merged = df_price.join_asof(
df_financial.select(["ts_code", "f_ann_date"] + financial_cols),
left_on="trade_date",
right_on="f_ann_date",
by="ts_code",
strategy="backward",
)
return merged
def _load_from_db(
self,
table_name: str,
columns: List[str],
start_date: str,
end_date: str,
ts_code: Optional[str] = None,
) -> pl.DataFrame:
"""从数据库加载财务数据(内部方法)。"""
conn = self.storage._connection
cols_str = ", ".join(f'"{c}"' for c in columns)
start_dt = datetime.strptime(start_date, "%Y%m%d").date()
end_dt = datetime.strptime(end_date, "%Y%m%d").date()
conditions = [f"f_ann_date BETWEEN '{start_dt}' AND '{end_dt}'"]
if ts_code:
conditions.append(f"ts_code = '{ts_code}'")
where_clause = " AND ".join(conditions)
query = f"SELECT {cols_str} FROM {table_name} WHERE {where_clause} ORDER BY ts_code, f_ann_date"
try:
df = conn.sql(query).pl()
return df
except Exception as e:
print(f"[FinancialLoader] 加载 {table_name} 失败: {e}")
return pl.DataFrame()
def get_date_range_with_lookback(
self,
start_date: str,
end_date: str,
lookback_years: int = 1,
) -> tuple[str, str]:
"""计算包含回看期的日期范围。
Args:
start_date: 原始开始日期YYYYMMDD
end_date: 原始结束日期YYYYMMDD
lookback_years: 回看年数默认1年
Returns:
(扩展后的开始日期, 结束日期)
"""
start_dt = datetime.strptime(start_date, "%Y%m%d")
adjusted_start = start_dt - timedelta(days=365 * lookback_years)
return adjusted_start.strftime("%Y%m%d"), end_date