diff --git a/vnpy/app/csv_loader/__init__.py b/vnpy/app/csv_loader/__init__.py index c346646f..a50dc47d 100644 --- a/vnpy/app/csv_loader/__init__.py +++ b/vnpy/app/csv_loader/__init__.py @@ -10,7 +10,7 @@ class CsvLoaderApp(BaseApp): app_name = APP_NAME app_module = __module__ app_path = Path(__file__).parent - display_name = "CSV加载器" + display_name = "CSV载入" engine_class = CsvLoaderEngine widget_name = "CsvLoaderWidget" icon_name = "csv.ico" diff --git a/vnpy/app/csv_loader/engine.py b/vnpy/app/csv_loader/engine.py index 0f4152d2..7c403ddd 100644 --- a/vnpy/app/csv_loader/engine.py +++ b/vnpy/app/csv_loader/engine.py @@ -10,12 +10,12 @@ Sample csv file: ```csv "Datetime","Open","High","Low","Close","Volume" -2010-04-16T09:16:00.000000,3450.0,3488.0,3450.0,3468.0,489 -2010-04-16T09:17:00.000000,3468.0,3473.8,3467.0,3467.0,302 -2010-04-16T09:18:00.000000,3467.0,3471.0,3466.0,3467.0,203 -2010-04-16T09:19:00.000000,3467.0,3468.2,3448.0,3448.0,280 -2010-04-16T09:20:00.000000,3448.0,3459.0,3448.0,3454.0,250 -2010-04-16T09:21:00.000000,3454.0,3456.8,3454.0,3456.8,109 +2010-04-16 09:16:00,3450.0,3488.0,3450.0,3468.0,489 +2010-04-16 09:17:00,3468.0,3473.8,3467.0,3467.0,302 +2010-04-16 09:18:00,3467.0,3471.0,3466.0,3467.0,203 +2010-04-16 09:19:00,3467.0,3468.2,3448.0,3448.0,280 +2010-04-16 09:20:00,3448.0,3459.0,3448.0,3454.0,250 +2010-04-16 09:21:00,3454.0,3456.8,3454.0,3456.8,109 ``` """ @@ -51,17 +51,20 @@ class CsvLoaderEngine(BaseEngine): self.high_head: str = '' self.volume_head: str = '' - def load(self, - file_path: str, - symbol: str, - exchange: Exchange, - interval: Interval, - datetime_head: str, - open_head: str, - close_head: str, - low_head: str, - high_head: str, - volume_head: str): + def load( + self, + file_path: str, + symbol: str, + exchange: Exchange, + interval: Interval, + datetime_head: str, + open_head: str, + close_head: str, + low_head: str, + high_head: str, + volume_head: str, + datetime_format: str + ): """""" vt_symbol = f"{symbol}.{exchange.value}" @@ -77,7 +80,9 @@ class CsvLoaderEngine(BaseEngine): db_bar.symbol = symbol db_bar.exchange = exchange.value - db_bar.datetime = datetime.fromisoformat(item[datetime_head]) + db_bar.datetime = datetime.strptime( + item[datetime_head], datetime_format + ) db_bar.interval = interval.value db_bar.volume = item[volume_head] db_bar.open_price = item[open_head] @@ -87,7 +92,7 @@ class CsvLoaderEngine(BaseEngine): db_bar.vt_symbol = vt_symbol db_bar.gateway_name = "DB" - db_bar.save() + db_bar.replace() # do some statistics count += 1 diff --git a/vnpy/app/csv_loader/ui/csv_loader.ui b/vnpy/app/csv_loader/ui/csv_loader.ui deleted file mode 100644 index 44b6542c..00000000 --- a/vnpy/app/csv_loader/ui/csv_loader.ui +++ /dev/null @@ -1,166 +0,0 @@ - - - CsvLoader - - - CSV行情载入器 - - - - - - - - 选择文件 - - - - - - - - - - - - - - 合约信息 - - - - - - - Symbol - - - - - - - - - - Interval - - - - - - - - - - 表头属性 - - - - - - - Datetime - - - - - - - Datetime - - - - - - - Open - - - - - - - Open - - - - - - - High - - - - - - - High - - - - - - - Low - - - - - - - Low - - - - - - - Close - - - - - - - Close - - - - - - - Volume - - - - - - - Volume - - - - - - - Exchange - - - - - - - - - - - - 载入 - - - - - - - - diff --git a/vnpy/app/csv_loader/ui/uic/uic_csv_loader.py b/vnpy/app/csv_loader/ui/uic/uic_csv_loader.py deleted file mode 100644 index b96bd980..00000000 --- a/vnpy/app/csv_loader/ui/uic/uic_csv_loader.py +++ /dev/null @@ -1,117 +0,0 @@ -# -*- coding: utf-8 -*- - -# Form implementation generated from reading ui file '../csv_loader.ui' -# -# Created by: PyQt5 UI code generator 5.11.3 -# -# WARNING! All changes made in this file will be lost! - -from PyQt5 import QtCore, QtGui, QtWidgets - -class Ui_CsvLoader(object): - def setupUi(self, CsvLoader): - CsvLoader.setObjectName("CsvLoader") - self.verticalLayout = QtWidgets.QVBoxLayout(CsvLoader) - self.verticalLayout.setObjectName("verticalLayout") - self.horizontalLayout = QtWidgets.QHBoxLayout() - self.horizontalLayout.setObjectName("horizontalLayout") - self.choose_button = QtWidgets.QPushButton(CsvLoader) - self.choose_button.setObjectName("choose_button") - self.horizontalLayout.addWidget(self.choose_button) - self.file_edit = QtWidgets.QLineEdit(CsvLoader) - self.file_edit.setObjectName("file_edit") - self.horizontalLayout.addWidget(self.file_edit) - self.verticalLayout.addLayout(self.horizontalLayout) - self.formLayout = QtWidgets.QFormLayout() - self.formLayout.setObjectName("formLayout") - self.label_8 = QtWidgets.QLabel(CsvLoader) - self.label_8.setObjectName("label_8") - self.formLayout.setWidget(0, QtWidgets.QFormLayout.FieldRole, self.label_8) - self.label_9 = QtWidgets.QLabel(CsvLoader) - self.label_9.setObjectName("label_9") - self.formLayout.setWidget(1, QtWidgets.QFormLayout.LabelRole, self.label_9) - self.symbol_edit = QtWidgets.QLineEdit(CsvLoader) - self.symbol_edit.setObjectName("symbol_edit") - self.formLayout.setWidget(1, QtWidgets.QFormLayout.FieldRole, self.symbol_edit) - self.label_11 = QtWidgets.QLabel(CsvLoader) - self.label_11.setObjectName("label_11") - self.formLayout.setWidget(3, QtWidgets.QFormLayout.LabelRole, self.label_11) - self.interval_combo = QtWidgets.QComboBox(CsvLoader) - self.interval_combo.setObjectName("interval_combo") - self.formLayout.setWidget(3, QtWidgets.QFormLayout.FieldRole, self.interval_combo) - self.label = QtWidgets.QLabel(CsvLoader) - self.label.setObjectName("label") - self.formLayout.setWidget(4, QtWidgets.QFormLayout.FieldRole, self.label) - self.label_2 = QtWidgets.QLabel(CsvLoader) - self.label_2.setObjectName("label_2") - self.formLayout.setWidget(5, QtWidgets.QFormLayout.LabelRole, self.label_2) - self.datetime_edit = QtWidgets.QLineEdit(CsvLoader) - self.datetime_edit.setObjectName("datetime_edit") - self.formLayout.setWidget(5, QtWidgets.QFormLayout.FieldRole, self.datetime_edit) - self.label_3 = QtWidgets.QLabel(CsvLoader) - self.label_3.setObjectName("label_3") - self.formLayout.setWidget(6, QtWidgets.QFormLayout.LabelRole, self.label_3) - self.open_edit = QtWidgets.QLineEdit(CsvLoader) - self.open_edit.setObjectName("open_edit") - self.formLayout.setWidget(6, QtWidgets.QFormLayout.FieldRole, self.open_edit) - self.label_4 = QtWidgets.QLabel(CsvLoader) - self.label_4.setObjectName("label_4") - self.formLayout.setWidget(7, QtWidgets.QFormLayout.LabelRole, self.label_4) - self.high_edit = QtWidgets.QLineEdit(CsvLoader) - self.high_edit.setObjectName("high_edit") - self.formLayout.setWidget(7, QtWidgets.QFormLayout.FieldRole, self.high_edit) - self.label_5 = QtWidgets.QLabel(CsvLoader) - self.label_5.setObjectName("label_5") - self.formLayout.setWidget(8, QtWidgets.QFormLayout.LabelRole, self.label_5) - self.low_edit = QtWidgets.QLineEdit(CsvLoader) - self.low_edit.setObjectName("low_edit") - self.formLayout.setWidget(8, QtWidgets.QFormLayout.FieldRole, self.low_edit) - self.label_6 = QtWidgets.QLabel(CsvLoader) - self.label_6.setObjectName("label_6") - self.formLayout.setWidget(9, QtWidgets.QFormLayout.LabelRole, self.label_6) - self.close_edit = QtWidgets.QLineEdit(CsvLoader) - self.close_edit.setObjectName("close_edit") - self.formLayout.setWidget(9, QtWidgets.QFormLayout.FieldRole, self.close_edit) - self.label_7 = QtWidgets.QLabel(CsvLoader) - self.label_7.setObjectName("label_7") - self.formLayout.setWidget(10, QtWidgets.QFormLayout.LabelRole, self.label_7) - self.volume_edit = QtWidgets.QLineEdit(CsvLoader) - self.volume_edit.setObjectName("volume_edit") - self.formLayout.setWidget(10, QtWidgets.QFormLayout.FieldRole, self.volume_edit) - self.label_12 = QtWidgets.QLabel(CsvLoader) - self.label_12.setObjectName("label_12") - self.formLayout.setWidget(2, QtWidgets.QFormLayout.LabelRole, self.label_12) - self.exchange_combo = QtWidgets.QComboBox(CsvLoader) - self.exchange_combo.setObjectName("exchange_combo") - self.formLayout.setWidget(2, QtWidgets.QFormLayout.FieldRole, self.exchange_combo) - self.verticalLayout.addLayout(self.formLayout) - self.load_button = QtWidgets.QPushButton(CsvLoader) - self.load_button.setObjectName("load_button") - self.verticalLayout.addWidget(self.load_button) - - self.retranslateUi(CsvLoader) - QtCore.QMetaObject.connectSlotsByName(CsvLoader) - - def retranslateUi(self, CsvLoader): - _translate = QtCore.QCoreApplication.translate - CsvLoader.setWindowTitle(_translate("CsvLoader", "CSV行情载入器")) - self.choose_button.setText(_translate("CsvLoader", "选择文件")) - self.label_8.setText(_translate("CsvLoader", "合约信息")) - self.label_9.setText(_translate("CsvLoader", "Symbol")) - self.label_11.setText(_translate("CsvLoader", "Interval")) - self.label.setText(_translate("CsvLoader", "表头属性")) - self.label_2.setText(_translate("CsvLoader", "Datetime")) - self.datetime_edit.setText(_translate("CsvLoader", "Datetime")) - self.label_3.setText(_translate("CsvLoader", "Open")) - self.open_edit.setText(_translate("CsvLoader", "Open")) - self.label_4.setText(_translate("CsvLoader", "High")) - self.high_edit.setText(_translate("CsvLoader", "High")) - self.label_5.setText(_translate("CsvLoader", "Low")) - self.low_edit.setText(_translate("CsvLoader", "Low")) - self.label_6.setText(_translate("CsvLoader", "Close")) - self.close_edit.setText(_translate("CsvLoader", "Close")) - self.label_7.setText(_translate("CsvLoader", "Volume")) - self.volume_edit.setText(_translate("CsvLoader", "Volume")) - self.label_12.setText(_translate("CsvLoader", "Exchange")) - self.load_button.setText(_translate("CsvLoader", "载入")) - diff --git a/vnpy/app/csv_loader/ui/widget.py b/vnpy/app/csv_loader/ui/widget.py index a9ea2008..8de067c7 100644 --- a/vnpy/app/csv_loader/ui/widget.py +++ b/vnpy/app/csv_loader/ui/widget.py @@ -1,21 +1,12 @@ """ -Author: nanoric - -UI is designed by Qt Designer. source at csv_loader.ui -compile: -``` -pyuic5 csv_loader.ui -o uic/uic_csv_loader.py -``` +Author: Zehua Wei (nanoric) """ -from gettext import gettext as _ - from vnpy.event import EventEngine from vnpy.trader.constant import Exchange, Interval from vnpy.trader.engine import MainEngine from vnpy.trader.ui import QtWidgets, QtCore -from .uic.uic_csv_loader import Ui_CsvLoader from ..engine import APP_NAME @@ -32,38 +23,91 @@ class CsvLoaderWidget(QtWidgets.QWidget): def init_ui(self): """""" + self.setWindowTitle("CSV载入") + self.setFixedWidth(300) + self.setWindowFlags( - (self.windowFlags() | QtCore.Qt.CustomizeWindowHint) - & ~QtCore.Qt.WindowMaximizeButtonHint) + (self.windowFlags() | QtCore.Qt.CustomizeWindowHint) & + ~QtCore.Qt.WindowMaximizeButtonHint) - self.ui = Ui_CsvLoader() - self.ui.setupUi(self) + file_button = QtWidgets.QPushButton("选择文件") + file_button.clicked.connect(self.select_file) - for i in Interval: - self.ui.interval_combo.addItem(str(i.name), i) + load_button = QtWidgets.QPushButton("载入数据") + load_button.clicked.connect(self.load_data) + self.file_edit = QtWidgets.QLineEdit() + self.symbol_edit = QtWidgets.QLineEdit() + + self.exchange_combo = QtWidgets.QComboBox() for i in Exchange: - self.ui.exchange_combo.addItem(str(i.name), i) + self.exchange_combo.addItem(str(i.name), i) - def on_choose_button_pressed(self): + self.interval_combo = QtWidgets.QComboBox() + for i in Interval: + self.interval_combo.addItem(str(i.name), i) + + self.datetime_edit = QtWidgets.QLineEdit("Datetime") + self.open_edit = QtWidgets.QLineEdit("Open") + self.high_edit = QtWidgets.QLineEdit("High") + self.low_edit = QtWidgets.QLineEdit("Low") + self.close_edit = QtWidgets.QLineEdit("Close") + self.volume_edit = QtWidgets.QLineEdit("Volume") + + self.format_edit = QtWidgets.QLineEdit("%Y-%m-%d %H:%M:%S") + + info_label = QtWidgets.QLabel("合约信息") + info_label.setAlignment(QtCore.Qt.AlignCenter) + + head_label = QtWidgets.QLabel("表头信息") + head_label.setAlignment(QtCore.Qt.AlignCenter) + + format_label = QtWidgets.QLabel("格式信息") + format_label.setAlignment(QtCore.Qt.AlignCenter) + + form = QtWidgets.QFormLayout() + form.addRow(file_button, self.file_edit) + form.addRow(QtWidgets.QLabel()) + form.addRow(info_label) + form.addRow("代码", self.symbol_edit) + form.addRow("交易所", self.exchange_combo) + form.addRow("周期", self.interval_combo) + form.addRow(QtWidgets.QLabel()) + form.addRow(head_label) + form.addRow("时间戳", self.datetime_edit) + form.addRow("开盘价", self.open_edit) + form.addRow("最高价", self.high_edit) + form.addRow("最低价", self.low_edit) + form.addRow("收盘价", self.close_edit) + form.addRow("成交量", self.volume_edit) + form.addRow(QtWidgets.QLabel()) + form.addRow(format_label) + form.addRow("时间格式", self.format_edit) + form.addRow(QtWidgets.QLabel()) + form.addRow(load_button) + + self.setLayout(form) + + def select_file(self): """""" result: str = QtWidgets.QFileDialog.getOpenFileName(self) filename = result[0] if filename: - self.ui.file_edit.setText(filename) + self.file_edit.setText(filename) - def on_load_button_pressed(self): + def load_data(self): """""" - file_path = self.ui.file_edit.text() - symbol = self.ui.symbol_edit.text() - exchange = self.ui.exchange_combo.currentData() - interval = self.ui.interval_combo.currentData() - datetime_head = self.ui.datetime_edit.text() - open_head = self.ui.open_edit.text() - low_head = self.ui.low_edit.text() - high_head = self.ui.high_edit.text() - close_head = self.ui.close_edit.text() - volume_head = self.ui.volume_edit.text() + file_path = self.file_edit.text() + symbol = self.symbol_edit.text() + exchange = self.exchange_combo.currentData() + interval = self.interval_combo.currentData() + datetime_head = self.datetime_edit.text() + open_head = self.open_edit.text() + low_head = self.low_edit.text() + high_head = self.high_edit.text() + close_head = self.close_edit.text() + volume_head = self.volume_edit.text() + datetime_format = self.format_edit.text() start, end, count = self.engine.load( file_path, @@ -75,16 +119,17 @@ class CsvLoaderWidget(QtWidgets.QWidget): high_head, low_head, close_head, - volume_head + volume_head, + datetime_format ) - msg = f""" - CSV载入成功 - 代码:{symbol} - 交易所:{exchange.value} - 周期:{interval.value} - 起始:{start} - 结束:{end} - 总数量:{count} - """ - QtWidgets.QMessageBox.information(self, _("载入成功!"), msg) + msg = f"\ + CSV载入成功\n\ + 代码:{symbol}\n\ + 交易所:{exchange.value}\n\ + 周期:{interval.value}\n\ + 起始:{start}\n\ + 结束:{end}\n\ + 总数量:{count}\n\ + " + QtWidgets.QMessageBox.information(self, "载入成功!", msg) diff --git a/vnpy/trader/ui/mainwindow.py b/vnpy/trader/ui/mainwindow.py index 2171a42c..d8c6280b 100644 --- a/vnpy/trader/ui/mainwindow.py +++ b/vnpy/trader/ui/mainwindow.py @@ -110,7 +110,7 @@ class MainWindow(QtWidgets.QMainWindow): func = partial(self.open_widget, widget_class, app.app_name) icon_path = str(app.app_path.joinpath("ui", app.icon_name)) self.add_menu_action( - app_menu, f"打开{app.display_name}", icon_path, func + app_menu, app.display_name, icon_path, func ) # Help menu