hikyuu 2.6.3__py3-none-win_amd64.whl → 2.6.6__py3-none-win_amd64.whl
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.
- hikyuu/__init__.py +6 -0
- hikyuu/__init__.pyi +548 -546
- hikyuu/analysis/__init__.pyi +519 -514
- hikyuu/analysis/analysis.pyi +520 -515
- hikyuu/core.pyi +521 -516
- hikyuu/cpp/__init__.pyi +2 -2
- hikyuu/cpp/boost_date_time-mt.dll +0 -0
- hikyuu/cpp/boost_serialization-mt.dll +0 -0
- hikyuu/cpp/boost_wserialization-mt.dll +0 -0
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +167 -36
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +167 -36
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +167 -36
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +167 -36
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +167 -36
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/cpp/i18n/__init__.py +0 -0
- hikyuu/cpp/i18n/zh_CN.mo +0 -0
- hikyuu/cpp/sqlite3.dll +0 -0
- hikyuu/data/clickhouse_upgrade/__init__.py +1 -0
- hikyuu/data/clickhouse_upgrade/createdb.sql +1085 -0
- hikyuu/data/common.py +1 -1
- hikyuu/data/common_clickhouse.py +512 -0
- hikyuu/data/common_mysql.py +19 -0
- hikyuu/data/common_pytdx.py +2 -0
- hikyuu/data/common_sqlite3.py +1 -0
- hikyuu/data/em_block_to_clickhouse.py +120 -0
- hikyuu/data/hku_config_template.py +70 -1
- hikyuu/data/mysql_upgrade/0028.sql +95 -0
- hikyuu/data/pytdx_finance_to_clickhouse.py +107 -0
- hikyuu/data/pytdx_to_clickhouse.py +841 -0
- hikyuu/data/pytdx_to_h5.py +53 -13
- hikyuu/data/pytdx_to_mysql.py +42 -9
- hikyuu/data/pytdx_to_taos.py +736 -0
- hikyuu/data/pytdx_weight_to_clickhouse.py +191 -0
- hikyuu/data/sqlite_upgrade/0028.sql +97 -0
- hikyuu/data/tdx_to_clickhouse.py +448 -0
- hikyuu/data/zh_bond10_to_clickhouse.py +49 -0
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/__init__.pyi +8 -8
- hikyuu/draw/drawplot/bokeh_draw.pyi +538 -536
- hikyuu/draw/drawplot/common.pyi +1 -1
- hikyuu/draw/drawplot/echarts_draw.pyi +540 -538
- hikyuu/draw/drawplot/matplotlib_draw.py +7 -7
- hikyuu/draw/drawplot/matplotlib_draw.pyi +550 -548
- hikyuu/draw/elder.pyi +11 -11
- hikyuu/draw/kaufman.pyi +18 -18
- hikyuu/draw/volume.pyi +10 -10
- hikyuu/examples/notebook/001-overview.ipynb +65 -100
- hikyuu/examples/notebook/004-IndicatorOverview.ipynb +34 -32
- hikyuu/examples/notebook/007-SystemDetails.ipynb +64 -50
- hikyuu/examples/notebook/010-Portfolio.ipynb +120 -124
- hikyuu/extend.py +1 -1
- hikyuu/extend.pyi +527 -527
- hikyuu/fetcher/stock/zh_block_em.py +349 -5
- hikyuu/fetcher/stock/zh_stock_a_pytdx.py +11 -21
- hikyuu/fetcher/stock/zh_stock_a_qmt.py +4 -5
- hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +16 -60
- hikyuu/flat/Spot.py +96 -200
- hikyuu/gui/HikyuuTDX.py +175 -23
- hikyuu/gui/data/ImportBlockInfoTask.py +12 -1
- hikyuu/gui/data/ImportHistoryFinanceTask.py +62 -44
- hikyuu/gui/data/ImportPytdxTimeToH5Task.py +14 -2
- hikyuu/gui/data/ImportPytdxToH5Task.py +17 -3
- hikyuu/gui/data/ImportPytdxTransToH5Task.py +14 -2
- hikyuu/gui/data/ImportTdxToH5Task.py +13 -1
- hikyuu/gui/data/ImportWeightToSqliteTask.py +16 -2
- hikyuu/gui/data/ImportZhBond10Task.py +12 -1
- hikyuu/gui/data/MainWindow.py +191 -110
- hikyuu/gui/data/UsePytdxImportToH5Thread.py +52 -29
- hikyuu/gui/data/UseQmtImportToH5Thread.py +1 -0
- hikyuu/gui/data/UseTdxImportToH5Thread.py +21 -2
- hikyuu/gui/dataserver.py +12 -4
- hikyuu/gui/spot_server.py +30 -40
- hikyuu/gui/start_qmt.py +20 -3
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/DataType.h +11 -0
- hikyuu/include/hikyuu/MarketInfo.h +6 -0
- hikyuu/include/hikyuu/StockManager.h +8 -0
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +35 -0
- hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +1 -0
- hikyuu/include/hikyuu/global/GlobalSpotAgent.h +1 -1
- hikyuu/include/hikyuu/global/SpotRecord.h +15 -31
- hikyuu/include/hikyuu/global/agent/spot_generated.h +48 -232
- hikyuu/include/hikyuu/global/schedule/scheduler.h +1 -1
- hikyuu/include/hikyuu/indicator/build_in.h +1 -0
- hikyuu/include/hikyuu/indicator/crt/BARSLASTCOUNT.h +33 -0
- hikyuu/include/hikyuu/indicator/imp/IBarsLastCount.h +27 -0
- hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +3 -0
- hikyuu/include/hikyuu/plugin/backtest.h +2 -2
- hikyuu/include/hikyuu/plugin/dataserver.h +26 -1
- hikyuu/include/hikyuu/plugin/device.h +8 -4
- hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +1 -1
- hikyuu/include/hikyuu/plugin/interface/DataDriverPluginInterface.h +27 -0
- hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +2 -1
- hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +2 -1
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +3 -0
- hikyuu/include/hikyuu/plugin/interface/TMReportPluginInterface.h +80 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
- hikyuu/include/hikyuu/strategy/Strategy.h +0 -9
- hikyuu/include/hikyuu/trade_manage/Performance.h +17 -9
- hikyuu/include/hikyuu/trade_manage/PositionExtInfo.h +92 -0
- hikyuu/include/hikyuu/trade_manage/PositionRecord.h +7 -1
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +60 -1
- hikyuu/include/hikyuu/trade_sys/selector/crt/SE_Optimal.h +8 -0
- hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalEvaluateSelector.h +28 -0
- hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +1 -0
- hikyuu/include/hikyuu/utilities/DllLoader.h +226 -0
- hikyuu/include/hikyuu/utilities/config.h +1 -1
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +20 -0
- hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +6 -0
- hikyuu/include/hikyuu/utilities/mo/mo.h +30 -14
- hikyuu/include/hikyuu/utilities/os.h +6 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +10 -10
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +13 -7
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +13 -6
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/plugin/backtest.dll +0 -0
- hikyuu/plugin/clickhousedriver.dll +0 -0
- hikyuu/plugin/dataserver.dll +0 -0
- hikyuu/plugin/device.dll +0 -0
- hikyuu/plugin/extind.dll +0 -0
- hikyuu/plugin/import2hdf5.dll +0 -0
- hikyuu/plugin/tmreport.dll +0 -0
- hikyuu/trade_manage/__init__.pyi +537 -535
- hikyuu/trade_manage/broker.pyi +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +1 -1
- hikyuu/trade_manage/trade.pyi +537 -535
- hikyuu/util/__init__.py +1 -0
- hikyuu/util/__init__.pyi +4 -3
- hikyuu/util/check.py +8 -0
- hikyuu/util/check.pyi +5 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/METADATA +4 -3
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/RECORD +144 -123
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/top_level.txt +2 -2
- hikyuu/include/hikyuu/global/agent/hikyuu/__init__.py +0 -1
- hikyuu/include/hikyuu/global/agent/hikyuu/flat/__init__.py +0 -1
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/LICENSE +0 -0
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/WHEEL +0 -0
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/entry_points.txt +0 -0
|
@@ -6,8 +6,12 @@
|
|
|
6
6
|
|
|
7
7
|
import requests
|
|
8
8
|
import math
|
|
9
|
+
import time
|
|
10
|
+
import random
|
|
9
11
|
import akshare as ak
|
|
10
12
|
import pandas as pd
|
|
13
|
+
import re
|
|
14
|
+
from functools import lru_cache
|
|
11
15
|
from hikyuu.util import *
|
|
12
16
|
|
|
13
17
|
em_num_per_page = 100
|
|
@@ -42,6 +46,7 @@ def get_hybk_names():
|
|
|
42
46
|
continue
|
|
43
47
|
tmp = [(v['f12'], v['f14']) for v in data_json["data"]["diff"]]
|
|
44
48
|
ret.extend(tmp)
|
|
49
|
+
time.sleep(random.uniform(1, 3))
|
|
45
50
|
return ret
|
|
46
51
|
|
|
47
52
|
|
|
@@ -73,6 +78,7 @@ def get_hybk_cons_code(blk_code):
|
|
|
73
78
|
if data_json["data"] is None:
|
|
74
79
|
continue
|
|
75
80
|
tmp = [v['f12'] for v in data_json["data"]['diff']]
|
|
81
|
+
time.sleep(random.uniform(1, 3))
|
|
76
82
|
ret.extend(tmp)
|
|
77
83
|
return ret
|
|
78
84
|
|
|
@@ -90,15 +96,350 @@ def get_all_hybk_info(code_market_dict, sep=""):
|
|
|
90
96
|
return ret
|
|
91
97
|
|
|
92
98
|
|
|
99
|
+
def get_tqdm(enable: bool = True):
|
|
100
|
+
"""
|
|
101
|
+
返回适用于当前环境的 tqdm 对象。
|
|
102
|
+
|
|
103
|
+
Args:
|
|
104
|
+
enable (bool): 是否启用进度条。默认为 True。
|
|
105
|
+
|
|
106
|
+
Returns:
|
|
107
|
+
tqdm 对象。
|
|
108
|
+
"""
|
|
109
|
+
if not enable:
|
|
110
|
+
# 如果进度条被禁用,返回一个不显示进度条的 tqdm 对象
|
|
111
|
+
return lambda iterable, *args, **kwargs: iterable
|
|
112
|
+
|
|
113
|
+
try:
|
|
114
|
+
# 尝试检查是否在 jupyter notebook 环境中,有利于退出进度条
|
|
115
|
+
# noinspection PyUnresolvedReferences
|
|
116
|
+
shell = get_ipython().__class__.__name__
|
|
117
|
+
if shell == "ZMQInteractiveShell":
|
|
118
|
+
from tqdm.notebook import tqdm
|
|
119
|
+
else:
|
|
120
|
+
from tqdm import tqdm
|
|
121
|
+
except (NameError, ImportError):
|
|
122
|
+
# 如果不在 Jupyter 环境中,就使用标准 tqdm
|
|
123
|
+
from tqdm import tqdm
|
|
124
|
+
|
|
125
|
+
return tqdm
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
def fetch_paginated_data(url: str, base_params: dict, timeout: int = 15):
|
|
129
|
+
"""
|
|
130
|
+
东方财富-分页获取数据并合并结果
|
|
131
|
+
https://quote.eastmoney.com/f1.html?newcode=0.000001
|
|
132
|
+
:param url: 股票代码
|
|
133
|
+
:type url: str
|
|
134
|
+
:param base_params: 基础请求参数
|
|
135
|
+
:type base_params: dict
|
|
136
|
+
:param timeout: 请求超时时间
|
|
137
|
+
:type timeout: str
|
|
138
|
+
:return: 合并后的数据
|
|
139
|
+
:rtype: pandas.DataFrame
|
|
140
|
+
"""
|
|
141
|
+
# 复制参数以避免修改原始参数
|
|
142
|
+
params = base_params.copy()
|
|
143
|
+
# 获取第一页数据,用于确定分页信息
|
|
144
|
+
r = requests.get(url, params=params, timeout=timeout)
|
|
145
|
+
data_json = r.json()
|
|
146
|
+
# 计算分页信息
|
|
147
|
+
per_page_num = len(data_json["data"]["diff"])
|
|
148
|
+
total_page = math.ceil(data_json["data"]["total"] / per_page_num)
|
|
149
|
+
# 存储所有页面数据
|
|
150
|
+
temp_list = []
|
|
151
|
+
# 添加第一页数据
|
|
152
|
+
temp_list.append(pd.DataFrame(data_json["data"]["diff"]))
|
|
153
|
+
# 获取进度条
|
|
154
|
+
tqdm = get_tqdm()
|
|
155
|
+
# 获取剩余页面数据
|
|
156
|
+
for page in tqdm(range(2, total_page + 1), leave=False):
|
|
157
|
+
params.update({"pn": page})
|
|
158
|
+
r = requests.get(url, params=params, timeout=timeout)
|
|
159
|
+
data_json = r.json()
|
|
160
|
+
inner_temp_df = pd.DataFrame(data_json["data"]["diff"])
|
|
161
|
+
temp_list.append(inner_temp_df)
|
|
162
|
+
time.sleep(random.uniform(1, 3))
|
|
163
|
+
# 合并所有数据
|
|
164
|
+
temp_df = pd.concat(temp_list, ignore_index=True)
|
|
165
|
+
temp_df["f3"] = pd.to_numeric(temp_df["f3"], errors="coerce")
|
|
166
|
+
temp_df.sort_values(by=["f3"], ascending=False, inplace=True, ignore_index=True)
|
|
167
|
+
temp_df.reset_index(inplace=True)
|
|
168
|
+
temp_df["index"] = temp_df["index"].astype(int) + 1
|
|
169
|
+
return temp_df
|
|
170
|
+
|
|
171
|
+
|
|
172
|
+
def stock_board_concept_name_em() -> pd.DataFrame:
|
|
173
|
+
"""
|
|
174
|
+
from akshare
|
|
175
|
+
东方财富网-行情中心-沪深京板块-概念板块-名称
|
|
176
|
+
https://quote.eastmoney.com/center/boardlist.html#concept_board
|
|
177
|
+
:return: 概念板块-名称
|
|
178
|
+
:rtype: pandas.DataFrame
|
|
179
|
+
"""
|
|
180
|
+
url = "https://59.push2.eastmoney.com/api/qt/clist/get"
|
|
181
|
+
params = {
|
|
182
|
+
"pn": "1",
|
|
183
|
+
"pz": "100",
|
|
184
|
+
"po": "1",
|
|
185
|
+
"np": "1",
|
|
186
|
+
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
187
|
+
"fltt": "2",
|
|
188
|
+
"invt": "2",
|
|
189
|
+
"fid": "f12",
|
|
190
|
+
"fs": "m:90 t:3 f:!50",
|
|
191
|
+
"fields": "f2,f3,f4,f8,f12,f14,f15,f16,f17,f18,f20,f21,f24,f25,f22,f33,f11,f62,f128,f124,f107,f104,f105,f136",
|
|
192
|
+
}
|
|
193
|
+
temp_df = fetch_paginated_data(url, params)
|
|
194
|
+
temp_df.columns = [
|
|
195
|
+
"排名",
|
|
196
|
+
"最新价",
|
|
197
|
+
"涨跌幅",
|
|
198
|
+
"涨跌额",
|
|
199
|
+
"换手率",
|
|
200
|
+
"_",
|
|
201
|
+
"板块代码",
|
|
202
|
+
"板块名称",
|
|
203
|
+
"_",
|
|
204
|
+
"_",
|
|
205
|
+
"_",
|
|
206
|
+
"_",
|
|
207
|
+
"总市值",
|
|
208
|
+
"_",
|
|
209
|
+
"_",
|
|
210
|
+
"_",
|
|
211
|
+
"_",
|
|
212
|
+
"_",
|
|
213
|
+
"_",
|
|
214
|
+
"上涨家数",
|
|
215
|
+
"下跌家数",
|
|
216
|
+
"_",
|
|
217
|
+
"_",
|
|
218
|
+
"领涨股票",
|
|
219
|
+
"_",
|
|
220
|
+
"_",
|
|
221
|
+
"领涨股票-涨跌幅",
|
|
222
|
+
]
|
|
223
|
+
temp_df = temp_df[
|
|
224
|
+
[
|
|
225
|
+
"排名",
|
|
226
|
+
"板块名称",
|
|
227
|
+
"板块代码",
|
|
228
|
+
"最新价",
|
|
229
|
+
"涨跌额",
|
|
230
|
+
"涨跌幅",
|
|
231
|
+
"总市值",
|
|
232
|
+
"换手率",
|
|
233
|
+
"上涨家数",
|
|
234
|
+
"下跌家数",
|
|
235
|
+
"领涨股票",
|
|
236
|
+
"领涨股票-涨跌幅",
|
|
237
|
+
]
|
|
238
|
+
]
|
|
239
|
+
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
|
|
240
|
+
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
|
|
241
|
+
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
|
|
242
|
+
temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
|
|
243
|
+
temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
|
|
244
|
+
temp_df["上涨家数"] = pd.to_numeric(temp_df["上涨家数"], errors="coerce")
|
|
245
|
+
temp_df["下跌家数"] = pd.to_numeric(temp_df["下跌家数"], errors="coerce")
|
|
246
|
+
temp_df["领涨股票-涨跌幅"] = pd.to_numeric(
|
|
247
|
+
temp_df["领涨股票-涨跌幅"], errors="coerce"
|
|
248
|
+
)
|
|
249
|
+
return temp_df
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
@lru_cache()
|
|
253
|
+
def __stock_board_concept_name_em() -> pd.DataFrame:
|
|
254
|
+
"""
|
|
255
|
+
东方财富网-行情中心-沪深京板块-概念板块-名称
|
|
256
|
+
https://quote.eastmoney.com/center/boardlist.html#concept_board
|
|
257
|
+
:return: 概念板块-名称
|
|
258
|
+
:rtype: pandas.DataFrame
|
|
259
|
+
"""
|
|
260
|
+
url = "https://79.push2.eastmoney.com/api/qt/clist/get"
|
|
261
|
+
params = {
|
|
262
|
+
"pn": "1",
|
|
263
|
+
"pz": "100",
|
|
264
|
+
"po": "1",
|
|
265
|
+
"np": "1",
|
|
266
|
+
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
267
|
+
"fltt": "2",
|
|
268
|
+
"invt": "2",
|
|
269
|
+
"fid": "f12",
|
|
270
|
+
"fs": "m:90 t:3 f:!50",
|
|
271
|
+
"fields": "f2,f3,f4,f8,f12,f14,f15,f16,f17,f18,f20,f21,f24,f25,f22,f33,f11,f62,f128,f124,f107,f104,f105,f136",
|
|
272
|
+
}
|
|
273
|
+
temp_df = fetch_paginated_data(url, params)
|
|
274
|
+
temp_df.columns = [
|
|
275
|
+
"排名",
|
|
276
|
+
"最新价",
|
|
277
|
+
"涨跌幅",
|
|
278
|
+
"涨跌额",
|
|
279
|
+
"换手率",
|
|
280
|
+
"_",
|
|
281
|
+
"板块代码",
|
|
282
|
+
"板块名称",
|
|
283
|
+
"_",
|
|
284
|
+
"_",
|
|
285
|
+
"_",
|
|
286
|
+
"_",
|
|
287
|
+
"总市值",
|
|
288
|
+
"_",
|
|
289
|
+
"_",
|
|
290
|
+
"_",
|
|
291
|
+
"_",
|
|
292
|
+
"_",
|
|
293
|
+
"_",
|
|
294
|
+
"上涨家数",
|
|
295
|
+
"下跌家数",
|
|
296
|
+
"_",
|
|
297
|
+
"_",
|
|
298
|
+
"领涨股票",
|
|
299
|
+
"_",
|
|
300
|
+
"_",
|
|
301
|
+
"领涨股票-涨跌幅",
|
|
302
|
+
]
|
|
303
|
+
temp_df = temp_df[
|
|
304
|
+
[
|
|
305
|
+
"排名",
|
|
306
|
+
"板块名称",
|
|
307
|
+
"板块代码",
|
|
308
|
+
"最新价",
|
|
309
|
+
"涨跌额",
|
|
310
|
+
"涨跌幅",
|
|
311
|
+
"总市值",
|
|
312
|
+
"换手率",
|
|
313
|
+
"上涨家数",
|
|
314
|
+
"下跌家数",
|
|
315
|
+
"领涨股票",
|
|
316
|
+
"领涨股票-涨跌幅",
|
|
317
|
+
]
|
|
318
|
+
]
|
|
319
|
+
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
|
|
320
|
+
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
|
|
321
|
+
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
|
|
322
|
+
temp_df["总市值"] = pd.to_numeric(temp_df["总市值"], errors="coerce")
|
|
323
|
+
temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
|
|
324
|
+
temp_df["上涨家数"] = pd.to_numeric(temp_df["上涨家数"], errors="coerce")
|
|
325
|
+
temp_df["下跌家数"] = pd.to_numeric(temp_df["下跌家数"], errors="coerce")
|
|
326
|
+
temp_df["领涨股票-涨跌幅"] = pd.to_numeric(
|
|
327
|
+
temp_df["领涨股票-涨跌幅"], errors="coerce"
|
|
328
|
+
)
|
|
329
|
+
return temp_df
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def stock_board_concept_cons_em(symbol: str = "融资融券") -> pd.DataFrame:
|
|
333
|
+
"""
|
|
334
|
+
东方财富-沪深板块-概念板块-板块成份
|
|
335
|
+
https://quote.eastmoney.com/center/boardlist.html#boards-BK06551
|
|
336
|
+
:param symbol: 板块名称或者板块代码
|
|
337
|
+
:type symbol: str
|
|
338
|
+
:return: 板块成份
|
|
339
|
+
:rtype: pandas.DataFrame
|
|
340
|
+
"""
|
|
341
|
+
if re.match(pattern=r"^BK\d+", string=symbol):
|
|
342
|
+
stock_board_code = symbol
|
|
343
|
+
else:
|
|
344
|
+
stock_board_concept_em_map = __stock_board_concept_name_em()
|
|
345
|
+
stock_board_code = stock_board_concept_em_map[
|
|
346
|
+
stock_board_concept_em_map["板块名称"] == symbol
|
|
347
|
+
]["板块代码"].values[0]
|
|
348
|
+
url = "https://29.push2.eastmoney.com/api/qt/clist/get"
|
|
349
|
+
params = {
|
|
350
|
+
"pn": "1",
|
|
351
|
+
"pz": "100",
|
|
352
|
+
"po": "1",
|
|
353
|
+
"np": "1",
|
|
354
|
+
"ut": "bd1d9ddb04089700cf9c27f6f7426281",
|
|
355
|
+
"fltt": "2",
|
|
356
|
+
"invt": "2",
|
|
357
|
+
"fid": "f12",
|
|
358
|
+
"fs": f"b:{stock_board_code} f:!50",
|
|
359
|
+
"fields": "f1,f2,f3,f4,f5,f6,f7,f8,f9,f10,f12,f13,f14,f15,f16,f17,f18,f20,f21,f23,"
|
|
360
|
+
"f24,f25,f22,f11,f62,f128,f136,f115,f152,f45",
|
|
361
|
+
}
|
|
362
|
+
temp_df = fetch_paginated_data(url, params)
|
|
363
|
+
temp_df.columns = [
|
|
364
|
+
"序号",
|
|
365
|
+
"_",
|
|
366
|
+
"最新价",
|
|
367
|
+
"涨跌幅",
|
|
368
|
+
"涨跌额",
|
|
369
|
+
"成交量",
|
|
370
|
+
"成交额",
|
|
371
|
+
"振幅",
|
|
372
|
+
"换手率",
|
|
373
|
+
"市盈率-动态",
|
|
374
|
+
"_",
|
|
375
|
+
"_",
|
|
376
|
+
"代码",
|
|
377
|
+
"_",
|
|
378
|
+
"名称",
|
|
379
|
+
"最高",
|
|
380
|
+
"最低",
|
|
381
|
+
"今开",
|
|
382
|
+
"昨收",
|
|
383
|
+
"_",
|
|
384
|
+
"_",
|
|
385
|
+
"_",
|
|
386
|
+
"市净率",
|
|
387
|
+
"_",
|
|
388
|
+
"_",
|
|
389
|
+
"_",
|
|
390
|
+
"_",
|
|
391
|
+
"_",
|
|
392
|
+
"_",
|
|
393
|
+
"_",
|
|
394
|
+
"_",
|
|
395
|
+
"_",
|
|
396
|
+
"_",
|
|
397
|
+
]
|
|
398
|
+
temp_df = temp_df[
|
|
399
|
+
[
|
|
400
|
+
"序号",
|
|
401
|
+
"代码",
|
|
402
|
+
"名称",
|
|
403
|
+
"最新价",
|
|
404
|
+
"涨跌幅",
|
|
405
|
+
"涨跌额",
|
|
406
|
+
"成交量",
|
|
407
|
+
"成交额",
|
|
408
|
+
"振幅",
|
|
409
|
+
"最高",
|
|
410
|
+
"最低",
|
|
411
|
+
"今开",
|
|
412
|
+
"昨收",
|
|
413
|
+
"换手率",
|
|
414
|
+
"市盈率-动态",
|
|
415
|
+
"市净率",
|
|
416
|
+
]
|
|
417
|
+
]
|
|
418
|
+
temp_df["最新价"] = pd.to_numeric(temp_df["最新价"], errors="coerce")
|
|
419
|
+
temp_df["涨跌幅"] = pd.to_numeric(temp_df["涨跌幅"], errors="coerce")
|
|
420
|
+
temp_df["涨跌额"] = pd.to_numeric(temp_df["涨跌额"], errors="coerce")
|
|
421
|
+
temp_df["成交量"] = pd.to_numeric(temp_df["成交量"], errors="coerce")
|
|
422
|
+
temp_df["成交额"] = pd.to_numeric(temp_df["成交额"], errors="coerce")
|
|
423
|
+
temp_df["振幅"] = pd.to_numeric(temp_df["振幅"], errors="coerce")
|
|
424
|
+
temp_df["最高"] = pd.to_numeric(temp_df["最高"], errors="coerce")
|
|
425
|
+
temp_df["最低"] = pd.to_numeric(temp_df["最低"], errors="coerce")
|
|
426
|
+
temp_df["今开"] = pd.to_numeric(temp_df["今开"], errors="coerce")
|
|
427
|
+
temp_df["昨收"] = pd.to_numeric(temp_df["昨收"], errors="coerce")
|
|
428
|
+
temp_df["换手率"] = pd.to_numeric(temp_df["换手率"], errors="coerce")
|
|
429
|
+
temp_df["市盈率-动态"] = pd.to_numeric(temp_df["市盈率-动态"], errors="coerce")
|
|
430
|
+
temp_df["市净率"] = pd.to_numeric(temp_df["市净率"], errors="coerce")
|
|
431
|
+
return temp_df
|
|
432
|
+
|
|
433
|
+
|
|
93
434
|
@hku_catch(ret={}, trace=True)
|
|
94
435
|
def get_all_gnbk_info(code_market_dict, sep=""):
|
|
95
436
|
"""获取所有概念版本列表"""
|
|
96
|
-
blk_names =
|
|
437
|
+
blk_names = stock_board_concept_name_em()['板块名称']
|
|
97
438
|
ret = {}
|
|
98
|
-
for blk_name in blk_names:
|
|
99
|
-
stk_codes =
|
|
439
|
+
for i, blk_name in enumerate(blk_names):
|
|
440
|
+
stk_codes = stock_board_concept_cons_em(blk_name)
|
|
100
441
|
stk_codes = stk_codes['代码'].to_list()
|
|
101
|
-
hku_info(f"获取概念板块{blk_name}成分: {len(stk_codes)}")
|
|
442
|
+
hku_info(f"{i} 获取概念板块{blk_name}成分: {len(stk_codes)}")
|
|
102
443
|
ret[blk_name] = [
|
|
103
444
|
f"{code_market_dict[stk_code]}{sep}{stk_code}" for stk_code in stk_codes if stk_code in code_market_dict]
|
|
104
445
|
return ret
|
|
@@ -133,6 +474,7 @@ def get_dybk_names():
|
|
|
133
474
|
data_json = r.json()
|
|
134
475
|
if data_json["data"] is not None:
|
|
135
476
|
ret.extend([(v["f12"], v["f14"]) for v in data_json["data"]["diff"]])
|
|
477
|
+
time.sleep(random.uniform(1, 3))
|
|
136
478
|
return ret
|
|
137
479
|
|
|
138
480
|
|
|
@@ -179,6 +521,7 @@ def get_all_dybk_info(code_market_dict, sep=""):
|
|
|
179
521
|
stk_json = stk_json["data"]["diff"]
|
|
180
522
|
ret[blk_name].extend(
|
|
181
523
|
[f"{code_market_dict[v['f12']]}{sep}{v['f12']}" for v in stk_json if v["f12"] in code_market_dict])
|
|
524
|
+
time.sleep(random.uniform(1, 3))
|
|
182
525
|
hku_info(f'获取地域板块{blk_name}成分: {len(ret[blk_name])}')
|
|
183
526
|
|
|
184
527
|
return ret
|
|
@@ -214,5 +557,6 @@ def get_all_zsbk_info(code_market_dict, sep=""):
|
|
|
214
557
|
|
|
215
558
|
|
|
216
559
|
if __name__ == "__main__":
|
|
217
|
-
blks =
|
|
560
|
+
blks = get_hybk_names()
|
|
561
|
+
# blks = get_hybk_cons_code('BK0480')
|
|
218
562
|
print(blks)
|
|
@@ -41,30 +41,19 @@ def parse_one_result(quotes):
|
|
|
41
41
|
else:
|
|
42
42
|
result['volume'] = float(quotes['vol']) # 成交的股票手数
|
|
43
43
|
result['amount'] = round(quotes['amount'] * 0.0001, 2) # 成交金额,单位为“元”,若要以“万元”为成交金额的单位,需要把该值除以一万
|
|
44
|
-
|
|
45
|
-
result['
|
|
46
|
-
|
|
47
|
-
result['
|
|
48
|
-
|
|
49
|
-
result['
|
|
50
|
-
|
|
51
|
-
result['
|
|
52
|
-
|
|
53
|
-
result['bid5'] = float(quotes['bid5'])
|
|
54
|
-
result['ask1_amount'] = float(quotes['ask_vol1']) # “卖一”申报3100股,即31手
|
|
55
|
-
result['ask1'] = float(quotes['ask1']) # “卖一”报价
|
|
56
|
-
result['ask2_amount'] = float(quotes['ask_vol2'])
|
|
57
|
-
result['ask2'] = float(quotes['ask2'])
|
|
58
|
-
result['ask3_amount'] = float(quotes['ask_vol3'])
|
|
59
|
-
result['ask3'] = float(quotes['ask3'])
|
|
60
|
-
result['ask4_amount'] = float(quotes['ask_vol4'])
|
|
61
|
-
result['ask4'] = float(quotes['ask4'])
|
|
62
|
-
result['ask5_amount'] = float(quotes['ask_vol5'])
|
|
63
|
-
result['ask5'] = float(quotes['ask5'])
|
|
44
|
+
|
|
45
|
+
result['bid'] = [float(quotes['bid1']), float(quotes['bid2']), float(
|
|
46
|
+
quotes['bid3']), float(quotes['bid4']), float(quotes['bid5'])]
|
|
47
|
+
result['bid_amount'] = [float(quotes['bid_vol1']), float(quotes['bid_vol2']), float(
|
|
48
|
+
quotes['bid_vol3']), float(quotes['bid_vol4']), float(quotes['bid_vol5'])]
|
|
49
|
+
result['ask'] = [float(quotes['ask1']), float(quotes['ask2']), float(
|
|
50
|
+
quotes['ask3']), float(quotes['ask4']), float(quotes['ask5'])]
|
|
51
|
+
result['ask_amount'] = [float(quotes['ask_vol1']), float(quotes['ask_vol2']), float(
|
|
52
|
+
quotes['ask_vol3']), float(quotes['ask_vol4']), float(quotes['ask_vol5'])]
|
|
64
53
|
return result
|
|
65
54
|
|
|
66
55
|
|
|
67
|
-
@
|
|
56
|
+
@hku_catch(ret=[], trace=True)
|
|
68
57
|
def request_data(api, stklist, parse_one_result):
|
|
69
58
|
"""请求失败将抛出异常"""
|
|
70
59
|
quotes_list = api.get_security_quotes(stklist)
|
|
@@ -103,6 +92,7 @@ def inner_get_spot(stocklist, ip, port, batch_func=None):
|
|
|
103
92
|
batch_func(phase_result)
|
|
104
93
|
else:
|
|
105
94
|
err_list.extend(tmplist)
|
|
95
|
+
api.disconnect()
|
|
106
96
|
return result, err_list
|
|
107
97
|
|
|
108
98
|
|
|
@@ -33,11 +33,10 @@ try:
|
|
|
33
33
|
result['amount'] = data['amount'] * 0.0001 # 转千元
|
|
34
34
|
result['volume'] = data['pvolume'] * 0.01 # 转手数
|
|
35
35
|
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
result[f'ask{i+1}_amount'] = data['askVol'][i]
|
|
36
|
+
result['bid'] = data['bidPrice']
|
|
37
|
+
result['bid_amount'] = data['bidVol']
|
|
38
|
+
result['ask'] = data['askPrice']
|
|
39
|
+
result['ask_amount'] = data['askVol']
|
|
41
40
|
return result
|
|
42
41
|
|
|
43
42
|
def get_spot(stocklist, unused1=None, unused2=None, batch_func=None):
|
|
@@ -80,26 +80,21 @@ def parse_one_result_qq(resultstr):
|
|
|
80
80
|
# result['amount'] = float(a[6]) # 成交量
|
|
81
81
|
# 7: 外盘 ?
|
|
82
82
|
# 8:内盘 ?
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
result['
|
|
89
|
-
result['
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
result['
|
|
96
|
-
result['
|
|
97
|
-
|
|
98
|
-
result['ask3_amount'] = float(a[24])
|
|
99
|
-
result['ask4'] = float(a[25])
|
|
100
|
-
result['ask4_amount'] = float(a[26])
|
|
101
|
-
result['ask5'] = float(a[27])
|
|
102
|
-
result['ask5_amount'] = float(a[28])
|
|
83
|
+
bid = []
|
|
84
|
+
bid_amount = []
|
|
85
|
+
for i in range(9, 18, 2):
|
|
86
|
+
bid.append(float(a[i]))
|
|
87
|
+
bid_amount.append(float(a[i + 1]))
|
|
88
|
+
result['bid'] = bid
|
|
89
|
+
result['bid_amount'] = bid_amount
|
|
90
|
+
ask = []
|
|
91
|
+
ask_amount = []
|
|
92
|
+
for i in range(19, 28, 2):
|
|
93
|
+
ask.append(float(a[i]))
|
|
94
|
+
ask_amount.append(float(a[i + 1]))
|
|
95
|
+
result['ask'] = ask
|
|
96
|
+
result['ask_amount'] = ask_amount
|
|
97
|
+
|
|
103
98
|
# result['最近逐笔成交'] = float(a[29])
|
|
104
99
|
x = a[30]
|
|
105
100
|
result['datetime'] = datetime.datetime(
|
|
@@ -139,46 +134,6 @@ def request_data(querystr, parse_one_result, use_proxy=False):
|
|
|
139
134
|
return result
|
|
140
135
|
|
|
141
136
|
|
|
142
|
-
def get_spotV1(stocklist, source='qq', use_proxy=False, batch_func=None):
|
|
143
|
-
"""获取实时数据,获取失败时,抛出异常
|
|
144
|
-
|
|
145
|
-
:param list stocklist: 股票名称列表,股票名称示例:sh000001, sz000001
|
|
146
|
-
:param str source: 使用 sina 还是 qq 作为数据来源
|
|
147
|
-
:param boolean: use_proxy: 是否使用代理
|
|
148
|
-
:param function batch_func: 当网络请求返回一个批次数据时,调用该函数,通常用于向数据库写入数据
|
|
149
|
-
"""
|
|
150
|
-
if source == 'sina':
|
|
151
|
-
queryStr = "http://hq.sinajs.cn/list="
|
|
152
|
-
max_size = 140
|
|
153
|
-
parse_one_result = parse_one_result_sina
|
|
154
|
-
hku_error("新浪接口已不再支持!")
|
|
155
|
-
else:
|
|
156
|
-
queryStr = "http://qt.gtimg.cn/q="
|
|
157
|
-
max_size = 60
|
|
158
|
-
parse_one_result = parse_one_result_qq
|
|
159
|
-
count = 0
|
|
160
|
-
tmpstr = queryStr
|
|
161
|
-
result = []
|
|
162
|
-
for stock in stocklist:
|
|
163
|
-
tmpstr += ("%s,") % (stock)
|
|
164
|
-
count += 1
|
|
165
|
-
if count >= max_size:
|
|
166
|
-
phase_result = request_data(tmpstr, parse_one_result, use_proxy)
|
|
167
|
-
if phase_result:
|
|
168
|
-
result.extend(phase_result)
|
|
169
|
-
if batch_func:
|
|
170
|
-
batch_func(phase_result)
|
|
171
|
-
count = 0
|
|
172
|
-
tmpstr = queryStr
|
|
173
|
-
if tmpstr != queryStr:
|
|
174
|
-
phase_result = request_data(tmpstr, parse_one_result, use_proxy)
|
|
175
|
-
if phase_result:
|
|
176
|
-
result.extend(phase_result)
|
|
177
|
-
if batch_func:
|
|
178
|
-
batch_func(phase_result)
|
|
179
|
-
return result
|
|
180
|
-
|
|
181
|
-
|
|
182
137
|
def get_spot(stocklist, source='sina', use_proxy=False, batch_func=None):
|
|
183
138
|
"""并发网络请求获取实时数据,获取失败时,抛出异常
|
|
184
139
|
|
|
@@ -188,6 +143,7 @@ def get_spot(stocklist, source='sina', use_proxy=False, batch_func=None):
|
|
|
188
143
|
:param function batch_func: 当网络请求返回一个批次数据时,调用该函数,通常用于向数据库写入数据
|
|
189
144
|
"""
|
|
190
145
|
if source == 'sina':
|
|
146
|
+
raise Exception("新浪数据源已不支持")
|
|
191
147
|
queryStr = "http://hq.sinajs.cn/list="
|
|
192
148
|
max_size = 140
|
|
193
149
|
parse_one_result = parse_one_result_sina
|