dragon-quant 0.2.2__tar.gz → 0.2.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.
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/PKG-INFO +20 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/README.md +19 -0
- dragon_quant-0.2.3/dragon_quant/_version.py +1 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/cli.py +16 -0
- dragon_quant-0.2.3/dragon_quant/config/__init__.py +4 -0
- dragon_quant-0.2.3/dragon_quant/config/api_config.py +173 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/data.py +12 -2
- dragon_quant-0.2.3/dragon_quant/fix_api.py +411 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/logging/reporter.py +42 -14
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/base.py +3 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/tencent.py +3 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/xueqiu.py +3 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/rate_limit.py +12 -7
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/scorers/absorption.py +182 -43
- dragon_quant-0.2.3/dragon_quant/scorers/anti_drop.py +408 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/scorers/drive.py +58 -18
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/storage/db.py +307 -20
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/PKG-INFO +20 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/SOURCES.txt +4 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/pyproject.toml +4 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_logging.py +70 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_providers_parsing.py +26 -1
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_rate_limit.py +20 -1
- dragon_quant-0.2.3/tests/test_scorers_absorption.py +201 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_scorers_anti_drop.py +102 -3
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_scorers_drive.py +70 -2
- dragon_quant-0.2.3/tests/test_storage.py +286 -0
- dragon_quant-0.2.3/web_ui/index.html +426 -0
- dragon_quant-0.2.2/dragon_quant/_version.py +0 -1
- dragon_quant-0.2.2/dragon_quant/scorers/anti_drop.py +0 -206
- dragon_quant-0.2.2/tests/test_scorers_absorption.py +0 -50
- dragon_quant-0.2.2/tests/test_storage.py +0 -125
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/LICENSE +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/__main__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/analyze.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/cache/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/cache/data_cache.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/logging/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/logging/logger.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/logging/query.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/models/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/models/types.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/orchestrator.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/browser.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/cookie.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/providers/eastmoney.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/review.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/scorers/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/scorers/leadership.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/storage/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/storage/manager.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/storage/paths.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/utils/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant/utils/trading.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/dependency_links.txt +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/entry_points.txt +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/requires.txt +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/dragon_quant.egg-info/top_level.txt +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/setup.cfg +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_cache.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_models.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_orchestrator_helpers.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_providers_cookie.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_review.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/tests/test_scorers_leadership.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/web_ui/__init__.py +0 -0
- {dragon_quant-0.2.2 → dragon_quant-0.2.3}/web_ui/server.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dragon-quant
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.3
|
|
4
4
|
Summary: 龙头战法四维量化筛选系统 — A股涨停板龙头识别工具
|
|
5
5
|
Author: gitBingxu
|
|
6
6
|
License-Expression: MIT
|
|
@@ -138,6 +138,25 @@ dragon-quant data batch-quote --codes 600172,000001,002409
|
|
|
138
138
|
dragon-quant data cookie-status # 查看 Cookie 状态
|
|
139
139
|
dragon-quant data cookie-fetch # 刷新全部 Cookie
|
|
140
140
|
dragon-quant data cookie-fetch --source xueqiu # 只刷新雪球
|
|
141
|
+
|
|
142
|
+
# 手动设置 Cookie(推荐兜底方案)
|
|
143
|
+
# 适用场景:Playwright 自动获取失败/被风控;或你已经在浏览器里抓到了可用 Cookie。
|
|
144
|
+
#
|
|
145
|
+
# 1) 从浏览器开发者工具(Network)里复制请求头中的 Cookie(整段)
|
|
146
|
+
# 2) 写入本地(注意:Cookie 属于敏感信息,请勿提交到仓库/群聊)
|
|
147
|
+
|
|
148
|
+
# 设置东财 Cookie
|
|
149
|
+
python3 -m dragon_quant.providers.cookie set --source em --cookie 'qgqp_b_id=...; st_nvi=...; nid18=...'
|
|
150
|
+
|
|
151
|
+
# 设置雪球 Cookie
|
|
152
|
+
python3 -m dragon_quant.providers.cookie set --source xq --cookie 'xq_a_token=...; xq_is_login=1; u=...'
|
|
153
|
+
|
|
154
|
+
# 查看是否生效
|
|
155
|
+
python3 -m dragon_quant.providers.cookie status --show
|
|
156
|
+
|
|
157
|
+
# Cookie 文件默认位置(macOS)
|
|
158
|
+
# ~/Library/Application Support/dragon-quant/cookies/eastmoney
|
|
159
|
+
# ~/Library/Application Support/dragon-quant/cookies/xueqiu
|
|
141
160
|
```
|
|
142
161
|
|
|
143
162
|
### `review` — 龙头回测
|
|
@@ -119,6 +119,25 @@ dragon-quant data batch-quote --codes 600172,000001,002409
|
|
|
119
119
|
dragon-quant data cookie-status # 查看 Cookie 状态
|
|
120
120
|
dragon-quant data cookie-fetch # 刷新全部 Cookie
|
|
121
121
|
dragon-quant data cookie-fetch --source xueqiu # 只刷新雪球
|
|
122
|
+
|
|
123
|
+
# 手动设置 Cookie(推荐兜底方案)
|
|
124
|
+
# 适用场景:Playwright 自动获取失败/被风控;或你已经在浏览器里抓到了可用 Cookie。
|
|
125
|
+
#
|
|
126
|
+
# 1) 从浏览器开发者工具(Network)里复制请求头中的 Cookie(整段)
|
|
127
|
+
# 2) 写入本地(注意:Cookie 属于敏感信息,请勿提交到仓库/群聊)
|
|
128
|
+
|
|
129
|
+
# 设置东财 Cookie
|
|
130
|
+
python3 -m dragon_quant.providers.cookie set --source em --cookie 'qgqp_b_id=...; st_nvi=...; nid18=...'
|
|
131
|
+
|
|
132
|
+
# 设置雪球 Cookie
|
|
133
|
+
python3 -m dragon_quant.providers.cookie set --source xq --cookie 'xq_a_token=...; xq_is_login=1; u=...'
|
|
134
|
+
|
|
135
|
+
# 查看是否生效
|
|
136
|
+
python3 -m dragon_quant.providers.cookie status --show
|
|
137
|
+
|
|
138
|
+
# Cookie 文件默认位置(macOS)
|
|
139
|
+
# ~/Library/Application Support/dragon-quant/cookies/eastmoney
|
|
140
|
+
# ~/Library/Application Support/dragon-quant/cookies/xueqiu
|
|
122
141
|
```
|
|
123
142
|
|
|
124
143
|
### `review` — 龙头回测
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
__version__ = "0.2.3"
|
|
@@ -7,6 +7,7 @@ CLI 入口 — dragon-quant 命令行工具
|
|
|
7
7
|
dragon-quant data {sector,components,kline,minute,quote,batch-quote} [options]
|
|
8
8
|
dragon-quant review [--date DATE] [--top N] [--force]
|
|
9
9
|
dragon-quant storage {status,size,clear} [options]
|
|
10
|
+
dragon-quant fix-api [--provider eastmoney] [--show-browser]
|
|
10
11
|
"""
|
|
11
12
|
|
|
12
13
|
import argparse
|
|
@@ -222,6 +223,12 @@ def _cmd_review_ui(args):
|
|
|
222
223
|
start_server(port=args.port, open_browser=not args.no_browser)
|
|
223
224
|
|
|
224
225
|
|
|
226
|
+
def _cmd_fix_api(args):
|
|
227
|
+
"""修复 API 配置命令"""
|
|
228
|
+
from dragon_quant.fix_api import fix_api
|
|
229
|
+
fix_api(provider=args.fix_provider, headless=not args.show_browser)
|
|
230
|
+
|
|
231
|
+
|
|
225
232
|
def _cmd_storage(args):
|
|
226
233
|
"""存储管理命令"""
|
|
227
234
|
mgr = StorageManager()
|
|
@@ -388,6 +395,13 @@ def main():
|
|
|
388
395
|
clear_p.add_argument("--logs", action="store_true", help="清理日志")
|
|
389
396
|
clear_p.add_argument("--days", type=int, default=None, help="保留最近N天")
|
|
390
397
|
|
|
398
|
+
# fix-api 子命令
|
|
399
|
+
fix_p = sub.add_parser("fix-api", help="从目标网站自动捕获并修复 API 配置")
|
|
400
|
+
fix_p.add_argument("--provider", dest="fix_provider", default="eastmoney",
|
|
401
|
+
choices=["eastmoney"], help="要修复的 provider (默认: eastmoney)")
|
|
402
|
+
fix_p.add_argument("--show-browser", action="store_true",
|
|
403
|
+
help="显示浏览器窗口 (默认无头运行)")
|
|
404
|
+
|
|
391
405
|
args = parser.parse_args()
|
|
392
406
|
|
|
393
407
|
if args.command == "scan":
|
|
@@ -400,6 +414,8 @@ def main():
|
|
|
400
414
|
_cmd_storage(args)
|
|
401
415
|
elif args.command == "review":
|
|
402
416
|
_cmd_review(args)
|
|
417
|
+
elif args.command == "fix-api":
|
|
418
|
+
_cmd_fix_api(args)
|
|
403
419
|
|
|
404
420
|
else:
|
|
405
421
|
parser.print_help()
|
|
@@ -0,0 +1,173 @@
|
|
|
1
|
+
"""
|
|
2
|
+
API 请求模板 — 持久化配置管理
|
|
3
|
+
|
|
4
|
+
每个 provider 下的每个 endpoint 对应一个 RequestTemplate,
|
|
5
|
+
封装请求 URL 拼接和 Header 构建。
|
|
6
|
+
|
|
7
|
+
配置存储路径: {DATA_DIR}/config/api_config.json
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
import json
|
|
11
|
+
import os
|
|
12
|
+
import threading
|
|
13
|
+
from dataclasses import dataclass, field
|
|
14
|
+
from typing import Optional
|
|
15
|
+
|
|
16
|
+
import urllib.parse
|
|
17
|
+
import time
|
|
18
|
+
|
|
19
|
+
from dragon_quant.storage.paths import DATA_DIR
|
|
20
|
+
|
|
21
|
+
CONFIG_DIR = DATA_DIR / "config"
|
|
22
|
+
CONFIG_PATH = CONFIG_DIR / "api_config.json"
|
|
23
|
+
|
|
24
|
+
CONFIG_VERSION = "1"
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@dataclass
|
|
28
|
+
class RequestTemplate:
|
|
29
|
+
base: str
|
|
30
|
+
path: str
|
|
31
|
+
fixed_params: dict = field(default_factory=dict)
|
|
32
|
+
headers: dict = field(default_factory=dict)
|
|
33
|
+
referer: str = ""
|
|
34
|
+
|
|
35
|
+
def build_url(self, **dynamic_params) -> str:
|
|
36
|
+
params = {**self.fixed_params, **dynamic_params}
|
|
37
|
+
if "cb" not in params:
|
|
38
|
+
# 尽量对齐东财前端 JSONP callback 命名,降低风控概率
|
|
39
|
+
# 形如:jQuery112307663912278618489_1780992936600
|
|
40
|
+
# 注:callback 名称不会影响我们 _parse_jsonp 的解析。
|
|
41
|
+
ts = int(time.time() * 1000)
|
|
42
|
+
pseudo_rand = int(str(ts)[-6:]) * 123457 # 仅用于仿真格式,无安全意义
|
|
43
|
+
params["cb"] = f"jQuery{pseudo_rand}_{ts}"
|
|
44
|
+
if "_" not in params:
|
|
45
|
+
params["_"] = str(int(time.time() * 1000))
|
|
46
|
+
qs = urllib.parse.urlencode(params)
|
|
47
|
+
return f"{self.base}{self.path}?{qs}"
|
|
48
|
+
|
|
49
|
+
def build_headers(self, referer: str = "", cookie: str = "") -> dict:
|
|
50
|
+
headers = {}
|
|
51
|
+
if self.headers:
|
|
52
|
+
headers.update(self.headers)
|
|
53
|
+
if referer or self.referer:
|
|
54
|
+
headers["Referer"] = referer or self.referer
|
|
55
|
+
if cookie:
|
|
56
|
+
headers["Cookie"] = cookie
|
|
57
|
+
return headers
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
def _ensure_config_dir():
|
|
61
|
+
CONFIG_DIR.mkdir(parents=True, exist_ok=True)
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def load_templates(provider: str) -> Optional[dict[str, RequestTemplate]]:
|
|
65
|
+
if not CONFIG_PATH.exists():
|
|
66
|
+
return None
|
|
67
|
+
try:
|
|
68
|
+
with open(CONFIG_PATH) as f:
|
|
69
|
+
data = json.load(f)
|
|
70
|
+
provider_data = data.get(provider, {})
|
|
71
|
+
if not provider_data:
|
|
72
|
+
return None
|
|
73
|
+
templates = {}
|
|
74
|
+
for ep_name, ep_cfg in provider_data.items():
|
|
75
|
+
templates[ep_name] = RequestTemplate(
|
|
76
|
+
base=ep_cfg["base"],
|
|
77
|
+
path=ep_cfg["path"],
|
|
78
|
+
fixed_params=ep_cfg.get("fixed_params", {}),
|
|
79
|
+
headers=ep_cfg.get("headers", {}),
|
|
80
|
+
referer=ep_cfg.get("referer", ""),
|
|
81
|
+
)
|
|
82
|
+
return templates
|
|
83
|
+
except Exception:
|
|
84
|
+
return None
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
def save_templates(provider: str, templates: dict[str, RequestTemplate]):
|
|
88
|
+
_ensure_config_dir()
|
|
89
|
+
existing = {}
|
|
90
|
+
if CONFIG_PATH.exists():
|
|
91
|
+
try:
|
|
92
|
+
with open(CONFIG_PATH) as f:
|
|
93
|
+
existing = json.load(f)
|
|
94
|
+
except Exception:
|
|
95
|
+
existing = {}
|
|
96
|
+
existing.setdefault("version", CONFIG_VERSION)
|
|
97
|
+
provider_data = {}
|
|
98
|
+
for name, tpl in templates.items():
|
|
99
|
+
provider_data[name] = {
|
|
100
|
+
"base": tpl.base,
|
|
101
|
+
"path": tpl.path,
|
|
102
|
+
"fixed_params": tpl.fixed_params,
|
|
103
|
+
"headers": tpl.headers,
|
|
104
|
+
"referer": tpl.referer,
|
|
105
|
+
}
|
|
106
|
+
existing[provider] = provider_data
|
|
107
|
+
tmp_path = CONFIG_PATH.with_suffix(".tmp")
|
|
108
|
+
with open(tmp_path, "w") as f:
|
|
109
|
+
json.dump(existing, f, ensure_ascii=False, indent=2)
|
|
110
|
+
os.replace(tmp_path, CONFIG_PATH)
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def save_single_template(provider: str, endpoint: str, tpl: RequestTemplate):
|
|
114
|
+
existing = {}
|
|
115
|
+
if CONFIG_PATH.exists():
|
|
116
|
+
try:
|
|
117
|
+
with open(CONFIG_PATH) as f:
|
|
118
|
+
existing = json.load(f)
|
|
119
|
+
except Exception:
|
|
120
|
+
existing = {}
|
|
121
|
+
existing.setdefault("version", CONFIG_VERSION)
|
|
122
|
+
existing.setdefault(provider, {})
|
|
123
|
+
existing[provider][endpoint] = {
|
|
124
|
+
"base": tpl.base,
|
|
125
|
+
"path": tpl.path,
|
|
126
|
+
"fixed_params": tpl.fixed_params,
|
|
127
|
+
"headers": tpl.headers,
|
|
128
|
+
"referer": tpl.referer,
|
|
129
|
+
}
|
|
130
|
+
_ensure_config_dir()
|
|
131
|
+
tmp_path = CONFIG_PATH.with_suffix(".tmp")
|
|
132
|
+
with open(tmp_path, "w") as f:
|
|
133
|
+
json.dump(existing, f, ensure_ascii=False, indent=2)
|
|
134
|
+
os.replace(tmp_path, CONFIG_PATH)
|
|
135
|
+
|
|
136
|
+
|
|
137
|
+
def hardcoded_templates(provider: str) -> dict[str, RequestTemplate]:
|
|
138
|
+
if provider == "eastmoney":
|
|
139
|
+
return {
|
|
140
|
+
"sector_ranking": RequestTemplate(
|
|
141
|
+
base="https://push2.eastmoney.com",
|
|
142
|
+
path="/webguest/api/qt/clist/get",
|
|
143
|
+
fixed_params={
|
|
144
|
+
"np": "1", "fltt": "1", "invt": "2",
|
|
145
|
+
"timil": "1", "dect": "1", "wbp2u": "|0|0|0|web",
|
|
146
|
+
},
|
|
147
|
+
headers={},
|
|
148
|
+
referer="https://quote.eastmoney.com/center/hsbk.html",
|
|
149
|
+
),
|
|
150
|
+
"sector_components": RequestTemplate(
|
|
151
|
+
base="https://push2.eastmoney.com",
|
|
152
|
+
path="/api/qt/clist/get",
|
|
153
|
+
fixed_params={
|
|
154
|
+
"np": "1", "fltt": "2", "invt": "2",
|
|
155
|
+
"dect": "1",
|
|
156
|
+
},
|
|
157
|
+
headers={},
|
|
158
|
+
referer="https://quote.eastmoney.com/center/gridlist.html",
|
|
159
|
+
),
|
|
160
|
+
"sector_5min_kline": RequestTemplate(
|
|
161
|
+
base="https://push2his.eastmoney.com",
|
|
162
|
+
path="/api/qt/stock/kline/get",
|
|
163
|
+
fixed_params={
|
|
164
|
+
"fqt": "1",
|
|
165
|
+
"beg": "0",
|
|
166
|
+
"end": "20500101",
|
|
167
|
+
"smplmt": "460",
|
|
168
|
+
},
|
|
169
|
+
headers={},
|
|
170
|
+
referer="https://quote.eastmoney.com/bk/90.{code}.html",
|
|
171
|
+
),
|
|
172
|
+
}
|
|
173
|
+
return {}
|
|
@@ -81,17 +81,27 @@ def get_sector_ranking(asc: bool = False) -> list[SectorPerformance]:
|
|
|
81
81
|
return em.get_sector_ranking(asc=asc)
|
|
82
82
|
|
|
83
83
|
|
|
84
|
-
def get_sector_components(sector_code: str
|
|
84
|
+
def get_sector_components(sector_code: str, page: int = 1,
|
|
85
|
+
all_pages: bool = False,
|
|
86
|
+
page_size: int = 50) -> list[StockInfo]:
|
|
85
87
|
"""获取概念板块成分股列表(按涨跌幅降序)
|
|
86
88
|
|
|
87
89
|
Args:
|
|
88
90
|
sector_code: 板块代码,如 "BK0487"
|
|
91
|
+
page: 页码(默认第一页)
|
|
92
|
+
all_pages: 是否自动拉取全量分页
|
|
93
|
+
page_size: 每页大小
|
|
89
94
|
Returns:
|
|
90
95
|
list[StockInfo] 成分股列表
|
|
91
96
|
"""
|
|
92
97
|
providers = _get_providers()
|
|
93
98
|
em = providers["eastmoney"]
|
|
94
|
-
return em.get_sector_components(
|
|
99
|
+
return em.get_sector_components(
|
|
100
|
+
sector_code,
|
|
101
|
+
page=page,
|
|
102
|
+
all_pages=all_pages,
|
|
103
|
+
page_size=page_size,
|
|
104
|
+
)
|
|
95
105
|
|
|
96
106
|
|
|
97
107
|
def get_sector_5min_kline(sector_code: str, bars: int = 100) -> list[KBar]:
|