ashare-quant-data-sdk 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.
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: ashare-quant-data-sdk
3
+ Version: 0.1.0
4
+ Summary: A 股量化数据 HTTP 客户端(QuantClient),只依赖 pandas
5
+ Author-email: dekeky <dekeky@163.com>
6
+ Project-URL: Homepage, https://github.com/chocochato0713/ashare-quant-data
7
+ Project-URL: Repository, https://github.com/chocochato0713/ashare-quant-data
8
+ Keywords: 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
+ # ashare-quant-data-sdk
24
+
25
+ A 股量化数据 HTTP 客户端。安装后 `from ashare_quant_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
26
+
27
+ ```bash
28
+ pip install ashare-quant-data-sdk
29
+ ```
30
+
31
+ ```python
32
+ from ashare_quant_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
+ ```
39
+
40
+ 日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `quant-data serve`。直连 ClickHouse 请安装服务包 `quant-data`,使用 `QuantClient.from_clickhouse()`。
@@ -0,0 +1,18 @@
1
+ # ashare-quant-data-sdk
2
+
3
+ A 股量化数据 HTTP 客户端。安装后 `from ashare_quant_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
4
+
5
+ ```bash
6
+ pip install ashare-quant-data-sdk
7
+ ```
8
+
9
+ ```python
10
+ from ashare_quant_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
+ ```
17
+
18
+ 日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `quant-data serve`。直连 ClickHouse 请安装服务包 `quant-data`,使用 `QuantClient.from_clickhouse()`。
@@ -0,0 +1,36 @@
1
+ [project]
2
+ name = "ashare-quant-data-sdk"
3
+ version = "0.1.0"
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 = ["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/ashare-quant-data"
28
+ Repository = "https://github.com/chocochato0713/ashare-quant-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 = ["ashare_quant_data_sdk*"]
@@ -0,0 +1,7 @@
1
+ """A 股量化数据 HTTP SDK(不含拉取、存储等服务端业务)。"""
2
+
3
+ from . import cols
4
+ from .client import QuantClient, QuantClientError
5
+
6
+ __version__ = "0.1.0"
7
+ __all__ = ["QuantClient", "QuantClientError", "cols", "__version__"]
@@ -0,0 +1,178 @@
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 = 60.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 stocks(
64
+ self,
65
+ listed: int | None = None,
66
+ symbol: str | None = None,
67
+ fields: str | None = None,
68
+ limit: int | None = None,
69
+ ) -> pd.DataFrame:
70
+ return self._to_frame(
71
+ self._get("/v1/stocks", listed=listed, symbol=symbol, fields=fields, limit=limit)
72
+ )
73
+
74
+ def calendar(
75
+ self,
76
+ start: str | date | None = None,
77
+ end: str | date | None = None,
78
+ trading_only: int = 1,
79
+ fields: str | None = None,
80
+ limit: int | None = None,
81
+ ) -> pd.DataFrame:
82
+ return self._to_frame(
83
+ self._get(
84
+ "/v1/calendar",
85
+ start=_to_ymd(start),
86
+ end=_to_ymd(end),
87
+ trading_only=trading_only,
88
+ fields=fields,
89
+ limit=limit,
90
+ )
91
+ )
92
+
93
+ def kline(
94
+ self,
95
+ symbol: str | None = None,
96
+ symbols: list[str] | str | None = None,
97
+ start: str | date | None = None,
98
+ end: str | date | None = None,
99
+ adj: str = "none",
100
+ fields: str | None = None,
101
+ limit: int | None = None,
102
+ ) -> pd.DataFrame:
103
+ """时序日 K:单股或多股 + 日期区间。adj=none|qfq|hfq。"""
104
+ params: dict[str, Any] = {
105
+ "start": _to_ymd(start),
106
+ "end": _to_ymd(end),
107
+ "adj": adj,
108
+ "fields": fields,
109
+ "limit": limit,
110
+ }
111
+ if symbols is not None:
112
+ params["symbols"] = _join_symbols(symbols)
113
+ else:
114
+ params["symbol"] = symbol
115
+ return self._to_frame(self._get("/v1/kline", **params))
116
+
117
+ def snapshot(
118
+ self,
119
+ trade_date: str | date,
120
+ symbols: list[str] | str | None = None,
121
+ adj: str = "none",
122
+ fields: str | None = None,
123
+ limit: int | None = None,
124
+ ) -> pd.DataFrame:
125
+ """单日截面:不传 symbols 则全市场当日。"""
126
+ return self._to_frame(
127
+ self._get(
128
+ "/v1/snapshot",
129
+ trade_date=_to_ymd(trade_date),
130
+ symbols=_join_symbols(symbols),
131
+ adj=adj,
132
+ fields=fields,
133
+ limit=limit,
134
+ )
135
+ )
136
+
137
+ def fina(
138
+ self,
139
+ symbol: str | None = None,
140
+ symbols: list[str] | str | None = None,
141
+ start: str | date | None = None,
142
+ end: str | date | None = None,
143
+ fields: str | None = None,
144
+ limit: int | None = None,
145
+ ) -> pd.DataFrame:
146
+ return self._to_frame(
147
+ self._get(
148
+ "/v1/fina",
149
+ symbol=symbol if symbols is None else None,
150
+ symbols=_join_symbols(symbols),
151
+ start=_to_ymd(start),
152
+ end=_to_ymd(end),
153
+ fields=fields,
154
+ limit=limit,
155
+ )
156
+ )
157
+
158
+ def adj_factor(
159
+ self,
160
+ symbol: str | None = None,
161
+ symbols: list[str] | str | None = None,
162
+ start: str | date | None = None,
163
+ end: str | date | None = None,
164
+ fields: str | None = None,
165
+ limit: int | None = None,
166
+ ) -> pd.DataFrame:
167
+ """除权/复权因子(ex_date, fore/back/adjust_factor)。"""
168
+ return self._to_frame(
169
+ self._get(
170
+ "/v1/adj-factor",
171
+ symbol=symbol if symbols is None else None,
172
+ symbols=_join_symbols(symbols),
173
+ start=_to_ymd(start),
174
+ end=_to_ymd(end),
175
+ fields=fields,
176
+ limit=limit,
177
+ )
178
+ )
@@ -0,0 +1,85 @@
1
+ """各 `QuantClient` 方法返回的列名。
2
+
3
+ 用法::
4
+
5
+ from ashare_quant_data_sdk import QuantClient, cols
6
+
7
+ c.kline(..., fields=cols.kline.CLOSE)
8
+ c.fina(..., fields=cols.fina.EPS_BASIC)
9
+ """
10
+
11
+
12
+ class stocks:
13
+ """`stocks()` 股池。"""
14
+
15
+ SYMBOL = "symbol" # 股票代码
16
+ EXCHANGE = "exchange" # 交易所
17
+ NAME = "name" # 简称
18
+ CODE = "code" # Baostock 代码,如 sh.600519
19
+ IPO_DATE = "ipoDate" # 上市日
20
+ OUT_DATE = "outDate" # 退市日,在市为 None
21
+ TYPE = "type" # 证券类型,1=股票
22
+ STATUS = "status" # 上市状态,1=在市 0=退市
23
+
24
+
25
+ class calendar:
26
+ """`calendar()` 交易日历。"""
27
+
28
+ TRADE_DATE = "trade_date" # 日历日
29
+ IS_TRADING = "is_trading" # 1=交易日 0=非交易日
30
+
31
+
32
+ class kline:
33
+ """`kline()` 日 K 时序。`snapshot()` 列相同。"""
34
+
35
+ SYMBOL = "symbol" # 股票代码
36
+ DATE = "date" # 交易日
37
+ OPEN = "open" # 开盘价
38
+ HIGH = "high" # 最高价
39
+ LOW = "low" # 最低价
40
+ CLOSE = "close" # 收盘价
41
+ PRECLOSE = "preclose" # 昨收
42
+ VOLUME = "volume" # 成交量
43
+ AMOUNT = "amount" # 成交额
44
+ TURN = "turn" # 换手率(表字段 turnover)
45
+ PCT_CHG = "pct_chg" # 涨跌幅
46
+ PE_TTM = "pe_ttm" # 市盈率 TTM
47
+ PB_MRQ = "pb_mrq" # 市净率 MRQ
48
+ PS_TTM = "ps_ttm" # 市销率 TTM
49
+ PCF_NCF_TTM = "pcf_ncf_ttm" # 市现率 TTM
50
+ TRADE_STATUS = "trade_status" # 交易状态,1=正常
51
+ IS_ST = "is_st" # 是否 ST
52
+ ADJ_TYPE = "adj_type" # 复权类型 none|qfq|hfq
53
+
54
+
55
+ class snapshot(kline):
56
+ """`snapshot()` 单日截面,列与 `kline` 相同。"""
57
+
58
+
59
+ class fina:
60
+ """`fina()` 季频财务指标。另有维度列 symbol / exchange / report_date / season_label。"""
61
+
62
+ EPS_BASIC = "eps_basic" # 基本每股收益
63
+ BPS = "bps" # 每股净资产
64
+ ROE_DILUTED = "roe_diluted" # 摊薄净资产收益率
65
+ ROA = "roa" # 总资产净利率
66
+ GROSS_PROFIT_RATIO = "gross_profit_ratio" # 销售毛利率
67
+ NET_PROFIT_RATIO = "net_profit_ratio" # 销售净利率
68
+ TOTAL_OPERATE_REVENUE = "total_operate_revenue" # 营业总收入
69
+ PARENT_NET_PROFIT = "parent_net_profit" # 归母净利润
70
+ DEDU_PARENT_PROFIT = "dedu_parent_profit" # 扣非归母净利润
71
+ REVENUE_YOY = "revenue_yoy" # 营业总收入同比
72
+ PARENT_NET_PROFIT_YOY = "parent_net_profit_yoy" # 归母净利润同比
73
+ REVENUE_QOQ = "revenue_qoq" # 营业总收入环比
74
+ NET_PROFIT_QOQ = "net_profit_qoq" # 净利润环比
75
+
76
+
77
+ class adj_factor:
78
+ """`adj_factor()` 除权 / 复权因子。"""
79
+
80
+ SYMBOL = "symbol" # 股票代码
81
+ EXCHANGE = "exchange" # 交易所
82
+ EX_DATE = "ex_date" # 除权除息日
83
+ FORE_ADJUST_FACTOR = "fore_adjust_factor" # 前复权因子
84
+ BACK_ADJUST_FACTOR = "back_adjust_factor" # 后复权因子
85
+ ADJUST_FACTOR = "adjust_factor" # Baostock 原始调整因子
@@ -0,0 +1,40 @@
1
+ Metadata-Version: 2.4
2
+ Name: ashare-quant-data-sdk
3
+ Version: 0.1.0
4
+ Summary: A 股量化数据 HTTP 客户端(QuantClient),只依赖 pandas
5
+ Author-email: dekeky <dekeky@163.com>
6
+ Project-URL: Homepage, https://github.com/chocochato0713/ashare-quant-data
7
+ Project-URL: Repository, https://github.com/chocochato0713/ashare-quant-data
8
+ Keywords: 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
+ # ashare-quant-data-sdk
24
+
25
+ A 股量化数据 HTTP 客户端。安装后 `from ashare_quant_data_sdk import QuantClient`,只依赖 pandas,不含拉取与 ClickHouse 业务代码。
26
+
27
+ ```bash
28
+ pip install ashare-quant-data-sdk
29
+ ```
30
+
31
+ ```python
32
+ from ashare_quant_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
+ ```
39
+
40
+ 日期参数为 `YYYYMMDD`,区间两端包含。需先启动本仓库的 `quant-data serve`。直连 ClickHouse 请安装服务包 `quant-data`,使用 `QuantClient.from_clickhouse()`。
@@ -0,0 +1,10 @@
1
+ README.md
2
+ pyproject.toml
3
+ python/ashare_quant_data_sdk/__init__.py
4
+ python/ashare_quant_data_sdk/client.py
5
+ python/ashare_quant_data_sdk/cols.py
6
+ python/ashare_quant_data_sdk.egg-info/PKG-INFO
7
+ python/ashare_quant_data_sdk.egg-info/SOURCES.txt
8
+ python/ashare_quant_data_sdk.egg-info/dependency_links.txt
9
+ python/ashare_quant_data_sdk.egg-info/requires.txt
10
+ python/ashare_quant_data_sdk.egg-info/top_level.txt
@@ -0,0 +1,4 @@
1
+ [egg_info]
2
+ tag_build =
3
+ tag_date = 0
4
+