Problem Description
Solution
To get the list of securities just added to your universe in QuantConnect, you must override the on_securities_changed event handler.
This method receives a SecurityChanges object, which contains a property called added_securities. This property is a list of Security objects that have entered the universe during the current time step.
Implementation Details
- Define
on_securities_changed: This method is automatically called by the LEAN engine whenever the universe composition changes. - Access
changes.added_securities: Iterate through this list to access the new securities. - Access Properties: Since the list contains
Securityobjects (not just symbols), you can access properties likesecurity.symbol,security.price, orsecurity.fundamentalsimmediately.
Code Example
Here is a complete example demonstrating how to log the symbols of securities added to the universe.
from AlgorithmImports import *
class UniverseSelectionAlgorithm(QCAlgorithm):
def initialize(self):
self.set_start_date(2023, 1, 1)
self.set_cash(100000)
# Add a universe (e.g., top 10 stocks by dollar volume) to trigger changes
self.add_universe(self.coarse_selection_function)
def coarse_selection_function(self, coarse):
# Select top 10 liquid stocks
sorted_by_volume = sorted(coarse, key=lambda x: x.dollar_volume, reverse=True)
return [x.symbol for x in sorted_by_volume[:10]]
def on_securities_changed(self, changes: SecurityChanges) -> None:
"""
Event handler for universe changes.
Args:
changes: SecurityChanges object containing AddedSecurities and RemovedSecurities lists
"""
# Check if there are any new securities
if len(changes.added_securities) > 0:
for security in changes.added_securities:
# 'security' is a Security object. Use .symbol to get the Symbol.
self.log(f"Security Added: {security.symbol}")
# Example: Set a specific fee model for new securities
# security.set_fee_model(ConstantFeeModel(1.0))
# It is also best practice to handle removed securities here
for security in changes.removed_securities:
if security.invested:
self.liquidate(security.symbol, "Removed from Universe")
Key Considerations
- Timing:
on_securities_changedis called after the universe selection function returns but beforeon_data. This allows you to set up indicators or history requests for the new assets before the algorithm attempts to trade them. - Data Availability: When a security is in
added_securities, thesecurityobject is fully initialized. You can accessself.securities[security.symbol]immediately. - PEP8 Compliance: In the modern Python API, use snake_case properties:
changes.added_securitiesandchanges.removed_securities.
Q&A
Q: Does changes.added_securities contain ticker strings or objects?
A: It contains Security objects. To get the ticker symbol, you must access the .symbol property (e.g., security.symbol).
Q: Will on_securities_changed run if the universe does not change?
A: No. This event handler is only triggered when there is a difference between the universe constituents of the previous step and the current step.
Q: Can I place orders inside on_securities_changed?
A: Yes, you can place orders immediately. However, it is generally recommended to perform logic setup (like creating indicators) in this handler and execute entry logic in on_data to ensure you are acting on the specific slice data. Liquidating removed securities in this handler is a common exception.