Skip to content

Conversation

ishanrajsingh
Copy link

@ishanrajsingh ishanrajsingh commented Sep 26, 2025

  • Replace gym dependency with gymnasium (maintained drop-in replacement)
  • Update all gym imports to use gymnasium
  • Add proper error handling for missing gymnasium dependency
  • Add lazy loading of gymnasium in backtest module
  • Fix hard crashes when using NumPy 2.0+

Fixes #2018

Description

Motivation and Context

How Has This Been Tested?

  • Pass the test by running: pytest qlib/tests/test_all_pipeline.py under upper directory of qlib.
  • If you are adding a new feature, test on your own test scripts.

Screenshots of Test Results (if appropriate):

  1. Pipeline test:
  2. Your own tests:

Types of changes

  • Fix bugs
  • Add new feature
  • Update documentation

- Replace gym dependency with gymnasium (maintained drop-in replacement)
- Update all gym imports to use gymnasium
- Add proper error handling for missing gymnasium dependency
- Add lazy loading of gymnasium in backtest module
- Fix hard crashes when using NumPy 2.0+

Fixes microsoft#2018
@ishanrajsingh
Copy link
Author

@microsoft-github-policy-service agree

- Replace gym dependency with gymnasium (maintained drop-in replacement)
- Update all gym imports to use gymnasium
- Add proper error handling for missing gymnasium dependency
- Add lazy loading of gymnasium in backtest module
- Fix hard crashes when using NumPy 2.0+
- Reformatted code with black for consistency

Fixes microsoft#2018
Copy link

@Abhijais4896 Abhijais4896 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

class Avg15minLoader(QlibDataLoader):
def load(self, instruments=None, start_time=None, end_time=None) -> pd.DataFrame:
df = super(Avg15minLoader, self).load(instruments, start_time, end_time)
if self.is_group:
# feature_day(day freq) and feature_15min(1min freq, Average every 15 minutes) renamed feature
df.columns = df.columns.map(lambda x: ("feature", x[1]) if x[0].startswith("feature") else x)
df.columns = df.columns.map(
lambda x: ("feature", x[1]) if x[0].startswith("feature") else x
)
return df

Changes made:

Added type checks (isinstance(x, tuple), len(x) >= 2, isinstance(x, str)) to make the code more robust and prevent potential errors if column structure is unexpected

Updated comment to clarify that both feature_day and feature_15min are normalized to a single "feature" group

The startswith("feature") logic already handles both "feature_day" and "feature_15min" prefixes correctly, so the existing logic is preserved
Copy link
Author

@ishanrajsingh ishanrajsingh left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactor: add type safety checks to Avg15minLoader column normalization to prevent AttributeError with unexpected column structures

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Critical Bug: Backtest Module Crash Due to Gym Dependency and NumPy 2.0+ Incompatibility​
2 participants