datasinking 0.1.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- datasinking-0.1.0/LICENSE +21 -0
- datasinking-0.1.0/PKG-INFO +123 -0
- datasinking-0.1.0/README.md +103 -0
- datasinking-0.1.0/datasinking/__init__.py +12 -0
- datasinking-0.1.0/datasinking/client.py +126 -0
- datasinking-0.1.0/datasinking.egg-info/PKG-INFO +123 -0
- datasinking-0.1.0/datasinking.egg-info/SOURCES.txt +10 -0
- datasinking-0.1.0/datasinking.egg-info/dependency_links.txt +1 -0
- datasinking-0.1.0/datasinking.egg-info/requires.txt +1 -0
- datasinking-0.1.0/datasinking.egg-info/top_level.txt +1 -0
- datasinking-0.1.0/pyproject.toml +28 -0
- datasinking-0.1.0/setup.cfg +4 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 DataSinking
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: datasinking
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for DataSinking — full-text China A-share financial reports as Markdown.
|
|
5
|
+
Author: DataSinking
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://datasink.ing
|
|
8
|
+
Project-URL: Documentation, https://datasink.ing/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/heubme2020/datasinking
|
|
10
|
+
Keywords: a-share,china,financial reports,markdown,api,stock
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# DataSinking
|
|
22
|
+
|
|
23
|
+
**Full-text A-share financial reports, as clean Markdown.**
|
|
24
|
+
|
|
25
|
+
[DataSinking](https://datasink.ing) is a **China stock market data API** that serves
|
|
26
|
+
**full-text A-share financial reports** — annual, semi-annual and quarterly — as clean
|
|
27
|
+
**Markdown**. Download China A-share financial statements (balance sheet, income statement,
|
|
28
|
+
cash flow) by FMP-style symbol (`600519.SS`) or filter by exchange / report period, through a
|
|
29
|
+
simple REST API. Raw PDFs are sourced from [cninfo.com.cn](http://www.cninfo.com.cn) (the
|
|
30
|
+
officially designated disclosure platform) and parsed into structured Markdown with YAML
|
|
31
|
+
frontmatter, preserved headings, paragraphs and tables — ready for LLM reading and analysis.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What this repo is
|
|
36
|
+
|
|
37
|
+
Examples, research and tutorials showing how to work with financial report data, including reproducing the presentation styles found in financial-report research papers.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
datasinking/
|
|
41
|
+
├── examples/ # Example scripts: pull data from the API and analyze it
|
|
42
|
+
├── research/ # Research notes / blog posts (reproducing paper-style presentation)
|
|
43
|
+
├── datasinking/ # Python client — pip install datasinking
|
|
44
|
+
├── llm-examples.md # Ask an LLM — no code needed (3 end-to-end examples)
|
|
45
|
+
└── README.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
1. Get an API key at [datasink.ing](https://datasink.ing)
|
|
51
|
+
2. Pull data (FMP-style `?apikey=`):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# List exchanges
|
|
55
|
+
curl "https://api.datasink.ing/exchanges?apikey=YOUR_KEY"
|
|
56
|
+
|
|
57
|
+
# List all of Kweichow Moutai's reports
|
|
58
|
+
curl "https://api.datasink.ing/documents?symbol=600519.SS&apikey=YOUR_KEY"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
3. Or use the Python client:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install datasinking
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from datasinking import DataSinking
|
|
69
|
+
|
|
70
|
+
ds = DataSinking("YOUR_KEY")
|
|
71
|
+
|
|
72
|
+
# Latest 3 reports of Kweichow Moutai (full markdown content included)
|
|
73
|
+
for r in ds.get_stock_reports("600519.SS", limit=3):
|
|
74
|
+
print(r["report_period"], r["title"], len(r["content"]), "chars")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Ask an LLM (no code)
|
|
78
|
+
|
|
79
|
+
Don't want to write code? Point any LLM at [datasink.ing](https://datasink.ing),
|
|
80
|
+
give it your API key, and ask in plain language. See
|
|
81
|
+
[`llm-examples.md`](llm-examples.md) for three end-to-end examples — explore
|
|
82
|
+
coverage, list a company's reports, and extract a figure with correct units.
|
|
83
|
+
|
|
84
|
+
## Examples (`examples/`)
|
|
85
|
+
|
|
86
|
+
| File | What it does |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `01_quickstart.py` | The 5 core functions: list exchanges / stocks / reports / fetch a report / fetch a stock's reports |
|
|
89
|
+
| `02_download_company.py` | Download a company's full reports to local Markdown files |
|
|
90
|
+
| `03_download_exchange.py` | Download an entire exchange's reports (all stocks) to local Markdown files |
|
|
91
|
+
|
|
92
|
+
Every example pulls from the live API and runs as-is.
|
|
93
|
+
|
|
94
|
+
> `03_download_exchange.py` fetches every report on an exchange (e.g. all of Shenzhen — 130k+ documents). Free keys work too, but fall back to slow per-document fetching (1 req/s + shared daily quota); a **paid (yearly)** key is strongly recommended for full-exchange downloads.
|
|
95
|
+
|
|
96
|
+
## Research (`research/`)
|
|
97
|
+
|
|
98
|
+
`research/` hosts research notes and blog posts, each based on DataSinking data with the source cited. You can reproduce charts and presentations found in financial-report research papers, e.g.:
|
|
99
|
+
|
|
100
|
+
- Long-term revenue / profit trends
|
|
101
|
+
- Industry comparison and distribution
|
|
102
|
+
- Time series of financial metrics
|
|
103
|
+
|
|
104
|
+
Start from [`research/TEMPLATE.md`](research/TEMPLATE.md).
|
|
105
|
+
|
|
106
|
+
## Data overview
|
|
107
|
+
|
|
108
|
+
| | |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Coverage | SSE / SZSE / BSE, 5,000+ A-share companies |
|
|
111
|
+
| Document types | annual / semiannual / q1 / q3 / amendment |
|
|
112
|
+
| Format | Full-text Markdown (with YAML frontmatter) |
|
|
113
|
+
| API | REST — `GET /documents`, batch download, `with_content=1` for full text |
|
|
114
|
+
| Symbols | FMP style: `600519.SS` / `000001.SZ` / `830799.BJ` |
|
|
115
|
+
| Auth | `?apikey=` query parameter (FMP style) |
|
|
116
|
+
|
|
117
|
+
## Data source
|
|
118
|
+
|
|
119
|
+
All reports originate from [cninfo.com.cn](http://www.cninfo.com.cn), the officially designated information disclosure platform of China's listed companies.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
# DataSinking
|
|
2
|
+
|
|
3
|
+
**Full-text A-share financial reports, as clean Markdown.**
|
|
4
|
+
|
|
5
|
+
[DataSinking](https://datasink.ing) is a **China stock market data API** that serves
|
|
6
|
+
**full-text A-share financial reports** — annual, semi-annual and quarterly — as clean
|
|
7
|
+
**Markdown**. Download China A-share financial statements (balance sheet, income statement,
|
|
8
|
+
cash flow) by FMP-style symbol (`600519.SS`) or filter by exchange / report period, through a
|
|
9
|
+
simple REST API. Raw PDFs are sourced from [cninfo.com.cn](http://www.cninfo.com.cn) (the
|
|
10
|
+
officially designated disclosure platform) and parsed into structured Markdown with YAML
|
|
11
|
+
frontmatter, preserved headings, paragraphs and tables — ready for LLM reading and analysis.
|
|
12
|
+
|
|
13
|
+
---
|
|
14
|
+
|
|
15
|
+
## What this repo is
|
|
16
|
+
|
|
17
|
+
Examples, research and tutorials showing how to work with financial report data, including reproducing the presentation styles found in financial-report research papers.
|
|
18
|
+
|
|
19
|
+
```
|
|
20
|
+
datasinking/
|
|
21
|
+
├── examples/ # Example scripts: pull data from the API and analyze it
|
|
22
|
+
├── research/ # Research notes / blog posts (reproducing paper-style presentation)
|
|
23
|
+
├── datasinking/ # Python client — pip install datasinking
|
|
24
|
+
├── llm-examples.md # Ask an LLM — no code needed (3 end-to-end examples)
|
|
25
|
+
└── README.md
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## Quick start
|
|
29
|
+
|
|
30
|
+
1. Get an API key at [datasink.ing](https://datasink.ing)
|
|
31
|
+
2. Pull data (FMP-style `?apikey=`):
|
|
32
|
+
|
|
33
|
+
```bash
|
|
34
|
+
# List exchanges
|
|
35
|
+
curl "https://api.datasink.ing/exchanges?apikey=YOUR_KEY"
|
|
36
|
+
|
|
37
|
+
# List all of Kweichow Moutai's reports
|
|
38
|
+
curl "https://api.datasink.ing/documents?symbol=600519.SS&apikey=YOUR_KEY"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
3. Or use the Python client:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
pip install datasinking
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
```python
|
|
48
|
+
from datasinking import DataSinking
|
|
49
|
+
|
|
50
|
+
ds = DataSinking("YOUR_KEY")
|
|
51
|
+
|
|
52
|
+
# Latest 3 reports of Kweichow Moutai (full markdown content included)
|
|
53
|
+
for r in ds.get_stock_reports("600519.SS", limit=3):
|
|
54
|
+
print(r["report_period"], r["title"], len(r["content"]), "chars")
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## Ask an LLM (no code)
|
|
58
|
+
|
|
59
|
+
Don't want to write code? Point any LLM at [datasink.ing](https://datasink.ing),
|
|
60
|
+
give it your API key, and ask in plain language. See
|
|
61
|
+
[`llm-examples.md`](llm-examples.md) for three end-to-end examples — explore
|
|
62
|
+
coverage, list a company's reports, and extract a figure with correct units.
|
|
63
|
+
|
|
64
|
+
## Examples (`examples/`)
|
|
65
|
+
|
|
66
|
+
| File | What it does |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `01_quickstart.py` | The 5 core functions: list exchanges / stocks / reports / fetch a report / fetch a stock's reports |
|
|
69
|
+
| `02_download_company.py` | Download a company's full reports to local Markdown files |
|
|
70
|
+
| `03_download_exchange.py` | Download an entire exchange's reports (all stocks) to local Markdown files |
|
|
71
|
+
|
|
72
|
+
Every example pulls from the live API and runs as-is.
|
|
73
|
+
|
|
74
|
+
> `03_download_exchange.py` fetches every report on an exchange (e.g. all of Shenzhen — 130k+ documents). Free keys work too, but fall back to slow per-document fetching (1 req/s + shared daily quota); a **paid (yearly)** key is strongly recommended for full-exchange downloads.
|
|
75
|
+
|
|
76
|
+
## Research (`research/`)
|
|
77
|
+
|
|
78
|
+
`research/` hosts research notes and blog posts, each based on DataSinking data with the source cited. You can reproduce charts and presentations found in financial-report research papers, e.g.:
|
|
79
|
+
|
|
80
|
+
- Long-term revenue / profit trends
|
|
81
|
+
- Industry comparison and distribution
|
|
82
|
+
- Time series of financial metrics
|
|
83
|
+
|
|
84
|
+
Start from [`research/TEMPLATE.md`](research/TEMPLATE.md).
|
|
85
|
+
|
|
86
|
+
## Data overview
|
|
87
|
+
|
|
88
|
+
| | |
|
|
89
|
+
|---|---|
|
|
90
|
+
| Coverage | SSE / SZSE / BSE, 5,000+ A-share companies |
|
|
91
|
+
| Document types | annual / semiannual / q1 / q3 / amendment |
|
|
92
|
+
| Format | Full-text Markdown (with YAML frontmatter) |
|
|
93
|
+
| API | REST — `GET /documents`, batch download, `with_content=1` for full text |
|
|
94
|
+
| Symbols | FMP style: `600519.SS` / `000001.SZ` / `830799.BJ` |
|
|
95
|
+
| Auth | `?apikey=` query parameter (FMP style) |
|
|
96
|
+
|
|
97
|
+
## Data source
|
|
98
|
+
|
|
99
|
+
All reports originate from [cninfo.com.cn](http://www.cninfo.com.cn), the officially designated information disclosure platform of China's listed companies.
|
|
100
|
+
|
|
101
|
+
## License
|
|
102
|
+
|
|
103
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""DataSinking Python client.
|
|
3
|
+
|
|
4
|
+
Usage:
|
|
5
|
+
from datasinking import DataSinking
|
|
6
|
+
ds = DataSinking("YOUR_API_KEY")
|
|
7
|
+
ds.list_exchanges()
|
|
8
|
+
"""
|
|
9
|
+
from .client import DataSinking
|
|
10
|
+
|
|
11
|
+
__version__ = "0.1.0"
|
|
12
|
+
__all__ = ["DataSinking"]
|
|
@@ -0,0 +1,126 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
"""DataSinking Python client — 5 个核心函数。
|
|
3
|
+
|
|
4
|
+
list_exchanges() 列交易所
|
|
5
|
+
list_stocks(exchange) 列某交易所的股票
|
|
6
|
+
list_reports(symbol, doc_type=?) 列某股票的报告列表(元数据, 无全文)
|
|
7
|
+
get_report(doc_id) 拉指定报告(全文)
|
|
8
|
+
get_stock_reports(symbol, ..., limit=7) 拉某股票的报告(全文)
|
|
9
|
+
|
|
10
|
+
返回类型约定: list_* 一律返回 list, get_report 返回单个 dict, get_stock_reports 返回 list。
|
|
11
|
+
"""
|
|
12
|
+
import time
|
|
13
|
+
|
|
14
|
+
import requests
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
class DataSinking:
|
|
18
|
+
def __init__(self, api_key, base_url="https://api.datasink.ing"):
|
|
19
|
+
self.base_url = base_url.rstrip("/")
|
|
20
|
+
self.api_key = api_key
|
|
21
|
+
self.session = requests.Session()
|
|
22
|
+
|
|
23
|
+
# ---- 内部方法 ----
|
|
24
|
+
def _get(self, path, params=None, retries=5):
|
|
25
|
+
params = {**(params or {}), "apikey": self.api_key}
|
|
26
|
+
for i in range(retries):
|
|
27
|
+
try:
|
|
28
|
+
r = self.session.get(f"{self.base_url}{path}", params=params, timeout=60)
|
|
29
|
+
if r.status_code == 429: # 限流, 稍等重试
|
|
30
|
+
time.sleep(2)
|
|
31
|
+
continue
|
|
32
|
+
r.raise_for_status()
|
|
33
|
+
return r.json()
|
|
34
|
+
except (requests.exceptions.SSLError, requests.exceptions.ConnectionError):
|
|
35
|
+
time.sleep(1 + i)
|
|
36
|
+
raise RuntimeError("Request failed after multiple retries")
|
|
37
|
+
|
|
38
|
+
def _post(self, path, json=None, retries=5):
|
|
39
|
+
params = {"apikey": self.api_key}
|
|
40
|
+
for i in range(retries):
|
|
41
|
+
try:
|
|
42
|
+
r = self.session.post(f"{self.base_url}{path}", params=params, json=json, timeout=60)
|
|
43
|
+
if r.status_code == 429:
|
|
44
|
+
time.sleep(2)
|
|
45
|
+
continue
|
|
46
|
+
r.raise_for_status()
|
|
47
|
+
return r.json()
|
|
48
|
+
except (requests.exceptions.SSLError, requests.exceptions.ConnectionError):
|
|
49
|
+
time.sleep(1 + i)
|
|
50
|
+
raise RuntimeError("Request failed after multiple retries")
|
|
51
|
+
|
|
52
|
+
def _fetch_all_meta(self, params):
|
|
53
|
+
"""分页拉全 metadata(无 content), 200/页"""
|
|
54
|
+
items = []
|
|
55
|
+
page = 1
|
|
56
|
+
while True:
|
|
57
|
+
d = self._get("/documents", dict(params, page=page, size=200))
|
|
58
|
+
items.extend(d["items"])
|
|
59
|
+
if not d["items"] or len(items) >= d["total"]:
|
|
60
|
+
break
|
|
61
|
+
page += 1
|
|
62
|
+
return items
|
|
63
|
+
|
|
64
|
+
def _batch_content(self, ids, batch_size=127):
|
|
65
|
+
"""批量拉全文; free 计划 batch 返回 403 时自动回退逐篇拉取"""
|
|
66
|
+
items = []
|
|
67
|
+
batch_ok = True
|
|
68
|
+
for i in range(0, len(ids), batch_size):
|
|
69
|
+
chunk = ids[i : i + batch_size]
|
|
70
|
+
if batch_ok:
|
|
71
|
+
try:
|
|
72
|
+
b = self._post("/documents/batch", {"doc_ids": chunk})
|
|
73
|
+
items.extend(b["items"])
|
|
74
|
+
continue
|
|
75
|
+
except requests.exceptions.HTTPError as e:
|
|
76
|
+
if e.response is not None and e.response.status_code == 403:
|
|
77
|
+
batch_ok = False
|
|
78
|
+
else:
|
|
79
|
+
raise
|
|
80
|
+
for did in chunk:
|
|
81
|
+
items.append(self._get(f"/documents/{did}"))
|
|
82
|
+
return items
|
|
83
|
+
|
|
84
|
+
# ---- 5 个核心函数 ----
|
|
85
|
+
def list_exchanges(self):
|
|
86
|
+
"""列交易所 -> list[str], 如 ['bj', 'sse', 'szse']"""
|
|
87
|
+
return self._get("/exchanges")["exchanges"]
|
|
88
|
+
|
|
89
|
+
def list_stocks(self, exchange):
|
|
90
|
+
"""列某交易所的股票 -> list[dict] (stock_code / stock_name / report_count)"""
|
|
91
|
+
return self._get("/stocks", {"exchange": exchange})["items"]
|
|
92
|
+
|
|
93
|
+
def list_reports(self, symbol, doc_type=None):
|
|
94
|
+
"""列某股票的报告列表(元数据, 无全文) -> list[dict]
|
|
95
|
+
|
|
96
|
+
doc_type: annual / semiannual / q1 / q3 / amendment
|
|
97
|
+
"""
|
|
98
|
+
params = {"symbol": symbol}
|
|
99
|
+
if doc_type:
|
|
100
|
+
params["doc_type"] = doc_type
|
|
101
|
+
return self._fetch_all_meta(params)
|
|
102
|
+
|
|
103
|
+
def get_report(self, doc_id):
|
|
104
|
+
"""拉指定报告(全文) -> dict, 含 content"""
|
|
105
|
+
return self._get(f"/documents/{doc_id}")
|
|
106
|
+
|
|
107
|
+
def get_stock_reports(self, symbol, period_from=None, period_to=None, limit=7, doc_type=None):
|
|
108
|
+
"""拉某股票的报告(全文) -> list[dict]
|
|
109
|
+
|
|
110
|
+
period_from / period_to: 按报告期(report_period, YYYY-MM-DD), 不是发布日。
|
|
111
|
+
limit: 最近 N 篇(按报告期倒序); -1 = 全部(自动分页拉全)。
|
|
112
|
+
doc_type: annual / semiannual / q1 / q3 / amendment
|
|
113
|
+
"""
|
|
114
|
+
params = {"symbol": symbol}
|
|
115
|
+
if period_from:
|
|
116
|
+
params["report_period_from"] = period_from
|
|
117
|
+
if period_to:
|
|
118
|
+
params["report_period_to"] = period_to
|
|
119
|
+
if doc_type:
|
|
120
|
+
params["doc_type"] = doc_type
|
|
121
|
+
if limit == -1:
|
|
122
|
+
ids = [m["id"] for m in self._fetch_all_meta(params)]
|
|
123
|
+
else:
|
|
124
|
+
d = self._get("/documents", dict(params, size=limit, order="desc"))
|
|
125
|
+
ids = [it["id"] for it in d["items"]]
|
|
126
|
+
return self._batch_content(ids)
|
|
@@ -0,0 +1,123 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: datasinking
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python client for DataSinking — full-text China A-share financial reports as Markdown.
|
|
5
|
+
Author: DataSinking
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://datasink.ing
|
|
8
|
+
Project-URL: Documentation, https://datasink.ing/docs
|
|
9
|
+
Project-URL: Repository, https://github.com/heubme2020/datasinking
|
|
10
|
+
Keywords: a-share,china,financial reports,markdown,api,stock
|
|
11
|
+
Classifier: Programming Language :: Python :: 3
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
15
|
+
Requires-Python: >=3.8
|
|
16
|
+
Description-Content-Type: text/markdown
|
|
17
|
+
License-File: LICENSE
|
|
18
|
+
Requires-Dist: requests
|
|
19
|
+
Dynamic: license-file
|
|
20
|
+
|
|
21
|
+
# DataSinking
|
|
22
|
+
|
|
23
|
+
**Full-text A-share financial reports, as clean Markdown.**
|
|
24
|
+
|
|
25
|
+
[DataSinking](https://datasink.ing) is a **China stock market data API** that serves
|
|
26
|
+
**full-text A-share financial reports** — annual, semi-annual and quarterly — as clean
|
|
27
|
+
**Markdown**. Download China A-share financial statements (balance sheet, income statement,
|
|
28
|
+
cash flow) by FMP-style symbol (`600519.SS`) or filter by exchange / report period, through a
|
|
29
|
+
simple REST API. Raw PDFs are sourced from [cninfo.com.cn](http://www.cninfo.com.cn) (the
|
|
30
|
+
officially designated disclosure platform) and parsed into structured Markdown with YAML
|
|
31
|
+
frontmatter, preserved headings, paragraphs and tables — ready for LLM reading and analysis.
|
|
32
|
+
|
|
33
|
+
---
|
|
34
|
+
|
|
35
|
+
## What this repo is
|
|
36
|
+
|
|
37
|
+
Examples, research and tutorials showing how to work with financial report data, including reproducing the presentation styles found in financial-report research papers.
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
datasinking/
|
|
41
|
+
├── examples/ # Example scripts: pull data from the API and analyze it
|
|
42
|
+
├── research/ # Research notes / blog posts (reproducing paper-style presentation)
|
|
43
|
+
├── datasinking/ # Python client — pip install datasinking
|
|
44
|
+
├── llm-examples.md # Ask an LLM — no code needed (3 end-to-end examples)
|
|
45
|
+
└── README.md
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## Quick start
|
|
49
|
+
|
|
50
|
+
1. Get an API key at [datasink.ing](https://datasink.ing)
|
|
51
|
+
2. Pull data (FMP-style `?apikey=`):
|
|
52
|
+
|
|
53
|
+
```bash
|
|
54
|
+
# List exchanges
|
|
55
|
+
curl "https://api.datasink.ing/exchanges?apikey=YOUR_KEY"
|
|
56
|
+
|
|
57
|
+
# List all of Kweichow Moutai's reports
|
|
58
|
+
curl "https://api.datasink.ing/documents?symbol=600519.SS&apikey=YOUR_KEY"
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
3. Or use the Python client:
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
pip install datasinking
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
from datasinking import DataSinking
|
|
69
|
+
|
|
70
|
+
ds = DataSinking("YOUR_KEY")
|
|
71
|
+
|
|
72
|
+
# Latest 3 reports of Kweichow Moutai (full markdown content included)
|
|
73
|
+
for r in ds.get_stock_reports("600519.SS", limit=3):
|
|
74
|
+
print(r["report_period"], r["title"], len(r["content"]), "chars")
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## Ask an LLM (no code)
|
|
78
|
+
|
|
79
|
+
Don't want to write code? Point any LLM at [datasink.ing](https://datasink.ing),
|
|
80
|
+
give it your API key, and ask in plain language. See
|
|
81
|
+
[`llm-examples.md`](llm-examples.md) for three end-to-end examples — explore
|
|
82
|
+
coverage, list a company's reports, and extract a figure with correct units.
|
|
83
|
+
|
|
84
|
+
## Examples (`examples/`)
|
|
85
|
+
|
|
86
|
+
| File | What it does |
|
|
87
|
+
|---|---|
|
|
88
|
+
| `01_quickstart.py` | The 5 core functions: list exchanges / stocks / reports / fetch a report / fetch a stock's reports |
|
|
89
|
+
| `02_download_company.py` | Download a company's full reports to local Markdown files |
|
|
90
|
+
| `03_download_exchange.py` | Download an entire exchange's reports (all stocks) to local Markdown files |
|
|
91
|
+
|
|
92
|
+
Every example pulls from the live API and runs as-is.
|
|
93
|
+
|
|
94
|
+
> `03_download_exchange.py` fetches every report on an exchange (e.g. all of Shenzhen — 130k+ documents). Free keys work too, but fall back to slow per-document fetching (1 req/s + shared daily quota); a **paid (yearly)** key is strongly recommended for full-exchange downloads.
|
|
95
|
+
|
|
96
|
+
## Research (`research/`)
|
|
97
|
+
|
|
98
|
+
`research/` hosts research notes and blog posts, each based on DataSinking data with the source cited. You can reproduce charts and presentations found in financial-report research papers, e.g.:
|
|
99
|
+
|
|
100
|
+
- Long-term revenue / profit trends
|
|
101
|
+
- Industry comparison and distribution
|
|
102
|
+
- Time series of financial metrics
|
|
103
|
+
|
|
104
|
+
Start from [`research/TEMPLATE.md`](research/TEMPLATE.md).
|
|
105
|
+
|
|
106
|
+
## Data overview
|
|
107
|
+
|
|
108
|
+
| | |
|
|
109
|
+
|---|---|
|
|
110
|
+
| Coverage | SSE / SZSE / BSE, 5,000+ A-share companies |
|
|
111
|
+
| Document types | annual / semiannual / q1 / q3 / amendment |
|
|
112
|
+
| Format | Full-text Markdown (with YAML frontmatter) |
|
|
113
|
+
| API | REST — `GET /documents`, batch download, `with_content=1` for full text |
|
|
114
|
+
| Symbols | FMP style: `600519.SS` / `000001.SZ` / `830799.BJ` |
|
|
115
|
+
| Auth | `?apikey=` query parameter (FMP style) |
|
|
116
|
+
|
|
117
|
+
## Data source
|
|
118
|
+
|
|
119
|
+
All reports originate from [cninfo.com.cn](http://www.cninfo.com.cn), the officially designated information disclosure platform of China's listed companies.
|
|
120
|
+
|
|
121
|
+
## License
|
|
122
|
+
|
|
123
|
+
[MIT](LICENSE)
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
LICENSE
|
|
2
|
+
README.md
|
|
3
|
+
pyproject.toml
|
|
4
|
+
datasinking/__init__.py
|
|
5
|
+
datasinking/client.py
|
|
6
|
+
datasinking.egg-info/PKG-INFO
|
|
7
|
+
datasinking.egg-info/SOURCES.txt
|
|
8
|
+
datasinking.egg-info/dependency_links.txt
|
|
9
|
+
datasinking.egg-info/requires.txt
|
|
10
|
+
datasinking.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
requests
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
datasinking
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "datasinking"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python client for DataSinking — full-text China A-share financial reports as Markdown."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = { text = "MIT" }
|
|
12
|
+
authors = [{ name = "DataSinking" }]
|
|
13
|
+
keywords = ["a-share", "china", "financial reports", "markdown", "api", "stock"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Operating System :: OS Independent",
|
|
18
|
+
"Topic :: Office/Business :: Financial",
|
|
19
|
+
]
|
|
20
|
+
dependencies = ["requests"]
|
|
21
|
+
|
|
22
|
+
[project.urls]
|
|
23
|
+
Homepage = "https://datasink.ing"
|
|
24
|
+
Documentation = "https://datasink.ing/docs"
|
|
25
|
+
Repository = "https://github.com/heubme2020/datasinking"
|
|
26
|
+
|
|
27
|
+
[tool.setuptools]
|
|
28
|
+
packages = ["datasinking"]
|