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.
- hikyuu/__init__.py +16 -0
- hikyuu/__init__.pyi +484 -474
- hikyuu/analysis/__init__.pyi +466 -445
- hikyuu/analysis/analysis.pyi +467 -446
- hikyuu/core.pyi +468 -447
- 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 +1070 -878
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +1070 -878
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +1070 -878
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +1070 -876
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +1070 -878
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/cpp/i18n/__init__.py +0 -0
- hikyuu/cpp/i18n/zh_CN/__init__.py +0 -0
- hikyuu/cpp/i18n/zh_CN/hikyuu.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_clickhouse.py +465 -0
- hikyuu/data/em_block_to_clickhouse.py +120 -0
- hikyuu/data/hku_config_template.py +58 -3
- hikyuu/data/pytdx_finance_to_clickhouse.py +107 -0
- hikyuu/data/pytdx_to_clickhouse.py +841 -0
- hikyuu/data/pytdx_to_mysql.py +4 -4
- hikyuu/data/pytdx_weight_to_clickhouse.py +191 -0
- hikyuu/data/tdx_to_clickhouse.py +448 -0
- hikyuu/data/tdx_to_h5.py +1 -1
- hikyuu/data/zh_bond10_to_clickhouse.py +49 -0
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/bokeh_draw.pyi +479 -471
- hikyuu/draw/drawplot/echarts_draw.py +9 -8
- hikyuu/draw/drawplot/echarts_draw.pyi +479 -471
- hikyuu/draw/drawplot/matplotlib_draw.py +3 -3
- hikyuu/draw/drawplot/matplotlib_draw.pyi +479 -471
- hikyuu/draw/elder.pyi +6 -6
- hikyuu/draw/kaufman.py +1 -1
- hikyuu/draw/kaufman.pyi +10 -10
- hikyuu/draw/volume.pyi +5 -5
- hikyuu/examples/notebook/000-Index.ipynb +1 -1
- hikyuu/examples/notebook/001-overview.ipynb +78 -63
- hikyuu/examples/notebook/002-HowToGetStock.ipynb +259 -40
- hikyuu/examples/notebook/003-HowToGetKDataAndDraw.ipynb +49 -41
- hikyuu/examples/notebook/004-IndicatorOverview.ipynb +29 -29
- hikyuu/examples/notebook/005-Drawplot.ipynb +66 -37
- hikyuu/examples/notebook/006-TradeManager.ipynb +808 -61
- hikyuu/examples/notebook/007-SystemDetails.ipynb +23 -23
- hikyuu/examples/notebook/009-RealData.ipynb +3 -3
- hikyuu/examples/notebook/010-Portfolio.ipynb +761 -122
- hikyuu/extend.py +15 -100
- hikyuu/extend.pyi +478 -493
- hikyuu/fetcher/stock/zh_stock_a_pytdx.py +9 -20
- 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 +134 -7
- hikyuu/gui/data/ImportBlockInfoTask.py +11 -0
- hikyuu/gui/data/ImportHistoryFinanceTask.py +15 -1
- hikyuu/gui/data/ImportPytdxTimeToH5Task.py +11 -1
- hikyuu/gui/data/ImportPytdxToH5Task.py +13 -1
- hikyuu/gui/data/ImportPytdxTransToH5Task.py +11 -1
- hikyuu/gui/data/ImportTdxToH5Task.py +13 -1
- hikyuu/gui/data/ImportWeightToSqliteTask.py +14 -1
- hikyuu/gui/data/ImportZhBond10Task.py +11 -0
- hikyuu/gui/data/MainWindow.py +210 -135
- hikyuu/gui/data/UsePytdxImportToH5Thread.py +45 -26
- hikyuu/gui/data/UseTdxImportToH5Thread.py +19 -1
- 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 +2 -0
- hikyuu/include/hikyuu/KQuery.h +22 -28
- hikyuu/include/hikyuu/MarketInfo.h +1 -1
- hikyuu/include/hikyuu/Stock.h +15 -3
- hikyuu/include/hikyuu/StockManager.h +12 -3
- hikyuu/include/hikyuu/StockTypeInfo.h +6 -0
- hikyuu/include/hikyuu/TransRecord.h +2 -8
- hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +1 -0
- hikyuu/include/hikyuu/doc.h +4 -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/Indicator.h +37 -0
- hikyuu/include/hikyuu/lang.h +27 -0
- hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +9 -1
- hikyuu/include/hikyuu/plugin/dataserver.h +26 -1
- hikyuu/include/hikyuu/plugin/device.h +2 -1
- hikyuu/include/hikyuu/plugin/hkuextra.h +56 -0
- 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 +1 -1
- hikyuu/include/hikyuu/plugin/interface/HkuExtraPluginInterface.h +38 -0
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +13 -1
- hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
- hikyuu/include/hikyuu/python/pybind_utils.h +9 -0
- hikyuu/include/hikyuu/strategy/Strategy.h +0 -9
- hikyuu/include/hikyuu/trade_manage/TradeRecord.h +1 -1
- hikyuu/include/hikyuu/utilities/config.h +0 -2
- hikyuu/include/hikyuu/utilities/os.h +9 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +2 -1
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/include/hikyuu/view/MarketView.h +59 -0
- hikyuu/indicator/__init__.py +0 -1
- hikyuu/indicator/indicator.py +14 -53
- 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/hkuextra.dll +0 -0
- hikyuu/plugin/import2hdf5.dll +0 -0
- hikyuu/plugin/tmreport.dll +0 -0
- hikyuu/test/test_init.py +59 -0
- hikyuu/test/test_real_tdx_import.py +336 -0
- hikyuu/test/test_tdx_import.py +315 -0
- hikyuu/test/test_tdx_real_data_import.py +281 -0
- hikyuu/trade_manage/__init__.pyi +479 -471
- hikyuu/trade_manage/trade.py +4 -65
- hikyuu/trade_manage/trade.pyi +479 -483
- hikyuu/trade_sys/__init__.py +11 -0
- hikyuu/util/__init__.py +1 -0
- hikyuu/util/__init__.pyi +4 -4
- hikyuu/util/check.py +8 -0
- hikyuu/util/check.pyi +5 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/METADATA +7 -5
- {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/RECORD +142 -124
- {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/top_level.txt +4 -3
- hikyuu/include/hikyuu/global/agent/hikyuu/flat/__init__.py +0 -1
- hikyuu/include/hikyuu/utilities/mo/__init__.py +0 -1
- hikyuu/include/hikyuu/utilities/mo/mo.h +0 -48
- hikyuu/indicator/talib_wrap.py +0 -1273
- /hikyuu/include/hikyuu/utilities/{mo/moFileReader.h → moFileReader.h} +0 -0
- /hikyuu/include/hikyuu/{global/agent/hikyuu → view}/__init__.py +0 -0
- {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/LICENSE +0 -0
- {hikyuu-2.6.5.dist-info → hikyuu-2.6.7.dist-info}/WHEEL +0 -0
- {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
|
-
|
|
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(
|
|
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
|
-
|
|
45
|
-
fb.
|
|
46
|
-
fb.
|
|
47
|
-
fb.
|
|
48
|
-
fb.
|
|
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.
|
|
104
|
-
print(spot.
|
|
105
|
-
print(spot.
|
|
106
|
-
print(spot.
|
|
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
|
-
|
|
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(
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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.
|
hikyuu/include/hikyuu/DataType.h
CHANGED
hikyuu/include/hikyuu/KQuery.h
CHANGED
|
@@ -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
|
|
65
|
+
static vector<KType> getBaseKTypeList();
|
|
74
66
|
|
|
75
|
-
|
|
67
|
+
/** 获取所有扩展 KType */
|
|
68
|
+
static vector<KType> getExtraKTypeList();
|
|
76
69
|
|
|
77
|
-
|
|
78
|
-
|
|
70
|
+
static int32_t getKTypeInMin(const KType& ktype);
|
|
71
|
+
|
|
72
|
+
static int32_t getBaseKTypeInMin(const KType& ktype);
|
|
79
73
|
|
|
80
74
|
/**
|
|
81
75
|
* 复权类型
|
hikyuu/include/hikyuu/Stock.h
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
25
|
+
int direct; // 买卖盘性质:1--sell 0--buy 2--集合竞价 其他未知
|
|
32
26
|
|
|
33
27
|
TransRecord();
|
|
34
|
-
TransRecord(const Datetime& datetime, price_t price, price_t vol,
|
|
28
|
+
TransRecord(const Datetime& datetime, price_t price, price_t vol, int direct);
|
|
35
29
|
|
|
36
30
|
bool isValid() const;
|
|
37
31
|
};
|
hikyuu/include/hikyuu/doc.h
CHANGED