ohlcvault 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.
- ohlcvault-0.1.0/.gitignore +24 -0
- ohlcvault-0.1.0/LICENSE +21 -0
- ohlcvault-0.1.0/PKG-INFO +197 -0
- ohlcvault-0.1.0/README.md +168 -0
- ohlcvault-0.1.0/SPEC.md +658 -0
- ohlcvault-0.1.0/ohlcvault/__init__.py +282 -0
- ohlcvault-0.1.0/ohlcvault/adjust.py +61 -0
- ohlcvault-0.1.0/ohlcvault/client.py +203 -0
- ohlcvault-0.1.0/ohlcvault/codes.py +127 -0
- ohlcvault-0.1.0/ohlcvault/config.py +54 -0
- ohlcvault-0.1.0/ohlcvault/errors.py +53 -0
- ohlcvault-0.1.0/ohlcvault/store.py +640 -0
- ohlcvault-0.1.0/pyproject.toml +49 -0
- ohlcvault-0.1.0/schema/example-calendar.json +1 -0
- ohlcvault-0.1.0/schema/example-idx-monthly.json +1 -0
- ohlcvault-0.1.0/schema/example-latest.json +1 -0
- ohlcvault-0.1.0/schema/example-manifest.json +1 -0
- ohlcvault-0.1.0/schema/example-monthly.json +1 -0
- ohlcvault-0.1.0/schema/example-snapshot.json +1 -0
- ohlcvault-0.1.0/schema/example-symbols.json +1 -0
- ohlcvault-0.1.0/tests/conftest.py +88 -0
- ohlcvault-0.1.0/tests/test_adjust.py +98 -0
- ohlcvault-0.1.0/tests/test_client.py +151 -0
- ohlcvault-0.1.0/tests/test_store.py +300 -0
- ohlcvault-0.1.0/tests/test_symbols.py +83 -0
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
# 构建产物
|
|
2
|
+
build/
|
|
3
|
+
dist/
|
|
4
|
+
*.egg-info/
|
|
5
|
+
__pycache__/
|
|
6
|
+
*.py[cod]
|
|
7
|
+
|
|
8
|
+
# 虚拟环境
|
|
9
|
+
.venv/
|
|
10
|
+
venv/
|
|
11
|
+
|
|
12
|
+
# 测试与缓存
|
|
13
|
+
.pytest_cache/
|
|
14
|
+
.ruff_cache/
|
|
15
|
+
.coverage
|
|
16
|
+
htmlcov/
|
|
17
|
+
|
|
18
|
+
# 编辑器 / 系统
|
|
19
|
+
.DS_Store
|
|
20
|
+
.idea/
|
|
21
|
+
.vscode/
|
|
22
|
+
|
|
23
|
+
# 契约镜像是**生成物**,由 ohlcvault_server/tools/sync_contract.py 写入,
|
|
24
|
+
# 但**必须提交**(消费方要能独立校验契约),所以这里不忽略。
|
ohlcvault-0.1.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 HelpQuant
|
|
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.
|
ohlcvault-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: ohlcvault
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Reproducible, checksummed daily OHLCV data for A-share, HK and US markets — static files, content-addressed snapshots, zero API keys.
|
|
5
|
+
Project-URL: Homepage, https://helpquant.com
|
|
6
|
+
Project-URL: Documentation, https://github.com/helpquant/ohlcvault#readme
|
|
7
|
+
Project-URL: Issues, https://github.com/helpquant/ohlcvault/issues
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: a-share,backtest,hk-stocks,market-data,ohlcv,quant,reproducible,us-stocks
|
|
11
|
+
Classifier: Development Status :: 3 - Alpha
|
|
12
|
+
Classifier: Intended Audience :: Financial and Insurance Industry
|
|
13
|
+
Classifier: Intended Audience :: Science/Research
|
|
14
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
15
|
+
Classifier: Programming Language :: Python :: 3
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
20
|
+
Classifier: Topic :: Office/Business :: Financial :: Investment
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Provides-Extra: dev
|
|
23
|
+
Requires-Dist: pandas>=2.0; extra == 'dev'
|
|
24
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
25
|
+
Requires-Dist: ruff>=0.6; extra == 'dev'
|
|
26
|
+
Provides-Extra: pandas
|
|
27
|
+
Requires-Dist: pandas>=2.0; extra == 'pandas'
|
|
28
|
+
Description-Content-Type: text/markdown
|
|
29
|
+
|
|
30
|
+
# OHLCVault
|
|
31
|
+
|
|
32
|
+
> OHLCV = Open/High/Low/Close/Volume, the universal bar format.
|
|
33
|
+
> Vault = immutable, checksummed snapshots.
|
|
34
|
+
|
|
35
|
+
Reproducible daily OHLCV data for **A-share, Hong Kong and US markets** — served as
|
|
36
|
+
static files from a CDN. No API keys, no rate limits, no per-request billing.
|
|
37
|
+
|
|
38
|
+
```python
|
|
39
|
+
import ohlcvault as ov
|
|
40
|
+
|
|
41
|
+
ov.connect()
|
|
42
|
+
df = ov.daily("600519.SH").to_pandas() # 跨月自动拼接
|
|
43
|
+
ov.cross_section("cn", 20260918, limit=50) # 当日全市场截面,按成交额排序
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
## Why this exists
|
|
47
|
+
|
|
48
|
+
Most free market-data endpoints are **APIs**: stateful, rate-limited, silently
|
|
49
|
+
revised, and impossible to reproduce. A backtest that ran last month can't be rerun
|
|
50
|
+
today with the same inputs.
|
|
51
|
+
|
|
52
|
+
OHLCVault publishes **immutable monthly shards with checksums** instead. Each read is
|
|
53
|
+
anchored to a snapshot id you can write down and reproduce later, on any machine.
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
pip install ohlcvault # core, zero runtime dependencies
|
|
59
|
+
pip install "ohlcvault[pandas]" # + DataFrame helpers
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
The core has **no third-party dependencies** — only the standard library. That's
|
|
63
|
+
deliberate: a data client shouldn't drag a dependency tree into your project, and it
|
|
64
|
+
matters even more for agent/tooling contexts.
|
|
65
|
+
|
|
66
|
+
## Usage
|
|
67
|
+
|
|
68
|
+
### Everything (the five things you actually need)
|
|
69
|
+
|
|
70
|
+
```python
|
|
71
|
+
import ohlcvault as ov
|
|
72
|
+
ov.connect()
|
|
73
|
+
|
|
74
|
+
# 1. Trading calendar
|
|
75
|
+
ov.calendar("cn", start=20260101)
|
|
76
|
+
|
|
77
|
+
# 2. Stock daily bars (cross-month stitching is handled for you)
|
|
78
|
+
ov.daily("600519.SH", start=20260101, end=20260918)
|
|
79
|
+
|
|
80
|
+
# 3. Index daily bars — a separate namespace, never mixed with stocks
|
|
81
|
+
ov.index_daily("000300.SH")
|
|
82
|
+
|
|
83
|
+
# 4. Symbol list — includes delisted stocks
|
|
84
|
+
ov.symbols("cn", type="stock")
|
|
85
|
+
ov.symbols("cn", type="stock", status="delisted")
|
|
86
|
+
|
|
87
|
+
# 5. Daily cross-section — sorted by turnover, no extra data files
|
|
88
|
+
ov.cross_section("cn", 20260918, sort_by="amount", limit=50)
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
### Batch backtests
|
|
92
|
+
|
|
93
|
+
Month shards hold **every symbol in the market** for that month. Loading 200 symbols
|
|
94
|
+
one-by-one would decompress the same file 200 times:
|
|
95
|
+
|
|
96
|
+
```python
|
|
97
|
+
bars = ov.daily_many(["600519.SH", "000001.SZ", "300750.SZ"], start=20260101)
|
|
98
|
+
bars["600519.SH"].to_pandas()
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
### Adjustment is a view, not a stored field
|
|
102
|
+
|
|
103
|
+
The dataset stores **unadjusted prices only**, plus the official cumulative
|
|
104
|
+
back-adjustment factor. Forward/backward adjusted prices are computed client-side:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
b = ov.daily("600519.SH")
|
|
108
|
+
ov.adjust(b, to="hfq") # 后复权
|
|
109
|
+
ov.adjust(b, to="qfq") # 前复权
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This is not a limitation — it's the reason historical files never change. If
|
|
113
|
+
forward-adjusted prices were stored, every dividend would rewrite all of history, and
|
|
114
|
+
`immutable` caching would be impossible.
|
|
115
|
+
|
|
116
|
+
### Reproducibility
|
|
117
|
+
|
|
118
|
+
```python
|
|
119
|
+
st = ov.connect()
|
|
120
|
+
sid = st.snapshot # e.g. "6b197df3723871c5"
|
|
121
|
+
ov.connect(snapshot=sid) # later, anywhere: exact same inputs
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Offline / self-hosted mirrors
|
|
125
|
+
|
|
126
|
+
A mirror can be an HTTP(S) URL **or a local directory**:
|
|
127
|
+
|
|
128
|
+
```python
|
|
129
|
+
ov.connect(mirrors=["/path/to/data"])
|
|
130
|
+
```
|
|
131
|
+
|
|
132
|
+
Mirrors are tried in order; whichever one succeeds is promoted to first place. Every
|
|
133
|
+
file is checked against the `sha256` in the snapshot manifest, and anything that
|
|
134
|
+
fails is **discarded and the next mirror is tried** — bad bytes are never handed to
|
|
135
|
+
the caller.
|
|
136
|
+
|
|
137
|
+
## Data integrity
|
|
138
|
+
|
|
139
|
+
| Guarantee | How |
|
|
140
|
+
|---|---|
|
|
141
|
+
| No silently-corrupted data | Every file verified against the snapshot's `sha256` |
|
|
142
|
+
| No silently-changed history | Sealed months are never rewritten |
|
|
143
|
+
| No unverifiable numbers | Missing adjustment factors raise, instead of returning raw prices |
|
|
144
|
+
| No hidden survivorship bias | Delisted stocks are kept in the universe and in the data |
|
|
145
|
+
| Byte-for-byte reproduction | Fixed-point integers, `gzip` with `MTIME=0`, no wall-clock timestamps |
|
|
146
|
+
|
|
147
|
+
**Delisted stocks matter.** If your backtest universe only contains companies that
|
|
148
|
+
are still listed today, your historical returns are systematically overstated.
|
|
149
|
+
`ov.symbols("cn", status="delisted")` returns them, and their daily bars are complete
|
|
150
|
+
over `ipo … out`.
|
|
151
|
+
|
|
152
|
+
## Coverage and known gaps
|
|
153
|
+
|
|
154
|
+
Coverage is declared explicitly in `meta/symbols/{market}.json` under `coverage`, and
|
|
155
|
+
`ov.connect()` prints it on startup. Current state:
|
|
156
|
+
|
|
157
|
+
| Market | Status | Gaps |
|
|
158
|
+
|---|---|---|
|
|
159
|
+
| `cn` | Daily bars + indices, 2000→present | **No Beijing Stock Exchange** (upstream source doesn't provide it) |
|
|
160
|
+
| `hk` | Symbol list only | No daily bars yet; **list is current listings only** |
|
|
161
|
+
| `us` | Symbol list only | No daily bars yet; **list is current listings only** |
|
|
162
|
+
|
|
163
|
+
`hk` / `us` symbol lists carry **survivorship bias** (the upstream source only returns
|
|
164
|
+
currently-listed securities) and have no IPO dates. Their daily bars are pending.
|
|
165
|
+
|
|
166
|
+
An honest data project states its gaps. A dataset that quietly omits them is worse
|
|
167
|
+
than one that is merely incomplete.
|
|
168
|
+
|
|
169
|
+
## API
|
|
170
|
+
|
|
171
|
+
| Function | Purpose |
|
|
172
|
+
|---|---|
|
|
173
|
+
| `connect(mirrors=, cache_dir=, snapshot=)` | Build the default client |
|
|
174
|
+
| `symbols(market, type=, status=, board=)` | Symbol list |
|
|
175
|
+
| `symbol(code)` | Single symbol entry |
|
|
176
|
+
| `calendar(market, start=, end=)` | Trading calendar |
|
|
177
|
+
| `daily(code, start=, end=)` | Stock daily bars, cross-month stitching |
|
|
178
|
+
| `index_daily(code, start=, end=)` | Index daily bars |
|
|
179
|
+
| `daily_many(codes, start=, end=)` | Batch read (preferred for backtests) |
|
|
180
|
+
| `cross_section(market, date, sort_by=, limit=)` | Daily cross-section |
|
|
181
|
+
| `adjust(bars_or_df, to="qfq"\|"hfq"\|"none")` | Adjustment view |
|
|
182
|
+
| `snapshot()` | Current snapshot id |
|
|
183
|
+
|
|
184
|
+
Date parameters (`start` / `end` / `date`) accept an `int` `YYYYMMDD` (preferred)
|
|
185
|
+
or common string forms — `"2026-09-18"`, `"20260918"`, `"2026/09/18"`. Anything
|
|
186
|
+
unparseable raises `DateError` instead of failing deep inside the library.
|
|
187
|
+
|
|
188
|
+
The frozen data contract lives in [`SPEC.md`](SPEC.md) — the client and the pipeline
|
|
189
|
+
share nothing but this document and the files it describes. `schema/example-*.json`
|
|
190
|
+
are machine-generated from real data, so the examples cannot drift from the contract.
|
|
191
|
+
|
|
192
|
+
## License
|
|
193
|
+
|
|
194
|
+
MIT. See [LICENSE](LICENSE).
|
|
195
|
+
|
|
196
|
+
Data is gathered from public sources. Verify before relying on it for anything
|
|
197
|
+
consequential.
|
|
@@ -0,0 +1,168 @@
|
|
|
1
|
+
# OHLCVault
|
|
2
|
+
|
|
3
|
+
> OHLCV = Open/High/Low/Close/Volume, the universal bar format.
|
|
4
|
+
> Vault = immutable, checksummed snapshots.
|
|
5
|
+
|
|
6
|
+
Reproducible daily OHLCV data for **A-share, Hong Kong and US markets** — served as
|
|
7
|
+
static files from a CDN. No API keys, no rate limits, no per-request billing.
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
import ohlcvault as ov
|
|
11
|
+
|
|
12
|
+
ov.connect()
|
|
13
|
+
df = ov.daily("600519.SH").to_pandas() # 跨月自动拼接
|
|
14
|
+
ov.cross_section("cn", 20260918, limit=50) # 当日全市场截面,按成交额排序
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Why this exists
|
|
18
|
+
|
|
19
|
+
Most free market-data endpoints are **APIs**: stateful, rate-limited, silently
|
|
20
|
+
revised, and impossible to reproduce. A backtest that ran last month can't be rerun
|
|
21
|
+
today with the same inputs.
|
|
22
|
+
|
|
23
|
+
OHLCVault publishes **immutable monthly shards with checksums** instead. Each read is
|
|
24
|
+
anchored to a snapshot id you can write down and reproduce later, on any machine.
|
|
25
|
+
|
|
26
|
+
## Install
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
pip install ohlcvault # core, zero runtime dependencies
|
|
30
|
+
pip install "ohlcvault[pandas]" # + DataFrame helpers
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
The core has **no third-party dependencies** — only the standard library. That's
|
|
34
|
+
deliberate: a data client shouldn't drag a dependency tree into your project, and it
|
|
35
|
+
matters even more for agent/tooling contexts.
|
|
36
|
+
|
|
37
|
+
## Usage
|
|
38
|
+
|
|
39
|
+
### Everything (the five things you actually need)
|
|
40
|
+
|
|
41
|
+
```python
|
|
42
|
+
import ohlcvault as ov
|
|
43
|
+
ov.connect()
|
|
44
|
+
|
|
45
|
+
# 1. Trading calendar
|
|
46
|
+
ov.calendar("cn", start=20260101)
|
|
47
|
+
|
|
48
|
+
# 2. Stock daily bars (cross-month stitching is handled for you)
|
|
49
|
+
ov.daily("600519.SH", start=20260101, end=20260918)
|
|
50
|
+
|
|
51
|
+
# 3. Index daily bars — a separate namespace, never mixed with stocks
|
|
52
|
+
ov.index_daily("000300.SH")
|
|
53
|
+
|
|
54
|
+
# 4. Symbol list — includes delisted stocks
|
|
55
|
+
ov.symbols("cn", type="stock")
|
|
56
|
+
ov.symbols("cn", type="stock", status="delisted")
|
|
57
|
+
|
|
58
|
+
# 5. Daily cross-section — sorted by turnover, no extra data files
|
|
59
|
+
ov.cross_section("cn", 20260918, sort_by="amount", limit=50)
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
### Batch backtests
|
|
63
|
+
|
|
64
|
+
Month shards hold **every symbol in the market** for that month. Loading 200 symbols
|
|
65
|
+
one-by-one would decompress the same file 200 times:
|
|
66
|
+
|
|
67
|
+
```python
|
|
68
|
+
bars = ov.daily_many(["600519.SH", "000001.SZ", "300750.SZ"], start=20260101)
|
|
69
|
+
bars["600519.SH"].to_pandas()
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### Adjustment is a view, not a stored field
|
|
73
|
+
|
|
74
|
+
The dataset stores **unadjusted prices only**, plus the official cumulative
|
|
75
|
+
back-adjustment factor. Forward/backward adjusted prices are computed client-side:
|
|
76
|
+
|
|
77
|
+
```python
|
|
78
|
+
b = ov.daily("600519.SH")
|
|
79
|
+
ov.adjust(b, to="hfq") # 后复权
|
|
80
|
+
ov.adjust(b, to="qfq") # 前复权
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
This is not a limitation — it's the reason historical files never change. If
|
|
84
|
+
forward-adjusted prices were stored, every dividend would rewrite all of history, and
|
|
85
|
+
`immutable` caching would be impossible.
|
|
86
|
+
|
|
87
|
+
### Reproducibility
|
|
88
|
+
|
|
89
|
+
```python
|
|
90
|
+
st = ov.connect()
|
|
91
|
+
sid = st.snapshot # e.g. "6b197df3723871c5"
|
|
92
|
+
ov.connect(snapshot=sid) # later, anywhere: exact same inputs
|
|
93
|
+
```
|
|
94
|
+
|
|
95
|
+
### Offline / self-hosted mirrors
|
|
96
|
+
|
|
97
|
+
A mirror can be an HTTP(S) URL **or a local directory**:
|
|
98
|
+
|
|
99
|
+
```python
|
|
100
|
+
ov.connect(mirrors=["/path/to/data"])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
Mirrors are tried in order; whichever one succeeds is promoted to first place. Every
|
|
104
|
+
file is checked against the `sha256` in the snapshot manifest, and anything that
|
|
105
|
+
fails is **discarded and the next mirror is tried** — bad bytes are never handed to
|
|
106
|
+
the caller.
|
|
107
|
+
|
|
108
|
+
## Data integrity
|
|
109
|
+
|
|
110
|
+
| Guarantee | How |
|
|
111
|
+
|---|---|
|
|
112
|
+
| No silently-corrupted data | Every file verified against the snapshot's `sha256` |
|
|
113
|
+
| No silently-changed history | Sealed months are never rewritten |
|
|
114
|
+
| No unverifiable numbers | Missing adjustment factors raise, instead of returning raw prices |
|
|
115
|
+
| No hidden survivorship bias | Delisted stocks are kept in the universe and in the data |
|
|
116
|
+
| Byte-for-byte reproduction | Fixed-point integers, `gzip` with `MTIME=0`, no wall-clock timestamps |
|
|
117
|
+
|
|
118
|
+
**Delisted stocks matter.** If your backtest universe only contains companies that
|
|
119
|
+
are still listed today, your historical returns are systematically overstated.
|
|
120
|
+
`ov.symbols("cn", status="delisted")` returns them, and their daily bars are complete
|
|
121
|
+
over `ipo … out`.
|
|
122
|
+
|
|
123
|
+
## Coverage and known gaps
|
|
124
|
+
|
|
125
|
+
Coverage is declared explicitly in `meta/symbols/{market}.json` under `coverage`, and
|
|
126
|
+
`ov.connect()` prints it on startup. Current state:
|
|
127
|
+
|
|
128
|
+
| Market | Status | Gaps |
|
|
129
|
+
|---|---|---|
|
|
130
|
+
| `cn` | Daily bars + indices, 2000→present | **No Beijing Stock Exchange** (upstream source doesn't provide it) |
|
|
131
|
+
| `hk` | Symbol list only | No daily bars yet; **list is current listings only** |
|
|
132
|
+
| `us` | Symbol list only | No daily bars yet; **list is current listings only** |
|
|
133
|
+
|
|
134
|
+
`hk` / `us` symbol lists carry **survivorship bias** (the upstream source only returns
|
|
135
|
+
currently-listed securities) and have no IPO dates. Their daily bars are pending.
|
|
136
|
+
|
|
137
|
+
An honest data project states its gaps. A dataset that quietly omits them is worse
|
|
138
|
+
than one that is merely incomplete.
|
|
139
|
+
|
|
140
|
+
## API
|
|
141
|
+
|
|
142
|
+
| Function | Purpose |
|
|
143
|
+
|---|---|
|
|
144
|
+
| `connect(mirrors=, cache_dir=, snapshot=)` | Build the default client |
|
|
145
|
+
| `symbols(market, type=, status=, board=)` | Symbol list |
|
|
146
|
+
| `symbol(code)` | Single symbol entry |
|
|
147
|
+
| `calendar(market, start=, end=)` | Trading calendar |
|
|
148
|
+
| `daily(code, start=, end=)` | Stock daily bars, cross-month stitching |
|
|
149
|
+
| `index_daily(code, start=, end=)` | Index daily bars |
|
|
150
|
+
| `daily_many(codes, start=, end=)` | Batch read (preferred for backtests) |
|
|
151
|
+
| `cross_section(market, date, sort_by=, limit=)` | Daily cross-section |
|
|
152
|
+
| `adjust(bars_or_df, to="qfq"\|"hfq"\|"none")` | Adjustment view |
|
|
153
|
+
| `snapshot()` | Current snapshot id |
|
|
154
|
+
|
|
155
|
+
Date parameters (`start` / `end` / `date`) accept an `int` `YYYYMMDD` (preferred)
|
|
156
|
+
or common string forms — `"2026-09-18"`, `"20260918"`, `"2026/09/18"`. Anything
|
|
157
|
+
unparseable raises `DateError` instead of failing deep inside the library.
|
|
158
|
+
|
|
159
|
+
The frozen data contract lives in [`SPEC.md`](SPEC.md) — the client and the pipeline
|
|
160
|
+
share nothing but this document and the files it describes. `schema/example-*.json`
|
|
161
|
+
are machine-generated from real data, so the examples cannot drift from the contract.
|
|
162
|
+
|
|
163
|
+
## License
|
|
164
|
+
|
|
165
|
+
MIT. See [LICENSE](LICENSE).
|
|
166
|
+
|
|
167
|
+
Data is gathered from public sources. Verify before relying on it for anything
|
|
168
|
+
consequential.
|