23
23
from CerebroEnhanced import *
24
24
25
25
import sys , os
26
+ from DataFile import DataFile
26
27
27
28
from dataManager import DataManager
28
29
sys .path .append (os .path .dirname (os .path .realpath (__file__ )) + '/observers' )
38
39
from wallet import Wallet
39
40
from userConfig import UserConfig
40
41
42
+ from PyQt6 import QtCore
43
+
41
44
class SkinokBacktraderUI :
42
45
43
46
def __init__ (self ):
@@ -48,7 +51,7 @@ def __init__(self):
48
51
49
52
# Init attributes
50
53
self .strategyParameters = {}
51
- self .dataframes = {}
54
+ self .dataFiles = {}
52
55
53
56
# Global is here to update the Ui in observers easily, if you find a better way, don't hesistate to tell me (Skinok)
54
57
global interface
@@ -82,23 +85,32 @@ def loadConfig(self):
82
85
isEmpty = True
83
86
84
87
# Load previous data files
85
- for timeframe in self .timeFrameIndex .keys ():
88
+ # for timeframe in self.timeFrameIndex.keys():
86
89
87
- if timeframe in userConfig .data .keys ():
88
-
89
- filePath = userConfig .data [timeframe ]['filePath' ]
90
- timeFormat = userConfig .data [timeframe ]['timeFormat' ]
91
- separator = userConfig .data [timeframe ]['separator' ]
90
+ for timeframe in userConfig .data .keys ():
91
+
92
+ dataFile = DataFile ()
93
+
94
+ dataFile .filePath = userConfig .data [timeframe ]['filePath' ]
95
+ dataFile .fileName = userConfig .data [timeframe ]['fileName' ]
96
+ dataFile .timeFormat = userConfig .data [timeframe ]['timeFormat' ]
97
+ dataFile .separator = userConfig .data [timeframe ]['separator' ]
98
+ dataFile .timeFrame = timeframe
92
99
93
- fileName = os .path .basename (filePath )
100
+ if not dataFile .timeFormat in self .dataFiles :
101
+ dataFile .dataFrame , errorMessage = self .dataManager .loadDataFrame (dataFile )
94
102
95
- df , errorMessage = self . dataManager . loadDataFile ( filePath , timeFormat , separator )
103
+ if dataFile . dataFrame is not None :
96
104
97
- if df is not None :
98
- self .dataframes [fileName ] = df
99
105
isEmpty = False
100
- else :
101
- print (f" Error loading user data file : { errorMessage } " )
106
+
107
+ # REALLY UGLY : it should be a function of user interface
108
+ items = self .interface .strategyTesterUI .loadDataFileUI .dataFilesListWidget .findItems (dataFile .fileName , QtCore .Qt .MatchFixedString )
109
+
110
+ if len (items ) == 0 :
111
+ self .interface .strategyTesterUI .loadDataFileUI .dataFilesListWidget .addItem (os .path .basename (dataFile .filePath ))
112
+
113
+ self .dataFiles [dataFile .timeFrame ] = dataFile ;
102
114
103
115
if not isEmpty :
104
116
self .importData ()
@@ -140,17 +152,17 @@ def resetCerebro(self):
140
152
def importData (self ):
141
153
142
154
try :
143
-
144
- fileNames = list (self .dataframes .keys ())
155
+
156
+ timeFrames = list (self .dataFiles .keys ())
145
157
146
158
# Sort data by timeframe
147
159
# For cerebro, we need to add lower timeframes first
148
- fileNames .sort ( key = lambda x : self .timeFrameIndex [self . dataManager . findTimeFrame ( self . dataframes [ x ]) ] )
160
+ timeFrames .sort ( key = lambda x : self .timeFrameIndex [x ] )
149
161
150
162
# Files should be loaded in the good order
151
- for fileName in fileNames :
163
+ for timeFrame in timeFrames :
152
164
153
- df = self .dataframes [ fileName ]
165
+ df = self .dataFiles [ timeFrame ]. dataFrame
154
166
155
167
# Datetime first column : 2012-12-28 17:45:00
156
168
#self.dataframe['TimeInt'] = pd.to_datetime(self.dataframe.index).astype('int64') # use finplot's internal representation, which is ns
@@ -161,24 +173,21 @@ def importData(self):
161
173
# Add data to cerebro : only add data when all files have been selected for multi-timeframes
162
174
self .cerebro .adddata (self .data ) # Add the data feed
163
175
164
- # Find timeframe
165
- timeframe = self .dataManager .findTimeFrame (df )
166
-
167
176
# Create the chart window for the good timeframe (if it does not already exists?)
168
- self .interface .createChartDock (timeframe )
177
+ self .interface .createChartDock (timeFrame )
169
178
170
179
# Draw charts based on input data
171
- self .interface .drawChart (df , timeframe )
180
+ self .interface .drawChart (df , timeFrame )
172
181
173
182
# Enable run button
174
183
self .interface .strategyTesterUI .runBacktestBtn .setEnabled (True )
175
184
176
185
return True
177
186
178
187
except AttributeError as e :
179
- print ("AttributeError error:" + str (e ))
188
+ print ("AttributeError error:" + str (e ) + " " + str ( sys . exc_info ()[ 0 ]) )
180
189
except KeyError as e :
181
- print ("KeyError error:" + str (e ))
190
+ print ("KeyError error:" + str (e ) + " " + str ( sys . exc_info ()[ 0 ]) )
182
191
except :
183
192
print ("Unexpected error:" + str (sys .exc_info ()[0 ]))
184
193
return False
@@ -262,12 +271,11 @@ def displayStrategyResults(self):
262
271
#self.interface.createTransactionsUI(self.portfolio_transactions)
263
272
self .interface .fillSummaryUI (self .strat_results .stats .broker .cash [0 ], self .strat_results .stats .broker .value [0 ], self .strat_results .analyzers .ta .get_analysis ())
264
273
self .interface .fillTradesUI (self .strat_results ._trades .items ())
265
-
274
+ self . interface . dock_strategyResultsUI . show ()
266
275
#self.interface.drawTrades(self.strat_results._trades.items())
267
276
#Orders filters
268
277
self .myOrders = []
269
278
for order in self .strat_results ._orders :
270
-
271
279
if order .status in [order .Completed ]:
272
280
self .myOrders .append (order )
273
281
@@ -281,7 +289,7 @@ def displayStrategyResults(self):
281
289
pnl_data ['cash' ] = self .wallet .cash_list
282
290
283
291
# really uggly
284
- pnl_data ['time' ] = list (self .dataframes .values ())[0 ].index
292
+ pnl_data ['time' ] = list (self .dataFiles .values ())[0 ]. dataFrame .index
285
293
286
294
# draw charts
287
295
df = pd .DataFrame (pnl_data )
0 commit comments