11import os
22from pathlib import Path
3- from typing import List , Union
3+ from typing import List , Union , Callable
44from logging import getLogger
55from random import Random
66
1212
1313def save_backtests_to_directory (
1414 backtests : List [Backtest ],
15- directory_path : Union [str , Path ]
15+ directory_path : Union [str , Path ],
16+ dir_name_generation_function : Callable [[Backtest ], str ] = None ,
17+ filter_function : Callable [[Backtest ], bool ] = None
1618) -> None :
1719 """
1820 Saves a list of Backtest objects to the specified directory.
@@ -21,6 +23,14 @@ def save_backtests_to_directory(
2123 backtests (List[Backtest]): List of Backtest objects to save.
2224 directory_path (str): Path to the directory where backtests
2325 will be saved.
26+ dir_name_generation_function (Callable[[Backtest], str], optional):
27+ A function that takes a Backtest object as input and returns
28+ a string to be used as the directory name for that backtest.
29+ If not provided, the backtest's metadata 'id' will be used.
30+ Defaults to None.
31+ filter_function (Callable[[Backtest], bool], optional): A function
32+ that takes a Backtest object as input and returns True if the
33+ backtest should be saved. Defaults to None.
2434
2535 Returns:
2636 None
@@ -30,28 +40,40 @@ def save_backtests_to_directory(
3040 os .makedirs (directory_path )
3141
3242 for backtest in backtests :
33- # Check if there is an ID in the backtest metadata
34- backtest_id = backtest .metadata .get ('id' )
3543
36- if backtest_id is None :
44+ if filter_function is not None :
45+ if not filter_function (backtest ):
46+ continue
47+
48+ if dir_name_generation_function is not None :
49+ dir_name = dir_name_generation_function (backtest )
50+ else :
51+ # Check if there is an ID in the backtest metadata
52+ dir_name = backtest .metadata .get ('id' , None )
53+
54+ if dir_name is None :
3755 logger .warning (
38- "Backtest is missing 'id' in metadata . "
39- "Generating a random ID as name for backtest file ."
56+ "Backtest metadata does not contain an 'id' field . "
57+ "Generating a random directory name."
4058 )
41- backtest_id = str (Random ().randint (100000 , 999999 ))
59+ dir_name = str (Random ().randint (100000 , 999999 ))
4260
43- backtest .save (os .path .join (directory_path , backtest_id ))
61+ backtest .save (os .path .join (directory_path , dir_name ))
4462
4563
4664def load_backtests_from_directory (
47- directory_path : Union [str , Path ]
65+ directory_path : Union [str , Path ],
66+ filter_function : Callable [[Backtest ], bool ] = None
4867) -> List [Backtest ]:
4968 """
5069 Loads Backtest objects from the specified directory.
5170
5271 Args:
5372 directory_path (str): Path to the directory from which backtests
5473 will be loaded.
74+ filter_function (Callable[[Backtest], bool], optional): A function
75+ that takes a Backtest object as input and returns True if the
76+ backtest should be included in the result. Defaults to None.
5577
5678 Returns:
5779 List[Backtest]: List of loaded Backtest objects.
@@ -71,6 +93,11 @@ def load_backtests_from_directory(
7193
7294 try :
7395 backtest = Backtest .open (file_path )
96+
97+ if filter_function is not None :
98+ if not filter_function (backtest ):
99+ continue
100+
74101 backtests .append (backtest )
75102 except Exception as e :
76103 logger .error (
0 commit comments