11import json
22import os
3+ from uuid import uuid4
34from pathlib import Path
45from dataclasses import dataclass , field
56from logging import getLogger
@@ -46,6 +47,7 @@ class Backtest:
4647 algorithm_id (int): The ID of the algorithm associated with this
4748 backtest.
4849 """
50+ id : str = field (default_factory = lambda : str (uuid4 ()))
4951 backtest_runs : List [BacktestRun ] = field (default_factory = list )
5052 backtest_summary : BacktestSummaryMetrics = field (default = None )
5153 backtest_permutation_tests : List [BacktestPermutationTest ] = \
@@ -199,6 +201,7 @@ def open(directory_path: Union[str, Path]) -> 'Backtest':
199201 OperationalException: If the directory does not exist or if
200202 there is an error loading the files.
201203 """
204+ id = None
202205 backtest_runs = []
203206 backtest_summary_metrics = None
204207 permutation_metrics = []
@@ -210,6 +213,17 @@ def open(directory_path: Union[str, Path]) -> 'Backtest':
210213 f"The directory { directory_path } does not exist."
211214 )
212215
216+ # Load id if available
217+ id_file = os .path .join (directory_path , "id.json" )
218+ if os .path .isfile (id_file ):
219+ with open (id_file , 'r' ) as f :
220+ try :
221+ id = json .load (f ).get ('id' , None )
222+ except json .JSONDecodeError as e :
223+ logger .error (f"Error decoding id JSON: { e } " )
224+ id = None
225+ # Load combined backtest metrics if available
226+
213227 summary_file = os .path .join (directory_path , "summary.json" )
214228
215229 if os .path .isfile (summary_file ):
@@ -259,6 +273,7 @@ def open(directory_path: Union[str, Path]) -> 'Backtest':
259273 risk_free_rate = None
260274
261275 return Backtest (
276+ id = id ,
262277 backtest_runs = backtest_runs ,
263278 backtest_summary = backtest_summary_metrics ,
264279 backtest_permutation_tests = permutation_metrics ,
@@ -287,6 +302,11 @@ def save(self, directory_path: Union[str, Path]) -> None:
287302 if not os .path .exists (directory_path ):
288303 os .makedirs (directory_path )
289304
305+ # Save id of the backtest
306+ id_file = os .path .join (directory_path , "id.json" )
307+ with open (id_file , 'w' ) as f :
308+ json .dump ({'id' : self .id }, f , indent = 4 )
309+
290310 # Call the save method of all backtest runs
291311 if self .backtest_runs :
292312 run_path = os .path .join (directory_path , "runs" )
@@ -429,11 +449,7 @@ def add_permutation_test(
429449 self .backtest_permutation_tests .append (permutation_test )
430450
431451 def __hash__ (self ):
432- start_dates = [run .backtest_start_date for run in self .backtest_runs ]
433- end_dates = [run .backtest_end_date for run in self .backtest_runs ]
434- metadata_items = tuple (sorted (self .metadata .items ()))
435- return hash ((
436- tuple (sorted (start_dates )),
437- tuple (sorted (end_dates )),
438- metadata_items
439- ))
452+ return hash (self .id )
453+
454+ def __eq__ (self , other ):
455+ return isinstance (other , Backtest ) and self .id == other .id
0 commit comments