hikyuu 2.6.3__py3-none-win_amd64.whl → 2.6.6__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- hikyuu/__init__.py +6 -0
- hikyuu/__init__.pyi +548 -546
- hikyuu/analysis/__init__.pyi +519 -514
- hikyuu/analysis/analysis.pyi +520 -515
- hikyuu/core.pyi +521 -516
- hikyuu/cpp/__init__.pyi +2 -2
- hikyuu/cpp/boost_date_time-mt.dll +0 -0
- hikyuu/cpp/boost_serialization-mt.dll +0 -0
- hikyuu/cpp/boost_wserialization-mt.dll +0 -0
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +167 -36
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +167 -36
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +167 -36
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +167 -36
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +167 -36
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/cpp/i18n/__init__.py +0 -0
- hikyuu/cpp/i18n/zh_CN.mo +0 -0
- hikyuu/cpp/sqlite3.dll +0 -0
- hikyuu/data/clickhouse_upgrade/__init__.py +1 -0
- hikyuu/data/clickhouse_upgrade/createdb.sql +1085 -0
- hikyuu/data/common.py +1 -1
- hikyuu/data/common_clickhouse.py +512 -0
- hikyuu/data/common_mysql.py +19 -0
- hikyuu/data/common_pytdx.py +2 -0
- hikyuu/data/common_sqlite3.py +1 -0
- hikyuu/data/em_block_to_clickhouse.py +120 -0
- hikyuu/data/hku_config_template.py +70 -1
- hikyuu/data/mysql_upgrade/0028.sql +95 -0
- hikyuu/data/pytdx_finance_to_clickhouse.py +107 -0
- hikyuu/data/pytdx_to_clickhouse.py +841 -0
- hikyuu/data/pytdx_to_h5.py +53 -13
- hikyuu/data/pytdx_to_mysql.py +42 -9
- hikyuu/data/pytdx_to_taos.py +736 -0
- hikyuu/data/pytdx_weight_to_clickhouse.py +191 -0
- hikyuu/data/sqlite_upgrade/0028.sql +97 -0
- hikyuu/data/tdx_to_clickhouse.py +448 -0
- hikyuu/data/zh_bond10_to_clickhouse.py +49 -0
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/__init__.pyi +8 -8
- hikyuu/draw/drawplot/bokeh_draw.pyi +538 -536
- hikyuu/draw/drawplot/common.pyi +1 -1
- hikyuu/draw/drawplot/echarts_draw.pyi +540 -538
- hikyuu/draw/drawplot/matplotlib_draw.py +7 -7
- hikyuu/draw/drawplot/matplotlib_draw.pyi +550 -548
- hikyuu/draw/elder.pyi +11 -11
- hikyuu/draw/kaufman.pyi +18 -18
- hikyuu/draw/volume.pyi +10 -10
- hikyuu/examples/notebook/001-overview.ipynb +65 -100
- hikyuu/examples/notebook/004-IndicatorOverview.ipynb +34 -32
- hikyuu/examples/notebook/007-SystemDetails.ipynb +64 -50
- hikyuu/examples/notebook/010-Portfolio.ipynb +120 -124
- hikyuu/extend.py +1 -1
- hikyuu/extend.pyi +527 -527
- hikyuu/fetcher/stock/zh_block_em.py +349 -5
- hikyuu/fetcher/stock/zh_stock_a_pytdx.py +11 -21
- hikyuu/fetcher/stock/zh_stock_a_qmt.py +4 -5
- hikyuu/fetcher/stock/zh_stock_a_sina_qq.py +16 -60
- hikyuu/flat/Spot.py +96 -200
- hikyuu/gui/HikyuuTDX.py +175 -23
- hikyuu/gui/data/ImportBlockInfoTask.py +12 -1
- hikyuu/gui/data/ImportHistoryFinanceTask.py +62 -44
- hikyuu/gui/data/ImportPytdxTimeToH5Task.py +14 -2
- hikyuu/gui/data/ImportPytdxToH5Task.py +17 -3
- hikyuu/gui/data/ImportPytdxTransToH5Task.py +14 -2
- hikyuu/gui/data/ImportTdxToH5Task.py +13 -1
- hikyuu/gui/data/ImportWeightToSqliteTask.py +16 -2
- hikyuu/gui/data/ImportZhBond10Task.py +12 -1
- hikyuu/gui/data/MainWindow.py +191 -110
- hikyuu/gui/data/UsePytdxImportToH5Thread.py +52 -29
- hikyuu/gui/data/UseQmtImportToH5Thread.py +1 -0
- hikyuu/gui/data/UseTdxImportToH5Thread.py +21 -2
- hikyuu/gui/dataserver.py +12 -4
- hikyuu/gui/spot_server.py +30 -40
- hikyuu/gui/start_qmt.py +20 -3
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/DataType.h +11 -0
- hikyuu/include/hikyuu/MarketInfo.h +6 -0
- hikyuu/include/hikyuu/StockManager.h +8 -0
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +35 -0
- hikyuu/include/hikyuu/data_driver/kdata/mysql/KRecordTable.h +1 -0
- hikyuu/include/hikyuu/global/GlobalSpotAgent.h +1 -1
- hikyuu/include/hikyuu/global/SpotRecord.h +15 -31
- hikyuu/include/hikyuu/global/agent/spot_generated.h +48 -232
- hikyuu/include/hikyuu/global/schedule/scheduler.h +1 -1
- hikyuu/include/hikyuu/indicator/build_in.h +1 -0
- hikyuu/include/hikyuu/indicator/crt/BARSLASTCOUNT.h +33 -0
- hikyuu/include/hikyuu/indicator/imp/IBarsLastCount.h +27 -0
- hikyuu/include/hikyuu/plugin/KDataToHdf5Importer.h +3 -0
- hikyuu/include/hikyuu/plugin/backtest.h +2 -2
- hikyuu/include/hikyuu/plugin/dataserver.h +26 -1
- hikyuu/include/hikyuu/plugin/device.h +8 -4
- hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +1 -1
- hikyuu/include/hikyuu/plugin/interface/DataDriverPluginInterface.h +27 -0
- hikyuu/include/hikyuu/plugin/interface/DataServerPluginInterface.h +2 -1
- hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +2 -1
- hikyuu/include/hikyuu/plugin/interface/ImportKDataToHdf5PluginInterface.h +3 -0
- hikyuu/include/hikyuu/plugin/interface/TMReportPluginInterface.h +80 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
- hikyuu/include/hikyuu/strategy/Strategy.h +0 -9
- hikyuu/include/hikyuu/trade_manage/Performance.h +17 -9
- hikyuu/include/hikyuu/trade_manage/PositionExtInfo.h +92 -0
- hikyuu/include/hikyuu/trade_manage/PositionRecord.h +7 -1
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +60 -1
- hikyuu/include/hikyuu/trade_sys/selector/crt/SE_Optimal.h +8 -0
- hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalEvaluateSelector.h +28 -0
- hikyuu/include/hikyuu/trade_sys/selector/imp/optimal/OptimalSelectorBase.h +1 -0
- hikyuu/include/hikyuu/utilities/DllLoader.h +226 -0
- hikyuu/include/hikyuu/utilities/config.h +1 -1
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +20 -0
- hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +6 -0
- hikyuu/include/hikyuu/utilities/mo/mo.h +30 -14
- hikyuu/include/hikyuu/utilities/os.h +6 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +10 -10
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +13 -7
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +13 -6
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/plugin/backtest.dll +0 -0
- hikyuu/plugin/clickhousedriver.dll +0 -0
- hikyuu/plugin/dataserver.dll +0 -0
- hikyuu/plugin/device.dll +0 -0
- hikyuu/plugin/extind.dll +0 -0
- hikyuu/plugin/import2hdf5.dll +0 -0
- hikyuu/plugin/tmreport.dll +0 -0
- hikyuu/trade_manage/__init__.pyi +537 -535
- hikyuu/trade_manage/broker.pyi +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +1 -1
- hikyuu/trade_manage/trade.pyi +537 -535
- hikyuu/util/__init__.py +1 -0
- hikyuu/util/__init__.pyi +4 -3
- hikyuu/util/check.py +8 -0
- hikyuu/util/check.pyi +5 -1
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/METADATA +4 -3
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/RECORD +144 -123
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/top_level.txt +2 -2
- hikyuu/include/hikyuu/global/agent/hikyuu/__init__.py +0 -1
- hikyuu/include/hikyuu/global/agent/hikyuu/flat/__init__.py +0 -1
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/LICENSE +0 -0
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/WHEEL +0 -0
- {hikyuu-2.6.3.dist-info → hikyuu-2.6.6.dist-info}/entry_points.txt +0 -0
hikyuu/gui/HikyuuTDX.py
CHANGED
|
@@ -22,6 +22,8 @@ import mysql.connector
|
|
|
22
22
|
from mysql.connector import errorcode
|
|
23
23
|
from mysql.connector.locales.eng import client_error # 此句仅为pyinstaller打包时能够自动引入
|
|
24
24
|
|
|
25
|
+
import clickhouse_connect
|
|
26
|
+
|
|
25
27
|
from hikyuu.gui.data.MainWindow import *
|
|
26
28
|
from hikyuu.gui.data.EscapetimeThread import EscapetimeThread
|
|
27
29
|
from hikyuu.gui.data.UseTdxImportToH5Thread import UseTdxImportToH5Thread
|
|
@@ -34,7 +36,7 @@ from hikyuu.gui.data.CollectSpotThread import CollectSpotThread
|
|
|
34
36
|
from hikyuu.gui.data.SchedImportThread import SchedImportThread
|
|
35
37
|
from hikyuu.gui.spot_server import release_nng_senders
|
|
36
38
|
|
|
37
|
-
from hikyuu import can_upgrade, get_last_version, fetch_trial_license, view_license
|
|
39
|
+
from hikyuu import can_upgrade, get_last_version, fetch_trial_license, view_license, is_valid_license
|
|
38
40
|
from hikyuu.data import hku_config_template
|
|
39
41
|
from hikyuu.util import *
|
|
40
42
|
|
|
@@ -93,6 +95,7 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
93
95
|
def getHikyuuConfigFileName(self):
|
|
94
96
|
return self.getUserConfigDir() + '/hikyuu.ini'
|
|
95
97
|
|
|
98
|
+
@hku_catch()
|
|
96
99
|
def saveConfig(self):
|
|
97
100
|
if not os.path.lexists(self.getUserConfigDir()):
|
|
98
101
|
os.mkdir(self.getUserConfigDir())
|
|
@@ -105,7 +108,10 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
105
108
|
if current_config.getboolean('hdf5', 'enable', fallback=True):
|
|
106
109
|
data_dir = current_config['hdf5']['dir']
|
|
107
110
|
if not os.path.lexists(data_dir + '/tmp'):
|
|
108
|
-
|
|
111
|
+
try:
|
|
112
|
+
os.mkdir(data_dir + '/tmp')
|
|
113
|
+
except:
|
|
114
|
+
pass
|
|
109
115
|
# 此处不能使用 utf-8 参数,否则导致Windows下getBlock无法找到板块分类
|
|
110
116
|
with open(filename, 'w', encoding='utf-8') as f:
|
|
111
117
|
f.write(
|
|
@@ -140,8 +146,13 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
140
146
|
)
|
|
141
147
|
)
|
|
142
148
|
|
|
143
|
-
|
|
149
|
+
elif current_config.getboolean('mysql', 'enable', fallback=True):
|
|
144
150
|
data_dir = current_config['mysql']['tmpdir']
|
|
151
|
+
if not os.path.lexists(data_dir + '/tmp'):
|
|
152
|
+
try:
|
|
153
|
+
os.mkdir(data_dir + '/tmp')
|
|
154
|
+
except:
|
|
155
|
+
pass
|
|
145
156
|
with open(filename, 'w', encoding="utf-8") as f:
|
|
146
157
|
f.write(
|
|
147
158
|
hku_config_template.mysql_template.format(
|
|
@@ -178,16 +189,65 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
178
189
|
hour2_max=current_config.getint('preload', 'hour2_max', fallback=4096),
|
|
179
190
|
)
|
|
180
191
|
)
|
|
192
|
+
elif current_config.getboolean('clickhouse', 'enable', fallback=True):
|
|
193
|
+
data_dir = current_config['clickhouse']['tmpdir']
|
|
194
|
+
if not os.path.lexists(data_dir + '/tmp'):
|
|
195
|
+
try:
|
|
196
|
+
os.mkdir(data_dir + '/tmp')
|
|
197
|
+
except:
|
|
198
|
+
pass
|
|
199
|
+
with open(filename, 'w', encoding="utf-8") as f:
|
|
200
|
+
f.write(
|
|
201
|
+
hku_config_template.clickhouse_template.format(
|
|
202
|
+
dir=data_dir,
|
|
203
|
+
quotation_server=current_config.get(
|
|
204
|
+
'collect', 'quotation_server', fallback='ipc:///tmp/hikyuu_real.ipc'),
|
|
205
|
+
host=current_config['clickhouse']['host'],
|
|
206
|
+
port=current_config['clickhouse']['port'],
|
|
207
|
+
usr=current_config['clickhouse']['usr'],
|
|
208
|
+
pwd=current_config['clickhouse']['pwd'],
|
|
209
|
+
day=current_config.getboolean('preload', 'day', fallback=True),
|
|
210
|
+
week=current_config.getboolean('preload', 'week', fallback=False),
|
|
211
|
+
month=current_config.getboolean('preload', 'month', fallback=False),
|
|
212
|
+
quarter=current_config.getboolean('preload', 'quarter', fallback=False),
|
|
213
|
+
halfyear=current_config.getboolean('preload', 'halfyear', fallback=False),
|
|
214
|
+
year=current_config.getboolean('preload', 'year', fallback=False),
|
|
215
|
+
min1=current_config.getboolean('preload', 'min', fallback=False),
|
|
216
|
+
min5=current_config.getboolean('preload', 'min5', fallback=False),
|
|
217
|
+
min15=current_config.getboolean('preload', 'min15', fallback=False),
|
|
218
|
+
min30=current_config.getboolean('preload', 'min30', fallback=False),
|
|
219
|
+
min60=current_config.getboolean('preload', 'min60', fallback=False),
|
|
220
|
+
hour2=current_config.getboolean('preload', 'hour2', fallback=False),
|
|
221
|
+
day_max=current_config.getint('preload', 'day_max', fallback=100000),
|
|
222
|
+
week_max=current_config.getint('preload', 'week_max', fallback=100000),
|
|
223
|
+
month_max=current_config.getint('preload', 'month_max', fallback=100000),
|
|
224
|
+
quarter_max=current_config.getint('preload', 'quarter_max', fallback=100000),
|
|
225
|
+
halfyear_max=current_config.getint('preload', 'halfyear_max', fallback=100000),
|
|
226
|
+
year_max=current_config.getint('preload', 'year_max', fallback=100000),
|
|
227
|
+
min1_max=current_config.getint('preload', 'min_max', fallback=4096),
|
|
228
|
+
min5_max=current_config.getint('preload', 'min5_max', fallback=4096),
|
|
229
|
+
min15_max=current_config.getint('preload', 'min15_max', fallback=4096),
|
|
230
|
+
min30_max=current_config.getint('preload', 'min30_max', fallback=4096),
|
|
231
|
+
min60_max=current_config.getint('preload', 'min60_max', fallback=4096),
|
|
232
|
+
hour2_max=current_config.getint('preload', 'hour2_max', fallback=4096),
|
|
233
|
+
)
|
|
234
|
+
)
|
|
181
235
|
|
|
182
|
-
|
|
183
|
-
os.
|
|
236
|
+
try:
|
|
237
|
+
if not data_dir and not os.path.lexists(data_dir):
|
|
238
|
+
os.makedirs(data_dir)
|
|
239
|
+
except:
|
|
240
|
+
pass
|
|
184
241
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
242
|
+
try:
|
|
243
|
+
if not data_dir and not os.path.lexists(data_dir + '/block'):
|
|
244
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
245
|
+
dirname, _ = os.path.split(current_dir)
|
|
246
|
+
dirname = os.path.join(dirname, 'config/block')
|
|
247
|
+
shutil.copytree(dirname, data_dir + '/block')
|
|
248
|
+
os.remove(data_dir + '/block/__init__.py')
|
|
249
|
+
except:
|
|
250
|
+
pass
|
|
191
251
|
|
|
192
252
|
@pyqtSlot()
|
|
193
253
|
def on_save_pushButton_clicked(self):
|
|
@@ -267,6 +327,8 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
267
327
|
sys.stderr = self._stream
|
|
268
328
|
self.log_textEdit.document().setMaximumBlockCount(1000)
|
|
269
329
|
|
|
330
|
+
self.tabWidget.setCurrentIndex(0)
|
|
331
|
+
|
|
270
332
|
current_dir = os.path.dirname(__file__)
|
|
271
333
|
icon = QIcon(f"{current_dir}/images/hikyuu_small.png")
|
|
272
334
|
star_img = QPixmap(f"{current_dir}/images/star.png")
|
|
@@ -309,6 +371,8 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
309
371
|
|
|
310
372
|
# 初始化权息与财务数据设置
|
|
311
373
|
self.import_weight_checkBox.setChecked(import_config.getboolean('weight', 'enable', fallback=True))
|
|
374
|
+
self.import_history_finance_checkBox.setChecked(import_config.getboolean('finance', 'enable', fallback=True))
|
|
375
|
+
self.import_block_checkBox.setChecked(import_config.getboolean('block', 'enable', fallback=True))
|
|
312
376
|
|
|
313
377
|
# 初始化通道信目录配置
|
|
314
378
|
tdx_enable = import_config.getboolean('tdx', 'enable', fallback=False)
|
|
@@ -350,7 +414,8 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
350
414
|
if hdf5_enable:
|
|
351
415
|
mysql_enable = False
|
|
352
416
|
self.enable_mysql_radioButton.setChecked(mysql_enable)
|
|
353
|
-
self.mysql_tmpdir_lineEdit.setText(import_config.get('mysql', 'tmpdir', fallback='
|
|
417
|
+
self.mysql_tmpdir_lineEdit.setText(import_config.get('mysql', 'tmpdir', fallback='d:/stock'))
|
|
418
|
+
self.mysql_tmpdir_pushButton.setEnabled(mysql_enable)
|
|
354
419
|
mysql_ip = import_config.get('mysql', 'host', fallback='127.0.0.1')
|
|
355
420
|
self.mysql_ip_lineEdit.setText(mysql_ip)
|
|
356
421
|
self.mysql_ip_lineEdit.setEnabled(mysql_enable)
|
|
@@ -365,6 +430,30 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
365
430
|
self.mysql_pwd_lineEdit.setEnabled(mysql_enable)
|
|
366
431
|
self.mysql_test_pushButton.setEnabled(mysql_enable)
|
|
367
432
|
|
|
433
|
+
# 初始化clickhouse设置
|
|
434
|
+
clickhouse_enable = import_config.getboolean('clickhouse', 'enable', fallback=False)
|
|
435
|
+
if (not is_valid_license()) or hdf5_enable or mysql_enable:
|
|
436
|
+
clickhouse_enable = False
|
|
437
|
+
self.enable_clickhouse_radioButton.setChecked(clickhouse_enable)
|
|
438
|
+
self.clickhouse_tmpdir_lineEdit.setText(import_config.get('clickhouse', 'tmpdir', fallback='d:/stock'))
|
|
439
|
+
self.clickhouse_tmpdir_pushButton.setEnabled(clickhouse_enable)
|
|
440
|
+
clickhouse_ip = import_config.get('clickhouse', 'host', fallback='127.0.0.1')
|
|
441
|
+
self.clickhouse_ip_lineEdit.setText(clickhouse_ip)
|
|
442
|
+
self.clickhouse_ip_lineEdit.setEnabled(clickhouse_enable)
|
|
443
|
+
clickhouse_port = import_config.get('clickhouse', 'port', fallback='9000')
|
|
444
|
+
self.clickhouse_port_lineEdit.setText(clickhouse_port)
|
|
445
|
+
self.clickhouse_port_lineEdit.setEnabled(clickhouse_enable)
|
|
446
|
+
clickhouse_http_port = import_config.get('clickhouse', 'http_port', fallback='8123')
|
|
447
|
+
self.clickhouse_http_port_lineEdit.setText(clickhouse_http_port)
|
|
448
|
+
self.clickhouse_http_port_lineEdit.setEnabled(clickhouse_enable)
|
|
449
|
+
clickhouse_usr = import_config.get('clickhouse', 'usr', fallback='default')
|
|
450
|
+
self.clickhouse_usr_lineEdit.setText(clickhouse_usr)
|
|
451
|
+
self.clickhouse_usr_lineEdit.setEnabled(clickhouse_enable)
|
|
452
|
+
clickhouse_pwd = import_config.get('clickhouse', 'pwd', fallback='test')
|
|
453
|
+
self.clickhouse_pwd_lineEdit.setText(clickhouse_pwd)
|
|
454
|
+
self.clickhouse_pwd_lineEdit.setEnabled(clickhouse_enable)
|
|
455
|
+
self.clickhouse_test_pushButton.setEnabled(clickhouse_enable)
|
|
456
|
+
|
|
368
457
|
self.sched_import_timeEdit.setTime(
|
|
369
458
|
datetime.time.fromisoformat(import_config.get('schec', 'time', fallback='18:00'))
|
|
370
459
|
)
|
|
@@ -442,6 +531,12 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
442
531
|
import_config['weight'] = {
|
|
443
532
|
'enable': self.import_weight_checkBox.isChecked(),
|
|
444
533
|
}
|
|
534
|
+
import_config['finance'] = {
|
|
535
|
+
'enable': self.import_history_finance_checkBox.isChecked(),
|
|
536
|
+
}
|
|
537
|
+
import_config['block'] = {
|
|
538
|
+
'enable': self.import_block_checkBox.isChecked(),
|
|
539
|
+
}
|
|
445
540
|
import_config['tdx'] = {'enable': self.tdx_radioButton.isChecked(), 'dir': self.tdx_dir_lineEdit.text()}
|
|
446
541
|
import_config['pytdx'] = {
|
|
447
542
|
'enable': self.pytdx_radioButton.isChecked(),
|
|
@@ -460,6 +555,15 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
460
555
|
'usr': self.mysql_usr_lineEdit.text(),
|
|
461
556
|
'pwd': self.mysql_pwd_lineEdit.text()
|
|
462
557
|
}
|
|
558
|
+
import_config['clickhouse'] = {
|
|
559
|
+
'enable': is_valid_license() and self.enable_clickhouse_radioButton.isChecked(),
|
|
560
|
+
'tmpdir': self.clickhouse_tmpdir_lineEdit.text(),
|
|
561
|
+
'host': self.clickhouse_ip_lineEdit.text(),
|
|
562
|
+
'http_port': self.clickhouse_http_port_lineEdit.text(),
|
|
563
|
+
'port': self.clickhouse_port_lineEdit.text(),
|
|
564
|
+
'usr': self.clickhouse_usr_lineEdit.text(),
|
|
565
|
+
'pwd': self.clickhouse_pwd_lineEdit.text()
|
|
566
|
+
}
|
|
463
567
|
import_config['sched'] = {
|
|
464
568
|
'time': self.sched_import_timeEdit.time().toString(),
|
|
465
569
|
}
|
|
@@ -597,23 +701,38 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
597
701
|
def on_enable_hdf55_radioButton_clicked(self):
|
|
598
702
|
if self.enable_hdf55_radioButton.isChecked():
|
|
599
703
|
self.enable_mysql_radioButton.setChecked(False)
|
|
600
|
-
|
|
704
|
+
self.enable_clickhouse_radioButton.setChecked(False)
|
|
705
|
+
self.on_enable_database_toggled(hdf5=True, mysql=False, clickhouse=False)
|
|
601
706
|
|
|
602
707
|
@pyqtSlot()
|
|
603
708
|
def on_enable_mysql_radioButton_clicked(self):
|
|
604
709
|
if self.enable_mysql_radioButton.isChecked():
|
|
605
710
|
self.enable_hdf55_radioButton.setChecked(False)
|
|
606
|
-
|
|
711
|
+
self.enable_clickhouse_radioButton.setChecked(False)
|
|
712
|
+
self.on_enable_database_toggled(hdf5=False, mysql=True, clickhouse=False)
|
|
607
713
|
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
self.
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
self.
|
|
714
|
+
@pyqtSlot()
|
|
715
|
+
def on_enable_clickhouse_radioButton_clicked(self):
|
|
716
|
+
if self.enable_clickhouse_radioButton.isChecked():
|
|
717
|
+
self.enable_hdf55_radioButton.setChecked(False)
|
|
718
|
+
self.enable_mysql_radioButton.setChecked(False)
|
|
719
|
+
self.on_enable_database_toggled(hdf5=False, mysql=False, clickhouse=True)
|
|
720
|
+
|
|
721
|
+
def on_enable_database_toggled(self, hdf5, mysql, clickhouse):
|
|
722
|
+
self.hdf5_dir_lineEdit.setEnabled(hdf5)
|
|
723
|
+
self.mysql_ip_lineEdit.setEnabled(mysql)
|
|
724
|
+
self.mysql_port_lineEdit.setEnabled(mysql)
|
|
725
|
+
self.mysql_usr_lineEdit.setEnabled(mysql)
|
|
726
|
+
self.mysql_pwd_lineEdit.setEnabled(mysql)
|
|
727
|
+
self.mysql_test_pushButton.setEnabled(mysql)
|
|
728
|
+
self.mysql_tmpdir_pushButton.setEnabled(mysql)
|
|
729
|
+
self.clickhouse_ip_lineEdit.setEnabled(clickhouse)
|
|
730
|
+
self.clickhouse_http_port_lineEdit.setEnabled(clickhouse)
|
|
731
|
+
self.clickhouse_port_lineEdit.setEnabled(clickhouse)
|
|
732
|
+
self.clickhouse_usr_lineEdit.setEnabled(clickhouse)
|
|
733
|
+
self.clickhouse_pwd_lineEdit.setEnabled(clickhouse)
|
|
734
|
+
self.clickhouse_test_pushButton.setEnabled(clickhouse)
|
|
735
|
+
self.clickhouse_tmpdir_pushButton.setEnabled(clickhouse)
|
|
617
736
|
|
|
618
737
|
@pyqtSlot()
|
|
619
738
|
def on_mysql_tmpdir_pushButton_clicked(self):
|
|
@@ -625,6 +744,20 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
625
744
|
dirname = dlg.selectedFiles()
|
|
626
745
|
self.mysql_tmpdir_lineEdit.setText(dirname[0])
|
|
627
746
|
|
|
747
|
+
@pyqtSlot()
|
|
748
|
+
def on_clickhouse_tmpdir_pushButton_clicked(self):
|
|
749
|
+
if not is_valid_license():
|
|
750
|
+
QMessageBox.critical(self, "clickhouse引擎", "需要捐赠授权才能使用clickhouse引擎")
|
|
751
|
+
return
|
|
752
|
+
|
|
753
|
+
dlg = QFileDialog()
|
|
754
|
+
dlg.setFileMode(QFileDialog.Directory)
|
|
755
|
+
config = self.getCurrentConfig()
|
|
756
|
+
dlg.setDirectory(config['clickhouse']['tmpdir'])
|
|
757
|
+
if dlg.exec_():
|
|
758
|
+
dirname = dlg.selectedFiles()
|
|
759
|
+
self.clickhouse_tmpdir_lineEdit.setText(dirname[0])
|
|
760
|
+
|
|
628
761
|
@pyqtSlot()
|
|
629
762
|
def on_mysql_test_pushButton_clicked(self):
|
|
630
763
|
"""测试数据库连接"""
|
|
@@ -649,6 +782,25 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
649
782
|
|
|
650
783
|
QMessageBox.about(self, "测试数据库连接", " 连接成功!")
|
|
651
784
|
|
|
785
|
+
@pyqtSlot()
|
|
786
|
+
def on_clickhouse_test_pushButton_clicked(self):
|
|
787
|
+
"""测试数据库连接"""
|
|
788
|
+
db_config = {
|
|
789
|
+
'username': self.clickhouse_usr_lineEdit.text(),
|
|
790
|
+
'password': self.clickhouse_pwd_lineEdit.text(),
|
|
791
|
+
'host': self.clickhouse_ip_lineEdit.text(),
|
|
792
|
+
'port': self.clickhouse_http_port_lineEdit.text()
|
|
793
|
+
}
|
|
794
|
+
|
|
795
|
+
try:
|
|
796
|
+
cnx = clickhouse_connect.get_client(**db_config)
|
|
797
|
+
cnx.close()
|
|
798
|
+
except Exception as err:
|
|
799
|
+
QMessageBox.critical(self, "测试数据库连接失败", str(err))
|
|
800
|
+
return
|
|
801
|
+
|
|
802
|
+
QMessageBox.about(self, "测试数据库连接", " 连接成功!")
|
|
803
|
+
|
|
652
804
|
def reset_progress_bar(self):
|
|
653
805
|
self.hdf5_weight_label.setText('')
|
|
654
806
|
self.hdf5_day_progressBar.setValue(0)
|
|
@@ -9,6 +9,7 @@ import mysql.connector
|
|
|
9
9
|
from hikyuu.data.common import MARKET, get_stk_code_name_list
|
|
10
10
|
from hikyuu.data.em_block_to_mysql import em_import_block_to_mysql
|
|
11
11
|
from hikyuu.data.em_block_to_sqlite import em_import_block_to_sqlite
|
|
12
|
+
from hikyuu.data.em_block_to_clickhouse import em_import_block_to_clickhouse
|
|
12
13
|
from hikyuu.util import *
|
|
13
14
|
|
|
14
15
|
|
|
@@ -29,7 +30,7 @@ class ImportBlockInfoTask:
|
|
|
29
30
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
30
31
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
31
32
|
import_block = em_import_block_to_sqlite
|
|
32
|
-
|
|
33
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
33
34
|
db_config = {
|
|
34
35
|
'user': self.config['mysql']['usr'],
|
|
35
36
|
'password': self.config['mysql']['pwd'],
|
|
@@ -38,6 +39,16 @@ class ImportBlockInfoTask:
|
|
|
38
39
|
}
|
|
39
40
|
connect = mysql.connector.connect(**db_config)
|
|
40
41
|
import_block = em_import_block_to_mysql
|
|
42
|
+
elif self.config.getboolean('clickhouse', 'enable', fallback=True):
|
|
43
|
+
db_config = {
|
|
44
|
+
'username': self.config['clickhouse']['usr'],
|
|
45
|
+
'password': self.config['clickhouse']['pwd'],
|
|
46
|
+
'host': self.config['clickhouse']['host'],
|
|
47
|
+
'port': self.config['clickhouse']['http_port']
|
|
48
|
+
}
|
|
49
|
+
import clickhouse_connect
|
|
50
|
+
connect = clickhouse_connect.get_client(**db_config)
|
|
51
|
+
import_block = em_import_block_to_clickhouse
|
|
41
52
|
|
|
42
53
|
count = 0
|
|
43
54
|
try:
|
|
@@ -27,10 +27,11 @@ import shutil
|
|
|
27
27
|
import hashlib
|
|
28
28
|
import sqlite3
|
|
29
29
|
import mysql.connector
|
|
30
|
+
import clickhouse_connect
|
|
30
31
|
from pytdx.hq import TdxHq_API
|
|
31
32
|
from hikyuu.data.pytdx_finance_to_mysql import history_finance_import_mysql
|
|
32
33
|
from hikyuu.data.pytdx_finance_to_sqlite import history_finance_import_sqlite
|
|
33
|
-
from hikyuu.data.
|
|
34
|
+
from hikyuu.data.pytdx_finance_to_clickhouse import history_finance_import_clickhouse
|
|
34
35
|
from hikyuu.util import *
|
|
35
36
|
|
|
36
37
|
|
|
@@ -46,13 +47,13 @@ class ImportHistoryFinanceTask:
|
|
|
46
47
|
self.total_count = 0
|
|
47
48
|
self.status = "no run"
|
|
48
49
|
|
|
49
|
-
def
|
|
50
|
-
|
|
50
|
+
def connect_to_pytdx(self):
|
|
51
|
+
api = TdxHq_API()
|
|
51
52
|
# 不是所有服务器都提供下载
|
|
52
|
-
hku_check(
|
|
53
|
+
hku_check(api.connect('120.76.152.87', 7709), "failed connect pytdx!")
|
|
54
|
+
return api
|
|
53
55
|
|
|
54
56
|
def get_list_info(self):
|
|
55
|
-
result = []
|
|
56
57
|
content = self.api.get_report_file_by_size('tdxfin/gpcw.txt')
|
|
57
58
|
content = content.decode('utf-8')
|
|
58
59
|
content = content.strip().split('\r\n')
|
|
@@ -62,72 +63,89 @@ class ImportHistoryFinanceTask:
|
|
|
62
63
|
|
|
63
64
|
return [l2d(i.strip().split(',')) for i in content]
|
|
64
65
|
|
|
65
|
-
def
|
|
66
|
+
def connect_db(self):
|
|
66
67
|
if self.config.getboolean('hdf5', 'enable', fallback=True):
|
|
67
68
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
68
|
-
|
|
69
|
-
history_finance_import = history_finance_import_sqlite
|
|
70
|
-
|
|
69
|
+
self.db_connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
70
|
+
self.history_finance_import = history_finance_import_sqlite
|
|
71
|
+
self.engine = 'hdf5'
|
|
72
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
71
73
|
db_config = {
|
|
72
74
|
'user': self.config['mysql']['usr'],
|
|
73
75
|
'password': self.config['mysql']['pwd'],
|
|
74
76
|
'host': self.config['mysql']['host'],
|
|
75
77
|
'port': self.config['mysql']['port']
|
|
76
78
|
}
|
|
77
|
-
|
|
78
|
-
history_finance_import = history_finance_import_mysql
|
|
79
|
+
self.db_connect = mysql.connector.connect(**db_config)
|
|
80
|
+
self.history_finance_import = history_finance_import_mysql
|
|
81
|
+
self.engine = 'mysql'
|
|
82
|
+
elif self.config.getboolean('clickhouse', 'enable', fallback=True):
|
|
83
|
+
db_config = {
|
|
84
|
+
'username': self.config['clickhouse']['usr'],
|
|
85
|
+
'password': self.config['clickhouse']['pwd'],
|
|
86
|
+
'host': self.config['clickhouse']['host'],
|
|
87
|
+
'port': self.config['clickhouse']['http_port']
|
|
88
|
+
}
|
|
89
|
+
self.db_connect = clickhouse_connect.get_client(**db_config)
|
|
90
|
+
self.history_finance_import = history_finance_import_clickhouse
|
|
91
|
+
self.engine = 'clickhouse'
|
|
79
92
|
|
|
93
|
+
def import_to_db(self, filename):
|
|
80
94
|
try:
|
|
81
|
-
history_finance_import(
|
|
95
|
+
self.history_finance_import(self.db_connect, filename)
|
|
82
96
|
except Exception as e:
|
|
83
97
|
hku_error(str(e))
|
|
84
|
-
finally:
|
|
85
|
-
connect.commit()
|
|
86
|
-
connect.close()
|
|
87
98
|
|
|
88
|
-
def download_file(self, item):
|
|
99
|
+
def download_file(self, item, dest_dir):
|
|
89
100
|
filename = item['filename']
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
101
|
+
dest_file_name = dest_dir + "/" + filename
|
|
102
|
+
need_download = False
|
|
103
|
+
if not os.path.exists(dest_file_name):
|
|
104
|
+
need_download = True
|
|
105
|
+
else:
|
|
106
|
+
old_md5 = ''
|
|
107
|
+
with open(dest_file_name, 'rb') as f:
|
|
108
|
+
old_md5 = hashlib.md5(f.read()).hexdigest()
|
|
109
|
+
if old_md5 != item['hash']:
|
|
110
|
+
need_download = True
|
|
111
|
+
|
|
112
|
+
if need_download:
|
|
113
|
+
api = TdxHq_API()
|
|
114
|
+
# 不是所有服务器都提供下载
|
|
115
|
+
hku_check(api.connect('120.76.152.87', 7709), "failed connect pytdx!")
|
|
116
|
+
data = api.get_report_file_by_size(f'tdxfin/{filename}', 0)
|
|
117
|
+
hku_info(f"Download finance file: {filename}")
|
|
118
|
+
with open(dest_file_name, 'wb') as f:
|
|
119
|
+
f.write(data)
|
|
120
|
+
api.disconnect()
|
|
121
|
+
|
|
122
|
+
shutil.unpack_archive(dest_file_name, extract_dir=dest_dir)
|
|
123
|
+
self.import_to_db(f'{dest_dir}/{filename[0:-4]}.dat')
|
|
124
|
+
hku_info(f"Import finance file: {dest_dir}/{filename[0:-4]}.dat")
|
|
100
125
|
|
|
101
126
|
@hku_catch(trace=True)
|
|
102
127
|
def __call__(self):
|
|
103
128
|
self.status = "running"
|
|
104
129
|
capture_multiprocess_all_logger(self.log_queue)
|
|
105
|
-
self.
|
|
130
|
+
self.api = self.connect_to_pytdx()
|
|
106
131
|
data_list = self.get_list_info()
|
|
107
132
|
self.total_count = len(data_list)
|
|
108
133
|
count = 0
|
|
134
|
+
data_list.sort(key=lambda x: x['filename'])
|
|
135
|
+
|
|
136
|
+
self.connect_db()
|
|
109
137
|
for item in data_list:
|
|
110
138
|
try:
|
|
111
|
-
|
|
112
|
-
if not os.path.exists(dest_file):
|
|
113
|
-
self.download_file(item)
|
|
114
|
-
else:
|
|
115
|
-
old_md5 = ''
|
|
116
|
-
with open(dest_file, 'rb') as f:
|
|
117
|
-
old_md5 = hashlib.md5(f.read()).hexdigest()
|
|
118
|
-
if old_md5 != item['hash']:
|
|
119
|
-
self.download_file(item)
|
|
120
|
-
else:
|
|
121
|
-
# 不管是否有变化,都导入一次,以便切换引擎时可以导入
|
|
122
|
-
shutil.unpack_archive(dest_file, extract_dir=self.dest_dir)
|
|
123
|
-
filename = item['filename']
|
|
124
|
-
filename = f'{self.dest_dir}/{filename[0:-4]}.dat'
|
|
125
|
-
self.import_to_db(filename)
|
|
126
|
-
hku_info(f"Import finance file: {filename}")
|
|
139
|
+
self.download_file(item, self.dest_dir)
|
|
127
140
|
count += 1
|
|
128
141
|
self.queue.put([self.task_name, None, None, int(100 * count / self.total_count), self.total_count])
|
|
129
142
|
except Exception as e:
|
|
130
143
|
hku_error(str(e))
|
|
144
|
+
if self.engine == 'clickhouse':
|
|
145
|
+
hku_run_ignore_exception(self.db_connect.command, "OPTIMIZE TABLE hku_base.historyfinance FINAL")
|
|
146
|
+
self.db_connect.close()
|
|
147
|
+
self.api.disconnect()
|
|
148
|
+
|
|
131
149
|
self.queue.put([self.task_name, None, None, None, self.total_count])
|
|
132
150
|
self.status = "finished"
|
|
133
151
|
|
|
@@ -138,6 +156,6 @@ if __name__ == "__main__":
|
|
|
138
156
|
this_dir = os.path.expanduser('~') + '/.hikyuu'
|
|
139
157
|
import_config = ConfigParser()
|
|
140
158
|
import_config.read(this_dir + '/importdata-gui.ini', encoding='utf-8')
|
|
141
|
-
task = ImportHistoryFinanceTask(None, None,
|
|
159
|
+
task = ImportHistoryFinanceTask(None, None, import_config, "/Users/fasiondog/stock")
|
|
142
160
|
task()
|
|
143
161
|
print("over!")
|
|
@@ -25,9 +25,11 @@
|
|
|
25
25
|
import logging
|
|
26
26
|
import sqlite3
|
|
27
27
|
import mysql.connector
|
|
28
|
+
import clickhouse_connect
|
|
28
29
|
from pytdx.hq import TdxHq_API
|
|
29
30
|
from hikyuu.data.pytdx_to_h5 import import_time as h5_import_time
|
|
30
31
|
from hikyuu.data.pytdx_to_mysql import import_time as mysql_import_time
|
|
32
|
+
from hikyuu.data.pytdx_to_clickhouse import import_time as clickhouse_import_time
|
|
31
33
|
from hikyuu.util import *
|
|
32
34
|
|
|
33
35
|
|
|
@@ -64,7 +66,7 @@ class ImportPytdxTimeToH5:
|
|
|
64
66
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
65
67
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
66
68
|
import_time = h5_import_time
|
|
67
|
-
|
|
69
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
68
70
|
db_config = {
|
|
69
71
|
'user': self.config['mysql']['usr'],
|
|
70
72
|
'password': self.config['mysql']['pwd'],
|
|
@@ -73,6 +75,15 @@ class ImportPytdxTimeToH5:
|
|
|
73
75
|
}
|
|
74
76
|
connect = mysql.connector.connect(**db_config)
|
|
75
77
|
import_time = mysql_import_time
|
|
78
|
+
elif self.config.getboolean('clickhouse', 'enable', fallback=True):
|
|
79
|
+
db_config = {
|
|
80
|
+
'username': self.config['clickhouse']['usr'],
|
|
81
|
+
'password': self.config['clickhouse']['pwd'],
|
|
82
|
+
'host': self.config['clickhouse']['host'],
|
|
83
|
+
'port': self.config['clickhouse']['http_port']
|
|
84
|
+
}
|
|
85
|
+
connect = clickhouse_connect.get_client(**db_config)
|
|
86
|
+
import_time = clickhouse_import_time
|
|
76
87
|
|
|
77
88
|
count = 0
|
|
78
89
|
try:
|
|
@@ -84,10 +95,11 @@ class ImportPytdxTimeToH5:
|
|
|
84
95
|
connect, self.market, self.quotations, api, self.dest_dir, max_days=self.max_days, progress=progress
|
|
85
96
|
)
|
|
86
97
|
self.logger.info("导入 {} 分时记录数: {}".format(self.market, count))
|
|
98
|
+
api.disconnect()
|
|
87
99
|
except Exception as e:
|
|
88
100
|
self.logger.error(e)
|
|
89
101
|
finally:
|
|
90
|
-
|
|
102
|
+
api.close()
|
|
91
103
|
connect.close()
|
|
92
104
|
|
|
93
105
|
self.queue.put([self.task_name, self.market, 'TIME', None, count])
|
|
@@ -28,6 +28,7 @@ import mysql.connector
|
|
|
28
28
|
from pytdx.hq import TdxHq_API
|
|
29
29
|
from hikyuu.data.pytdx_to_h5 import import_data as h5_import_data
|
|
30
30
|
from hikyuu.data.pytdx_to_mysql import import_data as mysql_import_data
|
|
31
|
+
from hikyuu.data.pytdx_to_clickhouse import import_data as clickhouse_import_data
|
|
31
32
|
from hikyuu.util import *
|
|
32
33
|
|
|
33
34
|
|
|
@@ -66,16 +67,28 @@ class ImportPytdxToH5:
|
|
|
66
67
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
67
68
|
import_data = h5_import_data
|
|
68
69
|
self.logger.debug('use hdf5 import kdata')
|
|
69
|
-
|
|
70
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
70
71
|
db_config = {
|
|
71
72
|
'user': self.config['mysql']['usr'],
|
|
72
73
|
'password': self.config['mysql']['pwd'],
|
|
73
74
|
'host': self.config['mysql']['host'],
|
|
74
|
-
'port': self.config['mysql']['port']
|
|
75
|
+
'port': int(self.config['mysql']['port'])
|
|
75
76
|
}
|
|
76
77
|
connect = mysql.connector.connect(**db_config)
|
|
77
78
|
import_data = mysql_import_data
|
|
78
79
|
self.logger.debug('use mysql import kdata')
|
|
80
|
+
elif self.config.getboolean('clickhouse', 'enable', fallback=True):
|
|
81
|
+
db_config = {
|
|
82
|
+
'username': self.config['clickhouse']['usr'],
|
|
83
|
+
'password': self.config['clickhouse']['pwd'],
|
|
84
|
+
'host': self.config['clickhouse']['host'],
|
|
85
|
+
'port': int(self.config['clickhouse']['http_port']),
|
|
86
|
+
'send_receive_timeout': 60,
|
|
87
|
+
}
|
|
88
|
+
import clickhouse_connect
|
|
89
|
+
connect = clickhouse_connect.get_client(**db_config)
|
|
90
|
+
import_data = clickhouse_import_data
|
|
91
|
+
self.logger.debug('use clickhouse import kdata')
|
|
79
92
|
|
|
80
93
|
count = 0
|
|
81
94
|
try:
|
|
@@ -87,11 +100,12 @@ class ImportPytdxToH5:
|
|
|
87
100
|
connect, self.market, self.ktype, self.quotations, api, self.dest_dir, self.startDatetime, progress
|
|
88
101
|
)
|
|
89
102
|
self.logger.info("导入 {} {} 记录数: {}".format(self.market, self.ktype, count))
|
|
103
|
+
api.disconnect()
|
|
90
104
|
except Exception as e:
|
|
91
105
|
self.logger.error("ImportPytdxToH5Task failed! {}".format(e))
|
|
92
106
|
# self.queue.put([self.task_name, self.market, self.ktype, str(e), count])
|
|
93
107
|
finally:
|
|
94
|
-
|
|
108
|
+
api.close()
|
|
95
109
|
connect.close()
|
|
96
110
|
|
|
97
111
|
self.queue.put([self.task_name, self.market, self.ktype, None, count])
|
|
@@ -28,6 +28,7 @@ import mysql.connector
|
|
|
28
28
|
from pytdx.hq import TdxHq_API
|
|
29
29
|
from hikyuu.data.pytdx_to_h5 import import_trans as h5_import_trans
|
|
30
30
|
from hikyuu.data.pytdx_to_mysql import import_trans as mysql_import_trans
|
|
31
|
+
from hikyuu.data.pytdx_to_clickhouse import import_trans as clickhouse_import_trans
|
|
31
32
|
from hikyuu.util import *
|
|
32
33
|
|
|
33
34
|
|
|
@@ -64,7 +65,7 @@ class ImportPytdxTransToH5:
|
|
|
64
65
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
65
66
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
66
67
|
import_trans = h5_import_trans
|
|
67
|
-
|
|
68
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
68
69
|
db_config = {
|
|
69
70
|
'user': self.config['mysql']['usr'],
|
|
70
71
|
'password': self.config['mysql']['pwd'],
|
|
@@ -73,6 +74,16 @@ class ImportPytdxTransToH5:
|
|
|
73
74
|
}
|
|
74
75
|
connect = mysql.connector.connect(**db_config)
|
|
75
76
|
import_trans = mysql_import_trans
|
|
77
|
+
elif self.config.getboolean('clickhouse', 'enable', fallback=True):
|
|
78
|
+
db_config = {
|
|
79
|
+
'username': self.config['clickhouse']['usr'],
|
|
80
|
+
'password': self.config['clickhouse']['pwd'],
|
|
81
|
+
'host': self.config['clickhouse']['host'],
|
|
82
|
+
'port': self.config['clickhouse']['http_port']
|
|
83
|
+
}
|
|
84
|
+
import clickhouse_connect
|
|
85
|
+
connect = clickhouse_connect.get_client(**db_config)
|
|
86
|
+
import_trans = clickhouse_import_trans
|
|
76
87
|
|
|
77
88
|
count = 0
|
|
78
89
|
try:
|
|
@@ -84,10 +95,11 @@ class ImportPytdxTransToH5:
|
|
|
84
95
|
connect, self.market, self.quotations, api, self.dest_dir, max_days=self.max_days, progress=progress
|
|
85
96
|
)
|
|
86
97
|
self.logger.info("导入 {} 分笔记录数: {}".format(self.market, count))
|
|
98
|
+
api.disconnect()
|
|
87
99
|
except Exception as e:
|
|
88
100
|
self.logger.error(e)
|
|
89
101
|
finally:
|
|
90
|
-
|
|
102
|
+
api.close()
|
|
91
103
|
connect.close()
|
|
92
104
|
|
|
93
105
|
self.queue.put([self.task_name, self.market, 'TRANS', None, count])
|