Merge pull request #1497 from nanoric/csv_loader_designer
Csv loader designer
This commit is contained in:
commit
7c533458ff
2
.flake8
2
.flake8
@ -1,5 +1,5 @@
|
||||
[flake8]
|
||||
exclude = __pycache__,__init__.py,ib,talib
|
||||
exclude = __pycache__,__init__.py,ib,talib,uic
|
||||
ignore =
|
||||
E501 line too long, fixed by black
|
||||
W503 line break before binary operator
|
||||
|
16
vnpy/app/csv_loader/__init__.py
Normal file
16
vnpy/app/csv_loader/__init__.py
Normal file
@ -0,0 +1,16 @@
|
||||
from pathlib import Path
|
||||
|
||||
from vnpy.trader.app import BaseApp
|
||||
from .csv_loader import APP_NAME, CsvLoader
|
||||
|
||||
|
||||
class CsvLoaderApp(BaseApp):
|
||||
""""""
|
||||
|
||||
app_name = APP_NAME
|
||||
app_module = __module__
|
||||
app_path = Path(__file__).parent
|
||||
display_name = "CSV行情载入器"
|
||||
engine_class = CsvLoader
|
||||
widget_name = "CsvLoaderWidget"
|
||||
icon_name = "cta.ico"
|
81
vnpy/app/csv_loader/csv_loader.py
Normal file
81
vnpy/app/csv_loader/csv_loader.py
Normal file
@ -0,0 +1,81 @@
|
||||
"""
|
||||
Author: nanoric
|
||||
|
||||
Load data from a csv file.
|
||||
|
||||
Differences to 1.9.2:
|
||||
* combine Date column and Time column into one DateTime column
|
||||
|
||||
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
|
||||
```
|
||||
|
||||
"""
|
||||
|
||||
import csv
|
||||
from datetime import datetime
|
||||
|
||||
from vnpy.event import EventEngine
|
||||
from vnpy.trader.constant import Exchange, Interval
|
||||
from vnpy.trader.database import DbBarData
|
||||
from vnpy.trader.engine import BaseEngine, MainEngine
|
||||
from vnpy.trader.object import BarData
|
||||
|
||||
APP_NAME = "CsvLoader"
|
||||
|
||||
|
||||
class CsvLoader(BaseEngine):
|
||||
|
||||
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||
""""""
|
||||
super().__init__(main_engine, event_engine, APP_NAME)
|
||||
|
||||
self.file_path: str = ''
|
||||
|
||||
self.symbol: str = ""
|
||||
self.exchange: Exchange = Exchange.SSE
|
||||
self.interval: Interval = Interval.MINUTE
|
||||
self.datetime_head: str = ''
|
||||
self.open_head: str = ''
|
||||
self.close_head: str = ''
|
||||
self.low_head: str = ''
|
||||
self.high_head: str = ''
|
||||
self.volume_head: str = ''
|
||||
|
||||
def load(self):
|
||||
""""""
|
||||
symbol = self.symbol
|
||||
exchange = self.exchange
|
||||
interval = self.interval
|
||||
|
||||
datetime_head = self.datetime_head
|
||||
open_head = self.open_head
|
||||
close_head = self.close_head
|
||||
low_head = self.low_head
|
||||
high_head = self.high_head
|
||||
volume_head = self.volume_head
|
||||
|
||||
with open(self.file_path, 'rt') as f:
|
||||
reader = csv.DictReader(f)
|
||||
for item in reader:
|
||||
bar = BarData(
|
||||
'',
|
||||
symbol,
|
||||
exchange,
|
||||
datetime.fromisoformat(item[datetime_head]),
|
||||
interval,
|
||||
item[volume_head],
|
||||
item[open_head],
|
||||
item[high_head],
|
||||
item[low_head],
|
||||
item[close_head],
|
||||
)
|
||||
DbBarData.from_bar(bar).save()
|
1
vnpy/app/csv_loader/ui/__init__.py
Normal file
1
vnpy/app/csv_loader/ui/__init__.py
Normal file
@ -0,0 +1 @@
|
||||
from .csv_loader_widget import CsvLoaderWidget
|
166
vnpy/app/csv_loader/ui/csv_loader.ui
Normal file
166
vnpy/app/csv_loader/ui/csv_loader.ui
Normal file
@ -0,0 +1,166 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<ui version="4.0">
|
||||
<class>CsvLoader</class>
|
||||
<widget class="QDialog" name="CsvLoader">
|
||||
<property name="windowTitle">
|
||||
<string>Csv载入器</string>
|
||||
</property>
|
||||
<layout class="QVBoxLayout" name="verticalLayout">
|
||||
<item>
|
||||
<layout class="QHBoxLayout" name="horizontalLayout">
|
||||
<item>
|
||||
<widget class="QPushButton" name="choose_button">
|
||||
<property name="text">
|
||||
<string>选择文件</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QLineEdit" name="file_edit"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<layout class="QFormLayout" name="formLayout">
|
||||
<item row="0" column="1">
|
||||
<widget class="QLabel" name="label_8">
|
||||
<property name="text">
|
||||
<string>合约信息</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="0">
|
||||
<widget class="QLabel" name="label_9">
|
||||
<property name="text">
|
||||
<string>Symbol</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="1" column="1">
|
||||
<widget class="QLineEdit" name="symbol_edit"/>
|
||||
</item>
|
||||
<item row="3" column="0">
|
||||
<widget class="QLabel" name="label_11">
|
||||
<property name="text">
|
||||
<string>Interval</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="3" column="1">
|
||||
<widget class="QComboBox" name="interval_combo"/>
|
||||
</item>
|
||||
<item row="4" column="1">
|
||||
<widget class="QLabel" name="label">
|
||||
<property name="text">
|
||||
<string>表头属性</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="0">
|
||||
<widget class="QLabel" name="label_2">
|
||||
<property name="text">
|
||||
<string>Datetime</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="5" column="1">
|
||||
<widget class="QLineEdit" name="datetime_edit">
|
||||
<property name="text">
|
||||
<string>Datetime</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="0">
|
||||
<widget class="QLabel" name="label_3">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="6" column="1">
|
||||
<widget class="QLineEdit" name="open_edit">
|
||||
<property name="text">
|
||||
<string>Open</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="0">
|
||||
<widget class="QLabel" name="label_4">
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="7" column="1">
|
||||
<widget class="QLineEdit" name="high_edit">
|
||||
<property name="text">
|
||||
<string>High</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="0">
|
||||
<widget class="QLabel" name="label_5">
|
||||
<property name="text">
|
||||
<string>Low</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="8" column="1">
|
||||
<widget class="QLineEdit" name="low_edit">
|
||||
<property name="text">
|
||||
<string>Low</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="0">
|
||||
<widget class="QLabel" name="label_6">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="9" column="1">
|
||||
<widget class="QLineEdit" name="close_edit">
|
||||
<property name="text">
|
||||
<string>Close</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="0">
|
||||
<widget class="QLabel" name="label_7">
|
||||
<property name="text">
|
||||
<string>Volume</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="10" column="1">
|
||||
<widget class="QLineEdit" name="volume_edit">
|
||||
<property name="text">
|
||||
<string>Volume</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="0">
|
||||
<widget class="QLabel" name="label_12">
|
||||
<property name="text">
|
||||
<string>Exchange</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
<item row="2" column="1">
|
||||
<widget class="QComboBox" name="exchange_combo"/>
|
||||
</item>
|
||||
</layout>
|
||||
</item>
|
||||
<item>
|
||||
<widget class="QPushButton" name="load_button">
|
||||
<property name="text">
|
||||
<string>载入</string>
|
||||
</property>
|
||||
</widget>
|
||||
</item>
|
||||
</layout>
|
||||
</widget>
|
||||
<resources/>
|
||||
<connections/>
|
||||
</ui>
|
61
vnpy/app/csv_loader/ui/csv_loader_widget.py
Normal file
61
vnpy/app/csv_loader/ui/csv_loader_widget.py
Normal file
@ -0,0 +1,61 @@
|
||||
"""
|
||||
Author: nanoric
|
||||
|
||||
UI is designed by Qt Designer. source at csv_loader.ui
|
||||
compile:
|
||||
```
|
||||
pyuic5 csv_loader.ui -o uic/uic_csv_loader.py
|
||||
```
|
||||
"""
|
||||
from PyQt5.QtWidgets import QFileDialog
|
||||
from vnpy.event import EventEngine
|
||||
from vnpy.trader.constant import Interval, Exchange
|
||||
from vnpy.trader.engine import MainEngine
|
||||
from vnpy.trader.ui import QtWidgets
|
||||
|
||||
from .uic.uic_csv_loader import Ui_CsvLoader
|
||||
from ..csv_loader import CsvLoader
|
||||
|
||||
|
||||
class CsvLoaderWidget(QtWidgets.QWidget):
|
||||
""""""
|
||||
|
||||
def __init__(self, main_engine: MainEngine, event_engine: EventEngine):
|
||||
""""""
|
||||
super().__init__()
|
||||
self.loader = CsvLoader(main_engine, event_engine)
|
||||
self.ui = Ui_CsvLoader()
|
||||
|
||||
self.init_ui()
|
||||
|
||||
def init_ui(self):
|
||||
""""""
|
||||
self.ui.setupUi(self)
|
||||
|
||||
for i in Interval:
|
||||
self.ui.interval_combo.addItem(str(i), i)
|
||||
|
||||
for i in Exchange:
|
||||
self.ui.exchange_combo.addItem(str(i), i)
|
||||
|
||||
def on_choose_button_pressed(self):
|
||||
""""""
|
||||
result: str = QFileDialog.getOpenFileName(self)
|
||||
filename = result[0]
|
||||
if filename:
|
||||
self.ui.file_edit.setText(filename)
|
||||
|
||||
def on_load_button_pressed(self):
|
||||
""""""
|
||||
self.loader.file_path = self.ui.file_edit.text()
|
||||
self.loader.symbol = self.ui.symbol_edit.text()
|
||||
self.loader.exchange = self.ui.exchange_combo.currentData()
|
||||
self.loader.interval = self.ui.interval_combo.currentData()
|
||||
self.loader.datetime_head = self.ui.datetime_edit.text()
|
||||
self.loader.open_head = self.ui.open_edit.text()
|
||||
self.loader.close_head = self.ui.close_edit.text()
|
||||
self.loader.low_head = self.ui.low_edit.text()
|
||||
self.loader.high_head = self.ui.high_edit.text()
|
||||
self.loader.volume_head = self.ui.volume_edit.text()
|
||||
|
||||
self.loader.load()
|
117
vnpy/app/csv_loader/ui/uic/uic_csv_loader.py
Normal file
117
vnpy/app/csv_loader/ui/uic/uic_csv_loader.py
Normal file
@ -0,0 +1,117 @@
|
||||
# -*- 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", "载入"))
|
||||
|
Loading…
Reference in New Issue
Block a user