hikyuu 2.6.2__py3-none-win_amd64.whl → 2.6.5__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 +1 -1
- hikyuu/__init__.pyi +28 -13
- hikyuu/analysis/__init__.pyi +20 -0
- hikyuu/analysis/analysis.pyi +21 -1
- hikyuu/core.pyi +22 -2
- hikyuu/cpp/core310.pyd +0 -0
- hikyuu/cpp/core310.pyi +499 -50
- hikyuu/cpp/core311.pyd +0 -0
- hikyuu/cpp/core311.pyi +499 -50
- hikyuu/cpp/core312.pyd +0 -0
- hikyuu/cpp/core312.pyi +499 -50
- hikyuu/cpp/core313.pyd +0 -0
- hikyuu/cpp/core313.pyi +499 -50
- hikyuu/cpp/core39.pyd +0 -0
- hikyuu/cpp/core39.pyi +499 -50
- hikyuu/cpp/hikyuu.dll +0 -0
- hikyuu/cpp/hikyuu.lib +0 -0
- hikyuu/data/common.py +1 -1
- hikyuu/data/common_mysql.py +19 -0
- hikyuu/data/common_pytdx.py +2 -0
- hikyuu/data/common_sqlite3.py +1 -0
- hikyuu/data/hku_config_template.py +14 -0
- hikyuu/data/mysql_upgrade/0028.sql +95 -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/sqlite_upgrade/0028.sql +97 -0
- hikyuu/draw/__init__.pyi +1 -1
- hikyuu/draw/drawplot/__init__.pyi +1 -1
- hikyuu/draw/drawplot/bokeh_draw.pyi +24 -9
- hikyuu/draw/drawplot/echarts_draw.pyi +24 -9
- hikyuu/draw/drawplot/matplotlib_draw.py +26 -4
- hikyuu/draw/drawplot/matplotlib_draw.pyi +24 -9
- hikyuu/draw/kaufman.py +2 -2
- hikyuu/draw/kaufman.pyi +2 -2
- 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 +24 -9
- hikyuu/fetcher/stock/zh_block_em.py +349 -5
- hikyuu/fetcher/stock/zh_stock_a_pytdx.py +2 -1
- hikyuu/gui/HikyuuTDX.py +47 -24
- hikyuu/gui/data/ImportBlockInfoTask.py +1 -1
- hikyuu/gui/data/ImportHistoryFinanceTask.py +48 -44
- hikyuu/gui/data/ImportPytdxTimeToH5Task.py +3 -1
- hikyuu/gui/data/ImportPytdxToH5Task.py +4 -2
- hikyuu/gui/data/ImportPytdxTransToH5Task.py +3 -1
- hikyuu/gui/data/ImportWeightToSqliteTask.py +2 -1
- hikyuu/gui/data/ImportZhBond10Task.py +1 -1
- hikyuu/gui/data/MainWindow.py +123 -106
- hikyuu/gui/data/UsePytdxImportToH5Thread.py +7 -3
- hikyuu/gui/data/UseQmtImportToH5Thread.py +1 -0
- hikyuu/gui/data/UseTdxImportToH5Thread.py +2 -1
- hikyuu/hub.pyi +6 -6
- hikyuu/include/hikyuu/Block.h +20 -0
- hikyuu/include/hikyuu/KQuery.h +8 -0
- hikyuu/include/hikyuu/MarketInfo.h +6 -0
- hikyuu/include/hikyuu/Stock.h +1 -1
- hikyuu/include/hikyuu/StockManager.h +6 -0
- hikyuu/include/hikyuu/data_driver/BaseInfoDriver.h +35 -0
- hikyuu/include/hikyuu/indicator/Indicator.h +5 -0
- hikyuu/include/hikyuu/indicator/IndicatorImp.h +8 -3
- hikyuu/include/hikyuu/indicator/build_in.h +1 -0
- hikyuu/include/hikyuu/indicator/crt/BARSLASTCOUNT.h +33 -0
- hikyuu/include/hikyuu/indicator/crt/INSUM.h +5 -10
- hikyuu/include/hikyuu/indicator/crt/RSI.h +2 -18
- hikyuu/include/hikyuu/indicator/imp/IBarsLastCount.h +27 -0
- hikyuu/include/hikyuu/plugin/backtest.h +3 -2
- hikyuu/include/hikyuu/plugin/device.h +6 -3
- hikyuu/include/hikyuu/plugin/extind.h +150 -0
- hikyuu/include/hikyuu/plugin/interface/BackTestPluginInterface.h +2 -1
- hikyuu/include/hikyuu/plugin/interface/DevicePluginInterface.h +1 -0
- hikyuu/include/hikyuu/plugin/interface/ExtendIndicatorsPluginInterface.h +26 -0
- hikyuu/include/hikyuu/plugin/interface/TMReportPluginInterface.h +80 -0
- hikyuu/include/hikyuu/plugin/interface/plugins.h +4 -0
- hikyuu/include/hikyuu/strategy/BrokerTradeManager.h +7 -5
- hikyuu/include/hikyuu/strategy/Strategy.h +22 -9
- hikyuu/include/hikyuu/trade_manage/OrderBrokerBase.h +11 -4
- 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/TradeManager.h +8 -5
- hikyuu/include/hikyuu/trade_manage/TradeManagerBase.h +66 -5
- hikyuu/include/hikyuu/trade_manage/TradeRecord.h +9 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/MultiFactorBase.h +8 -5
- hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_EqualWeight.h +4 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICIRWeight.h +4 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_ICWeight.h +4 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/crt/MF_Weight.h +4 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/imp/EqualWeightMultiFactor.h +2 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICIRMultiFactor.h +2 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/imp/ICMultiFactor.h +2 -1
- hikyuu/include/hikyuu/trade_sys/multifactor/imp/WeightMultiFactor.h +1 -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/trade_sys/system/TradeRequest.h +7 -4
- hikyuu/include/hikyuu/trade_sys/system/imp/WalkForwardTradeManager.h +17 -13
- hikyuu/include/hikyuu/utilities/DllLoader.h +226 -0
- hikyuu/include/hikyuu/utilities/datetime/Datetime.h +20 -0
- hikyuu/include/hikyuu/utilities/datetime/TimeDelta.h +6 -0
- hikyuu/include/hikyuu/utilities/plugin/PluginLoader.h +10 -10
- hikyuu/include/hikyuu/utilities/thread/{MQStealThreadPool.h → GlobalMQStealThreadPool.h} +12 -12
- hikyuu/include/hikyuu/utilities/thread/GlobalMQThreadPool.h +271 -0
- hikyuu/include/hikyuu/utilities/thread/{StealThreadPool.h → GlobalStealThreadPool.h} +11 -10
- hikyuu/include/hikyuu/utilities/thread/GlobalThreadPool.h +224 -0
- hikyuu/include/hikyuu/utilities/thread/InterruptFlag.h +16 -0
- hikyuu/include/hikyuu/utilities/thread/MQThreadPool.h +40 -77
- hikyuu/include/hikyuu/utilities/thread/ThreadPool.h +31 -59
- hikyuu/include/hikyuu/utilities/thread/ThreadSafeQueue.h +4 -0
- hikyuu/include/hikyuu/utilities/thread/algorithm.h +9 -9
- hikyuu/include/hikyuu/utilities/thread/thread.h +4 -0
- hikyuu/include/hikyuu/version.h +4 -4
- hikyuu/plugin/backtest.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 +23 -8
- hikyuu/trade_manage/broker.py +8 -8
- hikyuu/trade_manage/broker.pyi +4 -4
- hikyuu/trade_manage/broker_easytrader.py +3 -3
- hikyuu/trade_manage/broker_easytrader.pyi +2 -2
- hikyuu/trade_manage/broker_mail.py +2 -2
- hikyuu/trade_manage/broker_mail.pyi +2 -2
- hikyuu/trade_manage/trade.pyi +23 -8
- hikyuu/util/singleton.pyi +1 -1
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/METADATA +4 -3
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/RECORD +136 -121
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/LICENSE +0 -0
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/WHEEL +0 -0
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/entry_points.txt +0 -0
- {hikyuu-2.6.2.dist-info → hikyuu-2.6.5.dist-info}/top_level.txt +0 -0
hikyuu/gui/HikyuuTDX.py
CHANGED
|
@@ -34,7 +34,7 @@ from hikyuu.gui.data.CollectSpotThread import CollectSpotThread
|
|
|
34
34
|
from hikyuu.gui.data.SchedImportThread import SchedImportThread
|
|
35
35
|
from hikyuu.gui.spot_server import release_nng_senders
|
|
36
36
|
|
|
37
|
-
from hikyuu import can_upgrade, get_last_version, fetch_trial_license, view_license
|
|
37
|
+
from hikyuu import can_upgrade, get_last_version, fetch_trial_license, view_license, is_valid_license
|
|
38
38
|
from hikyuu.data import hku_config_template
|
|
39
39
|
from hikyuu.util import *
|
|
40
40
|
|
|
@@ -93,6 +93,7 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
93
93
|
def getHikyuuConfigFileName(self):
|
|
94
94
|
return self.getUserConfigDir() + '/hikyuu.ini'
|
|
95
95
|
|
|
96
|
+
@hku_catch()
|
|
96
97
|
def saveConfig(self):
|
|
97
98
|
if not os.path.lexists(self.getUserConfigDir()):
|
|
98
99
|
os.mkdir(self.getUserConfigDir())
|
|
@@ -105,7 +106,10 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
105
106
|
if current_config.getboolean('hdf5', 'enable', fallback=True):
|
|
106
107
|
data_dir = current_config['hdf5']['dir']
|
|
107
108
|
if not os.path.lexists(data_dir + '/tmp'):
|
|
108
|
-
|
|
109
|
+
try:
|
|
110
|
+
os.mkdir(data_dir + '/tmp')
|
|
111
|
+
except:
|
|
112
|
+
pass
|
|
109
113
|
# 此处不能使用 utf-8 参数,否则导致Windows下getBlock无法找到板块分类
|
|
110
114
|
with open(filename, 'w', encoding='utf-8') as f:
|
|
111
115
|
f.write(
|
|
@@ -140,8 +144,13 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
140
144
|
)
|
|
141
145
|
)
|
|
142
146
|
|
|
143
|
-
|
|
147
|
+
elif current_config.getboolean('mysql', 'enable', fallback=True):
|
|
144
148
|
data_dir = current_config['mysql']['tmpdir']
|
|
149
|
+
if not os.path.lexists(data_dir + '/tmp'):
|
|
150
|
+
try:
|
|
151
|
+
os.mkdir(data_dir + '/tmp')
|
|
152
|
+
except:
|
|
153
|
+
pass
|
|
145
154
|
with open(filename, 'w', encoding="utf-8") as f:
|
|
146
155
|
f.write(
|
|
147
156
|
hku_config_template.mysql_template.format(
|
|
@@ -179,15 +188,21 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
179
188
|
)
|
|
180
189
|
)
|
|
181
190
|
|
|
182
|
-
|
|
183
|
-
os.
|
|
191
|
+
try:
|
|
192
|
+
if not data_dir and not os.path.lexists(data_dir):
|
|
193
|
+
os.makedirs(data_dir)
|
|
194
|
+
except:
|
|
195
|
+
pass
|
|
184
196
|
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
197
|
+
try:
|
|
198
|
+
if not data_dir and not os.path.lexists(data_dir + '/block'):
|
|
199
|
+
current_dir = os.path.dirname(os.path.abspath(__file__))
|
|
200
|
+
dirname, _ = os.path.split(current_dir)
|
|
201
|
+
dirname = os.path.join(dirname, 'config/block')
|
|
202
|
+
shutil.copytree(dirname, data_dir + '/block')
|
|
203
|
+
os.remove(data_dir + '/block/__init__.py')
|
|
204
|
+
except:
|
|
205
|
+
pass
|
|
191
206
|
|
|
192
207
|
@pyqtSlot()
|
|
193
208
|
def on_save_pushButton_clicked(self):
|
|
@@ -309,6 +324,8 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
309
324
|
|
|
310
325
|
# 初始化权息与财务数据设置
|
|
311
326
|
self.import_weight_checkBox.setChecked(import_config.getboolean('weight', 'enable', fallback=True))
|
|
327
|
+
self.import_history_finance_checkBox.setChecked(import_config.getboolean('finance', 'enable', fallback=True))
|
|
328
|
+
self.import_block_checkBox.setChecked(import_config.getboolean('block', 'enable', fallback=True))
|
|
312
329
|
|
|
313
330
|
# 初始化通道信目录配置
|
|
314
331
|
tdx_enable = import_config.getboolean('tdx', 'enable', fallback=False)
|
|
@@ -350,7 +367,8 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
350
367
|
if hdf5_enable:
|
|
351
368
|
mysql_enable = False
|
|
352
369
|
self.enable_mysql_radioButton.setChecked(mysql_enable)
|
|
353
|
-
self.mysql_tmpdir_lineEdit.setText(import_config.get('mysql', 'tmpdir', fallback='
|
|
370
|
+
self.mysql_tmpdir_lineEdit.setText(import_config.get('mysql', 'tmpdir', fallback='d:/stock'))
|
|
371
|
+
self.mysql_tmpdir_pushButton.setEnabled(mysql_enable)
|
|
354
372
|
mysql_ip = import_config.get('mysql', 'host', fallback='127.0.0.1')
|
|
355
373
|
self.mysql_ip_lineEdit.setText(mysql_ip)
|
|
356
374
|
self.mysql_ip_lineEdit.setEnabled(mysql_enable)
|
|
@@ -442,6 +460,12 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
442
460
|
import_config['weight'] = {
|
|
443
461
|
'enable': self.import_weight_checkBox.isChecked(),
|
|
444
462
|
}
|
|
463
|
+
import_config['finance'] = {
|
|
464
|
+
'enable': self.import_history_finance_checkBox.isChecked(),
|
|
465
|
+
}
|
|
466
|
+
import_config['block'] = {
|
|
467
|
+
'enable': self.import_block_checkBox.isChecked(),
|
|
468
|
+
}
|
|
445
469
|
import_config['tdx'] = {'enable': self.tdx_radioButton.isChecked(), 'dir': self.tdx_dir_lineEdit.text()}
|
|
446
470
|
import_config['pytdx'] = {
|
|
447
471
|
'enable': self.pytdx_radioButton.isChecked(),
|
|
@@ -597,23 +621,22 @@ class MyMainWindow(QMainWindow, Ui_MainWindow):
|
|
|
597
621
|
def on_enable_hdf55_radioButton_clicked(self):
|
|
598
622
|
if self.enable_hdf55_radioButton.isChecked():
|
|
599
623
|
self.enable_mysql_radioButton.setChecked(False)
|
|
600
|
-
self.
|
|
624
|
+
self.on_enable_database_toggled(hdf5=True, mysql=False)
|
|
601
625
|
|
|
602
626
|
@pyqtSlot()
|
|
603
627
|
def on_enable_mysql_radioButton_clicked(self):
|
|
604
628
|
if self.enable_mysql_radioButton.isChecked():
|
|
605
629
|
self.enable_hdf55_radioButton.setChecked(False)
|
|
606
|
-
self.
|
|
607
|
-
|
|
608
|
-
def
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
self.
|
|
612
|
-
self.
|
|
613
|
-
self.
|
|
614
|
-
self.
|
|
615
|
-
self.
|
|
616
|
-
self.mysql_test_pushButton.setEnabled(mysql_enable)
|
|
630
|
+
self.on_enable_database_toggled(hdf5=False, mysql=True)
|
|
631
|
+
|
|
632
|
+
def on_enable_database_toggled(self, hdf5, mysql):
|
|
633
|
+
self.hdf5_dir_lineEdit.setEnabled(hdf5)
|
|
634
|
+
self.mysql_ip_lineEdit.setEnabled(mysql)
|
|
635
|
+
self.mysql_port_lineEdit.setEnabled(mysql)
|
|
636
|
+
self.mysql_usr_lineEdit.setEnabled(mysql)
|
|
637
|
+
self.mysql_pwd_lineEdit.setEnabled(mysql)
|
|
638
|
+
self.mysql_test_pushButton.setEnabled(mysql)
|
|
639
|
+
self.mysql_tmpdir_pushButton.setEnabled(mysql)
|
|
617
640
|
|
|
618
641
|
@pyqtSlot()
|
|
619
642
|
def on_mysql_tmpdir_pushButton_clicked(self):
|
|
@@ -29,7 +29,7 @@ class ImportBlockInfoTask:
|
|
|
29
29
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
30
30
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
31
31
|
import_block = em_import_block_to_sqlite
|
|
32
|
-
|
|
32
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
33
33
|
db_config = {
|
|
34
34
|
'user': self.config['mysql']['usr'],
|
|
35
35
|
'password': self.config['mysql']['pwd'],
|
|
@@ -30,7 +30,6 @@ import mysql.connector
|
|
|
30
30
|
from pytdx.hq import TdxHq_API
|
|
31
31
|
from hikyuu.data.pytdx_finance_to_mysql import history_finance_import_mysql
|
|
32
32
|
from hikyuu.data.pytdx_finance_to_sqlite import history_finance_import_sqlite
|
|
33
|
-
from hikyuu.data.common_pytdx import search_best_tdx
|
|
34
33
|
from hikyuu.util import *
|
|
35
34
|
|
|
36
35
|
|
|
@@ -46,13 +45,13 @@ class ImportHistoryFinanceTask:
|
|
|
46
45
|
self.total_count = 0
|
|
47
46
|
self.status = "no run"
|
|
48
47
|
|
|
49
|
-
def
|
|
50
|
-
|
|
48
|
+
def connect_to_pytdx(self):
|
|
49
|
+
api = TdxHq_API()
|
|
51
50
|
# 不是所有服务器都提供下载
|
|
52
|
-
hku_check(
|
|
51
|
+
hku_check(api.connect('120.76.152.87', 7709), "failed connect pytdx!")
|
|
52
|
+
return api
|
|
53
53
|
|
|
54
54
|
def get_list_info(self):
|
|
55
|
-
result = []
|
|
56
55
|
content = self.api.get_report_file_by_size('tdxfin/gpcw.txt')
|
|
57
56
|
content = content.decode('utf-8')
|
|
58
57
|
content = content.strip().split('\r\n')
|
|
@@ -62,72 +61,77 @@ class ImportHistoryFinanceTask:
|
|
|
62
61
|
|
|
63
62
|
return [l2d(i.strip().split(',')) for i in content]
|
|
64
63
|
|
|
65
|
-
def
|
|
64
|
+
def connect_db(self):
|
|
66
65
|
if self.config.getboolean('hdf5', 'enable', fallback=True):
|
|
67
66
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
68
|
-
|
|
69
|
-
history_finance_import = history_finance_import_sqlite
|
|
70
|
-
|
|
67
|
+
self.db_connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
68
|
+
self.history_finance_import = history_finance_import_sqlite
|
|
69
|
+
self.engine = 'hdf5'
|
|
70
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
71
71
|
db_config = {
|
|
72
72
|
'user': self.config['mysql']['usr'],
|
|
73
73
|
'password': self.config['mysql']['pwd'],
|
|
74
74
|
'host': self.config['mysql']['host'],
|
|
75
75
|
'port': self.config['mysql']['port']
|
|
76
76
|
}
|
|
77
|
-
|
|
78
|
-
history_finance_import = history_finance_import_mysql
|
|
77
|
+
self.db_connect = mysql.connector.connect(**db_config)
|
|
78
|
+
self.history_finance_import = history_finance_import_mysql
|
|
79
|
+
self.engine = 'mysql'
|
|
79
80
|
|
|
81
|
+
def import_to_db(self, filename):
|
|
80
82
|
try:
|
|
81
|
-
history_finance_import(
|
|
83
|
+
self.history_finance_import(self.db_connect, filename)
|
|
82
84
|
except Exception as e:
|
|
83
85
|
hku_error(str(e))
|
|
84
|
-
finally:
|
|
85
|
-
connect.commit()
|
|
86
|
-
connect.close()
|
|
87
86
|
|
|
88
|
-
def download_file(self, item):
|
|
87
|
+
def download_file(self, item, dest_dir):
|
|
89
88
|
filename = item['filename']
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
89
|
+
dest_file_name = dest_dir + "/" + filename
|
|
90
|
+
need_download = False
|
|
91
|
+
if not os.path.exists(dest_file_name):
|
|
92
|
+
need_download = True
|
|
93
|
+
else:
|
|
94
|
+
old_md5 = ''
|
|
95
|
+
with open(dest_file_name, 'rb') as f:
|
|
96
|
+
old_md5 = hashlib.md5(f.read()).hexdigest()
|
|
97
|
+
if old_md5 != item['hash']:
|
|
98
|
+
need_download = True
|
|
99
|
+
|
|
100
|
+
if need_download:
|
|
101
|
+
api = TdxHq_API()
|
|
102
|
+
# 不是所有服务器都提供下载
|
|
103
|
+
hku_check(api.connect('120.76.152.87', 7709), "failed connect pytdx!")
|
|
104
|
+
data = api.get_report_file_by_size(f'tdxfin/{filename}', 0)
|
|
105
|
+
hku_info(f"Download finance file: {filename}")
|
|
106
|
+
with open(dest_file_name, 'wb') as f:
|
|
107
|
+
f.write(data)
|
|
108
|
+
api.disconnect()
|
|
109
|
+
|
|
110
|
+
shutil.unpack_archive(dest_file_name, extract_dir=dest_dir)
|
|
111
|
+
self.import_to_db(f'{dest_dir}/{filename[0:-4]}.dat')
|
|
112
|
+
hku_info(f"Import finance file: {dest_dir}/{filename[0:-4]}.dat")
|
|
100
113
|
|
|
101
114
|
@hku_catch(trace=True)
|
|
102
115
|
def __call__(self):
|
|
103
116
|
self.status = "running"
|
|
104
117
|
capture_multiprocess_all_logger(self.log_queue)
|
|
105
|
-
self.
|
|
118
|
+
self.api = self.connect_to_pytdx()
|
|
106
119
|
data_list = self.get_list_info()
|
|
107
120
|
self.total_count = len(data_list)
|
|
108
121
|
count = 0
|
|
122
|
+
data_list.sort(key=lambda x: x['filename'])
|
|
123
|
+
|
|
124
|
+
self.connect_db()
|
|
109
125
|
for item in data_list:
|
|
110
126
|
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}")
|
|
127
|
+
self.download_file(item, self.dest_dir)
|
|
127
128
|
count += 1
|
|
128
129
|
self.queue.put([self.task_name, None, None, int(100 * count / self.total_count), self.total_count])
|
|
129
130
|
except Exception as e:
|
|
130
131
|
hku_error(str(e))
|
|
132
|
+
self.db_connect.close()
|
|
133
|
+
self.api.disconnect()
|
|
134
|
+
|
|
131
135
|
self.queue.put([self.task_name, None, None, None, self.total_count])
|
|
132
136
|
self.status = "finished"
|
|
133
137
|
|
|
@@ -138,6 +142,6 @@ if __name__ == "__main__":
|
|
|
138
142
|
this_dir = os.path.expanduser('~') + '/.hikyuu'
|
|
139
143
|
import_config = ConfigParser()
|
|
140
144
|
import_config.read(this_dir + '/importdata-gui.ini', encoding='utf-8')
|
|
141
|
-
task = ImportHistoryFinanceTask(None, None, None, "
|
|
145
|
+
task = ImportHistoryFinanceTask(None, None, None, "/Users/fasiondog/stock")
|
|
142
146
|
task()
|
|
143
147
|
print("over!")
|
|
@@ -64,7 +64,7 @@ class ImportPytdxTimeToH5:
|
|
|
64
64
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
65
65
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
66
66
|
import_time = h5_import_time
|
|
67
|
-
|
|
67
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
68
68
|
db_config = {
|
|
69
69
|
'user': self.config['mysql']['usr'],
|
|
70
70
|
'password': self.config['mysql']['pwd'],
|
|
@@ -84,9 +84,11 @@ class ImportPytdxTimeToH5:
|
|
|
84
84
|
connect, self.market, self.quotations, api, self.dest_dir, max_days=self.max_days, progress=progress
|
|
85
85
|
)
|
|
86
86
|
self.logger.info("导入 {} 分时记录数: {}".format(self.market, count))
|
|
87
|
+
api.disconnect()
|
|
87
88
|
except Exception as e:
|
|
88
89
|
self.logger.error(e)
|
|
89
90
|
finally:
|
|
91
|
+
api.close()
|
|
90
92
|
connect.commit()
|
|
91
93
|
connect.close()
|
|
92
94
|
|
|
@@ -66,12 +66,12 @@ class ImportPytdxToH5:
|
|
|
66
66
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
67
67
|
import_data = h5_import_data
|
|
68
68
|
self.logger.debug('use hdf5 import kdata')
|
|
69
|
-
|
|
69
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
70
70
|
db_config = {
|
|
71
71
|
'user': self.config['mysql']['usr'],
|
|
72
72
|
'password': self.config['mysql']['pwd'],
|
|
73
73
|
'host': self.config['mysql']['host'],
|
|
74
|
-
'port': self.config['mysql']['port']
|
|
74
|
+
'port': int(self.config['mysql']['port'])
|
|
75
75
|
}
|
|
76
76
|
connect = mysql.connector.connect(**db_config)
|
|
77
77
|
import_data = mysql_import_data
|
|
@@ -87,10 +87,12 @@ class ImportPytdxToH5:
|
|
|
87
87
|
connect, self.market, self.ktype, self.quotations, api, self.dest_dir, self.startDatetime, progress
|
|
88
88
|
)
|
|
89
89
|
self.logger.info("导入 {} {} 记录数: {}".format(self.market, self.ktype, count))
|
|
90
|
+
api.disconnect()
|
|
90
91
|
except Exception as e:
|
|
91
92
|
self.logger.error("ImportPytdxToH5Task failed! {}".format(e))
|
|
92
93
|
# self.queue.put([self.task_name, self.market, self.ktype, str(e), count])
|
|
93
94
|
finally:
|
|
95
|
+
api.close()
|
|
94
96
|
connect.commit()
|
|
95
97
|
connect.close()
|
|
96
98
|
|
|
@@ -64,7 +64,7 @@ class ImportPytdxTransToH5:
|
|
|
64
64
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
65
65
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
66
66
|
import_trans = h5_import_trans
|
|
67
|
-
|
|
67
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
68
68
|
db_config = {
|
|
69
69
|
'user': self.config['mysql']['usr'],
|
|
70
70
|
'password': self.config['mysql']['pwd'],
|
|
@@ -84,9 +84,11 @@ class ImportPytdxTransToH5:
|
|
|
84
84
|
connect, self.market, self.quotations, api, self.dest_dir, max_days=self.max_days, progress=progress
|
|
85
85
|
)
|
|
86
86
|
self.logger.info("导入 {} 分笔记录数: {}".format(self.market, count))
|
|
87
|
+
api.disconnect()
|
|
87
88
|
except Exception as e:
|
|
88
89
|
self.logger.error(e)
|
|
89
90
|
finally:
|
|
91
|
+
api.close()
|
|
90
92
|
connect.commit()
|
|
91
93
|
connect.close()
|
|
92
94
|
|
|
@@ -67,7 +67,7 @@ class ImportWeightToSqliteTask:
|
|
|
67
67
|
pytdx_import_weight = pytdx_import_weight_to_sqlite
|
|
68
68
|
pytdx_import_finance = pytdx_import_finance_to_sqlite
|
|
69
69
|
self.logger.debug('use sqlite import weight')
|
|
70
|
-
|
|
70
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
71
71
|
db_config = {
|
|
72
72
|
'user': self.config['mysql']['usr'],
|
|
73
73
|
'password': self.config['mysql']['pwd'],
|
|
@@ -107,6 +107,7 @@ class ImportWeightToSqliteTask:
|
|
|
107
107
|
# self.queue.put([self.msg_name, str(e), -1, 0, total_count])
|
|
108
108
|
self.queue.put([self.msg_name, 'INFO', str(e), 0, 0])
|
|
109
109
|
finally:
|
|
110
|
+
api.close()
|
|
110
111
|
connect.commit()
|
|
111
112
|
connect.close()
|
|
112
113
|
|
|
@@ -27,7 +27,7 @@ class ImportZhBond10Task:
|
|
|
27
27
|
sqlite_file = "{}/stock.db".format(self.config['hdf5']['dir'])
|
|
28
28
|
connect = sqlite3.connect(sqlite_file, timeout=1800)
|
|
29
29
|
import_zh_bond10 = import_zh_bond10_to_sqlite
|
|
30
|
-
|
|
30
|
+
elif self.config.getboolean('mysql', 'enable', fallback=True):
|
|
31
31
|
db_config = {
|
|
32
32
|
'user': self.config['mysql']['usr'],
|
|
33
33
|
'password': self.config['mysql']['pwd'],
|