Skip to content

Commit 7635a05

Browse files
committed
Add filtering logic for backtest saving and loading
1 parent 6f57a3c commit 7635a05

File tree

1 file changed

+37
-10
lines changed

1 file changed

+37
-10
lines changed

investing_algorithm_framework/app/analysis/backtest_utils.py

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
from pathlib import Path
3-
from typing import List, Union
3+
from typing import List, Union, Callable
44
from logging import getLogger
55
from random import Random
66

@@ -12,7 +12,9 @@
1212

1313
def 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

4664
def 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

Comments
 (0)