hikyuu 2.6.5__py3-none-win_amd64.whl → 2.6.7__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 +16 -0
  2. hikyuu/__init__.pyi +484 -474
  3. hikyuu/analysis/__init__.pyi +466 -445
  4. hikyuu/analysis/analysis.pyi +467 -446
  5. hikyuu/core.pyi +468 -447
  6. hikyuu/cpp/boost_date_time-mt.dll +0 -0
  7. hikyuu/cpp/boost_serialization-mt.dll +0 -0
  8. hikyuu/cpp/boost_wserialization-mt.dll +0 -0
  9. hikyuu/cpp/core310.pyd +0 -0
  10. hikyuu/cpp/core310.pyi +1070 -878
  11. hikyuu/cpp/core311.pyd +0 -0
  12. hikyuu/cpp/core311.pyi +1070 -878
  13. hikyuu/cpp/core312.pyd +0 -0
  14. hikyuu/cpp/core312.pyi +1070 -878
  15. hikyuu/cpp/core313.pyd +0 -0
  16. hikyuu/cpp/core313.pyi +1070 -876
  17. hikyuu/cpp/core39.pyd +0 -0
  18. hikyuu/cpp/core39.pyi +1070 -878
  19. hikyuu/cpp/hikyuu.dll +0 -0
  20. hikyuu/cpp/hikyuu.lib +0 -0
  21. hikyuu/cpp/i18n/__init__.py +0 -0
  22. hikyuu/cpp/i18n/zh_CN/__init__.py +0 -0
  23. hikyuu/cpp/i18n/zh_CN/hikyuu.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_clickhouse.py +465 -0
  28. hikyuu/data/em_block_to_clickhouse.py +120 -0
  29. hikyuu/data/hku_config_template.py +58 -3
  30. hikyuu/data/pytdx_finance_to_clickhouse.py +107 -0
  31. hikyuu/data/pytdx_to_clickhouse.py +841 -0
  32. hikyuu/data/pytdx_to_mysql.py +4 -4
  33. hikyuu/data/pytdx_weight_to_clickhouse.py +191 -0
  34. hikyuu/data/tdx_to_clickhouse.py +448 -0
  35. hikyuu/data/tdx_to_h5.py +1 -1
  36. hikyuu/data/zh_bond10_to_clickhouse.py +49 -0
  37. hikyuu/draw/__init__.pyi +1 -1
  38. hikyuu/draw/drawplot/bokeh_draw.pyi +479 -471
  39. hikyuu/draw/drawplot/echarts_draw.py +9 -8
  40. hikyuu/draw/drawplot/echarts_draw.pyi +479 -471
  41. hikyuu/draw/drawplot/matplotlib_draw.py +3 -3
  42. hikyuu/draw/drawplot/matplotlib_draw.pyi +479 -471
  43. hikyuu/draw/elder.pyi +6 -6
  44. hikyuu/draw/kaufman.py +1 -1
  45. hikyuu/draw/kaufman.pyi +10 -10
  46. hikyuu/draw/volume.pyi +5 -5
  47. hikyuu/examples/notebook/000-Index.ipynb +1 -1
  48. hikyuu/examples/notebook/001-overview.ipynb +78 -63
  49. hikyuu/examples/notebook/002-HowToGetStock.ipynb +259 -40
  50. hikyuu/examples/notebook/003-HowToGetKDataAndDraw.ipynb +49 -41
  51. hikyuu/examples/notebook/004-IndicatorOverview.ipynb +29 -29
  52. hikyuu/examples/notebook/005-Drawplot.ipynb +66 -37
  53. hikyuu/examples/notebook/006-TradeManager.ipynb +808 -61
  54. hikyuu/examples/notebook/007-SystemDetails.ipynb +23 -23
  55. hikyuu/examples/notebook/009-RealData.ipynb +3 -3
  56. hikyuu/examples/notebook/010-Portfolio.ipynb +761 -122
  57. hikyuu/extend.py +15 -100
  58. hikyuu/extend.pyi +478 -493
  59. hikyuu/fetcher/stock/zh_stock_a_pytdx.py +9 -20
  60. hikyuu/fetcher/stock/zh_stock_a_qmt.py +4 -5
  61. hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +16 -60
  62. hikyuu/flat/Spot.py +96 -200
  63. hikyuu/gui/HikyuuTDX.py +134 -7
  64. hikyuu/gui/data/ImportBlockInfoTask.py +11 -0
  65. hikyuu/gui/data/ImportHistoryFinanceTask.py +15 -1
  66. hikyuu/gui/data/ImportPytdxTimeToH5Task.py +11 -1
  67. hikyuu/gui/data/ImportPytdxToH5Task.py +13 -1
  68. hikyuu/gui/data/ImportPytdxTransToH5Task.py +11 -1
  69. hikyuu/gui/data/ImportTdxToH5Task.py +13 -1
  70. hikyuu/gui/data/ImportWeightToSqliteTask.py +14 -1
  71. hikyuu/gui/data/ImportZhBond10Task.py +11 -0
  72. hikyuu/gui/data/MainWindow.py +210 -135
  73. hikyuu/gui/data/UsePytdxImportToH5Thread.py +45 -26
  74. hikyuu/gui/data/UseTdxImportToH5Thread.py +19 -1
  75. hikyuu/gui/dataserver.py +12 -4
  76. hikyuu/gui/spot_server.py +30 -40
  77. hikyuu/gui/start_qmt.py +20 -3
  78. hikyuu/hub.pyi +6 -6
  79. hikyuu/include/hikyuu/DataType.h +2 -0
  80. hikyuu/include/hikyuu/KQuery.h +22 -28
  81. hikyuu/include/hikyuu/MarketInfo.h +1 -1
  82. hikyuu/include/hikyuu/Stock.h +15 -3
  83. hikyuu/include/hikyuu/StockManager.h +12 -3
  84. hikyuu/include/hikyuu/StockTypeInfo.h +6 -0
  85. hikyuu/include/hikyuu/TransRecord.h +2 -8
  86. hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +1 -0
  87. hikyuu/include/hikyuu/doc.h +4 -0
  88. hikyuu/include/hikyuu/global/GlobalSpotAgent.h +1 -1
  89. hikyuu/include/hikyuu/global/SpotRecord.h +15 -31
  90. hikyuu/include/hikyuu/global/agent/spot_generated.h +48 -232
  91. hikyuu/include/hikyuu/global/schedule/scheduler.h +1 -1
  92. hikyuu/include/hikyuu/indicator/Indicator.h +37 -0
  93. hikyuu/include/hikyuu/lang.h +27 -0
  94. hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +9 -1
  95. hikyuu/include/hikyuu/plugin/dataserver.h +26 -1
  96. hikyuu/include/hikyuu/plugin/device.h +2 -1
  97. hikyuu/include/hikyuu/plugin/hkuextra.h +56 -0
  98. hikyuu/include/hikyuu/plugin/interface/DataDriverPluginInterface.h +27 -0
  99. hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +2 -1
  100. hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +1 -1
  101. hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +38 -0
  102. hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +13 -1
  103. hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
  104. hikyuu/include/hikyuu/python/pybind_utils.h +9 -0
  105. hikyuu/include/hikyuu/strategy/Strategy.h +0 -9
  106. hikyuu/include/hikyuu/trade_manage/TradeRecord.h +1 -1
  107. hikyuu/include/hikyuu/utilities/config.h +0 -2
  108. hikyuu/include/hikyuu/utilities/os.h +9 -0
  109. hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +2 -1
  110. hikyuu/include/hikyuu/version.h +4 -4
  111. hikyuu/include/hikyuu/view/MarketView.h +59 -0
  112. hikyuu/indicator/__init__.py +0 -1
  113. hikyuu/indicator/indicator.py +14 -53
  114. hikyuu/plugin/backtest.dll +0 -0
  115. hikyuu/plugin/clickhousedriver.dll +0 -0
  116. hikyuu/plugin/dataserver.dll +0 -0
  117. hikyuu/plugin/device.dll +0 -0
  118. hikyuu/plugin/extind.dll +0 -0
  119. hikyuu/plugin/hkuextra.dll +0 -0
  120. hikyuu/plugin/import2hdf5.dll +0 -0
  121. hikyuu/plugin/tmreport.dll +0 -0
  122. hikyuu/test/test_init.py +59 -0
  123. hikyuu/test/test_real_tdx_import.py +336 -0
  124. hikyuu/test/test_tdx_import.py +315 -0
  125. hikyuu/test/test_tdx_real_data_import.py +281 -0
  126. hikyuu/trade_manage/__init__.pyi +479 -471
  127. hikyuu/trade_manage/trade.py +4 -65
  128. hikyuu/trade_manage/trade.pyi +479 -483
  129. hikyuu/trade_sys/__init__.py +11 -0
  130. hikyuu/util/__init__.py +1 -0
  131. hikyuu/util/__init__.pyi +4 -4
  132. hikyuu/util/check.py +8 -0
  133. hikyuu/util/check.pyi +5 -1
  134. hikyuu/util/singleton.pyi +1 -1
  135. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/METADATA +7 -5
  136. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/RECORD +142 -124
  137. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/top_level.txt +4 -3
  138. hikyuu/include/hikyuu/global/agent/hikyuu/flat/__init__.py +0 -1
  139. hikyuu/include/hikyuu/utilities/mo/__init__.py +0 -1
  140. hikyuu/include/hikyuu/utilities/mo/mo.h +0 -48
  141. hikyuu/indicator/talib_wrap.py +0 -1273
  142. /hikyuu/include/hikyuu/utilities/{mo/moFileReader.h → moFileReader.h} +0 -0
  143. /hikyuu/include/hikyuu/{global/agent/hikyuu → view}/__init__.py +0 -0
  144. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/LICENSE +0 -0
  145. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/WHEEL +0 -0
  146. {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/entry_points.txt +0 -0
@@ -48,6 +48,12 @@ from hikyuu.data.common_mysql import create_database as mysql_create_database
48
48
  from hikyuu.data.common_mysql import import_new_holidays as mysql_import_new_holidays
49
49
  from hikyuu.data.pytdx_to_mysql import import_index_name as mysql_import_index_name
50
50
  from hikyuu.data.pytdx_to_mysql import import_stock_name as mysql_import_stock_name
51
+
52
+ from hikyuu.data.common_clickhouse import create_database as clickhouse_create_database
53
+ from hikyuu.data.common_clickhouse import import_new_holidays as clickhouse_import_new_holidays
54
+ from hikyuu.data.pytdx_to_clickhouse import import_index_name as clickhouse_import_index_name
55
+ from hikyuu.data.pytdx_to_clickhouse import import_stock_name as clickhouse_import_stock_name
56
+
51
57
  from hikyuu.util.mylog import class_logger
52
58
 
53
59
 
@@ -140,6 +146,32 @@ class UsePytdxImportToH5Thread(QThread):
140
146
  cur_host = 0
141
147
 
142
148
  # 以下按数据量从大到小依次使用速度从高到低的TDX服务器
149
+ if self.config.getboolean('ktype', 'min5', fallback=False):
150
+ start_date = datetime.datetime.strptime(
151
+ config['ktype']['min5_start_date'], '%Y-%m-%d').date()
152
+ for market in g_market_list:
153
+ self.tasks.append(
154
+ ImportPytdxToH5(
155
+ self.log_queue, self.queue, self.config, market,
156
+ '5MIN', self.quotations, use_hosts[cur_host][0],
157
+ use_hosts[cur_host][1], dest_dir,
158
+ start_date.year * 100000000 +
159
+ start_date.month * 1000000 + start_date.day * 10000))
160
+ cur_host += 1
161
+
162
+ if self.config.getboolean('ktype', 'day', fallback=False):
163
+ start_date = datetime.datetime.strptime(
164
+ config['ktype']['day_start_date'], '%Y-%m-%d').date()
165
+ for market in g_market_list:
166
+ self.tasks.append(
167
+ ImportPytdxToH5(
168
+ self.log_queue, self.queue, self.config, market, 'DAY',
169
+ self.quotations, use_hosts[cur_host][0],
170
+ use_hosts[cur_host][1], dest_dir,
171
+ start_date.year * 100000000 +
172
+ start_date.month * 1000000 + start_date.day * 10000))
173
+ cur_host += 1
174
+
143
175
  if self.config.getboolean('ktype', 'trans', fallback=False):
144
176
  today = datetime.date.today()
145
177
  trans_start_date = datetime.datetime.strptime(
@@ -182,32 +214,6 @@ class UsePytdxImportToH5Thread(QThread):
182
214
  time_max_days))
183
215
  cur_host += 1
184
216
 
185
- if self.config.getboolean('ktype', 'min5', fallback=False):
186
- start_date = datetime.datetime.strptime(
187
- config['ktype']['min5_start_date'], '%Y-%m-%d').date()
188
- for market in g_market_list:
189
- self.tasks.append(
190
- ImportPytdxToH5(
191
- self.log_queue, self.queue, self.config, market,
192
- '5MIN', self.quotations, use_hosts[cur_host][0],
193
- use_hosts[cur_host][1], dest_dir,
194
- start_date.year * 100000000 +
195
- start_date.month * 1000000 + start_date.day * 10000))
196
- cur_host += 1
197
-
198
- if self.config.getboolean('ktype', 'day', fallback=False):
199
- start_date = datetime.datetime.strptime(
200
- config['ktype']['day_start_date'], '%Y-%m-%d').date()
201
- for market in g_market_list:
202
- self.tasks.append(
203
- ImportPytdxToH5(
204
- self.log_queue, self.queue, self.config, market, 'DAY',
205
- self.quotations, use_hosts[cur_host][0],
206
- use_hosts[cur_host][1], dest_dir,
207
- start_date.year * 100000000 +
208
- start_date.month * 1000000 + start_date.day * 10000))
209
- cur_host += 1
210
-
211
217
  if self.config.getboolean('weight', 'enable', fallback=False):
212
218
  for market in g_market_list:
213
219
  self.tasks.append(
@@ -265,6 +271,19 @@ class UsePytdxImportToH5Thread(QThread):
265
271
  import_new_holidays = mysql_import_new_holidays
266
272
  import_index_name = mysql_import_index_name
267
273
  import_stock_name = mysql_import_stock_name
274
+ elif self.config.getboolean('clickhouse', 'enable', fallback=True):
275
+ db_config = {
276
+ 'username': self.config['clickhouse']['usr'],
277
+ 'password': self.config['clickhouse']['pwd'],
278
+ 'host': self.config['clickhouse']['host'],
279
+ 'port': self.config['clickhouse']['http_port']
280
+ }
281
+ import clickhouse_connect
282
+ connect = clickhouse_connect.get_client(**db_config)
283
+ create_database = clickhouse_create_database
284
+ import_new_holidays = clickhouse_import_new_holidays
285
+ import_index_name = clickhouse_import_index_name
286
+ import_stock_name = clickhouse_import_stock_name
268
287
 
269
288
  create_database(connect)
270
289
 
@@ -47,6 +47,10 @@ from hikyuu.data.common_mysql import create_database as mysql_create_database
47
47
  from hikyuu.data.common_mysql import import_new_holidays as mysql_import_new_holidays
48
48
  from hikyuu.data.pytdx_to_mysql import import_index_name as mysql_import_index_name
49
49
  from hikyuu.data.pytdx_to_mysql import import_stock_name as mysql_import_stock_name
50
+ from hikyuu.data.common_clickhouse import create_database as clickhouse_create_database
51
+ from hikyuu.data.common_clickhouse import import_new_holidays as clickhouse_import_new_holidays
52
+ from hikyuu.data.pytdx_to_clickhouse import import_index_name as clickhouse_import_index_name
53
+ from hikyuu.data.pytdx_to_clickhouse import import_stock_name as clickhouse_import_stock_name
50
54
  from hikyuu.util.mylog import class_logger
51
55
 
52
56
 
@@ -218,7 +222,7 @@ class UseTdxImportToH5Thread(QThread):
218
222
  import_new_holidays = sqlite_import_new_holidays
219
223
  import_index_name = sqlite_import_index_name
220
224
  import_stock_name = sqlite_import_stock_name
221
- else:
225
+ elif self.config.getboolean('mysql', 'enable', fallback=True):
222
226
  db_config = {
223
227
  'user': self.config['mysql']['usr'],
224
228
  'password': self.config['mysql']['pwd'],
@@ -231,6 +235,20 @@ class UseTdxImportToH5Thread(QThread):
231
235
  import_index_name = mysql_import_index_name
232
236
  import_stock_name = mysql_import_stock_name
233
237
 
238
+ elif self.config.getboolean('clickhouse', 'enable', fallback=True):
239
+ db_config = {
240
+ 'username': self.config['clickhouse']['usr'],
241
+ 'password': self.config['clickhouse']['pwd'],
242
+ 'host': self.config['clickhouse']['host'],
243
+ 'port': self.config['clickhouse']['http_port']
244
+ }
245
+ import clickhouse_connect
246
+ connect = clickhouse_connect.get_client(**db_config)
247
+ create_database = clickhouse_create_database
248
+ import_new_holidays = clickhouse_import_new_holidays
249
+ import_index_name = clickhouse_import_index_name
250
+ import_stock_name = clickhouse_import_stock_name
251
+
234
252
  create_database(connect)
235
253
 
236
254
  pytdx_api = TdxHq_API()
hikyuu/gui/dataserver.py CHANGED
@@ -7,13 +7,17 @@
7
7
  from hikyuu import start_data_server, stop_data_server
8
8
  import time
9
9
  import sys
10
+ import click
10
11
 
11
- if __name__ == "__main__":
12
- data_server_addr = "tcp://0.0.0.0:9201" if len(sys.argv) <= 1 else sys.argv[1]
13
- work_num = 2 if len(sys.argv) <= 2 else int(sys.argv[2])
14
12
 
13
+ @click.command()
14
+ @click.option('--addr', '-addr', default="tcp://127.0.0.1:9201", help='行情接收处理服务地址')
15
+ @click.option('--work_num', '-n', default=2, type=int, help='行情接收处理线程数')
16
+ @click.option('--save', '-save', default=False, type=bool, help='保存行情数据(仅支持clickhouse)')
17
+ @click.option('--buf', '-buf', default=False, type=bool, help='缓存行情数据')
18
+ def main(addr, work_num, save, buf):
15
19
  try:
16
- start_data_server(data_server_addr, work_num)
20
+ start_data_server(addr, work_num, save_tick=save, buf_tick=buf)
17
21
 
18
22
  while True:
19
23
  try:
@@ -23,3 +27,7 @@ if __name__ == "__main__":
23
27
 
24
28
  finally:
25
29
  stop_data_server()
30
+
31
+
32
+ if __name__ == "__main__":
33
+ main()
hikyuu/gui/spot_server.py CHANGED
@@ -29,6 +29,26 @@ def create_fb_spot_record(builder, record):
29
29
  name = builder.CreateString(record['name'])
30
30
  datetime = builder.CreateString(str(record['datetime']))
31
31
 
32
+ builder.StartVector(8, len(record['bid']), 8) # 8 字节 = double
33
+ for value in reversed(record['bid']): # 必须逆序添加元素
34
+ builder.PrependFloat64(value)
35
+ bid = builder.EndVector(len(record['bid']))
36
+
37
+ builder.StartVector(8, len(record['bid_amount']), 8)
38
+ for value in reversed(record['bid_amount']):
39
+ builder.PrependFloat64(value)
40
+ bid_amount = builder.EndVector(len(record['bid_amount']))
41
+
42
+ builder.StartVector(8, len(record['ask']), 8)
43
+ for value in reversed(record['ask']):
44
+ builder.PrependFloat64(value)
45
+ ask = builder.EndVector(len(record['ask']))
46
+
47
+ builder.StartVector(8, len(record['ask_amount']), 8)
48
+ for value in reversed(record['ask_amount']):
49
+ builder.PrependFloat64(value)
50
+ ask_amount = builder.EndVector(len(record['ask_amount']))
51
+
32
52
  fb.SpotStart(builder)
33
53
  fb.SpotAddMarket(builder, market)
34
54
  fb.SpotAddCode(builder, code)
@@ -41,29 +61,15 @@ def create_fb_spot_record(builder, record):
41
61
  fb.SpotAddClose(builder, record['close'])
42
62
  fb.SpotAddAmount(builder, record['amount'])
43
63
  fb.SpotAddVolume(builder, record['volume'])
44
- fb.SpotAddBid1(builder, record['bid1'])
45
- fb.SpotAddBid1Amount(builder, record['bid1_amount'])
46
- fb.SpotAddBid2(builder, record['bid2'])
47
- fb.SpotAddBid2Amount(builder, record['bid2_amount'])
48
- fb.SpotAddBid3(builder, record['bid3'])
49
- fb.SpotAddBid3Amount(builder, record['bid3_amount'])
50
- fb.SpotAddBid4(builder, record['bid4'])
51
- fb.SpotAddBid4Amount(builder, record['bid4_amount'])
52
- fb.SpotAddBid5(builder, record['bid5'])
53
- fb.SpotAddBid5Amount(builder, record['bid5_amount'])
54
- fb.SpotAddAsk1(builder, record['ask1'])
55
- fb.SpotAddAsk1Amount(builder, record['ask1_amount'])
56
- fb.SpotAddAsk2(builder, record['ask2'])
57
- fb.SpotAddAsk2Amount(builder, record['ask2_amount'])
58
- fb.SpotAddAsk3(builder, record['ask3'])
59
- fb.SpotAddAsk3Amount(builder, record['ask3_amount'])
60
- fb.SpotAddAsk4(builder, record['ask4'])
61
- fb.SpotAddAsk4Amount(builder, record['ask4_amount'])
62
- fb.SpotAddAsk5(builder, record['ask5'])
63
- fb.SpotAddAsk5Amount(builder, record['ask5_amount'])
64
+
65
+ fb.SpotAddBid(builder, bid)
66
+ fb.SpotAddBidAmount(builder, bid_amount)
67
+ fb.SpotAddAsk(builder, ask)
68
+ fb.SpotAddAskAmount(builder, ask_amount)
64
69
  return fb.SpotEnd(builder)
65
70
 
66
71
 
72
+ @hku_catch(trace=True)
67
73
  def create_fb_spot(records):
68
74
  builder = flatbuffers.Builder(0)
69
75
  end = None
@@ -100,26 +106,10 @@ def print_spot(spot):
100
106
  print(spot.Close())
101
107
  print(spot.Amount())
102
108
  print(spot.volume())
103
- print(spot.Bid1())
104
- print(spot.Bid1Amount())
105
- print(spot.Bid2())
106
- print(spot.Bid2Amount())
107
- print(spot.Bid3())
108
- print(spot.Bid3Amount())
109
- print(spot.Bid4())
110
- print(spot.Bid4Amount())
111
- print(spot.Bid5())
112
- print(spot.Bid5Amount())
113
- print(spot.Ask1())
114
- print(spot.Ask1Amount())
115
- print(spot.Ask2())
116
- print(spot.Ask2Amount())
117
- print(spot.Ask3())
118
- print(spot.Ask3Amount())
119
- print(spot.Ask4())
120
- print(spot.Ask4Amount())
121
- print(spot.Ask5())
122
- print(spot.Ask5Amount())
109
+ print(spot.Bid())
110
+ print(spot.BidAmount())
111
+ print(spot.Ask())
112
+ print(spot.AskAmount())
123
113
 
124
114
 
125
115
  def print_spot_list(buf):
hikyuu/gui/start_qmt.py CHANGED
@@ -4,13 +4,14 @@
4
4
 
5
5
  from hikyuu.fetcher.stock.zh_stock_a_qmt import parse_one_result_qmt, get_spot
6
6
  from hikyuu.gui.spot_server import release_nng_senders, start_send_spot, end_send_spot, send_spot
7
+ from hikyuu.util import hku_info
7
8
 
8
9
 
9
10
  def callback(datas):
10
11
  records = []
11
12
  for stock_code, data in datas.items():
12
13
  records.append(parse_one_result_qmt(stock_code, data))
13
- # print(len(records))
14
+ hku_info(f"接收: {len(records)}")
14
15
 
15
16
  if records:
16
17
  start_send_spot()
@@ -38,6 +39,10 @@ if __name__ == "__main__":
38
39
  hku_param["datadir"] = ini.get('hikyuu', 'datadir')
39
40
  if ini.has_option('hikyuu', 'quotation_server'):
40
41
  hku_param["quotation_server"] = ini['hikyuu']['quotation_server']
42
+ if ini.has_option('hikyuu', 'plugindir'):
43
+ hku_param["plugindir"] = ini.get('hikyuu', 'plugindir')
44
+ else:
45
+ hku_param["plugindir"] = plugin_path
41
46
 
42
47
  # 不加载历史财务信息及权息数据
43
48
  hku_param["load_history_finance"] = False
@@ -75,7 +80,7 @@ if __name__ == "__main__":
75
80
  hku_info("waiting all data loaded ...")
76
81
  while not sm.data_ready:
77
82
  import time
78
- time.sleep(100)
83
+ time.sleep(1)
79
84
 
80
85
  stk_list = [s for s in sm if s.valid and s.type in (
81
86
  constant.STOCKTYPE_A, constant.STOCKTYPE_INDEX, constant.STOCKTYPE_ETF,
@@ -84,7 +89,19 @@ if __name__ == "__main__":
84
89
  hku_info("start xtquant")
85
90
  code_list = [f'{s.code}.{s.market}' for s in stk_list]
86
91
  from xtquant import xtdata
87
- xtdata.subscribe_whole_quote(code_list, callback)
92
+ import time
93
+ # xtdata.subscribe_whole_quote(['SH', 'SZ', 'BJ'], callback)
94
+ batch_size = 250
95
+ n = len(code_list) // batch_size
96
+ for i in range(n):
97
+ codes = code_list[i * batch_size: (i + 1) * batch_size]
98
+ v = xtdata.subscribe_whole_quote(codes, callback)
99
+ hku_info_if(v < 0, "订阅失败")
100
+ time.sleep(0.5)
101
+ codes = code_list[n * batch_size:]
102
+ if codes:
103
+ v = xtdata.subscribe_whole_quote(codes, callback)
104
+ hku_info_if(v < 0, "订阅失败")
88
105
 
89
106
  # 每日 9:30 时,主动读取行情一次,以便 hikyuu 生成当日首个分钟线
90
107
  while True:
hikyuu/hub.pyi CHANGED
@@ -28,11 +28,11 @@ import sys as sys
28
28
  import typing
29
29
  __all__: list = ['add_remote_hub', 'add_local_hub', 'update_hub', 'remove_hub', 'build_hub', 'help_part', 'get_part', 'get_part_list', 'get_hub_path', 'get_part_info', 'get_part_module', 'print_part_info', 'get_hub_name_list', 'get_part_name_list', 'get_current_hub', 'search_part']
30
30
  class ConfigModel(sqlalchemy.orm.decl_api.Base):
31
- __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x254a51cdc10; ConfigModel>
31
+ __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x2b0b2e13af0; ConfigModel>
32
32
  __table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_config', MetaData(), Column('id', Integer(), table=<hub_config>, primary_key=True, nullable=False, default=Sequence('config_id_seq', metadata=MetaData())), Column('key', String(), table=<hub_config>), Column('value', String(), table=<hub_config>), schema=None)
33
33
  __table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('key', String(), table=<hub_config>)))
34
34
  __tablename__: typing.ClassVar[str] = 'hub_config'
35
- _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.ConfigModel'> at 254a521fbd0>
35
+ _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.ConfigModel'> at 2b0b2e14ef0>
36
36
  def __init__(self, **kwargs):
37
37
  """
38
38
  A simple constructor that allows initialization from kwargs.
@@ -109,11 +109,11 @@ class HubManager:
109
109
  def print_part_info(self, name):
110
110
  ...
111
111
  class HubModel(sqlalchemy.orm.decl_api.Base):
112
- __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x254a5259280; HubModel>
112
+ __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x2b0b2e13c70; HubModel>
113
113
  __table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_repo', MetaData(), Column('id', Integer(), table=<hub_repo>, primary_key=True, nullable=False, default=Sequence('remote_id_seq', metadata=MetaData())), Column('name', String(), table=<hub_repo>), Column('hub_type', String(), table=<hub_repo>), Column('local_base', String(), table=<hub_repo>), Column('local', String(), table=<hub_repo>), Column('url', String(), table=<hub_repo>), Column('branch', String(), table=<hub_repo>), schema=None)
114
114
  __table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_repo>)))
115
115
  __tablename__: typing.ClassVar[str] = 'hub_repo'
116
- _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at 254a5254630>
116
+ _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.HubModel'> at 2b0b2e429a0>
117
117
  def __init__(self, **kwargs):
118
118
  """
119
119
  A simple constructor that allows initialization from kwargs.
@@ -146,11 +146,11 @@ class ModuleConflictError(Exception):
146
146
  def __str__(self):
147
147
  ...
148
148
  class PartModel(sqlalchemy.orm.decl_api.Base):
149
- __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x254a52671f0; PartModel>
149
+ __mapper__: typing.ClassVar[sqlalchemy.orm.mapper.Mapper] # value = <Mapper at 0x2b0b2e507c0; PartModel>
150
150
  __table__: typing.ClassVar[sqlalchemy.sql.schema.Table] # value = Table('hub_part', MetaData(), Column('id', Integer(), table=<hub_part>, primary_key=True, nullable=False, default=Sequence('part_id_seq', metadata=MetaData())), Column('hub_name', String(), table=<hub_part>), Column('part', String(), table=<hub_part>), Column('name', String(), table=<hub_part>), Column('author', String(), table=<hub_part>), Column('version', String(), table=<hub_part>), Column('doc', String(), table=<hub_part>), Column('module_name', String(), table=<hub_part>), Column('label', String(), table=<hub_part>), schema=None)
151
151
  __table_args__: typing.ClassVar[tuple] # value = (UniqueConstraint(Column('name', String(), table=<hub_part>)))
152
152
  __tablename__: typing.ClassVar[str] = 'hub_part'
153
- _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at 254a52660e0>
153
+ _sa_class_manager: typing.ClassVar[sqlalchemy.orm.instrumentation.ClassManager] # value = <ClassManager of <class 'hikyuu.hub.PartModel'> at 2b0b2e52400>
154
154
  def __init__(self, **kwargs):
155
155
  """
156
156
  A simple constructor that allows initialization from kwargs.
@@ -39,6 +39,8 @@
39
39
  #include "utilities/Null.h"
40
40
  #include "utilities/arithmetic.h"
41
41
  #include "utilities/SpendTimer.h"
42
+ #include "utilities/config.h"
43
+ #include "lang.h"
42
44
 
43
45
  #if HKU_SUPPORT_SERIALIZATION
44
46
  #include <boost/serialization/nvp.hpp>
@@ -26,56 +26,50 @@ public:
26
26
  INVALID = 2
27
27
  };
28
28
 
29
- /// 查询K线类型:日线/周线等
30
- /*enum KType {
31
- //notes: 如添加新类型,请注意按大小顺序添加,否则可能出错
32
- MIN = 0, ///<1分钟线
33
- MIN5 = 1, ///<5分钟线
34
- MIN15 = 2, ///<15分钟线
35
- MIN30 = 3, ///<30分钟线
36
- MIN60 = 4, ///<60分钟线
37
- DAY = 5, ///<日线
38
- WEEK = 6, ///<周线
39
- MONTH = 7, ///<月线
40
- QUARTER = 8, ///<季线
41
- HALFYEAR = 9, ///<半年线
42
- YEAR = 10, ///<年线
43
-
44
- //BTC扩展
45
- MIN3 = 11, ///<3分钟线
46
- HOUR2 = 12, ///<2小时线
47
- HOUR4 = 13, ///<4小时线
48
- HOUR6 = 14, ///<6小时线
49
- HOUR12 = 15, ///<12小时线
50
- INVALID_KTYPE = 16
51
- };*/
52
29
  typedef string KType;
53
30
 
31
+ // 基础K线类型
54
32
  static const string MIN;
55
33
  static const string MIN5;
56
34
  static const string MIN15;
57
35
  static const string MIN30;
58
36
  static const string MIN60;
37
+ static const string HOUR2;
59
38
  static const string DAY;
60
39
  static const string WEEK;
61
40
  static const string MONTH;
62
41
  static const string QUARTER;
63
42
  static const string HALFYEAR;
64
43
  static const string YEAR;
44
+
45
+ // 扩展K线类型
46
+ static const string DAY3;
47
+ static const string DAY5;
48
+ static const string DAY7;
65
49
  static const string MIN3;
66
- static const string HOUR2;
67
50
  static const string HOUR4;
68
51
  static const string HOUR6;
69
52
  static const string HOUR12;
70
53
  // static const string INVALID_KTYPE;
71
54
 
55
+ /** 判断指定的K线类型是否有效 */
56
+ static bool isValidKType(const string& ktype);
57
+
58
+ /** 判断是否为有效 ktype */
59
+ static bool isBaseKType(const string& ktype);
60
+
61
+ /** 判断是否为扩展 ktype */
62
+ static bool isExtraKType(const string& ktype);
63
+
72
64
  /** 获取所有的 KType */
73
- static const vector<KType>& getAllKType();
65
+ static vector<KType> getBaseKTypeList();
74
66
 
75
- static int32_t getKTypeInMin(KType);
67
+ /** 获取所有扩展 KType */
68
+ static vector<KType> getExtraKTypeList();
76
69
 
77
- /** 判断是否为有效 ktype */
78
- static bool isKType(const string& ktype);
70
+ static int32_t getKTypeInMin(const KType& ktype);
71
+
72
+ static int32_t getBaseKTypeInMin(const KType& ktype);
79
73
 
80
74
  /**
81
75
  * 复权类型
@@ -41,7 +41,7 @@ public:
41
41
  MarketInfo& operator=(const MarketInfo&) = default;
42
42
 
43
43
  MarketInfo(MarketInfo&&);
44
- MarketInfo& operator=(MarketInfo&&);
44
+ MarketInfo& operator=(MarketInfo&&) noexcept;
45
45
 
46
46
  /** 获取市场简称 */
47
47
  const string& market() const {
@@ -230,10 +230,10 @@ public:
230
230
  * 将K线数据做自身缓存
231
231
  * @note 一般不主动调用,谨慎
232
232
  */
233
- void loadKDataToBuffer(KQuery::KType);
233
+ void loadKDataToBuffer(KQuery::KType) const;
234
234
 
235
235
  /** 释放对应的K线缓存 */
236
- void releaseKDataBuffer(KQuery::KType);
236
+ void releaseKDataBuffer(KQuery::KType) const;
237
237
 
238
238
  /** 指定类型的K线数据是否被缓存 */
239
239
  bool isBuffer(KQuery::KType) const;
@@ -258,12 +258,19 @@ private:
258
258
  bool _getIndexRangeByIndex(const KQuery&, size_t& out_start, size_t& out_end) const;
259
259
 
260
260
  // 以下函数属于基础操作添加了读锁
261
- size_t _getCountFromBuffer(KQuery::KType ktype) const;
261
+ size_t _getCountFromBuffer(const KQuery::KType& ktype) const;
262
262
  KRecord _getKRecordFromBuffer(size_t pos, const KQuery::KType& ktype) const;
263
263
  KRecordList _getKRecordListFromBuffer(size_t start_ix, size_t end_ix,
264
264
  KQuery::KType ktype) const;
265
265
  bool _getIndexRangeByDateFromBuffer(const KQuery&, size_t&, size_t&) const;
266
266
 
267
+ KRecordList _getKRecordList(const KQuery& query) const;
268
+
269
+ // 仅供 StockManager 初始化时调用
270
+ void setPreload(vector<KQuery::KType>& preload_ktypes);
271
+
272
+ bool isPreload(KQuery::KType ktype) const;
273
+
267
274
  private:
268
275
  struct HKU_API Data;
269
276
  shared_ptr<Data> m_data;
@@ -295,6 +302,7 @@ struct HKU_API Stock::Data {
295
302
  double m_minTradeNumber;
296
303
  double m_maxTradeNumber;
297
304
 
305
+ std::unordered_set<string> m_ktype_preload; // 记录当前证券的K线数据是否需要预加载
298
306
  unordered_map<string, KRecordList*> pKData;
299
307
  unordered_map<string, std::shared_mutex*> pMutex;
300
308
 
@@ -338,6 +346,10 @@ inline bool Stock::operator!=(const Stock& stock) const {
338
346
  return !(*this == stock);
339
347
  }
340
348
 
349
+ inline bool Stock::isNull() const {
350
+ return !m_data || !m_kdataDriver;
351
+ }
352
+
341
353
  } // namespace hku
342
354
 
343
355
  namespace std {
@@ -22,8 +22,6 @@
22
22
 
23
23
  namespace hku {
24
24
 
25
- typedef vector<string> MarketList;
26
-
27
25
  /**
28
26
  * 证券信息统一管理类
29
27
  * @ingroup StockManage
@@ -126,8 +124,11 @@ public:
126
124
  */
127
125
  StockTypeInfo getStockTypeInfo(uint32_t type) const;
128
126
 
127
+ /** 获取所有证券类型信息 */
128
+ vector<StockTypeInfo> getStockTypeInfoList() const;
129
+
129
130
  /** 获取市场简称列表 */
130
- MarketList getAllMarket() const;
131
+ StringList getAllMarket() const;
131
132
 
132
133
  /**
133
134
  * 获取预定义的板块
@@ -253,6 +254,9 @@ public:
253
254
  template <typename PluginInterfaceT>
254
255
  PluginInterfaceT* getPlugin(const std::string& pluginname) noexcept;
255
256
 
257
+ /** 设置多语言支持路径(仅在初始化之前有效) */
258
+ void setLanguagePath(const std::string& path);
259
+
256
260
  public:
257
261
  typedef StockMapIterator const_iterator;
258
262
  const_iterator begin() const {
@@ -332,6 +336,7 @@ private:
332
336
  std::unique_ptr<ThreadPool> m_load_tg; // 异步数据加载辅助线程组
333
337
 
334
338
  PluginManager m_plugin_manager;
339
+ std::string m_i18n_path;
335
340
  };
336
341
 
337
342
  inline size_t StockManager::size() const {
@@ -396,6 +401,10 @@ inline PluginInterfaceT* StockManager::getPlugin(const std::string& pluginname)
396
401
  return m_plugin_manager.getPlugin<PluginInterfaceT>(pluginname);
397
402
  }
398
403
 
404
+ inline void StockManager::setLanguagePath(const std::string& path) {
405
+ m_i18n_path = path;
406
+ }
407
+
399
408
  } // namespace hku
400
409
 
401
410
  #endif /* STOCKMANAGER_H_ */
@@ -38,6 +38,12 @@ public:
38
38
  StockTypeInfo();
39
39
  StockTypeInfo(uint32_t, const string&, price_t, price_t, int, double, double);
40
40
 
41
+ StockTypeInfo(const StockTypeInfo&) = default;
42
+ StockTypeInfo& operator=(const StockTypeInfo&) = default;
43
+
44
+ StockTypeInfo(StockTypeInfo&&);
45
+ StockTypeInfo& operator=(StockTypeInfo&&) noexcept;
46
+
41
47
  /** 获取证券类型 */
42
48
  uint32_t type() const {
43
49
  return m_type;
@@ -19,19 +19,13 @@ namespace hku {
19
19
  */
20
20
  class HKU_API TransRecord {
21
21
  public:
22
- enum DIRECT {
23
- BUY = 0, /**< 买盘 */
24
- SELL = 1, /**< 卖盘 */
25
- AUCTION = 2 /**< 集合竞价 */
26
- };
27
-
28
22
  Datetime datetime; // 时间
29
23
  price_t price; // 成交均价
30
24
  price_t vol; // 成交量
31
- DIRECT direct; // 买卖盘性质:1--sell 0--buy 2--集合竞价
25
+ int direct; // 买卖盘性质:1--sell 0--buy 2--集合竞价 其他未知
32
26
 
33
27
  TransRecord();
34
- TransRecord(const Datetime& datetime, price_t price, price_t vol, DIRECT);
28
+ TransRecord(const Datetime& datetime, price_t price, price_t vol, int direct);
35
29
 
36
30
  bool isValid() const;
37
31
  };
@@ -68,6 +68,7 @@ public:
68
68
  m_low = rhs.m_low;
69
69
  m_close = rhs.m_close;
70
70
  m_amount = rhs.m_amount;
71
+ m_count = rhs.m_count;
71
72
  }
72
73
  return *this;
73
74
  }
@@ -156,6 +156,10 @@
156
156
  *
157
157
  * @defgroup ThreadPool Thread Pool 线程池
158
158
  * @ingroup Utilities
159
+ *
160
+ * @defgroup View View数据视图
161
+ * 数据视图, 属于用于显示、打印数据
162
+ * @ingroup View
159
163
  */
160
164
 
161
165
  /**
@@ -26,7 +26,7 @@ void HKU_API startSpotAgent(bool print = true, size_t worker_num = 1,
26
26
  */
27
27
  void HKU_API stopSpotAgent();
28
28
 
29
- SpotAgent* getGlobalSpotAgent();
29
+ HKU_API SpotAgent* getGlobalSpotAgent();
30
30
 
31
31
  void HKU_API releaseGlobalSpotAgent();
32
32