Skip to content

Commit b41a222

Browse files
committed
Fix checkpoint loading
1 parent 8ac9c19 commit b41a222

2 files changed

Lines changed: 96 additions & 6 deletions

File tree

investing_algorithm_framework/domain/backtesting/backtest_metrics.py

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -363,14 +363,14 @@ def _parse_tuple_datetime(data) -> Tuple[float, datetime]:
363363
if data is None:
364364
return None, None
365365

366-
# Check if the value is NaN or None
367-
if pd.isna(data[0]) or data[0] is None:
366+
# Check if the value is NaN, None, or the string '<NA>'
367+
if pd.isna(data[0]) or data[0] is None or data[0] == '<NA>':
368368
value = pd.NA
369369
else:
370370
value = float(data[0])
371371

372372
# Parse the datetime string
373-
if data[1] is None or pd.isna(data[1]):
373+
if data[1] is None or pd.isna(data[1]) or data[1] == '<NA>':
374374
date_value = None
375375
else:
376376
# Convert the string to a datetime object
@@ -384,14 +384,14 @@ def _parse_tuple_date(data) -> Tuple[float, date]:
384384
if data is None:
385385
return None, None
386386

387-
# Check if the value is
388-
if pd.isna(data[0]) or data[0] is None:
387+
# Check if the value is NaN, None, or the string '<NA>'
388+
if pd.isna(data[0]) or data[0] is None or data[0] == '<NA>':
389389
value = pd.NA
390390
else:
391391
value = float(data[0])
392392

393393
# Parse the date string
394-
if data[1] is None or pd.isna(data[1]):
394+
if data[1] is None or pd.isna(data[1]) or data[1] == '<NA>':
395395
date = None
396396
else:
397397
date = datetime.fromisoformat(data[1]).date()

investing_algorithm_framework/infrastructure/services/backtesting/backtest_service.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -999,6 +999,33 @@ def run_vector_backtests(
999999
if alg_id not in filtered_algorithm_ids
10001000
]
10011001

1002+
# Clear filtered_out flag for backtests that passed
1003+
# the filter (they may have been filtered out before)
1004+
for alg_id in filtered_algorithm_ids:
1005+
backtest_dir = os.path.join(
1006+
backtest_storage_directory, alg_id
1007+
)
1008+
if os.path.exists(backtest_dir):
1009+
try:
1010+
backtest = Backtest.open(backtest_dir)
1011+
if backtest.metadata is not None and \
1012+
backtest.metadata.get(
1013+
'filtered_out', False
1014+
):
1015+
# Clear the filtered_out flag
1016+
backtest.metadata['filtered_out'] = False
1017+
if 'filtered_out_at_date_range' in \
1018+
backtest.metadata:
1019+
del backtest.metadata[
1020+
'filtered_out_at_date_range'
1021+
]
1022+
backtest.save(backtest_dir)
1023+
except Exception as e:
1024+
logger.warning(
1025+
f"Could not clear filtered_out flag "
1026+
f"for backtest {alg_id}: {e}"
1027+
)
1028+
10021029
# Mark filtered-out backtests with metadata flag
10031030
# This preserves them in storage for future runs
10041031
for alg_id in algorithms_to_mark:
@@ -1964,6 +1991,69 @@ def run_backtests(
19641991
]
19651992
for alg_id in algorithms_to_remove:
19661993
del backtests_by_algorithm[alg_id]
1994+
else:
1995+
# When using storage, update filtered_out metadata
1996+
algorithms_to_mark = [
1997+
alg_id for alg_id in active_algorithm_ids
1998+
if alg_id not in filtered_ids
1999+
]
2000+
2001+
# Clear filtered_out flag for backtests that passed
2002+
# the filter (they may have been filtered out before)
2003+
for alg_id in filtered_ids:
2004+
backtest_dir = os.path.join(
2005+
backtest_storage_directory, alg_id
2006+
)
2007+
if os.path.exists(backtest_dir):
2008+
try:
2009+
backtest = Backtest.open(backtest_dir)
2010+
if backtest.metadata is not None and \
2011+
backtest.metadata.get(
2012+
'filtered_out', False
2013+
):
2014+
backtest.metadata['filtered_out'] = False
2015+
if 'filtered_out_at_date_range' in \
2016+
backtest.metadata:
2017+
del backtest.metadata[
2018+
'filtered_out_at_date_range'
2019+
]
2020+
backtest.save(backtest_dir)
2021+
except Exception as e:
2022+
logger.warning(
2023+
f"Could not clear filtered_out flag "
2024+
f"for backtest {alg_id}: {e}"
2025+
)
2026+
2027+
# Mark filtered-out backtests with metadata flag
2028+
for alg_id in algorithms_to_mark:
2029+
backtest_dir = os.path.join(
2030+
backtest_storage_directory, alg_id
2031+
)
2032+
if os.path.exists(backtest_dir):
2033+
try:
2034+
backtest = Backtest.open(backtest_dir)
2035+
start_date = backtest_date_range.start_date
2036+
end_date = backtest_date_range.end_date
2037+
date_key = (
2038+
f"{start_date.isoformat()}_"
2039+
f"{end_date.isoformat()}"
2040+
)
2041+
if backtest.metadata is None:
2042+
backtest.metadata = {}
2043+
backtest.metadata['filtered_out'] = True
2044+
backtest.metadata[
2045+
'filtered_out_at_date_range'
2046+
] = (
2047+
backtest_date_range.name
2048+
if backtest_date_range.name
2049+
else date_key
2050+
)
2051+
backtest.save(backtest_dir)
2052+
except Exception as e:
2053+
logger.warning(
2054+
f"Could not mark backtest {alg_id} "
2055+
f"as filtered: {e}"
2056+
)
19672057

19682058
# Clear memory
19692059
del all_backtests

0 commit comments

Comments
 (0)