Skip to content

Handle backtest calendar right boundary#2282

Open
Kevin-Li-2025 wants to merge 1 commit into
microsoft:mainfrom
Kevin-Li-2025:kevin/fix-calendar-right-boundary
Open

Handle backtest calendar right boundary#2282
Kevin-Li-2025 wants to merge 1 commit into
microsoft:mainfrom
Kevin-Li-2025:kevin/fix-calendar-right-boundary

Conversation

@Kevin-Li-2025

Copy link
Copy Markdown

Summary

Fixes #2278.

TradeCalendarManager.get_step_time() forms each step interval as [calendar[i], epsilon_change(calendar[i + 1])]. When a provider has no future calendar extension and a backtest ends on the final available calendar bar, the last step has no calendar[i + 1] and raises an opaque IndexError.

This PR keeps the normal next-calendar path unchanged, but when the next calendar bar is unavailable it infers the right endpoint from the manager frequency (calendar[i] + freq) and then applies the existing epsilon_change closed-interval convention. For a daily final bar, the last interval becomes 2020-01-02 00:00:00 through 2020-01-02 23:59:59 instead of crashing.

Tests

  • PYTHONPYCACHEPREFIX=/private/tmp/qlib-pycache /usr/bin/python3 -m py_compile qlib/backtest/utils.py tests/backtest/test_trade_calendar_manager.py
  • git diff --check
  • /opt/homebrew/bin/python3.11 -m ruff check tests/backtest/test_trade_calendar_manager.py
  • isolated harness that stubs package-level Qlib imports, loads qlib/backtest/utils.py, and verifies both the normal next-calendar path and the final-calendar fallback

Note: direct local pytest -q tests/backtest/test_trade_calendar_manager.py is blocked in this unbuilt source checkout by missing compiled extensions (qlib.data._libs.rolling). The added test is a normal repository test and should run after CI builds the extension.

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.

Backtest IndexError at the right calendar boundary (get_step_time peeks calendar[index+1])

1 participant