Skip to content

Conversation

@Johnkhk
Copy link
Contributor

@Johnkhk Johnkhk commented Sep 30, 2025

Pull Request

NautilusTrader prioritizes correctness and reliability, please follow existing patterns for validation and testing.

  • I have reviewed the CONTRIBUTING.md and followed the established practices

Summary

Fixes a critical bug introduced in PR #2870 where historical bar subscriptions fail to resubscribe after IB Gateway disconnects/reconnects due to a parameter
signature mismatch. The fix stores start timestamps separately from the resubscription handle to prevent TypeError during automatic resubscription, restoring
proper data flow after connection loss.

Related Issues/PRs

Fixes #3001
Related to #2870

Type of change

  • Bug fix (non-breaking)
  • New feature (non-breaking)
  • Breaking change (impacts existing behavior)
  • Documentation update
  • Maintenance / chore

Breaking change details (if applicable)

N/A - This is a bug fix that restores intended behavior without changing the public API.

Documentation

  • Documentation changes follow the style guide (docs/developer_guide/docs.md)

No documentation changes required (code-only fix).

Release notes

  • I added a concise entry to RELEASES.md that follows the existing conventions (when applicable)

Will add after review.

Testing

Ensure new or changed logic is covered by tests.

  • Affected code paths are already covered by the test suite
  • I added/updated tests to cover new or changed logic

Technical Details

Problem:

  • PR Refine subscribe_historical_bars in IB adapter #2870 passes start as a separate kwarg to _subscribe() instead of within params
  • Creates functools.partial with start=<value> in kwargs
  • On resubscription, the partial calls subscribe_historical_bars(start=...)
  • Method signature only accepts params dict → TypeError
  • Resubscription silently fails, causing data starvation

Solution:

  • Store start times in separate _subscription_start_times dict (keyed by req_id)
  • Pass full params dict to _subscribe() instead of individual start kwarg
  • Retrieve start from stored dict when filtering bars (line 907)
  • Clean up stored start time on unsubscribe

Affected versions: 1.220.0, 1.221.0+
Last working version: 1.219.0

Fixes a critical bug where historical bar subscriptions fail to
resubscribe after IB Gateway disconnects/reconnects, causing complete
data starvation in live/paper trading.

Problem:
- PR nautechsystems#2870 added `params` dict parameter to subscribe_historical_bars
- Extracts `start` from params for duration calculation and bar filtering
- But passes `start` as separate kwarg to _subscribe(), not in params
- This creates functools.partial with start=<value> in kwargs
- When resubscription happens, partial is called with start kwarg
- Method signature only accepts params dict, not start parameter
- TypeError: subscribe_historical_bars() got unexpected keyword 'start'
- Resubscription silently fails, no more bar data received

Solution:
- Store start times separately in _subscription_start_times dict
- Pass full params dict to _subscribe (not individual start)
- Retrieve start from stored dict when filtering bars
- Clean up start time on unsubscribe

This separates one-time configuration (start) from reusable
subscription handle, preventing parameter signature mismatch.

Affected versions: 1.220.0, 1.221.0+
Last working: 1.219.0

Related: nautechsystems#2870
@CLAassistant
Copy link

CLAassistant commented Sep 30, 2025

CLA assistant check
All committers have signed the CLA.

@faysou
Copy link
Collaborator

faysou commented Sep 30, 2025

Looks almost good to me. Only one thing to do now that I'm understanding the resubscription process better with your change, could you change this line

to start = params.pop("start_ns", None). Because start_ns is meant to indicate the last stored ts_init for a bar type in the catalog and a resubscription after a disconnection shouldn't replay all bars since start_ns before the first subscription, so we should use start_ns only once then remove it from the params dict.

@faysou
Copy link
Collaborator

faysou commented Sep 30, 2025

Thanks for the update, as discussed just now offline, we could improve the reconnection in IB by storing the time of disconnection and take it into account in a resubscription. This could be done in another PR. I think the PR is good to go.

@cjdsellers
Copy link
Member

Hi @Johnkhk

Thank you for the fix with detailed explanations! 🙏

@cjdsellers cjdsellers merged commit 48a6535 into nautechsystems:develop Sep 30, 2025
17 checks passed
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.

IB Historical Bars Resubscription Fails After Connection Loss

4 participants