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.
Files changed (146) hide show
  1. hikyuu/__init__.py +6 -0
  2. hikyuu/__init__.pyi +548 -546
  3. hikyuu/analysis/__init__.pyi +519 -514
  4. hikyuu/analysis/analysis.pyi +520 -515
  5. hikyuu/core.pyi +521 -516
  6. hikyuu/cpp/__init__.pyi +2 -2
  7. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  8. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  9. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  10. hikyuu/cpp/core310.pyd +0 -0
  11. hikyuu/cpp/core310.pyi +167 -36
  12. hikyuu/cpp/core311.pyd +0 -0
  13. hikyuu/cpp/core311.pyi +167 -36
  14. hikyuu/cpp/core312.pyd +0 -0
  15. hikyuu/cpp/core312.pyi +167 -36
  16. hikyuu/cpp/core313.pyd +0 -0
  17. hikyuu/cpp/core313.pyi +167 -36
  18. hikyuu/cpp/core39.pyd +0 -0
  19. hikyuu/cpp/core39.pyi +167 -36
  20. hikyuu/cpp/hikyuu.dll +0 -0
  21. hikyuu/cpp/hikyuu.lib +0 -0
  22. hikyuu/cpp/i18n/__init__.py +0 -0
  23. hikyuu/cpp/i18n/zh_CN.mo +0 -0
  24. hikyuu/cpp/sqlite3.dll +0 -0
  25. hikyuu/data/clickhouse_upgrade/__init__.py +1 -0
  26. hikyuu/data/clickhouse_upgrade/createdb.sql +1085 -0
  27. hikyuu/data/common.py +1 -1
  28. hikyuu/data/common_clickhouse.py +512 -0
  29. hikyuu/data/common_mysql.py +19 -0
  30. hikyuu/data/common_pytdx.py +2 -0
  31. hikyuu/data/common_sqlite3.py +1 -0
  32. hikyuu/data/em_block_to_clickhouse.py +120 -0
  33. hikyuu/data/hku_config_template.py +70 -1
  34. hikyuu/data/mysql_upgrade/0028.sql +95 -0
  35. hikyuu/data/pytdx_finance_to_clickhouse.py +107 -0
  36. hikyuu/data/pytdx_to_clickhouse.py +841 -0
  37. hikyuu/data/pytdx_to_h5.py +53 -13
  38. hikyuu/data/pytdx_to_mysql.py +42 -9
  39. hikyuu/data/pytdx_to_taos.py +736 -0
  40. hikyuu/data/pytdx_weight_to_clickhouse.py +191 -0
  41. hikyuu/data/sqlite_upgrade/0028.sql +97 -0
  42. hikyuu/data/tdx_to_clickhouse.py +448 -0
  43. hikyuu/data/zh_bond10_to_clickhouse.py +49 -0
  44. hikyuu/draw/__init__.pyi +1 -1
  45. hikyuu/draw/drawplot/__init__.pyi +8 -8
  46. hikyuu/draw/drawplot/bokeh_draw.pyi +538 -536
  47. hikyuu/draw/drawplot/common.pyi +1 -1
  48. hikyuu/draw/drawplot/echarts_draw.pyi +540 -538
  49. hikyuu/draw/drawplot/matplotlib_draw.py +7 -7
  50. hikyuu/draw/drawplot/matplotlib_draw.pyi +550 -548
  51. hikyuu/draw/elder.pyi +11 -11
  52. hikyuu/draw/kaufman.pyi +18 -18
  53. hikyuu/draw/volume.pyi +10 -10
  54. hikyuu/examples/notebook/001-overview.ipynb +65 -100
  55. hikyuu/examples/notebook/004-IndicatorOverview.ipynb +34 -32
  56. hikyuu/examples/notebook/007-SystemDetails.ipynb +64 -50
  57. hikyuu/examples/notebook/010-Portfolio.ipynb +120 -124
  58. hikyuu/extend.py +1 -1
  59. hikyuu/extend.pyi +527 -527
  60. hikyuu/fetcher/stock/zh_block_em.py +349 -5
  61. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +11 -21
  62. hikyuu/fetcher/stock/zh_stock_a_qmt.py +4 -5
  63. hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +16 -60
  64. hikyuu/flat/Spot.py +96 -200
  65. hikyuu/gui/HikyuuTDX.py +175 -23
  66. hikyuu/gui/data/ImportBlockInfoTask.py +12 -1
  67. hikyuu/gui/data/ImportHistoryFinanceTask.py +62 -44
  68. hikyuu/gui/data/ImportPytdxTimeToH5Task.py +14 -2
  69. hikyuu/gui/data/ImportPytdxToH5Task.py +17 -3
  70. hikyuu/gui/data/ImportPytdxTransToH5Task.py +14 -2
  71. hikyuu/gui/data/ImportTdxToH5Task.py +13 -1
  72. hikyuu/gui/data/ImportWeightToSqliteTask.py +16 -2
  73. hikyuu/gui/data/ImportZhBond10Task.py +12 -1
  74. hikyuu/gui/data/MainWindow.py +191 -110
  75. hikyuu/gui/data/UsePytdxImportToH5Thread.py +52 -29
  76. hikyuu/gui/data/UseQmtImportToH5Thread.py +1 -0
  77. hikyuu/gui/data/UseTdxImportToH5Thread.py +21 -2
  78. hikyuu/gui/dataserver.py +12 -4
  79. hikyuu/gui/spot_server.py +30 -40
  80. hikyuu/gui/start_qmt.py +20 -3
  81. hikyuu/hub.pyi +6 -6
  82. hikyuu/include/hikyuu/DataType.h +11 -0
  83. hikyuu/include/hikyuu/MarketInfo.h +6 -0
  84. hikyuu/include/hikyuu/StockManager.h +8 -0
  85. hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +35 -0
  86. hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +1 -0
  87. hikyuu/include/hikyuu/global/GlobalSpotAgent.h +1 -1
  88. hikyuu/include/hikyuu/global/SpotRecord.h +15 -31
  89. hikyuu/include/hikyuu/global/agent/spot_generated.h +48 -232
  90. hikyuu/include/hikyuu/global/schedule/scheduler.h +1 -1
  91. hikyuu/include/hikyuu/indicator/build_in.h +1 -0
  92. hikyuu/include/hikyuu/indicator/crt/BARSLASTCOUNT.h +33 -0
  93. hikyuu/include/hikyuu/indicator/imp/IBarsLastCount.h +27 -0
  94. hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +3 -0
  95. hikyuu/include/hikyuu/plugin/backtest.h +2 -2
  96. hikyuu/include/hikyuu/plugin/dataserver.h +26 -1
  97. hikyuu/include/hikyuu/plugin/device.h +8 -4
  98. hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +1 -1
  99. hikyuu/include/hikyuu/plugin/interface/DataDriverPluginInterface.h +27 -0
  100. hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +2 -1
  101. hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +2 -1
  102. hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +3 -0
  103. hikyuu/include/hikyuu/plugin/interface/TMReportPluginInterface.h +80 -0
  104. hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
  105. hikyuu/include/hikyuu/strategy/Strategy.h +0 -9
  106. hikyuu/include/hikyuu/trade_manage/Performance.h +17 -9
  107. hikyuu/include/hikyuu/trade_manage/PositionExtInfo.h +92 -0
  108. hikyuu/include/hikyuu/trade_manage/PositionRecord.h +7 -1
  109. hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +60 -1
  110. hikyuu/include/hikyuu/trade_sys/selector/crt/SE_Optimal.h +8 -0
  111. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalEvaluateSelector.h +28 -0
  112. hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +1 -0
  113. hikyuu/include/hikyuu/utilities/DllLoader.h +226 -0
  114. hikyuu/include/hikyuu/utilities/config.h +1 -1
  115. hikyuu/include/hikyuu/utilities/datetime/Datetime.h +20 -0
  116. hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +6 -0
  117. hikyuu/include/hikyuu/utilities/mo/mo.h +30 -14
  118. hikyuu/include/hikyuu/utilities/os.h +6 -0
  119. hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +10 -10
  120. hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +13 -7
  121. hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +13 -6
  122. hikyuu/include/hikyuu/version.h +4 -4
  123. hikyuu/plugin/backtest.dll +0 -0
  124. hikyuu/plugin/clickhousedriver.dll +0 -0
  125. hikyuu/plugin/dataserver.dll +0 -0
  126. hikyuu/plugin/device.dll +0 -0
  127. hikyuu/plugin/extind.dll +0 -0
  128. hikyuu/plugin/import2hdf5.dll +0 -0
  129. hikyuu/plugin/tmreport.dll +0 -0
  130. hikyuu/trade_manage/__init__.pyi +537 -535
  131. hikyuu/trade_manage/broker.pyi +3 -3
  132. hikyuu/trade_manage/broker_easytrader.pyi +1 -1
  133. hikyuu/trade_manage/trade.pyi +537 -535
  134. hikyuu/util/__init__.py +1 -0
  135. hikyuu/util/__init__.pyi +4 -3
  136. hikyuu/util/check.py +8 -0
  137. hikyuu/util/check.pyi +5 -1
  138. hikyuu/util/singleton.pyi +1 -1
  139. {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/METADATA +4 -3
  140. {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/RECORD +144 -123
  141. {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/top_level.txt +2 -2
  142. hikyuu/include/hikyuu/global/agent/hikyuu/__init__.py +0 -1
  143. hikyuu/include/hikyuu/global/agent/hikyuu/flat/__init__.py +0 -1
  144. {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/LICENSE +0 -0
  145. {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/WHEEL +0 -0
  146. {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 = ak.stock_board_concept_name_em()['板块名称']
437
+ blk_names = stock_board_concept_name_em()['板块名称']
97
438
  ret = {}
98
- for blk_name in blk_names:
99
- stk_codes = ak.stock_board_concept_cons_em(blk_name)
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 = get_hybk_cons_code('BK0475')
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
- result['bid1_amount'] = float(quotes['bid_vol1']) # “买一”申请4695股,即47手
45
- result['bid1'] = float(quotes['bid1']) # “买一”报价
46
- result['bid2_amount'] = float(quotes['bid_vol2'])
47
- result['bid2'] = float(quotes['bid2'])
48
- result['bid3_amount'] = float(quotes['bid_vol3'])
49
- result['bid3'] = float(quotes['bid3'])
50
- result['bid4_amount'] = float(quotes['bid_vol4'])
51
- result['bid4'] = float(quotes['bid4'])
52
- result['bid5_amount'] = float(quotes['bid_vol5'])
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
- @ hku_catch(ret=[], trace=True)
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
- for i in range(5):
37
- result[f'bid{i+1}'] = data['bidPrice'][i]
38
- result[f'bid{i+1}_amount'] = data['bidVol'][i]
39
- result[f'ask{i+1}'] = data['askPrice'][i]
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
- result['bid1'] = float(a[9]) # “买一”报价
84
- result['bid1_amount'] = float(a[10]) # “买一”申请4695股,即47手
85
- result['bid2'] = float(a[11])
86
- result['bid2_amount'] = float(a[12])
87
- result['bid3'] = float(a[13])
88
- result['bid3_amount'] = float(a[14])
89
- result['bid4'] = float(a[15])
90
- result['bid4_amount'] = float(a[16])
91
- result['bid5'] = float(a[17])
92
- result['bid5_amount'] = float(a[18])
93
- result['ask1'] = float(a[19]) # “卖一”报价
94
- result['ask1_amount'] = float(a[20]) # “卖一”申报3100股,即31手
95
- result['ask2'] = float(a[21])
96
- result['ask2_amount'] = float(a[22])
97
- result['ask3'] = float(a[23])
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