easyquotes 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,54 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ name: Build distribution packages
13
+ runs-on: ubuntu-latest
14
+ steps:
15
+ - name: Check out repository
16
+ uses: actions/checkout@v7
17
+
18
+ - name: Set up Python
19
+ uses: actions/setup-python@v6
20
+ with:
21
+ python-version: "3.10"
22
+
23
+ - name: Install build frontend
24
+ run: python -m pip install --upgrade build
25
+
26
+ - name: Build wheel and source distribution
27
+ run: python -m build
28
+
29
+ - name: Store distribution packages
30
+ uses: actions/upload-artifact@v7
31
+ with:
32
+ name: python-package-distributions
33
+ path: dist/
34
+
35
+ publish:
36
+ name: Publish distribution packages to PyPI
37
+ needs: build
38
+ runs-on: ubuntu-latest
39
+ environment:
40
+ name: pypi
41
+ url: https://pypi.org/p/easyquotes
42
+ permissions:
43
+ id-token: write
44
+ steps:
45
+ - name: Download distribution packages
46
+ uses: actions/download-artifact@v8
47
+ with:
48
+ name: python-package-distributions
49
+ path: dist/
50
+
51
+ - name: Publish to PyPI
52
+ uses: pypa/gh-action-pypi-publish@release/v1
53
+ with:
54
+ packages-dir: dist/
@@ -0,0 +1,13 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *.egg-info/
4
+ .coverage
5
+ .env
6
+ .env.*
7
+ .mypy_cache/
8
+ .pytest_cache/
9
+ .ruff_cache/
10
+ .venv/
11
+ build/
12
+ dist/
13
+ venv/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 EasyQuote contributors
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,284 @@
1
+ Metadata-Version: 2.4
2
+ Name: easyquotes
3
+ Version: 0.1.0
4
+ Summary: EasyQuote Python SDK — global market data (A-share, HK, US) in a few lines of code
5
+ Project-URL: Homepage, https://easyquote.io
6
+ Project-URL: Documentation, https://easyquote.io/docs
7
+ Project-URL: Repository, https://github.com/easyquotes/easyquotes
8
+ License: MIT
9
+ License-File: LICENSE
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: License :: OSI Approved :: MIT License
12
+ Classifier: Programming Language :: Python :: 3
13
+ Classifier: Programming Language :: Python :: 3.10
14
+ Classifier: Programming Language :: Python :: 3.11
15
+ Classifier: Programming Language :: Python :: 3.12
16
+ Classifier: Programming Language :: Python :: 3.13
17
+ Classifier: Topic :: Office/Business :: Financial
18
+ Requires-Python: >=3.10
19
+ Provides-Extra: stream
20
+ Requires-Dist: websocket-client>=1.6; extra == 'stream'
21
+ Provides-Extra: stream-async
22
+ Requires-Dist: websockets>=12.0; extra == 'stream-async'
23
+ Description-Content-Type: text/markdown
24
+
25
+ # EasyQuote Python SDK
26
+
27
+ A股、港股、美股及境外市场行情数据 Python 客户端。基于 EasyQuote HTTP API,支持实时行情、历史 K 线、逐笔成交、资金流向、基本面数据、板块数据及 WebSocket 推送。
28
+
29
+ ## 安装
30
+
31
+ ```bash
32
+ pip install easyquotes
33
+ ```
34
+
35
+ 可选扩展:
36
+
37
+ ```bash
38
+ pip install "easyquotes[stream]" # WebSocket 同步推送
39
+ pip install "easyquotes[stream-async]" # WebSocket 异步推送
40
+ ```
41
+
42
+ Python 版本要求:>= 3.10
43
+
44
+ ## 快速开始
45
+
46
+ 通过环境变量配置 API Key:
47
+
48
+ ```bash
49
+ export EASYQUOTE_API_KEY="eq_your_key_here"
50
+ ```
51
+
52
+ ```python
53
+ from easyquote import EasyQuoteClient
54
+
55
+ client = EasyQuoteClient() # 自动读取 EASYQUOTE_API_KEY
56
+ quote = client.get_quote("600519.SH")
57
+ print(f"{quote.name}: {quote.price} ({quote.change_pct:+.2f}%)")
58
+ ```
59
+
60
+ 也可以直接传入 api_key:
61
+
62
+ ```python
63
+ client = EasyQuoteClient(api_key="eq_your_key_here")
64
+ ```
65
+
66
+ ## 标的代码格式
67
+
68
+ | 市场 | 格式示例 | 说明 |
69
+ |----------|------------------|--------------------------|
70
+ | A 股上交 | `600519.SH` | 沪市,后缀 `.SH` |
71
+ | A 股深交 | `000001.SZ` | 深市,后缀 `.SZ` |
72
+ | A 股北交 | `836239.BJ` | 北交所,后缀 `.BJ` |
73
+ | 港股 | `00700.HK` | 五位数代码,后缀 `.HK` |
74
+ | 美股 | `TSLA.US` | 股票代码,后缀 `.US` |
75
+ | 指数 | `000001.SH` | 上证指数等 |
76
+
77
+ ## API 参考
78
+
79
+ ### 行情 (Quotes)
80
+
81
+ | 方法 | 说明 |
82
+ |------|------|
83
+ | `get_quote(symbol)` | 单只标的实时行情,返回 `Quote` |
84
+ | `get_quotes(symbols)` | 批量实时行情,返回 `list[Quote]` |
85
+ | `get_snapshots(symbols)` | 批量行情快照(mac 协议),`symbols` 为 `[{'market':'SH','code':'600519'}]` |
86
+ | `get_depths(symbols)` | 批量五档盘口(mac 协议) |
87
+
88
+ ### K 线 (K-Lines)
89
+
90
+ | 方法 | 说明 |
91
+ |------|------|
92
+ | `get_klines(symbol, period, count, start)` | A 股/港股/美股历史 K 线,返回 `list[KLine]` |
93
+ | `get_index_klines(symbol, period, count, start)` | 指数 K 线 |
94
+ | `get_global_klines(market, code, period, count, adjust)` | 境外行情 K 线,`adjust='qfq'`(前复权)/`'hfq'`(后复权) |
95
+
96
+ `period` 可选值:`"1m"` / `"5m"` / `"15m"` / `"30m"` / `"60m"` / `"daily"` / `"weekly"` / `"monthly"`
97
+
98
+ ### 分时 (Intraday)
99
+
100
+ | 方法 | 说明 |
101
+ |------|------|
102
+ | `get_minute(symbol)` | 当日分时数据,返回 `list[MinuteBar]` |
103
+ | `get_minute_history(symbol, date)` | 历史某日分时数据,`date='20260617'` |
104
+
105
+ ### 逐笔 (Transactions)
106
+
107
+ | 方法 | 说明 |
108
+ |------|------|
109
+ | `get_transactions(symbol, start, count)` | 今日逐笔成交明细 |
110
+ | `get_transaction_history(symbol, date, start, count)` | 历史逐笔成交,`date='20260617'` |
111
+
112
+ ### 资金流向 (Fund Flow)
113
+
114
+ | 方法 | 说明 |
115
+ |------|------|
116
+ | `get_fund_flow(symbol)` | 当日主力资金流向,返回 `FundFlow` |
117
+ | `get_fund_flow_history(symbol, start, count)` | 历史资金流向列表 |
118
+
119
+ ### 基本面 A 股 (A-share Fundamentals)
120
+
121
+ | 方法 | 说明 |
122
+ |------|------|
123
+ | `get_finance(symbol)` | A 股财务指标(PE/PB/EPS 等) |
124
+ | `get_xdxr(symbol)` | 除权除息记录 |
125
+ | `get_announcements(code, count, page)` | 公司公告列表,`code='600519'`(不含市场后缀) |
126
+
127
+ ### 基本面 全球 (Global Fundamentals)
128
+
129
+ | 方法 | 说明 |
130
+ |------|------|
131
+ | `get_company(symbol)` | 公司概况,返回 `Company`,支持 A 股/港股/美股 |
132
+ | `get_executives(symbol)` | 高管信息,返回 `list[Executive]` |
133
+ | `get_financial_reports(symbol, kind)` | 财务报告,`kind='ALL'/'ANNUAL'/'QUARTERLY'` |
134
+
135
+ ### 板块 (Sectors)
136
+
137
+ | 方法 | 说明 |
138
+ |------|------|
139
+ | `get_sectors(block_file)` | 板块数据,`block_file` 可选 `'block_zs.dat'`(行业指数)/ `'block_gn.dat'`(概念)/ `'block_fg.dat'`(风格) |
140
+ | `get_board_ranking(board_type, top_n, sort_by, ascending)` | 板块涨跌排行,`board_type='industry'/'concept'/'style'` |
141
+ | `get_board_members(board_symbol, count)` | 板块成员列表 |
142
+
143
+ ### 市场 (Market)
144
+
145
+ | 方法 | 说明 |
146
+ |------|------|
147
+ | `get_market_stat()` | 市场统计(涨跌家数、成交额等) |
148
+ | `get_security_list(market, start)` | 证券列表,`market='SH'/'SZ'/'BJ'` |
149
+ | `get_security_count(market)` | 证券总数,返回 `int` |
150
+
151
+ ### 境外行情 (Global Quotes)
152
+
153
+ | 方法 | 说明 |
154
+ |------|------|
155
+ | `get_global_quote(market, code)` | 境外单只行情,`market='NASDAQ'/'NYSE'/'HKEX'` 等 |
156
+ | `get_global_klines(market, code, period, count, adjust)` | 境外 K 线 |
157
+
158
+ ### 实时推送 (Streaming)
159
+
160
+ | 方法 | 说明 |
161
+ |------|------|
162
+ | `stream()` | 同步 WebSocket 推送,需安装 `easyquotes[stream]` |
163
+ | `stream_async()` | 异步 WebSocket 推送,需安装 `easyquotes[stream-async]` |
164
+
165
+ ## 使用示例
166
+
167
+ ### 批量获取行情
168
+
169
+ ```python
170
+ quotes = client.get_quotes(["600519.SH", "000001.SZ", "TSLA.US", "00700.HK"])
171
+ for q in quotes:
172
+ print(f"{q.symbol} {q.price:>10.2f} {q.change_pct:+.2f}%")
173
+ ```
174
+
175
+ ### K 线数据
176
+
177
+ ```python
178
+ klines = client.get_klines("600519.SH", period="daily", count=120)
179
+ for k in klines[-5:]:
180
+ print(f"{k.datetime} O:{k.open} H:{k.high} L:{k.low} C:{k.close} V:{k.volume}")
181
+ ```
182
+
183
+ ### 历史分时
184
+
185
+ ```python
186
+ bars = client.get_minute_history("600519.SH", date="20260617")
187
+ for b in bars[:10]:
188
+ print(b.time, b.price, b.volume)
189
+ ```
190
+
191
+ ### 资金流向
192
+
193
+ ```python
194
+ ff = client.get_fund_flow("600519.SH")
195
+ print(f"主力净流入: {ff.net_main / 1e8:.2f} 亿")
196
+ ```
197
+
198
+ ### 板块排行
199
+
200
+ ```python
201
+ ranking = client.get_board_ranking(board_type="industry", top_n=10, sort_by="change_pct")
202
+ for b in ranking:
203
+ print(b["name"], b["change_pct"])
204
+ ```
205
+
206
+ ### 同步 WebSocket 推送
207
+
208
+ ```python
209
+ with client.stream() as ws:
210
+ ws.subscribe(["600519.SH", "000001.SZ", "TSLA.US"])
211
+ for event in ws:
212
+ if event["op"] == "quotes":
213
+ for q in event["data"]:
214
+ print(q["symbol"], q["last_price"])
215
+ ```
216
+
217
+ ### 异步 WebSocket 推送
218
+
219
+ ```python
220
+ import asyncio
221
+
222
+ async def main():
223
+ async with client.stream_async() as ws:
224
+ await ws.subscribe(["600519.SH", "TSLA.US"])
225
+ async for event in ws:
226
+ print(event)
227
+
228
+ asyncio.run(main())
229
+ ```
230
+
231
+ ### 逐笔成交
232
+
233
+ ```python
234
+ ticks = client.get_transactions("600519.SH", start=0, count=50)
235
+ for t in ticks:
236
+ print(t["time"], t["price"], t["volume"], t["direction"])
237
+ ```
238
+
239
+ ### 境外行情
240
+
241
+ ```python
242
+ # 获取纳斯达克个股 K 线
243
+ klines = client.get_global_klines("NASDAQ", "TSLA", period="daily", count=60)
244
+
245
+ # 获取港股行情
246
+ quote = client.get_global_quote("HKEX", "00700")
247
+ ```
248
+
249
+ ## 错误处理
250
+
251
+ ```python
252
+ from easyquote import EasyQuoteClient
253
+ from easyquote import AuthError, RateLimitError, APIError, NotFoundError
254
+
255
+ client = EasyQuoteClient(api_key="eq_your_key")
256
+
257
+ try:
258
+ quote = client.get_quote("600519.SH")
259
+ except AuthError:
260
+ print("API Key 无效或未设置")
261
+ except RateLimitError:
262
+ print("请求频率超限,请稍后重试")
263
+ except NotFoundError:
264
+ print("标的不存在")
265
+ except APIError as e:
266
+ print(f"API 错误 {e.code}: {e.message}")
267
+ ```
268
+
269
+ ## 自托管部署
270
+
271
+ 如果使用自托管的 EasyQuote 后端(基于 easy-tdx 的 FastAPI 服务),可以通过 `base_url` 参数指定服务地址:
272
+
273
+ ```python
274
+ client = EasyQuoteClient(
275
+ api_key="eq_your_key",
276
+ base_url="http://localhost:8000",
277
+ )
278
+ ```
279
+
280
+ HTTP 和 WebSocket 均会自动切换到指定地址(`wss://` 对应 HTTPS,`ws://` 对应 HTTP)。
281
+
282
+ ## 许可证
283
+
284
+ MIT
@@ -0,0 +1,260 @@
1
+ # EasyQuote Python SDK
2
+
3
+ A股、港股、美股及境外市场行情数据 Python 客户端。基于 EasyQuote HTTP API,支持实时行情、历史 K 线、逐笔成交、资金流向、基本面数据、板块数据及 WebSocket 推送。
4
+
5
+ ## 安装
6
+
7
+ ```bash
8
+ pip install easyquotes
9
+ ```
10
+
11
+ 可选扩展:
12
+
13
+ ```bash
14
+ pip install "easyquotes[stream]" # WebSocket 同步推送
15
+ pip install "easyquotes[stream-async]" # WebSocket 异步推送
16
+ ```
17
+
18
+ Python 版本要求:>= 3.10
19
+
20
+ ## 快速开始
21
+
22
+ 通过环境变量配置 API Key:
23
+
24
+ ```bash
25
+ export EASYQUOTE_API_KEY="eq_your_key_here"
26
+ ```
27
+
28
+ ```python
29
+ from easyquote import EasyQuoteClient
30
+
31
+ client = EasyQuoteClient() # 自动读取 EASYQUOTE_API_KEY
32
+ quote = client.get_quote("600519.SH")
33
+ print(f"{quote.name}: {quote.price} ({quote.change_pct:+.2f}%)")
34
+ ```
35
+
36
+ 也可以直接传入 api_key:
37
+
38
+ ```python
39
+ client = EasyQuoteClient(api_key="eq_your_key_here")
40
+ ```
41
+
42
+ ## 标的代码格式
43
+
44
+ | 市场 | 格式示例 | 说明 |
45
+ |----------|------------------|--------------------------|
46
+ | A 股上交 | `600519.SH` | 沪市,后缀 `.SH` |
47
+ | A 股深交 | `000001.SZ` | 深市,后缀 `.SZ` |
48
+ | A 股北交 | `836239.BJ` | 北交所,后缀 `.BJ` |
49
+ | 港股 | `00700.HK` | 五位数代码,后缀 `.HK` |
50
+ | 美股 | `TSLA.US` | 股票代码,后缀 `.US` |
51
+ | 指数 | `000001.SH` | 上证指数等 |
52
+
53
+ ## API 参考
54
+
55
+ ### 行情 (Quotes)
56
+
57
+ | 方法 | 说明 |
58
+ |------|------|
59
+ | `get_quote(symbol)` | 单只标的实时行情,返回 `Quote` |
60
+ | `get_quotes(symbols)` | 批量实时行情,返回 `list[Quote]` |
61
+ | `get_snapshots(symbols)` | 批量行情快照(mac 协议),`symbols` 为 `[{'market':'SH','code':'600519'}]` |
62
+ | `get_depths(symbols)` | 批量五档盘口(mac 协议) |
63
+
64
+ ### K 线 (K-Lines)
65
+
66
+ | 方法 | 说明 |
67
+ |------|------|
68
+ | `get_klines(symbol, period, count, start)` | A 股/港股/美股历史 K 线,返回 `list[KLine]` |
69
+ | `get_index_klines(symbol, period, count, start)` | 指数 K 线 |
70
+ | `get_global_klines(market, code, period, count, adjust)` | 境外行情 K 线,`adjust='qfq'`(前复权)/`'hfq'`(后复权) |
71
+
72
+ `period` 可选值:`"1m"` / `"5m"` / `"15m"` / `"30m"` / `"60m"` / `"daily"` / `"weekly"` / `"monthly"`
73
+
74
+ ### 分时 (Intraday)
75
+
76
+ | 方法 | 说明 |
77
+ |------|------|
78
+ | `get_minute(symbol)` | 当日分时数据,返回 `list[MinuteBar]` |
79
+ | `get_minute_history(symbol, date)` | 历史某日分时数据,`date='20260617'` |
80
+
81
+ ### 逐笔 (Transactions)
82
+
83
+ | 方法 | 说明 |
84
+ |------|------|
85
+ | `get_transactions(symbol, start, count)` | 今日逐笔成交明细 |
86
+ | `get_transaction_history(symbol, date, start, count)` | 历史逐笔成交,`date='20260617'` |
87
+
88
+ ### 资金流向 (Fund Flow)
89
+
90
+ | 方法 | 说明 |
91
+ |------|------|
92
+ | `get_fund_flow(symbol)` | 当日主力资金流向,返回 `FundFlow` |
93
+ | `get_fund_flow_history(symbol, start, count)` | 历史资金流向列表 |
94
+
95
+ ### 基本面 A 股 (A-share Fundamentals)
96
+
97
+ | 方法 | 说明 |
98
+ |------|------|
99
+ | `get_finance(symbol)` | A 股财务指标(PE/PB/EPS 等) |
100
+ | `get_xdxr(symbol)` | 除权除息记录 |
101
+ | `get_announcements(code, count, page)` | 公司公告列表,`code='600519'`(不含市场后缀) |
102
+
103
+ ### 基本面 全球 (Global Fundamentals)
104
+
105
+ | 方法 | 说明 |
106
+ |------|------|
107
+ | `get_company(symbol)` | 公司概况,返回 `Company`,支持 A 股/港股/美股 |
108
+ | `get_executives(symbol)` | 高管信息,返回 `list[Executive]` |
109
+ | `get_financial_reports(symbol, kind)` | 财务报告,`kind='ALL'/'ANNUAL'/'QUARTERLY'` |
110
+
111
+ ### 板块 (Sectors)
112
+
113
+ | 方法 | 说明 |
114
+ |------|------|
115
+ | `get_sectors(block_file)` | 板块数据,`block_file` 可选 `'block_zs.dat'`(行业指数)/ `'block_gn.dat'`(概念)/ `'block_fg.dat'`(风格) |
116
+ | `get_board_ranking(board_type, top_n, sort_by, ascending)` | 板块涨跌排行,`board_type='industry'/'concept'/'style'` |
117
+ | `get_board_members(board_symbol, count)` | 板块成员列表 |
118
+
119
+ ### 市场 (Market)
120
+
121
+ | 方法 | 说明 |
122
+ |------|------|
123
+ | `get_market_stat()` | 市场统计(涨跌家数、成交额等) |
124
+ | `get_security_list(market, start)` | 证券列表,`market='SH'/'SZ'/'BJ'` |
125
+ | `get_security_count(market)` | 证券总数,返回 `int` |
126
+
127
+ ### 境外行情 (Global Quotes)
128
+
129
+ | 方法 | 说明 |
130
+ |------|------|
131
+ | `get_global_quote(market, code)` | 境外单只行情,`market='NASDAQ'/'NYSE'/'HKEX'` 等 |
132
+ | `get_global_klines(market, code, period, count, adjust)` | 境外 K 线 |
133
+
134
+ ### 实时推送 (Streaming)
135
+
136
+ | 方法 | 说明 |
137
+ |------|------|
138
+ | `stream()` | 同步 WebSocket 推送,需安装 `easyquotes[stream]` |
139
+ | `stream_async()` | 异步 WebSocket 推送,需安装 `easyquotes[stream-async]` |
140
+
141
+ ## 使用示例
142
+
143
+ ### 批量获取行情
144
+
145
+ ```python
146
+ quotes = client.get_quotes(["600519.SH", "000001.SZ", "TSLA.US", "00700.HK"])
147
+ for q in quotes:
148
+ print(f"{q.symbol} {q.price:>10.2f} {q.change_pct:+.2f}%")
149
+ ```
150
+
151
+ ### K 线数据
152
+
153
+ ```python
154
+ klines = client.get_klines("600519.SH", period="daily", count=120)
155
+ for k in klines[-5:]:
156
+ print(f"{k.datetime} O:{k.open} H:{k.high} L:{k.low} C:{k.close} V:{k.volume}")
157
+ ```
158
+
159
+ ### 历史分时
160
+
161
+ ```python
162
+ bars = client.get_minute_history("600519.SH", date="20260617")
163
+ for b in bars[:10]:
164
+ print(b.time, b.price, b.volume)
165
+ ```
166
+
167
+ ### 资金流向
168
+
169
+ ```python
170
+ ff = client.get_fund_flow("600519.SH")
171
+ print(f"主力净流入: {ff.net_main / 1e8:.2f} 亿")
172
+ ```
173
+
174
+ ### 板块排行
175
+
176
+ ```python
177
+ ranking = client.get_board_ranking(board_type="industry", top_n=10, sort_by="change_pct")
178
+ for b in ranking:
179
+ print(b["name"], b["change_pct"])
180
+ ```
181
+
182
+ ### 同步 WebSocket 推送
183
+
184
+ ```python
185
+ with client.stream() as ws:
186
+ ws.subscribe(["600519.SH", "000001.SZ", "TSLA.US"])
187
+ for event in ws:
188
+ if event["op"] == "quotes":
189
+ for q in event["data"]:
190
+ print(q["symbol"], q["last_price"])
191
+ ```
192
+
193
+ ### 异步 WebSocket 推送
194
+
195
+ ```python
196
+ import asyncio
197
+
198
+ async def main():
199
+ async with client.stream_async() as ws:
200
+ await ws.subscribe(["600519.SH", "TSLA.US"])
201
+ async for event in ws:
202
+ print(event)
203
+
204
+ asyncio.run(main())
205
+ ```
206
+
207
+ ### 逐笔成交
208
+
209
+ ```python
210
+ ticks = client.get_transactions("600519.SH", start=0, count=50)
211
+ for t in ticks:
212
+ print(t["time"], t["price"], t["volume"], t["direction"])
213
+ ```
214
+
215
+ ### 境外行情
216
+
217
+ ```python
218
+ # 获取纳斯达克个股 K 线
219
+ klines = client.get_global_klines("NASDAQ", "TSLA", period="daily", count=60)
220
+
221
+ # 获取港股行情
222
+ quote = client.get_global_quote("HKEX", "00700")
223
+ ```
224
+
225
+ ## 错误处理
226
+
227
+ ```python
228
+ from easyquote import EasyQuoteClient
229
+ from easyquote import AuthError, RateLimitError, APIError, NotFoundError
230
+
231
+ client = EasyQuoteClient(api_key="eq_your_key")
232
+
233
+ try:
234
+ quote = client.get_quote("600519.SH")
235
+ except AuthError:
236
+ print("API Key 无效或未设置")
237
+ except RateLimitError:
238
+ print("请求频率超限,请稍后重试")
239
+ except NotFoundError:
240
+ print("标的不存在")
241
+ except APIError as e:
242
+ print(f"API 错误 {e.code}: {e.message}")
243
+ ```
244
+
245
+ ## 自托管部署
246
+
247
+ 如果使用自托管的 EasyQuote 后端(基于 easy-tdx 的 FastAPI 服务),可以通过 `base_url` 参数指定服务地址:
248
+
249
+ ```python
250
+ client = EasyQuoteClient(
251
+ api_key="eq_your_key",
252
+ base_url="http://localhost:8000",
253
+ )
254
+ ```
255
+
256
+ HTTP 和 WebSocket 均会自动切换到指定地址(`wss://` 对应 HTTPS,`ws://` 对应 HTTP)。
257
+
258
+ ## 许可证
259
+
260
+ MIT
@@ -0,0 +1,24 @@
1
+ """EasyQuote Python SDK — Global market data in a few lines of code."""
2
+ from ._client import EasyQuoteClient
3
+ from ._exceptions import APIError, AuthError, EasyQuoteError, NotFoundError, RateLimitError
4
+ from ._models import Company, Executive, FinancialReport, FundFlow, KLine, MinuteBar, Quote
5
+
6
+ __all__ = [
7
+ "EasyQuoteClient",
8
+ # Models
9
+ "Quote",
10
+ "KLine",
11
+ "MinuteBar",
12
+ "FundFlow",
13
+ "Company",
14
+ "Executive",
15
+ "FinancialReport",
16
+ # Exceptions
17
+ "EasyQuoteError",
18
+ "AuthError",
19
+ "RateLimitError",
20
+ "NotFoundError",
21
+ "APIError",
22
+ ]
23
+
24
+ __version__ = "0.1.0"