From 56bd807d63eac2a68a374c2788d05493346c1deb Mon Sep 17 00:00:00 2001 From: Linlang <30293408+SunsetWolf@users.noreply.github.com> Date: Tue, 13 Jan 2026 14:41:35 +0800 Subject: [PATCH] fix: prevent calendar index overflow when signal data ends early (#1324) * fix: prevent calendar index overflow when signal data ends early * fix: make test_end optional to resolve Qlib backtest calendar misalignment * fix: enhance GPU information output in get_gpu_info function * fix: improve GPU information output in get_gpu_info function for better clarity --------- Co-authored-by: Xu Yang --- rdagent/app/qlib_rd_loop/conf.py | 8 ++++-- .../scenarios/qlib/developer/factor_runner.py | 3 +- .../scenarios/qlib/developer/model_runner.py | 3 +- rdagent/scenarios/qlib/docker/Dockerfile | 1 - .../factor_template/conf_baseline.yaml | 6 ++-- .../conf_combined_factors.yaml | 6 ++-- .../conf_combined_factors_sota_model.yaml | 6 ++-- .../conf_baseline_factors_model.yaml | 6 ++-- .../conf_sota_factors_model.yaml | 6 ++-- rdagent/scenarios/shared/runtime_info.py | 28 ++++++++++++++++--- rdagent/utils/__init__.py | 2 +- rdagent/utils/env.py | 2 +- 12 files changed, 50 insertions(+), 27 deletions(-) diff --git a/rdagent/app/qlib_rd_loop/conf.py b/rdagent/app/qlib_rd_loop/conf.py index 657502b4..891157ed 100644 --- a/rdagent/app/qlib_rd_loop/conf.py +++ b/rdagent/app/qlib_rd_loop/conf.py @@ -1,3 +1,5 @@ +from typing import Optional + from pydantic_settings import SettingsConfigDict from rdagent.components.workflow.conf import BasePropSetting @@ -43,7 +45,7 @@ class ModelBasePropSetting(BasePropSetting): test_start: str = "2017-01-01" """Start date of the test / backtest segment""" - test_end: str = "2020-12-31" + test_end: Optional[str] = None """End date of the test / backtest segment""" @@ -87,7 +89,7 @@ class FactorBasePropSetting(BasePropSetting): test_start: str = "2017-01-01" """Start date of the test / backtest segment""" - test_end: str = "2020-12-31" + test_end: Optional[str] = None """End date of the test / backtest segment""" @@ -164,7 +166,7 @@ class QuantBasePropSetting(BasePropSetting): test_start: str = "2017-01-01" """Start date of the test / backtest segment""" - test_end: str = "2020-12-31" + test_end: Optional[str] = None """End date of the test / backtest segment""" diff --git a/rdagent/scenarios/qlib/developer/factor_runner.py b/rdagent/scenarios/qlib/developer/factor_runner.py index d314f0f2..00304da2 100644 --- a/rdagent/scenarios/qlib/developer/factor_runner.py +++ b/rdagent/scenarios/qlib/developer/factor_runner.py @@ -89,8 +89,9 @@ class QlibFactorRunner(CachedRunner[QlibFactorExperiment]): "valid_start": fbps.valid_start, "valid_end": fbps.valid_end, "test_start": fbps.test_start, - "test_end": fbps.test_end, } + if fbps.test_end is not None: + env_to_use.update({"test_end": fbps.test_end}) if exp.based_experiments: SOTA_factor = None diff --git a/rdagent/scenarios/qlib/developer/model_runner.py b/rdagent/scenarios/qlib/developer/model_runner.py index a7835ab0..9e8e4e49 100644 --- a/rdagent/scenarios/qlib/developer/model_runner.py +++ b/rdagent/scenarios/qlib/developer/model_runner.py @@ -67,8 +67,9 @@ class QlibModelRunner(CachedRunner[QlibModelExperiment]): "valid_start": mbps.valid_start, "valid_end": mbps.valid_end, "test_start": mbps.test_start, - "test_end": mbps.test_end, } + if mbps.test_end is not None: + env_to_use.update({"test_end": mbps.test_end}) training_hyperparameters = exp.sub_tasks[0].training_hyperparameters if training_hyperparameters: diff --git a/rdagent/scenarios/qlib/docker/Dockerfile b/rdagent/scenarios/qlib/docker/Dockerfile index 598f2d92..e7c87260 100644 --- a/rdagent/scenarios/qlib/docker/Dockerfile +++ b/rdagent/scenarios/qlib/docker/Dockerfile @@ -21,5 +21,4 @@ RUN python -m pip install -e . RUN pip install catboost RUN pip install xgboost -RUN pip install scipy==1.11.4 RUN pip install tables diff --git a/rdagent/scenarios/qlib/experiment/factor_template/conf_baseline.yaml b/rdagent/scenarios/qlib/experiment/factor_template/conf_baseline.yaml index 5b371272..189333a4 100644 --- a/rdagent/scenarios/qlib/experiment/factor_template/conf_baseline.yaml +++ b/rdagent/scenarios/qlib/experiment/factor_template/conf_baseline.yaml @@ -7,7 +7,7 @@ benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: {{ train_start | default("2008-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} fit_start_time: {{ train_start | default("2008-01-01", true) }} fit_end_time: {{ train_end | default("2014-12-31", true) }} instruments: *market @@ -43,7 +43,7 @@ port_analysis_config: &port_analysis_config n_drop: 5 backtest: start_time: {{ test_start | default("2017-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} account: 100000000 benchmark: *benchmark exchange_kwargs: @@ -77,7 +77,7 @@ task: segments: train: [{{ train_start | default("2008-01-01", true) }}, {{ train_end | default("2014-12-31", true) }}] valid: [{{ valid_start | default("2015-01-01", true) }}, {{ valid_end | default("2016-12-31", true) }}] - test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default("2020-08-01", true) }}] + test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default(null, true) }}] record: - class: SignalRecord module_path: qlib.workflow.record_temp diff --git a/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors.yaml b/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors.yaml index dfca9a17..47ae345c 100644 --- a/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors.yaml +++ b/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors.yaml @@ -7,7 +7,7 @@ benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: {{ train_start | default("2008-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} instruments: *market data_loader: class: NestedDataLoader @@ -51,7 +51,7 @@ port_analysis_config: &port_analysis_config n_drop: 5 backtest: start_time: {{ test_start | default("2017-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} account: 100000000 benchmark: *benchmark exchange_kwargs: @@ -86,7 +86,7 @@ task: segments: train: [{{ train_start | default("2008-01-01", true) }}, {{ train_end | default("2014-12-31", true) }}] valid: [{{ valid_start | default("2015-01-01", true) }}, {{ valid_end | default("2016-12-31", true) }}] - test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default("2020-08-01", true) }}] + test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default(null, true) }}] record: - class: SignalRecord module_path: qlib.workflow.record_temp diff --git a/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors_sota_model.yaml b/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors_sota_model.yaml index de7dd1b3..9f786891 100644 --- a/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors_sota_model.yaml +++ b/rdagent/scenarios/qlib/experiment/factor_template/conf_combined_factors_sota_model.yaml @@ -7,7 +7,7 @@ benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: {{ train_start | default("2008-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} instruments: *market data_loader: class: NestedDataLoader @@ -61,7 +61,7 @@ port_analysis_config: &port_analysis_config n_drop: 5 backtest: start_time: {{ test_start | default("2017-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} account: 100000000 benchmark: *benchmark exchange_kwargs: @@ -100,7 +100,7 @@ task: segments: train: [{{ train_start | default("2008-01-01", true) }}, {{ train_end | default("2014-12-31", true) }}] valid: [{{ valid_start | default("2015-01-01", true) }}, {{ valid_end | default("2016-12-31", true) }}] - test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default("2020-08-01", true) }}] + test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default(null, true) }}] {% if step_len %}step_len: {{ step_len }}{% endif %} record: - class: SignalRecord diff --git a/rdagent/scenarios/qlib/experiment/model_template/conf_baseline_factors_model.yaml b/rdagent/scenarios/qlib/experiment/model_template/conf_baseline_factors_model.yaml index b48bea80..6673fec9 100644 --- a/rdagent/scenarios/qlib/experiment/model_template/conf_baseline_factors_model.yaml +++ b/rdagent/scenarios/qlib/experiment/model_template/conf_baseline_factors_model.yaml @@ -5,7 +5,7 @@ market: &market csi300 benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: {{ train_start | default("2008-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} fit_start_time: {{ train_start | default("2008-01-01", true) }} fit_end_time: {{ train_end | default("2014-12-31", true) }} instruments: *market @@ -41,7 +41,7 @@ port_analysis_config: &port_analysis_config n_drop: 5 backtest: start_time: {{ test_start | default("2017-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} account: 100000000 benchmark: *benchmark exchange_kwargs: @@ -80,7 +80,7 @@ task: segments: train: [{{ train_start | default("2008-01-01", true) }}, {{ train_end | default("2014-12-31", true) }}] valid: [{{ valid_start | default("2015-01-01", true) }}, {{ valid_end | default("2016-12-31", true) }}] - test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default("2020-08-01", true) }}] + test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default(null, true) }}] {% if step_len %}step_len: {{ step_len }}{% endif %} record: - class: SignalRecord diff --git a/rdagent/scenarios/qlib/experiment/model_template/conf_sota_factors_model.yaml b/rdagent/scenarios/qlib/experiment/model_template/conf_sota_factors_model.yaml index de7dd1b3..9f786891 100644 --- a/rdagent/scenarios/qlib/experiment/model_template/conf_sota_factors_model.yaml +++ b/rdagent/scenarios/qlib/experiment/model_template/conf_sota_factors_model.yaml @@ -7,7 +7,7 @@ benchmark: &benchmark SH000300 data_handler_config: &data_handler_config start_time: {{ train_start | default("2008-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} instruments: *market data_loader: class: NestedDataLoader @@ -61,7 +61,7 @@ port_analysis_config: &port_analysis_config n_drop: 5 backtest: start_time: {{ test_start | default("2017-01-01", true) }} - end_time: {{ test_end | default("2020-08-01", true) }} + end_time: {{ test_end | default(null, true) }} account: 100000000 benchmark: *benchmark exchange_kwargs: @@ -100,7 +100,7 @@ task: segments: train: [{{ train_start | default("2008-01-01", true) }}, {{ train_end | default("2014-12-31", true) }}] valid: [{{ valid_start | default("2015-01-01", true) }}, {{ valid_end | default("2016-12-31", true) }}] - test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default("2020-08-01", true) }}] + test: [{{ test_start | default("2017-01-01", true) }}, {{ test_end | default(null, true) }}] {% if step_len %}step_len: {{ step_len }}{% endif %} record: - class: SignalRecord diff --git a/rdagent/scenarios/shared/runtime_info.py b/rdagent/scenarios/shared/runtime_info.py index c1bb0408..3f3836df 100644 --- a/rdagent/scenarios/shared/runtime_info.py +++ b/rdagent/scenarios/shared/runtime_info.py @@ -17,10 +17,30 @@ def get_gpu_info(): if torch.cuda.is_available(): print("\n=== GPU Info (via PyTorch) ===") print(f"CUDA Version: {torch.version.cuda}") - print(f"GPU Device: {torch.cuda.get_device_name(0)}") - print(f"Total GPU Memory: {torch.cuda.get_device_properties(0).total_memory / 1024**3:.2f} GB") - print(f"Allocated Memory: {torch.cuda.memory_allocated(0) / 1024**3:.2f} GB") - print(f"Cached Memory: {torch.cuda.memory_reserved(0) / 1024**3:.2f} GB") + print(f"GPU Count: {torch.cuda.device_count()}") + if torch.cuda.device_count() > 0: + gpu_name_list = [] + gpu_total_mem_list = [] + gpu_allocated_mem_list = [] + gpu_cached_mem_list = [] + + for i in range(torch.cuda.device_count()): + gpu_name_list.append(torch.cuda.get_device_name(i)) + gpu_total_mem_list.append(torch.cuda.get_device_properties(i).total_memory) + gpu_allocated_mem_list.append(torch.cuda.memory_allocated(i)) + gpu_cached_mem_list.append(torch.cuda.memory_reserved(i)) + + for i in range(torch.cuda.device_count()): + print(f" - GPU {i}: {gpu_name_list[i]}") + print(f" Total Memory: {gpu_total_mem_list[i] / 1024**3:.2f} GB") + print(f" Allocated Memory: {gpu_allocated_mem_list[i] / 1024**3:.2f} GB") + print(f" Cached Memory: {gpu_cached_mem_list[i] / 1024**3:.2f} GB") + print(" - All GPUs Summary:") + print(f" Total Memory: {sum(gpu_total_mem_list) / 1024**3:.2f} GB") + print(f" Total Allocated Memory: {sum(gpu_allocated_mem_list) / 1024**3:.2f} GB") + print(f" Total Cached Memory: {sum(gpu_cached_mem_list) / 1024**3:.2f} GB") + else: + print("No CUDA GPU detected (PyTorch)!") else: print("\nNo CUDA GPU detected (PyTorch).") diff --git a/rdagent/utils/__init__.py b/rdagent/utils/__init__.py index 769c6fcf..2e811df7 100644 --- a/rdagent/utils/__init__.py +++ b/rdagent/utils/__init__.py @@ -119,7 +119,7 @@ def filter_redundant_text(stdout: str) -> str: filtered_stdout = try_regex_sub(progress_bar_pattern, filtered_stdout, flags=regex.VERBOSE) # Collapse any excessive blank lines/spaces - filtered_stdout = try_regex_sub(r"\s*\n\s*", filtered_stdout, replace_with="\n") + filtered_stdout = try_regex_sub(r"\s*\n", filtered_stdout, replace_with="\n") # remove repeated lines lines_to_count: dict[str, int] = {} diff --git a/rdagent/utils/env.py b/rdagent/utils/env.py index b66f1cc0..5ae073e9 100644 --- a/rdagent/utils/env.py +++ b/rdagent/utils/env.py @@ -687,7 +687,7 @@ class QlibCondaEnv(LocalEnv[QlibCondaConf]): shell=True, ) subprocess.check_call( - f"conda run -n {self.conf.conda_env_name} pip install catboost xgboost scipy==1.11.4 tables torch", + f"conda run -n {self.conf.conda_env_name} pip install catboost xgboost tables torch", shell=True, ) except Exception as e: