finclaw-data-sdk 0.1.3__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.
- finclaw_data_sdk-0.1.3/PKG-INFO +43 -0
- finclaw_data_sdk-0.1.3/README.md +21 -0
- finclaw_data_sdk-0.1.3/pyproject.toml +36 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk/__init__.py +7 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk/client.py +267 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk/cols.py +116 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk.egg-info/PKG-INFO +43 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk.egg-info/SOURCES.txt +10 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk.egg-info/dependency_links.txt +1 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk.egg-info/requires.txt +1 -0
- finclaw_data_sdk-0.1.3/python/finclaw_data_sdk.egg-info/top_level.txt +1 -0
- finclaw_data_sdk-0.1.3/setup.cfg +4 -0
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: finclaw-data-sdk
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: A 股量化数据 HTTP 客户端(QuantClient),只依赖 pandas
|
|
5
|
+
Author-email: dekeky <dekeky@163.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/chocochato0713/finclaw-data
|
|
7
|
+
Project-URL: Repository, https://github.com/chocochato0713/finclaw-data
|
|
8
|
+
Keywords: finclaw,ashare,quant,kline,clickhouse
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: pandas>=2.0
|
|
22
|
+
|
|
23
|
+
# finclaw-data-sdk
|
|
24
|
+
|
|
25
|
+
A 股量化数据 HTTP 客户端。安装后 `from finclaw_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install finclaw-data-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from finclaw_data_sdk import QuantClient, cols
|
|
33
|
+
|
|
34
|
+
c = QuantClient("http://127.0.0.1:8000")
|
|
35
|
+
bars = c.kline(symbol="600519", start="20240801", end="20240805", adj="qfq")
|
|
36
|
+
snap = c.snapshot(trade_date="20240819", symbols=["600519", "000001"], adj="qfq")
|
|
37
|
+
df = c.fina(symbol="600519", start="20240101", end="20241231", fields=cols.fina.EPS_BASIC)
|
|
38
|
+
idx = c.index_list()
|
|
39
|
+
idx_bars = c.index_kline(index="000300", start="20240801", end="20240805", fields=cols.index_kline.CLOSE)
|
|
40
|
+
cons = c.index_constituents(index="000300", fields=cols.index_constituents.SYMBOL)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `finclaw-data serve`。直连 ClickHouse 请安装服务包 `finclaw-data`,使用 `QuantClient.from_clickhouse()`。
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# finclaw-data-sdk
|
|
2
|
+
|
|
3
|
+
A 股量化数据 HTTP 客户端。安装后 `from finclaw_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
pip install finclaw-data-sdk
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from finclaw_data_sdk import QuantClient, cols
|
|
11
|
+
|
|
12
|
+
c = QuantClient("http://127.0.0.1:8000")
|
|
13
|
+
bars = c.kline(symbol="600519", start="20240801", end="20240805", adj="qfq")
|
|
14
|
+
snap = c.snapshot(trade_date="20240819", symbols=["600519", "000001"], adj="qfq")
|
|
15
|
+
df = c.fina(symbol="600519", start="20240101", end="20241231", fields=cols.fina.EPS_BASIC)
|
|
16
|
+
idx = c.index_list()
|
|
17
|
+
idx_bars = c.index_kline(index="000300", start="20240801", end="20240805", fields=cols.index_kline.CLOSE)
|
|
18
|
+
cons = c.index_constituents(index="000300", fields=cols.index_constituents.SYMBOL)
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `finclaw-data serve`。直连 ClickHouse 请安装服务包 `finclaw-data`,使用 `QuantClient.from_clickhouse()`。
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "finclaw-data-sdk"
|
|
3
|
+
version = "0.1.3"
|
|
4
|
+
description = "A 股量化数据 HTTP 客户端(QuantClient),只依赖 pandas"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.10"
|
|
7
|
+
authors = [
|
|
8
|
+
{ name = "dekeky", email = "dekeky@163.com" },
|
|
9
|
+
]
|
|
10
|
+
dependencies = [
|
|
11
|
+
"pandas>=2.0",
|
|
12
|
+
]
|
|
13
|
+
keywords = ["finclaw", "ashare", "quant", "kline", "clickhouse"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Programming Language :: Python :: 3",
|
|
16
|
+
"Programming Language :: Python :: 3.10",
|
|
17
|
+
"Programming Language :: Python :: 3.11",
|
|
18
|
+
"Programming Language :: Python :: 3.12",
|
|
19
|
+
"Programming Language :: Python :: 3.13",
|
|
20
|
+
"Programming Language :: Python :: 3.14",
|
|
21
|
+
"Operating System :: OS Independent",
|
|
22
|
+
"Topic :: Office/Business :: Financial",
|
|
23
|
+
"Intended Audience :: Developers",
|
|
24
|
+
"Intended Audience :: Financial and Insurance Industry",
|
|
25
|
+
]
|
|
26
|
+
[project.urls]
|
|
27
|
+
Homepage = "https://github.com/chocochato0713/finclaw-data"
|
|
28
|
+
Repository = "https://github.com/chocochato0713/finclaw-data"
|
|
29
|
+
|
|
30
|
+
[build-system]
|
|
31
|
+
requires = ["setuptools>=68"]
|
|
32
|
+
build-backend = "setuptools.build_meta"
|
|
33
|
+
|
|
34
|
+
[tool.setuptools.packages.find]
|
|
35
|
+
where = ["python"]
|
|
36
|
+
include = ["finclaw_data_sdk*"]
|
|
@@ -0,0 +1,267 @@
|
|
|
1
|
+
"""量化数据 HTTP 客户端。"""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import json
|
|
6
|
+
from datetime import date
|
|
7
|
+
from typing import Any
|
|
8
|
+
from urllib.error import HTTPError, URLError
|
|
9
|
+
from urllib.parse import urlencode
|
|
10
|
+
from urllib.request import Request, urlopen
|
|
11
|
+
|
|
12
|
+
import pandas as pd
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
def _to_ymd(value: str | date | None) -> str | None:
|
|
16
|
+
if value is None:
|
|
17
|
+
return None
|
|
18
|
+
if isinstance(value, date):
|
|
19
|
+
return value.strftime("%Y%m%d")
|
|
20
|
+
return str(value).replace("-", "")[:8]
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _join_symbols(symbols: list[str] | str | None, symbol: str | None = None) -> str | None:
|
|
24
|
+
codes = symbols if symbols is not None else symbol
|
|
25
|
+
if codes is None:
|
|
26
|
+
return None
|
|
27
|
+
if isinstance(codes, list):
|
|
28
|
+
return ",".join(str(s).zfill(6) for s in codes)
|
|
29
|
+
return str(codes)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class QuantClientError(RuntimeError):
|
|
33
|
+
pass
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
class QuantClient:
|
|
37
|
+
"""远程 HTTP 客户端。依赖仅 pandas,不导入服务端业务代码。"""
|
|
38
|
+
|
|
39
|
+
def __init__(self, base_url: str = "http://127.0.0.1:8000", timeout: float = 1800.0) -> None:
|
|
40
|
+
self.base_url = base_url.rstrip("/")
|
|
41
|
+
self.timeout = timeout
|
|
42
|
+
|
|
43
|
+
def _get(self, path: str, **params: Any) -> dict[str, Any]:
|
|
44
|
+
query = {k: v for k, v in params.items() if v is not None and v != ""}
|
|
45
|
+
url = f"{self.base_url}{path}"
|
|
46
|
+
if query:
|
|
47
|
+
url = f"{url}?{urlencode(query)}"
|
|
48
|
+
req = Request(url, headers={"Accept": "application/json"})
|
|
49
|
+
try:
|
|
50
|
+
with urlopen(req, timeout=self.timeout) as resp:
|
|
51
|
+
return json.loads(resp.read().decode("utf-8"))
|
|
52
|
+
except HTTPError as exc:
|
|
53
|
+
body = exc.read().decode("utf-8", errors="replace")
|
|
54
|
+
raise QuantClientError(f"HTTP {exc.code}: {body}") from exc
|
|
55
|
+
except URLError as exc:
|
|
56
|
+
raise QuantClientError(f"request failed: {exc}") from exc
|
|
57
|
+
|
|
58
|
+
@staticmethod
|
|
59
|
+
def _to_frame(body: dict[str, Any]) -> pd.DataFrame:
|
|
60
|
+
rows = body.get("rows") or []
|
|
61
|
+
return pd.DataFrame(rows)
|
|
62
|
+
|
|
63
|
+
def catalog(self) -> dict[str, Any]:
|
|
64
|
+
"""库存目录:各表行数、标的数、日期覆盖。"""
|
|
65
|
+
return self._get("/v1/catalog")
|
|
66
|
+
|
|
67
|
+
def catalog_preview(
|
|
68
|
+
self,
|
|
69
|
+
dataset: str,
|
|
70
|
+
symbol: str | None = None,
|
|
71
|
+
index: str | None = None,
|
|
72
|
+
start: str | date | None = None,
|
|
73
|
+
end: str | date | None = None,
|
|
74
|
+
limit: int = 50,
|
|
75
|
+
offset: int = 0,
|
|
76
|
+
) -> pd.DataFrame:
|
|
77
|
+
"""数据集分页预览,不走详情查询接口。"""
|
|
78
|
+
return self._to_frame(
|
|
79
|
+
self._get(
|
|
80
|
+
f"/v1/catalog/{dataset}/preview",
|
|
81
|
+
symbol=symbol,
|
|
82
|
+
index=index,
|
|
83
|
+
start=_to_ymd(start),
|
|
84
|
+
end=_to_ymd(end),
|
|
85
|
+
limit=limit,
|
|
86
|
+
offset=offset,
|
|
87
|
+
)
|
|
88
|
+
)
|
|
89
|
+
|
|
90
|
+
def stocks(
|
|
91
|
+
self,
|
|
92
|
+
listed: int | None = None,
|
|
93
|
+
symbol: str | None = None,
|
|
94
|
+
fields: str | None = None,
|
|
95
|
+
limit: int | None = None,
|
|
96
|
+
) -> pd.DataFrame:
|
|
97
|
+
return self._to_frame(
|
|
98
|
+
self._get("/v1/stocks", listed=listed, symbol=symbol, fields=fields, limit=limit)
|
|
99
|
+
)
|
|
100
|
+
|
|
101
|
+
def calendar(
|
|
102
|
+
self,
|
|
103
|
+
start: str | date | None = None,
|
|
104
|
+
end: str | date | None = None,
|
|
105
|
+
trading_only: int = 1,
|
|
106
|
+
fields: str | None = None,
|
|
107
|
+
limit: int | None = None,
|
|
108
|
+
) -> pd.DataFrame:
|
|
109
|
+
return self._to_frame(
|
|
110
|
+
self._get(
|
|
111
|
+
"/v1/calendar",
|
|
112
|
+
start=_to_ymd(start),
|
|
113
|
+
end=_to_ymd(end),
|
|
114
|
+
trading_only=trading_only,
|
|
115
|
+
fields=fields,
|
|
116
|
+
limit=limit,
|
|
117
|
+
)
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
def kline(
|
|
121
|
+
self,
|
|
122
|
+
symbol: str | None = None,
|
|
123
|
+
symbols: list[str] | str | None = None,
|
|
124
|
+
start: str | date | None = None,
|
|
125
|
+
end: str | date | None = None,
|
|
126
|
+
adj: str = "none",
|
|
127
|
+
fields: str | None = None,
|
|
128
|
+
limit: int | None = None,
|
|
129
|
+
) -> pd.DataFrame:
|
|
130
|
+
"""时序日 K:单股或多股 + 日期区间。adj=none|qfq|hfq。不传 limit 则不限制行数。"""
|
|
131
|
+
params: dict[str, Any] = {
|
|
132
|
+
"start": _to_ymd(start),
|
|
133
|
+
"end": _to_ymd(end),
|
|
134
|
+
"adj": adj,
|
|
135
|
+
"fields": fields,
|
|
136
|
+
}
|
|
137
|
+
if limit is not None:
|
|
138
|
+
params["limit"] = limit
|
|
139
|
+
if symbols is not None:
|
|
140
|
+
params["symbols"] = _join_symbols(symbols)
|
|
141
|
+
else:
|
|
142
|
+
params["symbol"] = symbol
|
|
143
|
+
return self._to_frame(self._get("/v1/kline", **params))
|
|
144
|
+
|
|
145
|
+
def snapshot(
|
|
146
|
+
self,
|
|
147
|
+
trade_date: str | date,
|
|
148
|
+
symbols: list[str] | str | None = None,
|
|
149
|
+
adj: str = "none",
|
|
150
|
+
fields: str | None = None,
|
|
151
|
+
limit: int | None = None,
|
|
152
|
+
) -> pd.DataFrame:
|
|
153
|
+
"""单日截面:不传 symbols 则全市场当日。"""
|
|
154
|
+
return self._to_frame(
|
|
155
|
+
self._get(
|
|
156
|
+
"/v1/snapshot",
|
|
157
|
+
trade_date=_to_ymd(trade_date),
|
|
158
|
+
symbols=_join_symbols(symbols),
|
|
159
|
+
adj=adj,
|
|
160
|
+
fields=fields,
|
|
161
|
+
limit=limit,
|
|
162
|
+
)
|
|
163
|
+
)
|
|
164
|
+
|
|
165
|
+
def fina(
|
|
166
|
+
self,
|
|
167
|
+
symbol: str | None = None,
|
|
168
|
+
symbols: list[str] | str | None = None,
|
|
169
|
+
start: str | date | None = None,
|
|
170
|
+
end: str | date | None = None,
|
|
171
|
+
fields: str | None = None,
|
|
172
|
+
limit: int | None = None,
|
|
173
|
+
) -> pd.DataFrame:
|
|
174
|
+
return self._to_frame(
|
|
175
|
+
self._get(
|
|
176
|
+
"/v1/fina",
|
|
177
|
+
symbol=symbol if symbols is None else None,
|
|
178
|
+
symbols=_join_symbols(symbols),
|
|
179
|
+
start=_to_ymd(start),
|
|
180
|
+
end=_to_ymd(end),
|
|
181
|
+
fields=fields,
|
|
182
|
+
limit=limit,
|
|
183
|
+
)
|
|
184
|
+
)
|
|
185
|
+
|
|
186
|
+
def adj_factor(
|
|
187
|
+
self,
|
|
188
|
+
symbol: str | None = None,
|
|
189
|
+
symbols: list[str] | str | None = None,
|
|
190
|
+
start: str | date | None = None,
|
|
191
|
+
end: str | date | None = None,
|
|
192
|
+
fields: str | None = None,
|
|
193
|
+
limit: int | None = None,
|
|
194
|
+
) -> pd.DataFrame:
|
|
195
|
+
"""除权/复权因子(ex_date, fore/back/adjust_factor)。"""
|
|
196
|
+
return self._to_frame(
|
|
197
|
+
self._get(
|
|
198
|
+
"/v1/adj-factor",
|
|
199
|
+
symbol=symbol if symbols is None else None,
|
|
200
|
+
symbols=_join_symbols(symbols),
|
|
201
|
+
start=_to_ymd(start),
|
|
202
|
+
end=_to_ymd(end),
|
|
203
|
+
fields=fields,
|
|
204
|
+
limit=limit,
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
def index_list(
|
|
209
|
+
self,
|
|
210
|
+
index: str | None = None,
|
|
211
|
+
fields: str | None = None,
|
|
212
|
+
limit: int | None = None,
|
|
213
|
+
) -> pd.DataFrame:
|
|
214
|
+
"""指数目录(index_meta)。"""
|
|
215
|
+
return self._to_frame(
|
|
216
|
+
self._get("/v1/index", index=index, fields=fields, limit=limit)
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
def index_kline(
|
|
220
|
+
self,
|
|
221
|
+
index: str | None = None,
|
|
222
|
+
indices: list[str] | str | None = None,
|
|
223
|
+
start: str | date | None = None,
|
|
224
|
+
end: str | date | None = None,
|
|
225
|
+
fields: str | None = None,
|
|
226
|
+
limit: int | None = None,
|
|
227
|
+
) -> pd.DataFrame:
|
|
228
|
+
"""指数日 K 时序。不传 limit 则不限制行数。"""
|
|
229
|
+
params: dict[str, Any] = {
|
|
230
|
+
"start": _to_ymd(start),
|
|
231
|
+
"end": _to_ymd(end),
|
|
232
|
+
"fields": fields,
|
|
233
|
+
}
|
|
234
|
+
if limit is not None:
|
|
235
|
+
params["limit"] = limit
|
|
236
|
+
if indices is not None:
|
|
237
|
+
params["indices"] = _join_symbols(indices)
|
|
238
|
+
else:
|
|
239
|
+
params["index"] = index
|
|
240
|
+
return self._to_frame(self._get("/v1/index/kline", **params))
|
|
241
|
+
|
|
242
|
+
def index_constituents(
|
|
243
|
+
self,
|
|
244
|
+
index: str,
|
|
245
|
+
date: str | date | None = None,
|
|
246
|
+
fields: str | None = None,
|
|
247
|
+
limit: int | None = None,
|
|
248
|
+
) -> pd.DataFrame:
|
|
249
|
+
"""指数成分股(asof 快照)。"""
|
|
250
|
+
return self._to_frame(
|
|
251
|
+
self._get(
|
|
252
|
+
"/v1/index/constituents",
|
|
253
|
+
index=index,
|
|
254
|
+
date=_to_ymd(date),
|
|
255
|
+
fields=fields,
|
|
256
|
+
limit=limit,
|
|
257
|
+
)
|
|
258
|
+
)
|
|
259
|
+
|
|
260
|
+
def indices(
|
|
261
|
+
self,
|
|
262
|
+
index: str | None = None,
|
|
263
|
+
fields: str | None = None,
|
|
264
|
+
limit: int | None = None,
|
|
265
|
+
) -> pd.DataFrame:
|
|
266
|
+
"""指数目录(`index_list` 别名)。"""
|
|
267
|
+
return self.index_list(index=index, fields=fields, limit=limit)
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
"""各 `QuantClient` 方法返回的列名。
|
|
2
|
+
|
|
3
|
+
用法::
|
|
4
|
+
|
|
5
|
+
from finclaw_data_sdk import QuantClient, cols
|
|
6
|
+
|
|
7
|
+
c.kline(..., fields=cols.kline.CLOSE)
|
|
8
|
+
c.fina(..., fields=cols.fina.EPS_BASIC)
|
|
9
|
+
c.index_kline(..., fields=cols.index_kline.CLOSE)
|
|
10
|
+
c.index_constituents(..., fields=cols.index_constituents.SYMBOL)
|
|
11
|
+
"""
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
class stocks:
|
|
15
|
+
"""`stocks()` 股池。"""
|
|
16
|
+
|
|
17
|
+
SYMBOL = "symbol" # 股票代码
|
|
18
|
+
EXCHANGE = "exchange" # 交易所
|
|
19
|
+
NAME = "name" # 简称
|
|
20
|
+
CODE = "code" # Baostock 代码,如 sh.600519
|
|
21
|
+
IPO_DATE = "ipoDate" # 上市日
|
|
22
|
+
OUT_DATE = "outDate" # 退市日,在市为 None
|
|
23
|
+
TYPE = "type" # 证券类型,1=股票
|
|
24
|
+
STATUS = "status" # 上市状态,1=在市 0=退市
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
class calendar:
|
|
28
|
+
"""`calendar()` 交易日历。"""
|
|
29
|
+
|
|
30
|
+
TRADE_DATE = "trade_date" # 日历日
|
|
31
|
+
IS_TRADING = "is_trading" # 1=交易日 0=非交易日
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
class kline:
|
|
35
|
+
"""`kline()` 日 K 时序。`snapshot()` 列相同。"""
|
|
36
|
+
|
|
37
|
+
SYMBOL = "symbol" # 股票代码
|
|
38
|
+
DATE = "date" # 交易日
|
|
39
|
+
OPEN = "open" # 开盘价
|
|
40
|
+
HIGH = "high" # 最高价
|
|
41
|
+
LOW = "low" # 最低价
|
|
42
|
+
CLOSE = "close" # 收盘价
|
|
43
|
+
PRECLOSE = "preclose" # 昨收
|
|
44
|
+
VOLUME = "volume" # 成交量
|
|
45
|
+
AMOUNT = "amount" # 成交额
|
|
46
|
+
TURN = "turn" # 换手率(表字段 turnover)
|
|
47
|
+
PCT_CHG = "pct_chg" # 涨跌幅
|
|
48
|
+
PE_TTM = "pe_ttm" # 市盈率 TTM
|
|
49
|
+
PB_MRQ = "pb_mrq" # 市净率 MRQ
|
|
50
|
+
PS_TTM = "ps_ttm" # 市销率 TTM
|
|
51
|
+
PCF_NCF_TTM = "pcf_ncf_ttm" # 市现率 TTM
|
|
52
|
+
TRADE_STATUS = "trade_status" # 交易状态,1=正常
|
|
53
|
+
IS_ST = "is_st" # 是否 ST
|
|
54
|
+
ADJ_TYPE = "adj_type" # 复权类型 none|qfq|hfq
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class snapshot(kline):
|
|
58
|
+
"""`snapshot()` 单日截面,列与 `kline` 相同。"""
|
|
59
|
+
|
|
60
|
+
|
|
61
|
+
class fina:
|
|
62
|
+
"""`fina()` 报告期累计财务指标。另有维度列 symbol / exchange / report_date / notice_date / season_label。"""
|
|
63
|
+
|
|
64
|
+
NOTICE_DATE = "notice_date" # 公告日;回测应用 notice_date ≤ 交易日
|
|
65
|
+
EPS_BASIC = "eps_basic" # 基本每股收益
|
|
66
|
+
BPS = "bps" # 每股净资产
|
|
67
|
+
ROE_DILUTED = "roe_diluted" # 加权净资产收益率(东财 ROEJQ;列名沿用)
|
|
68
|
+
ROA = "roa" # 总资产净利率
|
|
69
|
+
GROSS_PROFIT_RATIO = "gross_profit_ratio" # 销售毛利率
|
|
70
|
+
NET_PROFIT_RATIO = "net_profit_ratio" # 销售净利率
|
|
71
|
+
TOTAL_OPERATE_REVENUE = "total_operate_revenue" # 营业总收入
|
|
72
|
+
PARENT_NET_PROFIT = "parent_net_profit" # 归母净利润
|
|
73
|
+
DEDU_PARENT_PROFIT = "dedu_parent_profit" # 扣非归母净利润
|
|
74
|
+
REVENUE_YOY = "revenue_yoy" # 营业总收入同比
|
|
75
|
+
PARENT_NET_PROFIT_YOY = "parent_net_profit_yoy" # 归母净利润同比
|
|
76
|
+
REVENUE_QOQ = "revenue_qoq" # 营业总收入环比
|
|
77
|
+
NET_PROFIT_QOQ = "net_profit_qoq" # 净利润环比
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
class adj_factor:
|
|
81
|
+
"""`adj_factor()` 除权 / 复权因子。"""
|
|
82
|
+
|
|
83
|
+
SYMBOL = "symbol" # 股票代码
|
|
84
|
+
EXCHANGE = "exchange" # 交易所
|
|
85
|
+
EX_DATE = "ex_date" # 除权除息日
|
|
86
|
+
FORE_ADJUST_FACTOR = "fore_adjust_factor" # 前复权因子
|
|
87
|
+
BACK_ADJUST_FACTOR = "back_adjust_factor" # 后复权因子
|
|
88
|
+
ADJUST_FACTOR = "adjust_factor" # Baostock 原始调整因子
|
|
89
|
+
|
|
90
|
+
|
|
91
|
+
class index_kline:
|
|
92
|
+
"""`index_kline()` 指数日 K。无估值列、无复权。"""
|
|
93
|
+
|
|
94
|
+
INDEX_CODE = "index_code" # 指数代码
|
|
95
|
+
EXCHANGE = "exchange" # 交易所
|
|
96
|
+
DATE = "date" # 交易日
|
|
97
|
+
OPEN = "open" # 开盘
|
|
98
|
+
HIGH = "high" # 最高
|
|
99
|
+
LOW = "low" # 最低
|
|
100
|
+
CLOSE = "close" # 收盘
|
|
101
|
+
PRECLOSE = "preclose" # 昨收
|
|
102
|
+
VOLUME = "volume" # 成交量
|
|
103
|
+
AMOUNT = "amount" # 成交额
|
|
104
|
+
TURN = "turn" # 换手率(表字段 turnover)
|
|
105
|
+
PCT_CHG = "pct_chg" # 涨跌幅
|
|
106
|
+
|
|
107
|
+
|
|
108
|
+
class index_constituents:
|
|
109
|
+
"""`index_constituents()` 指数成分股 asof 快照。不含权重。"""
|
|
110
|
+
|
|
111
|
+
INDEX_CODE = "index_code" # 指数代码
|
|
112
|
+
SNAPSHOT_DATE = "snapshot_date" # 成分快照日
|
|
113
|
+
SYMBOL = "symbol" # 成分股代码
|
|
114
|
+
EXCHANGE = "exchange" # 交易所
|
|
115
|
+
NAME = "name" # 成分股简称
|
|
116
|
+
SOURCE = "source" # baostock 或 csindex
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: finclaw-data-sdk
|
|
3
|
+
Version: 0.1.3
|
|
4
|
+
Summary: A 股量化数据 HTTP 客户端(QuantClient),只依赖 pandas
|
|
5
|
+
Author-email: dekeky <dekeky@163.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/chocochato0713/finclaw-data
|
|
7
|
+
Project-URL: Repository, https://github.com/chocochato0713/finclaw-data
|
|
8
|
+
Keywords: finclaw,ashare,quant,kline,clickhouse
|
|
9
|
+
Classifier: Programming Language :: Python :: 3
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
15
|
+
Classifier: Operating System :: OS Independent
|
|
16
|
+
Classifier: Topic :: Office/Business :: Financial
|
|
17
|
+
Classifier: Intended Audience :: Developers
|
|
18
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
19
|
+
Requires-Python: >=3.10
|
|
20
|
+
Description-Content-Type: text/markdown
|
|
21
|
+
Requires-Dist: pandas>=2.0
|
|
22
|
+
|
|
23
|
+
# finclaw-data-sdk
|
|
24
|
+
|
|
25
|
+
A 股量化数据 HTTP 客户端。安装后 `from finclaw_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
pip install finclaw-data-sdk
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
```python
|
|
32
|
+
from finclaw_data_sdk import QuantClient, cols
|
|
33
|
+
|
|
34
|
+
c = QuantClient("http://127.0.0.1:8000")
|
|
35
|
+
bars = c.kline(symbol="600519", start="20240801", end="20240805", adj="qfq")
|
|
36
|
+
snap = c.snapshot(trade_date="20240819", symbols=["600519", "000001"], adj="qfq")
|
|
37
|
+
df = c.fina(symbol="600519", start="20240101", end="20241231", fields=cols.fina.EPS_BASIC)
|
|
38
|
+
idx = c.index_list()
|
|
39
|
+
idx_bars = c.index_kline(index="000300", start="20240801", end="20240805", fields=cols.index_kline.CLOSE)
|
|
40
|
+
cons = c.index_constituents(index="000300", fields=cols.index_constituents.SYMBOL)
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `finclaw-data serve`。直连 ClickHouse 请安装服务包 `finclaw-data`,使用 `QuantClient.from_clickhouse()`。
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
README.md
|
|
2
|
+
pyproject.toml
|
|
3
|
+
python/finclaw_data_sdk/__init__.py
|
|
4
|
+
python/finclaw_data_sdk/client.py
|
|
5
|
+
python/finclaw_data_sdk/cols.py
|
|
6
|
+
python/finclaw_data_sdk.egg-info/PKG-INFO
|
|
7
|
+
python/finclaw_data_sdk.egg-info/SOURCES.txt
|
|
8
|
+
python/finclaw_data_sdk.egg-info/dependency_links.txt
|
|
9
|
+
python/finclaw_data_sdk.egg-info/requires.txt
|
|
10
|
+
python/finclaw_data_sdk.egg-info/top_level.txt
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
pandas>=2.0
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
finclaw_data_sdk
|