Пример #1
0
    def on_start_import_pushButton_clicked(self):
        self.import_running = True
        self.start_import_pushButton.setEnabled(False)
        self.reset_progress_bar()

        self.escape_time = 0.0
        self.escape_time_thread = EscapetimeThread()
        self.escape_time_thread.message.connect(self.on_message_from_thread)
        self.escape_time_thread.start()

        config = self.getCurrentConfig()

        if self.tdx_radioButton.isChecked():
            self.hdf5_import_thread = UseTdxImportToH5Thread(config)
        else:
            self.hdf5_import_thread = UsePytdxImportToH5Thread(config)

        self.hdf5_import_thread.message.connect(self.on_message_from_thread)
        self.hdf5_import_thread.start()
Пример #2
0
    def on_start_import_pushButton_clicked(self):
        config = self.getCurrentConfig()
        dest_dir = config['hdf5']['dir']
        if not os.path.exists(dest_dir) or not os.path.isdir(dest_dir):
            QMessageBox.about(self, "错误", '指定的目标数据存放目录不存在!')
            return

        if config['tdx']['enable'] \
            and (not os.path.exists(config['tdx']['dir']
                 or os.path.isdir(config['tdx']['dir']))):
            QMessageBox.about(self, "错误", "请确认通达信安装目录是否正确!")
            return

        self.import_running = True
        self.start_import_pushButton.setEnabled(False)
        self.reset_progress_bar()

        self.escape_time = 0.0
        self.escape_time_thread = EscapetimeThread()
        self.escape_time_thread.message.connect(self.on_message_from_thread)
        self.escape_time_thread.start()

        if self.tdx_radioButton.isChecked():
            self.hdf5_import_thread = UseTdxImportToH5Thread(config)
        else:
            self.import_status_label.setText("正在搜索通达信行情服务器....")
            QApplication.processEvents()
            hosts = search_best_tdx()
            if not hosts:
                self.import_status_label.setText("无法连接通达信行情服务器!请检查网络设置!")
                QMessageBox.about(self, "提示", "无法连接的通达信行情服务器!请检查网络设置!")
                self.import_running = False
                self.start_import_pushButton.setEnabled(True)
                return
            self.hdf5_import_thread = UsePytdxImportToH5Thread(config, hosts)

        self.hdf5_import_thread.message.connect(self.on_message_from_thread)
        self.hdf5_import_thread.start()
Пример #3
0
class MyMainWindow(QMainWindow, Ui_MainWindow):
    def __init__(self, parent=None):
        super(MyMainWindow, self).__init__(parent)
        self.setupUi(self)
        self.initUI()
        self.initThreads()

    def closeEvent(self, event):
        if self.import_running:
            QMessageBox.about(self, '提示', '正在执行导入任务,请耐心等候!')
            event.ignore()
            return

        self.saveConfig()

        if self.hdf5_import_thread:
            self.hdf5_import_thread.stop()
        if self.escape_time_thread:
            self.escape_time_thread.stop()
        event.accept()

    def getUserConfigDir(self):
        return os.path.expanduser('~') + '/.hikyuu'

    def saveConfig(self):
        current_config = self.getCurrentConfig()
        filename = self.getUserConfigDir() + '/importdata-gui.ini'
        with open(filename, 'w', encoding='utf-8') as f:
            current_config.write(f)

        filename = self.getUserConfigDir() + '/hikyuu.ini'
        use_engine = current_config['default_engine']['engine']
        if use_engine == 'HDF5':
            data_dir = current_config['hdf5']['dir']
            with open(filename, 'w', encoding='utf-8') as f:
                f.write(hku_config_template.hdf5_template.format(dir=data_dir))
        else:
            data_dir = self.getUserConfigDir()
            with open(filename, 'w', encoding='utf-8') as f:
                f.write(
                    hku_config_template.mysql_template.format(
                        dir=data_dir,
                        host=current_config['mysql']['host'],
                        port=current_config['mysql']['port'],
                        usr=current_config['mysql']['usr'],
                        pwd=current_config['mysql']['pwd']))

    def initUI(self):
        self.setWindowIcon(QIcon("./hikyuu.ico"))
        self.setFixedSize(self.width(), self.height())
        self.import_status_label.setText('')
        self.import_detail_textEdit.clear()
        self.reset_progress_bar()

        #读取保存的配置文件信息,如果不存在,则使用默认配置
        this_dir = self.getUserConfigDir()
        import_config = ConfigParser()
        if os.path.exists(this_dir + '/importdata-gui.ini'):
            import_config.read(this_dir + '/importdata-gui.ini',
                               encoding='utf-8')

        #初始化导入行情数据类型配置
        self.import_stock_checkBox.setChecked(
            import_config.getboolean('quotation', 'stock', fallback=True))
        self.import_fund_checkBox.setChecked(
            import_config.getboolean('quotation', 'fund', fallback=True))
        self.import_future_checkBox.setChecked(
            import_config.getboolean('quotation', 'future', fallback=False))

        #初始化导入K线类型配置
        self.import_day_checkBox.setChecked(
            import_config.getboolean('ktype', 'day', fallback=True))
        self.import_min_checkBox.setChecked(
            import_config.getboolean('ktype', 'min', fallback=True))
        self.import_min5_checkBox.setChecked(
            import_config.getboolean('ktype', 'min5', fallback=True))
        self.import_tick_checkBox.setChecked(
            import_config.getboolean('ktype', 'tick', fallback=False))

        #初始化权息数据设置
        self.import_weight_checkBox.setChecked(
            import_config.getboolean('weight', 'enable', fallback=True))

        #初始化通道信目录配置
        tdx_enable = import_config.getboolean('tdx', 'enable', fallback=True)
        tdx_dir = import_config.get('tdx', 'dir', fallback='d:\TdxW_HuaTai')
        self.tdx_radioButton.setChecked(tdx_enable)
        self.tdx_dir_lineEdit.setEnabled(tdx_enable)
        self.select_tdx_dir_pushButton.setEnabled(tdx_enable)
        self.tdx_dir_lineEdit.setText(tdx_dir)
        self.tdx_radioButton.toggled.connect(self.on_tdx_or_pytdx_toggled)

        #初始化pytdx配置及显示
        pytdx_enable = import_config.getboolean('pytdx',
                                                'enable',
                                                fallback=False)
        pytdx_server = import_config.get('pytdx',
                                         'server',
                                         fallback='招商证券深圳行情')
        self.pytdx_radioButton.setChecked(pytdx_enable)
        self.tdx_servers_comboBox.setDuplicatesEnabled(True)
        default_tdx_index = 0
        for i, host in enumerate(hq_hosts):
            self.tdx_servers_comboBox.addItem(host[0], host[1])
            if host[0] == pytdx_server:
                default_tdx_index = i
        self.tdx_servers_comboBox.setCurrentIndex(default_tdx_index)
        self.tdx_port_lineEdit.setText(str(hq_hosts[default_tdx_index][2]))
        self.tdx_servers_comboBox.setEnabled(pytdx_enable)
        self.tdx_port_lineEdit.setEnabled(pytdx_enable)

        #初始化hdf5设置
        hdf5_enable = import_config.getboolean('hdf5', 'enable', fallback=True)
        hdf5_dir = import_config.get(
            'hdf5',
            'dir',
            fallback="c:\stock"
            if sys.platform == "win32" else os.path.expanduser('~') + "/stock")
        self.hdf5_enable_checkBox.setChecked(hdf5_enable)
        self.hdf5_dir_lineEdit.setText(hdf5_dir)

        #初始化MYSQL设置
        mysql_enable = import_config.getboolean('mysql',
                                                'enable',
                                                fallback=False)
        mysql_host = import_config.get('mysql', 'host', fallback='127.0.0.1')
        mysql_port = import_config.get('mysql', 'port', fallback='3306')
        mysql_usr = import_config.get('mysql', 'usr', fallback='root')
        mysql_pwd = import_config.get('mysql', 'pwd', fallback='')
        self.mysql_enable_checkBox.setChecked(mysql_enable)
        self.mysql_host_lineEdit.setText(mysql_host)
        self.mysql_port_lineEdit.setText(mysql_port)
        self.mysql_usr_lineEdit.setText(mysql_usr)
        self.mysql_pwd_lineEdit.setText(mysql_pwd)

        #初始化hikyuu交互式工具使用的默认数据库
        default_engine = import_config.get('default_engine',
                                           'engine',
                                           fallback='HDF5')
        if default_engine == 'HDF5':
            self.use_hdf5_radioButton.setChecked(True)
        else:
            self.use_mysql_radioButton.setChecked(True)

    def getCurrentConfig(self):
        import_config = ConfigParser()
        import_config['quotation'] = {
            'stock': self.import_stock_checkBox.isChecked(),
            'fund': self.import_fund_checkBox.isChecked(),
            'future': self.import_future_checkBox.isChecked()
        }
        import_config['ktype'] = {
            'day': self.import_day_checkBox.isChecked(),
            'min': self.import_min_checkBox.isChecked(),
            'min5': self.import_min5_checkBox.isChecked(),
            'tick': self.import_tick_checkBox.isChecked()
        }
        import_config['weight'] = {
            'enable': self.import_weight_checkBox.isChecked()
        }
        import_config['tdx'] = {
            'enable': self.tdx_radioButton.isChecked(),
            'dir': self.tdx_dir_lineEdit.text()
        }
        import_config['pytdx'] = {
            'enable': self.pytdx_radioButton.isChecked(),
            'server': self.tdx_servers_comboBox.currentText(),
            'ip': hq_hosts[self.tdx_servers_comboBox.currentIndex()][1],
            'port': hq_hosts[self.tdx_servers_comboBox.currentIndex()][2]
        }
        import_config['hdf5'] = {
            'enable': self.hdf5_enable_checkBox.isChecked(),
            'dir': self.hdf5_dir_lineEdit.text()
        }
        import_config['mysql'] = {
            'enable': self.mysql_enable_checkBox.isChecked(),
            'host': self.mysql_host_lineEdit.text(),
            'port': self.mysql_port_lineEdit.text(),
            'usr': self.mysql_usr_lineEdit.text(),
            'pwd': self.mysql_pwd_lineEdit.text()
        }
        import_config['default_engine'] = {
            'engine':
            "HDF5" if self.use_hdf5_radioButton.isChecked() else "MYSQL"
        }
        return import_config

    def initThreads(self):
        self.escape_time_thread = None
        self.hdf5_import_thread = None
        self.mysql_import_thread = None

        self.import_running = False
        self.hdf5_import_progress_bar = {
            'DAY': self.hdf5_day_progressBar,
            '1MIN': self.hdf5_min_progressBar,
            '5MIN': self.hdf5_5min_progressBar
        }

    def on_tdx_or_pytdx_toggled(self):
        tdx_enable = self.tdx_radioButton.isChecked()
        self.tdx_dir_lineEdit.setEnabled(tdx_enable)
        self.select_tdx_dir_pushButton.setEnabled(tdx_enable)
        self.tdx_servers_comboBox.setEnabled(not tdx_enable)
        self.tdx_port_lineEdit.setEnabled(not tdx_enable)

    @pyqtSlot()
    def on_select_tdx_dir_pushButton_clicked(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.Directory)
        config = self.getCurrentConfig()
        dlg.setDirectory(config['tdx']['dir'])
        if dlg.exec_():
            dirname = dlg.selectedFiles()
            self.tdx_dir_lineEdit.setText(dirname[0])

    @pyqtSlot()
    def on_select_dzh_dir_pushButton_clicked(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.Directory)
        config = self.getCurrentConfig()
        dlg.setDirectory(config['dzh']['dir'])
        if dlg.exec_():
            dirname = dlg.selectedFiles()
            self.dzh_dir_lineEdit.setText(dirname[0])

    @pyqtSlot()
    def on_hdf5_dir_pushButton_clicked(self):
        dlg = QFileDialog()
        dlg.setFileMode(QFileDialog.Directory)
        config = self.getCurrentConfig()
        dlg.setDirectory(config['hdf5']['dir'])
        if dlg.exec_():
            dirname = dlg.selectedFiles()
            self.hdf5_dir_lineEdit.setText(dirname[0])

    def reset_progress_bar(self):
        self.hdf5_weight_label.setText('')
        self.hdf5_day_progressBar.setValue(0)
        self.hdf5_min_progressBar.setValue(0)
        self.hdf5_5min_progressBar.setValue(0)
        self.import_detail_textEdit.clear()

    def on_escapte_time(self, escape):
        self.import_status_label.setText("耗时:{:>.2f} 秒".format(escape))

    def on_message_from_thread(self, msg):
        if not msg or len(msg) < 2:
            print("msg is empty!")
            return

        msg_name, msg_task_name = msg[:2]
        if msg_name == 'ESCAPE_TIME':
            self.escape_time = msg_task_name
            self.import_status_label.setText("耗时:{:>.2f} 秒 ({:>.2f}分钟)".format(
                self.escape_time, self.escape_time / 60))

        elif msg_name == 'HDF5_IMPORT':
            if msg_task_name == 'THREAD':
                status = msg[2]
                if status == 'FAILURE':
                    self.import_status_label.setText(
                        "耗时:{:>.2f} 秒 导入异常!".format(self.escape_time))
                    self.import_detail_textEdit.append(msg[3])
                self.hdf5_import_thread.terminate()
                self.hdf5_import_thread = None
                self.escape_time_thread.stop()
                self.escape_time_thread = None
                self.start_import_pushButton.setEnabled(True)
                self.import_detail_textEdit.append("导入完毕!")
                self.import_running = False

            elif msg_task_name == 'IMPORT_KDATA':
                ktype, progress = msg[2:4]
                if ktype != 'FINISHED':
                    self.hdf5_import_progress_bar[ktype].setValue(progress)
                else:
                    self.import_detail_textEdit.append(
                        '导入 {} {} 记录数:{}'.format(msg[3], msg[4], msg[5]))

            elif msg_task_name == 'IMPORT_WEIGHT':
                self.hdf5_weight_label.setText(msg[2])
                if msg[2] == '导入完成!':
                    self.import_detail_textEdit.append('导入权息记录数:{}'.format(
                        msg[3]))

    @pyqtSlot()
    def on_start_import_pushButton_clicked(self):
        self.import_running = True
        self.start_import_pushButton.setEnabled(False)
        self.reset_progress_bar()

        self.escape_time = 0.0
        self.escape_time_thread = EscapetimeThread()
        self.escape_time_thread.message.connect(self.on_message_from_thread)
        self.escape_time_thread.start()

        config = self.getCurrentConfig()

        if self.tdx_radioButton.isChecked():
            self.hdf5_import_thread = UseTdxImportToH5Thread(config)
        else:
            self.hdf5_import_thread = UsePytdxImportToH5Thread(config)

        self.hdf5_import_thread.message.connect(self.on_message_from_thread)
        self.hdf5_import_thread.start()