Skip to content

Add support for removing universes/entire chains via RemoveSecurity/UniverseManager.Remove#2039

Merged
mchandschuh merged 6 commits into
masterfrom
feature-1977-remove-universe-support
May 30, 2018
Merged

Add support for removing universes/entire chains via RemoveSecurity/UniverseManager.Remove#2039
mchandschuh merged 6 commits into
masterfrom
feature-1977-remove-universe-support

Conversation

@mchandschuh
Copy link
Copy Markdown
Contributor

Description

In support of #1977 we need to ensure we're able to add/remove derivative universes properly. This change implements universe removal coupled with a regression algorithm that adds and removes an option chain universe from the algorithm via OnData.

Related Issue

See #1977 (next PR will actually resolve the issue)

Motivation and Context

Aiming to support universe selection models that can add/remove

Requires Documentation Change

Yup, will want to show in documentation that you can now remove an entire option chain and all child contracts via RemoveSecurity(optionChainSymbol)

How Has This Been Tested?

Extensively tested locally as well as an extremely thorough regression test with many checks within the algorithm related to expected securities/data

Types of changes

  • Bug fix (non-breaking change which fixes an issue)
  • 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/ect)

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. (those that were passing :) )
  • My branch follows the naming convention bug-<issue#>-<description or feature-<issue#>-<description>

/// <returns>True if there are any differences between the two sets, false otherwise</returns>
public static bool HasDiffs<T>(this ISet<T> left, ISet<T> right)
{
return left.Except(right).Any() || right.Except(left).Any();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

👍 Nice method, perhaps could be named HasDifferences or IsDifferentFrom instead ?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

agreed, there's no need for us to be short with method names :)

Comment thread Algorithm/QCAlgorithm.cs
}

// finally, dispose and remove the canonical security from the universe manager
UniverseManager.Remove(symbol);
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

this block is some cool code

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

thanks! :)

/// <param name="expiration">Option expiration date</param>
/// <returns></returns>
/// <returns>The OSI ticker representation</returns>
public static string GenerateOptionTickerOSI(string underlying, OptionRight right, decimal strikePrice, DateTime expiration)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

👍

{
// don't remove universe subscriptions immediately, instead mark them as disposed
// so we can turn the crank one more time to ensure we emit security changes properly
if (subscription.IsUniverseSelectionSubscription && subscription.Universe.DisposeRequested)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Interesting... Does the security data arrive for the last crank?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

#1999 guarantees that we won't receive data after the subscription has been removed from the universe -- the final crank here is solely used to generate the security changes so that the algorithm is notified via that pathway that all of these securities have been removed.

Comment thread Algorithm/QCAlgorithm.cs Outdated
// remove child securities (option contracts for option chain universes)
foreach (var child in universe.Members.Values)
{
RemoveSecurity(child.Symbol);
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Need to add a check before removal to ensure it's not in an other universe

@mchandschuh mchandschuh force-pushed the feature-1977-remove-universe-support branch from fb01425 to 8796b48 Compare May 30, 2018 14:06
Easy to introduce bugs when each method that is intended to do the same thing
implements it internally instead of delegating to a common implementation.
Also simplified syntax of invoking event handler
Useful when writing regression tests to be able to use the OSI ticker
to define an expected option contract.
Implementation is simplified form of that used to detect diffs
in universe selection (selection updated to use simplified form
as well)
Adds the concept of universe disposal which is requested by an algorithm
through invocation of UniverseManager.Remove, which is invoked via
algorithm.RemoveSecurity. This instructs the data feed that the algorithm
has requested to completely remove the universe and any child subscriptions
from the feed. Security changes are fired for all removed securities.
No need to be so terse :)
Since we're moving towards better support of multiple universes,
it's important that we check that child subscriptions aren't in
those other universes before removing the security.
@mchandschuh mchandschuh force-pushed the feature-1977-remove-universe-support branch from 26d737d to 577c082 Compare May 30, 2018 19:57
@mchandschuh mchandschuh merged commit 9a67649 into master May 30, 2018
@mchandschuh mchandschuh deleted the feature-1977-remove-universe-support branch May 30, 2018 20:23
Martin-Molinero added a commit to Martin-Molinero/Lean that referenced this pull request Nov 27, 2018
- Previously when a user requested to remove a universe, they would call
`RemoveSecurity()`->`UniverseManager.Remove()`-> `Universe.Dispose()` ->
collection change notification would call `DataManager()` that would
call `RemoveSubscription()` that *would not perform any operation* since
it would return `false` through
`if(subscription.IsUniverseSelectionSubscription &&
subscription.Universe.DisposeRequested)`. Previous comment stated that
the `Subscription` would be removed by the `SubscriptionSynchronizer`
via `SubscriptionFinished()` but this called would go through the same
if statemente as above, returning false and no performing any operation.
So the `Universe` `Subscription` was never removed.
PR QuantConnect#2039
- In this PR I'm removing the mentioned `if` statement and the call
relation between `UniverseManager.Remove()` and
`DataManager.RemoveSubscription()` since this will be covered by the
`SubscriptionSynchronizer` in the next loop.
- Modified regression test (originally added with these changes at
QuantConnect#2039) to verify this issue.
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.

3 participants