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

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.

for i, _f in enumerate(fields):
_fields = [f"Ref(Mean({_f}, 15), {j * 15})" for j in range(1, 240 // 15)]
_names = [f"{names[i][:-1]}{int(names[i][-1])+j}" for j in range(240 // 15 - 1, 0, -1)]
_names = [
f"{names[i][:-1]}{int(names[i][-1])+j}"
for j in range(240 // 15 - 1, 0, -1)
]
_fields.append(f"Mean({_f}, 15)")
_names.append(f"{names[i][:-1]}{int(names[i][-1])+240 // 15}")
tmp_fields += _fields

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.

removed duplicate initialization of _names

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

2 participants