Skip to content

Commit a38b857

Browse files
committed
Remove already imported files from widget list
1 parent f12a190 commit a38b857

File tree

4 files changed

+158
-117
lines changed

4 files changed

+158
-117
lines changed
Lines changed: 100 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,100 @@
1+
# -*- coding: utf-8 -*-
2+
3+
# Form implementation generated from reading ui file 'c:\perso\trading\anaconda3\backtrader-ichimoku\ui\loadDataFiles.ui'
4+
#
5+
# Created by: PyQt5 UI code generator 5.15.5
6+
#
7+
# WARNING: Any manual changes made to this file will be lost when pyuic5 is
8+
# run again. Do not edit this file unless you know what you are doing.
9+
10+
11+
from PyQt5 import QtCore, QtGui, QtWidgets
12+
13+
14+
class Ui_Form(object):
15+
def setupUi(self, Form):
16+
Form.setObjectName("Form")
17+
Form.resize(390, 458)
18+
self.gridLayout_2 = QtWidgets.QGridLayout(Form)
19+
self.gridLayout_2.setObjectName("gridLayout_2")
20+
self.dataFilesListWidget = QtWidgets.QListWidget(Form)
21+
sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Preferred)
22+
sizePolicy.setHorizontalStretch(0)
23+
sizePolicy.setVerticalStretch(0)
24+
sizePolicy.setHeightForWidth(self.dataFilesListWidget.sizePolicy().hasHeightForWidth())
25+
self.dataFilesListWidget.setSizePolicy(sizePolicy)
26+
self.dataFilesListWidget.setObjectName("dataFilesListWidget")
27+
self.gridLayout_2.addWidget(self.dataFilesListWidget, 3, 0, 1, 1)
28+
self.label_4 = QtWidgets.QLabel(Form)
29+
self.label_4.setObjectName("label_4")
30+
self.gridLayout_2.addWidget(self.label_4, 2, 0, 1, 1)
31+
self.importPB = QtWidgets.QPushButton(Form)
32+
self.importPB.setObjectName("importPB")
33+
self.gridLayout_2.addWidget(self.importPB, 5, 0, 1, 2)
34+
self.verticalLayout = QtWidgets.QVBoxLayout()
35+
self.verticalLayout.setObjectName("verticalLayout")
36+
self.gridLayout_2.addLayout(self.verticalLayout, 3, 1, 1, 1)
37+
self.groupBox = QtWidgets.QGroupBox(Form)
38+
self.groupBox.setObjectName("groupBox")
39+
self.gridLayout = QtWidgets.QGridLayout(self.groupBox)
40+
self.gridLayout.setObjectName("gridLayout")
41+
self.label = QtWidgets.QLabel(self.groupBox)
42+
self.label.setObjectName("label")
43+
self.gridLayout.addWidget(self.label, 0, 0, 1, 1)
44+
self.filePathLE = QtWidgets.QLineEdit(self.groupBox)
45+
self.filePathLE.setObjectName("filePathLE")
46+
self.gridLayout.addWidget(self.filePathLE, 0, 1, 1, 2)
47+
self.openFilePB = QtWidgets.QToolButton(self.groupBox)
48+
self.openFilePB.setObjectName("openFilePB")
49+
self.gridLayout.addWidget(self.openFilePB, 0, 3, 1, 1)
50+
self.label_3 = QtWidgets.QLabel(self.groupBox)
51+
self.label_3.setObjectName("label_3")
52+
self.gridLayout.addWidget(self.label_3, 1, 0, 1, 1)
53+
self.datetimeFormatLE = QtWidgets.QLineEdit(self.groupBox)
54+
self.datetimeFormatLE.setObjectName("datetimeFormatLE")
55+
self.gridLayout.addWidget(self.datetimeFormatLE, 1, 1, 1, 2)
56+
self.label_2 = QtWidgets.QLabel(self.groupBox)
57+
self.label_2.setObjectName("label_2")
58+
self.gridLayout.addWidget(self.label_2, 2, 0, 1, 1)
59+
self.tabRB = QtWidgets.QRadioButton(self.groupBox)
60+
self.tabRB.setChecked(True)
61+
self.tabRB.setObjectName("tabRB")
62+
self.gridLayout.addWidget(self.tabRB, 2, 1, 1, 1)
63+
self.commaRB = QtWidgets.QRadioButton(self.groupBox)
64+
self.commaRB.setObjectName("commaRB")
65+
self.gridLayout.addWidget(self.commaRB, 2, 2, 1, 1)
66+
self.errorLabel = QtWidgets.QLabel(self.groupBox)
67+
self.errorLabel.setStyleSheet("color: red")
68+
self.errorLabel.setText("")
69+
self.errorLabel.setAlignment(QtCore.Qt.AlignCenter)
70+
self.errorLabel.setObjectName("errorLabel")
71+
self.gridLayout.addWidget(self.errorLabel, 4, 0, 1, 3)
72+
self.loadFilePB = QtWidgets.QPushButton(self.groupBox)
73+
self.loadFilePB.setObjectName("loadFilePB")
74+
self.gridLayout.addWidget(self.loadFilePB, 3, 1, 1, 2)
75+
self.gridLayout_2.addWidget(self.groupBox, 0, 0, 1, 2)
76+
self.label_5 = QtWidgets.QLabel(Form)
77+
self.label_5.setStyleSheet("font-style: italic")
78+
self.label_5.setScaledContents(False)
79+
self.label_5.setAlignment(QtCore.Qt.AlignCenter)
80+
self.label_5.setWordWrap(True)
81+
self.label_5.setObjectName("label_5")
82+
self.gridLayout_2.addWidget(self.label_5, 4, 0, 1, 1)
83+
84+
self.retranslateUi(Form)
85+
QtCore.QMetaObject.connectSlotsByName(Form)
86+
87+
def retranslateUi(self, Form):
88+
_translate = QtCore.QCoreApplication.translate
89+
Form.setWindowTitle(_translate("Form", "Import one or multiple data files"))
90+
self.label_4.setText(_translate("Form", "List of all files to import in cerebro"))
91+
self.importPB.setText(_translate("Form", "Import all data files"))
92+
self.groupBox.setTitle(_translate("Form", "Loading a new data file"))
93+
self.label.setText(_translate("Form", "Import a new data file"))
94+
self.openFilePB.setText(_translate("Form", "..."))
95+
self.label_3.setText(_translate("Form", "Date time format"))
96+
self.label_2.setText(_translate("Form", "Separator"))
97+
self.tabRB.setText(_translate("Form", "tab"))
98+
self.commaRB.setText(_translate("Form", "comma"))
99+
self.loadFilePB.setText(_translate("Form", "Load .CSV file"))
100+
self.label_5.setText(_translate("Form", "Files should be ordered from lower (on top) to higher timeframe (at bottom)."))

Controller.py

Lines changed: 39 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -106,14 +106,17 @@ def loadData(self, dataPath, datetimeFormat, separator):
106106
# We should code a widget that ask for options as : separators, date format, and so on...
107107
try:
108108
fileName = os.path.basename(dataPath)
109-
self.dataframes[fileName] = pd.read_csv(dataPath,
110-
sep=separator,
111-
parse_dates=[0],
112-
date_parser=lambda x: pd.to_datetime(x, format=datetimeFormat),
113-
skiprows=0,
114-
header=0,
115-
names=["Time", "Open", "High", "Low", "Close", "Volume"],
116-
index_col=0)
109+
110+
# Python contains
111+
if not dataPath in self.dataframes:
112+
self.dataframes[fileName] = pd.read_csv(dataPath,
113+
sep=separator,
114+
parse_dates=[0],
115+
date_parser=lambda x: pd.to_datetime(x, format=datetimeFormat),
116+
skiprows=0,
117+
header=0,
118+
names=["Time", "Open", "High", "Low", "Close", "Volume"],
119+
index_col=0)
117120

118121
except ValueError as err:
119122
return False, "ValueError error:" + str(err)
@@ -126,31 +129,40 @@ def loadData(self, dataPath, datetimeFormat, separator):
126129

127130
def importData(self, fileNamesOrdered):
128131

129-
# Files should be loaded in the good order
130-
for fileName in fileNamesOrdered:
131-
132-
df = self.dataframes[fileName]
132+
try:
133133

134-
# Datetime first column : 2012-12-28 17:45:00
135-
#self.dataframe['TimeInt'] = pd.to_datetime(self.dataframe.index).astype('int64') # use finplot's internal representation, which is ns
136-
137-
# Pass it to the backtrader datafeed and add it to the cerebro
138-
self.data = bt.feeds.PandasData(dataname=df, timeframe=bt.TimeFrame.Minutes)
134+
# Files should be loaded in the good order
135+
for fileName in fileNamesOrdered:
136+
137+
df = self.dataframes[fileName]
139138

140-
# Add data to cerebro : only add data when all files have been selected for multi-timeframes
141-
self.cerebro.adddata(self.data) # Add the data feed
139+
# Datetime first column : 2012-12-28 17:45:00
140+
#self.dataframe['TimeInt'] = pd.to_datetime(self.dataframe.index).astype('int64') # use finplot's internal representation, which is ns
141+
142+
# Pass it to the backtrader datafeed and add it to the cerebro
143+
self.data = bt.feeds.PandasData(dataname=df, timeframe=bt.TimeFrame.Minutes)
142144

143-
# find the time frame
144-
timeframe = self.findTimeFrame(df)
145+
# Add data to cerebro : only add data when all files have been selected for multi-timeframes
146+
self.cerebro.adddata(self.data) # Add the data feed
145147

146-
# Create the chart window for the good timeframe (if it does not already exists?)
147-
self.interface.createChartDock(timeframe)
148+
# find the time frame
149+
timeframe = self.findTimeFrame(df)
148150

149-
# Draw charts based on input data
150-
self.interface.drawChart(df, timeframe)
151+
# Create the chart window for the good timeframe (if it does not already exists?)
152+
self.interface.createChartDock(timeframe)
151153

152-
# Enable run button
153-
self.interface.strategyTesterUI.runBacktestPB.setEnabled(True)
154+
# Draw charts based on input data
155+
self.interface.drawChart(df, timeframe)
156+
157+
# Enable run button
158+
self.interface.strategyTesterUI.runBacktestPB.setEnabled(True)
159+
160+
return True
161+
162+
except:
163+
164+
print("Unexpected error:" + str(sys.exc_info()[0]))
165+
return False
154166

155167
pass
156168

@@ -178,7 +190,6 @@ def findTimeFrame(self,df):
178190

179191
pass
180192

181-
182193
def addStrategy(self, strategyName):
183194

184195
#For now, only one strategy is allowed at a time

loadDataFilesUI.py

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,6 @@ def __init__(self, controller, parent = None):
2626

2727
self.openFilePB = self.findChild(QtWidgets.QToolButton, "openFilePB")
2828
self.loadFilePB = self.findChild(QtWidgets.QPushButton, "loadFilePB")
29-
self.downPB = self.findChild(QtWidgets.QLineEdit, "downPB")
30-
self.upPB = self.findChild(QtWidgets.QLineEdit, "upPB")
3129
self.deletePB = self.findChild(QtWidgets.QLineEdit, "deletePB")
3230
self.importPB = self.findChild(QtWidgets.QPushButton, "importPB")
3331

@@ -46,10 +44,8 @@ def __init__(self, controller, parent = None):
4644
pass
4745

4846
def openFile(self):
49-
5047
self.dataFileName = QtWidgets.QFileDialog.getOpenFileName(self, 'Open data file', self.current_dir_path + "/data","CSV files (*.csv)")[0]
5148
self.filePathLE.setText(self.dataFileName)
52-
5349
pass
5450

5551
def loadFile(self):
@@ -64,7 +60,11 @@ def loadFile(self):
6460
self.errorLabel.setText("The file has been loaded correctly.")
6561

6662
# Add file name
67-
self.dataFilesListWidget.addItem(os.path.basename(self.dataFileName))
63+
fileName = os.path.basename(self.dataFileName)
64+
items = self.dataFilesListWidget.findItems(fileName, QtCore.Qt.MatchFixedString)
65+
66+
if len(items) == 0:
67+
self.dataFilesListWidget.addItem(os.path.basename(self.dataFileName))
6868

6969
else:
7070

@@ -82,9 +82,10 @@ def importFiles(self):
8282
items.append(self.dataFilesListWidget.item(x).text())
8383

8484
# Give all ordered data path to the controller
85-
self.controller.importData(items)
86-
self.hide()
87-
85+
if self.controller.importData(items):
86+
self.dataFilesListWidget.clear()
87+
self.hide()
88+
8889
pass
8990

9091
'''

ui/loadDataFiles.ui

Lines changed: 10 additions & 81 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
<rect>
77
<x>0</x>
88
<y>0</y>
9-
<width>596</width>
10-
<height>440</height>
9+
<width>390</width>
10+
<height>458</height>
1111
</rect>
1212
</property>
1313
<property name="windowTitle">
@@ -39,78 +39,7 @@
3939
</widget>
4040
</item>
4141
<item row="3" column="1">
42-
<layout class="QVBoxLayout" name="verticalLayout">
43-
<item>
44-
<widget class="QPushButton" name="downPB">
45-
<property name="sizePolicy">
46-
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
47-
<horstretch>0</horstretch>
48-
<verstretch>0</verstretch>
49-
</sizepolicy>
50-
</property>
51-
<property name="maximumSize">
52-
<size>
53-
<width>16777215</width>
54-
<height>16777215</height>
55-
</size>
56-
</property>
57-
<property name="text">
58-
<string>Down</string>
59-
</property>
60-
</widget>
61-
</item>
62-
<item>
63-
<widget class="QPushButton" name="upPB">
64-
<property name="sizePolicy">
65-
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
66-
<horstretch>0</horstretch>
67-
<verstretch>0</verstretch>
68-
</sizepolicy>
69-
</property>
70-
<property name="maximumSize">
71-
<size>
72-
<width>16777215</width>
73-
<height>16777215</height>
74-
</size>
75-
</property>
76-
<property name="text">
77-
<string>Up</string>
78-
</property>
79-
</widget>
80-
</item>
81-
<item>
82-
<widget class="QPushButton" name="deletePB">
83-
<property name="sizePolicy">
84-
<sizepolicy hsizetype="Minimum" vsizetype="Preferred">
85-
<horstretch>0</horstretch>
86-
<verstretch>0</verstretch>
87-
</sizepolicy>
88-
</property>
89-
<property name="maximumSize">
90-
<size>
91-
<width>16777215</width>
92-
<height>16777215</height>
93-
</size>
94-
</property>
95-
<property name="text">
96-
<string>Delete</string>
97-
</property>
98-
</widget>
99-
</item>
100-
<item>
101-
<spacer name="verticalSpacer">
102-
<property name="orientation">
103-
<enum>Qt::Vertical</enum>
104-
</property>
105-
<property name="sizeHint" stdset="0">
106-
<size>
107-
<width>20</width>
108-
<height>40</height>
109-
</size>
110-
</property>
111-
</spacer>
112-
</item>
113-
</layout>
42+
<layout class="QVBoxLayout" name="verticalLayout"/>
11443
</item>
11544
<item row="0" column="0" colspan="2">
11645
<widget class="QGroupBox" name="groupBox">
@@ -169,13 +98,6 @@
16998
</property>
17099
</widget>
171100
</item>
172-
<item row="3" column="1">
173-
<widget class="QPushButton" name="loadFilePB">
174-
<property name="text">
175-
<string>Load file</string>
176-
</property>
177-
</widget>
178-
</item>
179101
<item row="4" column="0" colspan="3">
180102
<widget class="QLabel" name="errorLabel">
181103
<property name="styleSheet">
@@ -189,6 +111,13 @@
189111
</property>
190112
</widget>
191113
</item>
114+
<item row="3" column="1" colspan="2">
115+
<widget class="QPushButton" name="loadFilePB">
116+
<property name="text">
117+
<string>Load .CSV file</string>
118+
</property>
119+
</widget>
120+
</item>
192121
</layout>
193122
</widget>
194123
</item>

0 commit comments

Comments
 (0)