Skip to content

Fix runtime error when an option universe is removed and re-added in the same time step#9626

Merged
jhonabreul merged 8 commits into
QuantConnect:masterfrom
jhonabreul:bug-option-universe-remove-readd
Jul 20, 2026
Merged

Fix runtime error when an option universe is removed and re-added in the same time step#9626
jhonabreul merged 8 commits into
QuantConnect:masterfrom
jhonabreul:bug-option-universe-remove-readd

Conversation

@jhonabreul

@jhonabreul jhonabreul commented Jul 17, 2026

Copy link
Copy Markdown
Collaborator

Description

Removing a non-user-defined universe (e.g. an option chain universe via RemoveSecurity(canonicalSymbol)) and adding a new universe with an equal configuration (e.g. AddOption for the same underlying) within the same time step caused an unhandled runtime error that stopped the algorithm:

Subscription.AddSubscriptionRequest(): Universe selection subscriptions should not have more than 1 SubscriptionRequest

Cause: the removed universe is disposed synchronously, but its subscription removal is deferred to the next SubscriptionSynchronizer loop. The new universe's subscription request then finds the slot still occupied by the stale subscription and throws.

The fix:

  • Subscription.AddSubscriptionRequest no longer throws on universe subscription collisions: it returns false, like it already did for user-defined universes.
  • When the incoming universe request collides with a subscription whose universes are all DisposeRequested, DataManager parks the request instead of dropping it.
  • The stale subscription is left in place, so the synchronizer's existing teardown runs untouched: final empty selection (members deselected, subscriptions removed, removed security changes emitted), then subscription removal.
  • On that removal, DataManager re-issues the parked request, creating the new universe's subscription in the now-free slot. It keeps the request's original start time (already adjusted to the previous tradable date) so the first selection happens right away, the same day.
  • Parked requests are dropped if their universe is disposed before being re-issued, and cleared on RemoveAllSubscriptions.

Related Issue

N/A (reported by a user: a monthly-rebalancing options algorithm that removes its option subscriptions with remove_security and re-adds them with add_option crashed whenever an underlying was selected in two consecutive months)

Motivation and Context

Removing an option universe and re-adding one for the same underlying in the same time step (e.g. a scheduled event rebalancing option positions) is legitimate API usage and should not crash the algorithm.

Requires Documentation Change

No

How Has This Been Tested?

  • DataManagerTests.ReplacesSubscriptionOfUniverseRemovedAndReAddedInSameTimeStep: unit test reproducing the collision at the DataManager level; asserts the request is parked while the stale subscription remains, and re-issued once it is removed.
  • New OptionUniverseRemovedAndReAddedRegressionAlgorithm (C#): removes and re-adds the AAPL option universe in the same time step; asserts option chain data flows both before and after the swap.
  • New OptionUniverseRemovedAndReAddedMemberCleanupRegressionAlgorithm (C#): re-adds the universe with a narrower filter; asserts deselected contracts' subscriptions are removed and removed security changes are emitted for them.
  • Full Engine.DataFeeds test suite: 927 passed, 0 failed.

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • Refactor (non-breaking change which improves implementation)
  • Performance (non-breaking change which improves performance. Please add associated performance test and results)
  • New feature (non-breaking change which adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Non-functional change (xml comments/documentation/etc)

Checklist:

  • My code follows the code style of this project.
  • I have read the CONTRIBUTING document.
  • I have added tests to cover my changes.
  • All new and existing tests passed.
  • My branch follows the naming convention bug-<issue#>-<description> or feature-<issue#>-<description>

@jhonabreul
jhonabreul marked this pull request as ready for review July 17, 2026 15:56
@jhonabreul
jhonabreul marked this pull request as draft July 17, 2026 22:04
@jhonabreul
jhonabreul marked this pull request as ready for review July 20, 2026 13:29
@jhonabreul
jhonabreul merged commit f910480 into QuantConnect:master Jul 20, 2026
8 checks passed
@jhonabreul
jhonabreul deleted the bug-option-universe-remove-readd branch July 20, 2026 21:43
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.

2 participants