import abc
import datetime
import typing

import QuantConnect
import QuantConnect.Algorithm
import QuantConnect.Algorithm.Framework
import QuantConnect.Algorithm.Framework.Alphas
import QuantConnect.Algorithm.Framework.Alphas.Analysis
import QuantConnect.Algorithm.Framework.Alphas.Serialization
import QuantConnect.Data
import QuantConnect.Data.Consolidators
import QuantConnect.Data.UniverseSelection
import QuantConnect.Indicators
import QuantConnect.Securities
import System
import System.Collections
import System.Collections.Generic

PyObject = typing.Any


class InsightScoreType(System.Enum):
    """Defines a specific type of score for a insight"""

    Direction = 0
    """Directional accuracy"""

    Magnitude = 1
    """Magnitude accuracy"""


class InsightScore(System.Object):
    """Defines the scores given to a particular insight"""

    @property
    def UpdatedTimeUtc(self) -> datetime.datetime:
        """Gets the time these scores were last updated"""
        ...

    @UpdatedTimeUtc.setter
    def UpdatedTimeUtc(self, value: datetime.datetime):
        """Gets the time these scores were last updated"""
        ...

    @property
    def Direction(self) -> float:
        """Gets the direction score"""
        ...

    @Direction.setter
    def Direction(self, value: float):
        """Gets the direction score"""
        ...

    @property
    def Magnitude(self) -> float:
        """Gets the magnitude score"""
        ...

    @Magnitude.setter
    def Magnitude(self, value: float):
        """Gets the magnitude score"""
        ...

    @property
    def IsFinalScore(self) -> bool:
        """Gets whether or not this is the insight's final score"""
        ...

    @IsFinalScore.setter
    def IsFinalScore(self, value: bool):
        """Gets whether or not this is the insight's final score"""
        ...

    @typing.overload
    def __init__(self) -> None:
        """Initializes a new, default instance of the InsightScore class"""
        ...

    @typing.overload
    def __init__(self, direction: float, magnitude: float, updatedTimeUtc: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Initializes a new instance of the InsightScore class
        
        :param direction: The insight direction score
        :param magnitude: The insight percent change score
        :param updatedTimeUtc: The algorithm utc time these scores were computed
        """
        ...

    def GetScore(self, type: QuantConnect.Algorithm.Framework.Alphas.InsightScoreType) -> float:
        """
        Gets the specified score
        
        :param type: The type of score to get, Direction/Magnitude
        :returns: The requested score.
        """
        ...

    def ToString(self) -> str:
        """
        Returns a string that represents the current object.
        
        :returns: A string that represents the current object.
        """
        ...


class InsightType(System.Enum):
    """Specifies the type of insight"""

    Price = 0
    """The insight is for a security's price"""

    Volatility = 1
    """The insight is for a security's price volatility"""


class InsightDirection(System.Enum):
    """Specifies the predicted direction for a insight (price/volatility)"""

    Down = -1
    """The value will go down"""

    Flat = 0
    """The value will stay flat"""

    Up = 1
    """The value will go up"""


class Insight(System.Object):
    """Defines a alpha prediction for a single symbol generated by the algorithm"""

    @property
    def Id(self) -> System.Guid:
        """Gets the unique identifier for this insight"""
        ...

    @Id.setter
    def Id(self, value: System.Guid):
        """Gets the unique identifier for this insight"""
        ...

    @property
    def GroupId(self) -> typing.Optional[System.Guid]:
        """Gets the group id this insight belongs to, null if not in a group"""
        ...

    @GroupId.setter
    def GroupId(self, value: typing.Optional[System.Guid]):
        """Gets the group id this insight belongs to, null if not in a group"""
        ...

    @property
    def SourceModel(self) -> str:
        """Gets an identifier for the source model that generated this insight."""
        ...

    @SourceModel.setter
    def SourceModel(self, value: str):
        """Gets an identifier for the source model that generated this insight."""
        ...

    @property
    def GeneratedTimeUtc(self) -> datetime.datetime:
        """Gets the utc time this insight was generated"""
        ...

    @GeneratedTimeUtc.setter
    def GeneratedTimeUtc(self, value: datetime.datetime):
        """Gets the utc time this insight was generated"""
        ...

    @property
    def CloseTimeUtc(self) -> datetime.datetime:
        """
        Gets the insight's prediction end time. This is the time when this
        insight prediction is expected to be fulfilled. This time takes into
        account market hours, weekends, as well as the symbol's data resolution
        """
        ...

    @CloseTimeUtc.setter
    def CloseTimeUtc(self, value: datetime.datetime):
        """
        Gets the insight's prediction end time. This is the time when this
        insight prediction is expected to be fulfilled. This time takes into
        account market hours, weekends, as well as the symbol's data resolution
        """
        ...

    @property
    def Symbol(self) -> QuantConnect.Symbol:
        """Gets the symbol this insight is for"""
        ...

    @Symbol.setter
    def Symbol(self, value: QuantConnect.Symbol):
        """Gets the symbol this insight is for"""
        ...

    @property
    def Type(self) -> int:
        """
        Gets the type of insight, for example, price insight or volatility insight
        
        This property contains the int value of a member of the QuantConnect.Algorithm.Framework.Alphas.InsightType enum.
        """
        ...

    @Type.setter
    def Type(self, value: int):
        """
        Gets the type of insight, for example, price insight or volatility insight
        
        This property contains the int value of a member of the QuantConnect.Algorithm.Framework.Alphas.InsightType enum.
        """
        ...

    @property
    def ReferenceValue(self) -> float:
        """Gets the initial reference value this insight is predicting against. The value is dependent on the specified InsightType"""
        ...

    @ReferenceValue.setter
    def ReferenceValue(self, value: float):
        """Gets the initial reference value this insight is predicting against. The value is dependent on the specified InsightType"""
        ...

    @property
    def ReferenceValueFinal(self) -> float:
        """Gets the final reference value, used for scoring, this insight is predicting against. The value is dependent on the specified InsightType"""
        ...

    @ReferenceValueFinal.setter
    def ReferenceValueFinal(self, value: float):
        """Gets the final reference value, used for scoring, this insight is predicting against. The value is dependent on the specified InsightType"""
        ...

    @property
    def Direction(self) -> int:
        """
        Gets the predicted direction, down, flat or up
        
        This property contains the int value of a member of the QuantConnect.Algorithm.Framework.Alphas.InsightDirection enum.
        """
        ...

    @Direction.setter
    def Direction(self, value: int):
        """
        Gets the predicted direction, down, flat or up
        
        This property contains the int value of a member of the QuantConnect.Algorithm.Framework.Alphas.InsightDirection enum.
        """
        ...

    @property
    def Period(self) -> datetime.timedelta:
        """Gets the period over which this insight is expected to come to fruition"""
        ...

    @Period.setter
    def Period(self, value: datetime.timedelta):
        """Gets the period over which this insight is expected to come to fruition"""
        ...

    @property
    def Magnitude(self) -> typing.Optional[float]:
        """Gets the predicted percent change in the insight type (price/volatility)"""
        ...

    @Magnitude.setter
    def Magnitude(self, value: typing.Optional[float]):
        """Gets the predicted percent change in the insight type (price/volatility)"""
        ...

    @property
    def Confidence(self) -> typing.Optional[float]:
        """Gets the confidence in this insight"""
        ...

    @Confidence.setter
    def Confidence(self, value: typing.Optional[float]):
        """Gets the confidence in this insight"""
        ...

    @property
    def Weight(self) -> typing.Optional[float]:
        """Gets the portfolio weight of this insight"""
        ...

    @Weight.setter
    def Weight(self, value: typing.Optional[float]):
        """Gets the portfolio weight of this insight"""
        ...

    @property
    def Score(self) -> QuantConnect.Algorithm.Framework.Alphas.InsightScore:
        """Gets the most recent scores for this insight"""
        ...

    @Score.setter
    def Score(self, value: QuantConnect.Algorithm.Framework.Alphas.InsightScore):
        """Gets the most recent scores for this insight"""
        ...

    @property
    def EstimatedValue(self) -> float:
        """Gets the estimated value of this insight in the account currency"""
        ...

    @EstimatedValue.setter
    def EstimatedValue(self, value: float):
        """Gets the estimated value of this insight in the account currency"""
        ...

    @typing.overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection) -> None:
        """
        Initializes a new instance of the Insight class
        
        :param symbol: The symbol this insight is for
        :param period: The period over which the prediction will come true
        :param type: The type of insight, price/volatility
        :param direction: The predicted direction
        """
        ...

    @typing.overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float], confidence: typing.Optional[float], sourceModel: str = None, weight: typing.Optional[float] = None) -> None:
        """
        Initializes a new instance of the Insight class
        
        :param symbol: The symbol this insight is for
        :param period: The period over which the prediction will come true
        :param type: The type of insight, price/volatility
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percentage change
        :param confidence: The confidence in this insight
        :param sourceModel: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        """
        ...

    @typing.overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str], expiryFunc: typing.Callable[[datetime.datetime], datetime.datetime], type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection) -> None:
        """
        Initializes a new instance of the Insight class
        
        :param symbol: The symbol this insight is for
        :param expiryFunc: Func that defines the expiry time
        :param type: The type of insight, price/volatility
        :param direction: The predicted direction
        """
        ...

    @typing.overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str], expiryFunc: typing.Callable[[datetime.datetime], datetime.datetime], type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float], confidence: typing.Optional[float], sourceModel: str = None, weight: typing.Optional[float] = None) -> None:
        """
        Initializes a new instance of the Insight class
        
        :param symbol: The symbol this insight is for
        :param expiryFunc: Func that defines the expiry time
        :param type: The type of insight, price/volatility
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percentage change
        :param confidence: The confidence in this insight
        :param sourceModel: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        """
        ...

    @typing.overload
    def __init__(self, generatedTimeUtc: typing.Union[datetime.datetime, datetime.date], symbol: typing.Union[QuantConnect.Symbol, str], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float], confidence: typing.Optional[float], sourceModel: str = None, weight: typing.Optional[float] = None) -> None:
        """
        Initializes a new instance of the Insight class.
        This constructor is provided mostly for testing purposes. When running inside an algorithm,
        the generated and close times are set based on the algorithm's time.
        
        :param generatedTimeUtc: The time this insight was generated in utc
        :param symbol: The symbol this insight is for
        :param period: The period over which the prediction will come true
        :param type: The type of insight, price/volatility
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percentage change
        :param confidence: The confidence in this insight
        :param sourceModel: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        """
        ...

    def Clone(self) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a deep clone of this insight instance
        
        :returns: A new insight with identical values, but new instances.
        """
        ...

    @staticmethod
    @typing.overload
    def ComputeCloseTime(exchangeHours: QuantConnect.Securities.SecurityExchangeHours, generatedTimeUtc: typing.Union[datetime.datetime, datetime.date], resolution: QuantConnect.Resolution, barCount: int) -> datetime.datetime:
        """
        Computes the insight closing time from the given generated time, resolution and bar count.
        This will step through market hours using the given resolution, respecting holidays, early closes, weekends, etc..
        
        :param exchangeHours: The exchange hours of the insight's security
        :param generatedTimeUtc: The insight's generated time in utc
        :param resolution: The resolution used to 'step-through' market hours to compute a reasonable close time
        :param barCount: The number of resolution steps to take
        :returns: The insight's closing time in utc.
        """
        ...

    @staticmethod
    @typing.overload
    def ComputeCloseTime(exchangeHours: QuantConnect.Securities.SecurityExchangeHours, generatedTimeUtc: typing.Union[datetime.datetime, datetime.date], period: datetime.timedelta) -> datetime.datetime:
        """
        computs the insight closing time from the given generated time and period
        
        :param exchangeHours: The exchange hours of the insight's security
        :param generatedTimeUtc: The insight's generated time in utc
        :param period: The insight's period
        :returns: The insight's closing time in utc.
        """
        ...

    @staticmethod
    def ComputePeriod(exchangeHours: QuantConnect.Securities.SecurityExchangeHours, generatedTimeUtc: typing.Union[datetime.datetime, datetime.date], closeTimeUtc: typing.Union[datetime.datetime, datetime.date]) -> datetime.timedelta:
        """
        Computes the insight period from the given generated and close times
        
        :param exchangeHours: The exchange hours of the insight's security
        :param generatedTimeUtc: The insight's generated time in utc
        :param closeTimeUtc: The insight's close time in utc
        :returns: The insight's period.
        """
        ...

    @staticmethod
    def FromSerializedInsight(serializedInsight: QuantConnect.Algorithm.Framework.Alphas.Serialization.SerializedInsight) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a new Insight object from the specified serialized form
        
        :param serializedInsight: The insight DTO
        :returns: A new insight containing the information specified.
        """
        ...

    @staticmethod
    @typing.overload
    def Group(*insights: QuantConnect.Algorithm.Framework.Alphas.Insight) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Creates a new, unique group id and sets it on each insight
        
        :param insights: The insights to be grouped
        """
        ...

    @staticmethod
    @typing.overload
    def Group(insight: QuantConnect.Algorithm.Framework.Alphas.Insight) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Creates a new, unique group id and sets it on each insight
        
        :param insight: The insight to be grouped
        """
        ...

    def IsActive(self, utcTime: typing.Union[datetime.datetime, datetime.date]) -> bool:
        """
        Determines whether or not this insight is considered active at the specified
        
        :param utcTime: The algorithm's current time in UTC. See IAlgorithm.UtcTime
        :returns: True if this insight is active, false otherwise.
        """
        ...

    def IsExpired(self, utcTime: typing.Union[datetime.datetime, datetime.date]) -> bool:
        """
        Determines whether or not this insight is considered expired at the specified
        
        :param utcTime: The algorithm's current time in UTC. See IAlgorithm.UtcTime
        :returns: True if this insight is expired, false otherwise.
        """
        ...

    @staticmethod
    @typing.overload
    def Price(symbol: typing.Union[QuantConnect.Symbol, str], resolution: QuantConnect.Resolution, barCount: int, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, sourceModel: str = None, weight: typing.Optional[float] = None) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a new insight for predicting the percent change in price over the specified period
        
        :param symbol: The symbol this insight is for
        :param resolution: The resolution used to define the insight's period and also used to determine the insight's close time
        :param barCount: The number of resolution time steps to make in market hours to compute the insight's closing time
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percent change
        :param confidence: The confidence in this insight
        :param sourceModel: The model generating this insight
        :param weight: The portfolio weight of this insight
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @typing.overload
    def Price(symbol: typing.Union[QuantConnect.Symbol, str], closeTimeLocal: typing.Union[datetime.datetime, datetime.date], direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, sourceModel: str = None, weight: typing.Optional[float] = None) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a new insight for predicting the percent change in price over the specified period
        
        :param symbol: The symbol this insight is for
        :param closeTimeLocal: The insight's closing time in the security's exchange time zone
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percent change
        :param confidence: The confidence in this insight
        :param sourceModel: The model generating this insight
        :param weight: The portfolio weight of this insight
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @typing.overload
    def Price(symbol: typing.Union[QuantConnect.Symbol, str], period: datetime.timedelta, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, sourceModel: str = None, weight: typing.Optional[float] = None) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a new insight for predicting the percent change in price over the specified period
        
        :param symbol: The symbol this insight is for
        :param period: The period over which the prediction will come true
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percent change
        :param confidence: The confidence in this insight
        :param sourceModel: The model generating this insight
        :param weight: The portfolio weight of this insight
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @typing.overload
    def Price(symbol: typing.Union[QuantConnect.Symbol, str], expiryFunc: typing.Callable[[datetime.datetime], datetime.datetime], direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, sourceModel: str = None, weight: typing.Optional[float] = None) -> QuantConnect.Algorithm.Framework.Alphas.Insight:
        """
        Creates a new insight for predicting the percent change in price over the specified period
        
        :param symbol: The symbol this insight is for
        :param expiryFunc: Func that defines the expiry time
        :param direction: The predicted direction
        :param magnitude: The predicted magnitude as a percent change
        :param confidence: The confidence in this insight
        :param sourceModel: The model generating this insight
        :param weight: The portfolio weight of this insight
        :returns: A new insight object for the specified parameters.
        """
        ...

    def SetPeriodAndCloseTime(self, exchangeHours: QuantConnect.Securities.SecurityExchangeHours) -> None:
        """
        Sets the insight period and close times if they have not already been set.
        
        :param exchangeHours: The insight's security exchange hours
        """
        ...

    def ShortToString(self) -> str:
        """
        Returns a short string that represents the current object.
        
        :returns: A string that represents the current object.
        """
        ...

    def ToString(self) -> str:
        """
        Returns a string that represents the current object.
        
        :returns: A string that represents the current object.
        """
        ...


class IAlphaModel(QuantConnect.Algorithm.Framework.INotifiedSecurityChanges, metaclass=abc.ABCMeta):
    """Algorithm framework model that produces insights"""

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class INamedModel(metaclass=abc.ABCMeta):
    """
    Provides a marker interface allowing models to define their own names.
    If not specified, the framework will use the model's type name.
    Implementation of this is not required unless you plan on running multiple models
    of the same type w/ different parameters.
    """

    @property
    @abc.abstractmethod
    def Name(self) -> str:
        """Defines a name for a framework model"""
        ...


class AlphaModel(System.Object, QuantConnect.Algorithm.Framework.Alphas.IAlphaModel, QuantConnect.Algorithm.Framework.Alphas.INamedModel):
    """Provides a base class for alpha models."""

    @property
    def Name(self) -> str:
        """Defines a name for a framework model"""
        ...

    @Name.setter
    def Name(self, value: str):
        """Defines a name for a framework model"""
        ...

    def __init__(self) -> None:
        """Initialize new AlphaModel"""
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class AlphaModelPythonWrapper(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Provides an implementation of IAlphaModel that wraps a PyObject object"""

    @property
    def Name(self) -> str:
        """Defines a name for a framework model"""
        ...

    @Name.setter
    def Name(self, value: str):
        """Defines a name for a framework model"""
        ...

    def __init__(self, model: typing.Any) -> None:
        """
        Constructor for initialising the IAlphaModel class with wrapped PyObject object
        
        :param model: >Model that generates alpha
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class AlphaModelExtensions(System.Object):
    """Provides extension methods for alpha models"""

    @staticmethod
    def GetModelName(model: QuantConnect.Algorithm.Framework.Alphas.IAlphaModel) -> str:
        """Gets the name of the alpha model"""
        ...


class CompositeAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """
    Provides an implementation of IAlphaModel that combines multiple alpha
    models into a single alpha model and properly sets each insights 'SourceModel' property.
    """

    @typing.overload
    def __init__(self, *alphaModels: QuantConnect.Algorithm.Framework.Alphas.IAlphaModel) -> None:
        """
        Initializes a new instance of the CompositeAlphaModel class
        
        :param alphaModels: The individual alpha models defining this composite model
        """
        ...

    @typing.overload
    def __init__(self, *alphaModels: PyObject) -> None:
        """
        Initializes a new instance of the CompositeAlphaModel class
        
        :param alphaModels: The individual alpha models defining this composite model
        """
        ...

    @typing.overload
    def __init__(self, alphaModel: typing.Any) -> None:
        """
        Initializes a new instance of the CompositeAlphaModel class
        
        :param alphaModel: The individual alpha model defining this composite model
        """
        ...

    @typing.overload
    def AddAlpha(self, alphaModel: QuantConnect.Algorithm.Framework.Alphas.IAlphaModel) -> None:
        """
        Adds a new AlphaModel
        
        :param alphaModel: The alpha model to add
        """
        ...

    @typing.overload
    def AddAlpha(self, pyAlphaModel: typing.Any) -> None:
        """
        Adds a new AlphaModel
        
        :param pyAlphaModel: The alpha model to add
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed.
        This method patches this call through the each of the wrapped models.
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities.
        This method patches this call through the each of the wrapped models.
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class NullAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Provides a null implementation of an alpha model"""

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class HistoricalReturnsAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Alpha model that uses historical returns to create insights"""

    def __init__(self, lookback: int = 1, resolution: QuantConnect.Resolution = ...) -> None:
        """
        Initializes a new instance of the HistoricalReturnsAlphaModel class
        
        :param lookback: Historical return lookback period
        :param resolution: The resolution of historical data
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class BasePairsTradingAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """
    This alpha model is designed to accept every possible pair combination
    from securities selected by the universe selection model
    This model generates alternating long ratio/short ratio insights emitted as a group
    """

    @property
    def Securities(self) -> System.Collections.Generic.HashSet[QuantConnect.Securities.Security]:
        """List of security objects present in the universe"""
        ...

    def __init__(self, lookback: int = 1, resolution: QuantConnect.Resolution = ..., threshold: float = 1) -> None:
        """
        Initializes a new instance of the BasePairsTradingAlphaModel class
        
        :param lookback: Lookback period of the analysis
        :param resolution: Analysis resolution
        :param threshold: The percent [0, 100] deviation of the ratio from the mean before emitting an insight
        """
        ...

    def HasPassedTest(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, asset1: typing.Union[QuantConnect.Symbol, str], asset2: typing.Union[QuantConnect.Symbol, str]) -> bool:
        """
        Check whether the assets pass a pairs trading test
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param asset1: The first asset's symbol in the pair
        :param asset2: The second asset's symbol in the pair
        :returns: True if the statistical test for the pair is successful.
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class PearsonCorrelationPairsTradingAlphaModel(QuantConnect.Algorithm.Framework.Alphas.BasePairsTradingAlphaModel):
    """
    This alpha model is designed to rank every pair combination by its pearson correlation
    and trade the pair with the hightest correlation
    This model generates alternating long ratio/short ratio insights emitted as a group
    """

    def __init__(self, lookback: int, resolution: QuantConnect.Resolution, threshold: float = 1, minimumCorrelation: float = .5) -> None:
        """
        Initializes a new instance of the PearsonCorrelationPairsTradingAlphaModel class
        
        :param lookback: Lookback period of the analysis
        :param resolution: Analysis resolution
        :param threshold: The percent [0, 100] deviation of the ratio from the mean before emitting an insight
        :param minimumCorrelation: The minimum correlation to consider a tradable pair
        """
        ...

    def HasPassedTest(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, asset1: typing.Union[QuantConnect.Symbol, str], asset2: typing.Union[QuantConnect.Symbol, str]) -> bool:
        """
        Check whether the assets pass a pairs trading test
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param asset1: The first asset's symbol in the pair
        :param asset2: The second asset's symbol in the pair
        :returns: True if the statistical test for the pair is successful.
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...


class ConstantAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Provides an implementation of IAlphaModel that always returns the same insight for each security"""

    @typing.overload
    def __init__(self, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, period: datetime.timedelta) -> None:
        """
        Initializes a new instance of the ConstantAlphaModel class
        
        :param type: The type of insight
        :param direction: The direction of the insight
        :param period: The period over which the insight with come to fruition
        """
        ...

    @typing.overload
    def __init__(self, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, period: datetime.timedelta, magnitude: typing.Optional[float], confidence: typing.Optional[float], weight: typing.Optional[float] = None) -> None:
        """
        Initializes a new instance of the ConstantAlphaModel class
        
        :param type: The type of insight
        :param direction: The direction of the insight
        :param period: The period over which the insight with come to fruition
        :param magnitude: The predicted change in magnitude as a +- percentage
        :param confidence: The confidence in the insight
        :param weight: The portfolio weight of the insights
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def ShouldEmitInsight(self, utcTime: typing.Union[datetime.datetime, datetime.date], symbol: typing.Union[QuantConnect.Symbol, str]) -> bool:
        """
        Determine if its time to emit insight for this symbol
        
        This method is protected.
        
        :param utcTime: Time of the insight
        :param symbol: The symbol to emit an insight for
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Creates a constant insight for each security as specified via the constructor
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class MacdAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """
    Defines a custom alpha model that uses MACD crossovers. The MACD signal line is
    used to generate up/down insights if it's stronger than the bounce threshold.
    If the MACD signal is within the bounce threshold then a flat price insight is returned.
    """

    class SymbolData(System.Object):
        """This class has no documentation."""

        @property
        def PreviousDirection(self) -> typing.Optional[QuantConnect.Algorithm.Framework.Alphas.InsightDirection]:
            ...

        @PreviousDirection.setter
        def PreviousDirection(self, value: typing.Optional[QuantConnect.Algorithm.Framework.Alphas.InsightDirection]):
            ...

        @property
        def Security(self) -> QuantConnect.Securities.Security:
            ...

        @property
        def Consolidator(self) -> QuantConnect.Data.Consolidators.IDataConsolidator:
            ...

        @property
        def MACD(self) -> QuantConnect.Indicators.MovingAverageConvergenceDivergence:
            ...

        def __init__(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, security: QuantConnect.Securities.Security, fastPeriod: int, slowPeriod: int, signalPeriod: int, movingAverageType: QuantConnect.Indicators.MovingAverageType, resolution: QuantConnect.Resolution) -> None:
            ...

    def __init__(self, fastPeriod: int = 12, slowPeriod: int = 26, signalPeriod: int = 9, movingAverageType: QuantConnect.Indicators.MovingAverageType = ..., resolution: QuantConnect.Resolution = ...) -> None:
        """
        Initializes a new instance of the MacdAlphaModel class
        
        :param fastPeriod: The MACD fast period
        :param slowPeriod: The MACD slow period
        :param signalPeriod: The smoothing period for the MACD signal
        :param movingAverageType: The type of moving average to use in the MACD
        :param resolution: The resolution of data sent into the MACD indicator
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed.
        This initializes the MACD for each added security and cleans up the indicator for each removed security.
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Determines an insight for each security based on it's current MACD signal
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class EmaCrossAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Alpha model that uses an EMA cross to create insights"""

    def __init__(self, fastPeriod: int = 12, slowPeriod: int = 26, resolution: QuantConnect.Resolution = ...) -> None:
        """
        Initializes a new instance of the EmaCrossAlphaModel class
        
        :param fastPeriod: The fast EMA period
        :param slowPeriod: The slow EMA period
        :param resolution: The resolution of data sent into the EMA indicators
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Event fired each time the we add/remove securities from the data feed
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class RsiAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """
    Uses Wilder's RSI to create insights. Using default settings, a cross over below 30 or above 70 will
    trigger a new insight.
    """

    def __init__(self, period: int = 14, resolution: QuantConnect.Resolution = ...) -> None:
        """
        Initializes a new instance of the RsiAlphaModel class
        
        :param period: The RSI indicator period
        :param resolution: The resolution of data sent into the RSI indicator
        """
        ...

    def OnSecuritiesChanged(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, changes: QuantConnect.Data.UniverseSelection.SecurityChanges) -> None:
        """
        Cleans out old security data and initializes the RSI for any newly added securities.
        This functional also seeds any new indicators using a history request.
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param changes: The security additions and removals from the algorithm
        """
        ...

    def Update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Updates this alpha model with the latest data from the algorithm.
        This is called each time the algorithm receives data for subscribed securities
        
        :param algorithm: The algorithm instance
        :param data: The new data available
        :returns: The new insights generated.
        """
        ...


class IInsightManagerExtension(metaclass=abc.ABCMeta):
    """
    Abstraction point to handle the various concerns from a common api.
    At the time of writing, these concerns are charting, scoring, perisistence and messaging.
    """

    def InitializeForRange(self, algorithmStartDate: typing.Union[datetime.datetime, datetime.date], algorithmEndDate: typing.Union[datetime.datetime, datetime.date], algorithmUtcTime: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Allows the extension to initialize itself over the expected range
        
        :param algorithmStartDate: The start date of the algorithm
        :param algorithmEndDate: The end date of the algorithm
        :param algorithmUtcTime: The algorithm's current utc time
        """
        ...

    def OnInsightAnalysisCompleted(self, context: QuantConnect.Algorithm.Framework.Alphas.Analysis.InsightAnalysisContext) -> None:
        """
        Invoked when the insight manager has completed analysis on an insight
        
        :param context: Context whose insight has just completed analysis
        """
        ...

    def OnInsightClosed(self, context: QuantConnect.Algorithm.Framework.Alphas.Analysis.InsightAnalysisContext) -> None:
        """
        Invoked when the insight manager detects that an insight has closed (frontier has passed insight period)
        
        :param context: Context whose insight has just closed
        """
        ...

    def OnInsightGenerated(self, context: QuantConnect.Algorithm.Framework.Alphas.Analysis.InsightAnalysisContext) -> None:
        """
        Invoked when the insight manager first received a generated insight from the algorithm
        
        :param context: Context whose insight has just generated
        """
        ...

    def Step(self, frontierTimeUtc: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Invokes the manager at the end of the time step.
        
        :param frontierTimeUtc: The current frontier time utc
        """
        ...


class GeneratedInsightsCollection(System.Object):
    """Defines a collection of insights that were generated at the same time step"""

    @property
    def DateTimeUtc(self) -> datetime.datetime:
        """The utc date time the insights were generated"""
        ...

    @property
    def Insights(self) -> System.Collections.Generic.List[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """The generated insights"""
        ...

    def __init__(self, dateTimeUtc: typing.Union[datetime.datetime, datetime.date], insights: System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight], clone: bool = True) -> None:
        """
        Initializes a new instance of the GeneratedInsightsCollection class
        
        :param dateTimeUtc: The utc date time the sinals were generated
        :param insights: The generated insights
        :param clone: Keep a clone of the generated insights
        """
        ...


class InsightCollection(System.Object, System.Collections.Generic.ICollection[QuantConnect.Algorithm.Framework.Alphas.Insight], typing.Iterable[QuantConnect.Algorithm.Framework.Alphas.Insight]):
    """
    Provides a collection for managing insights. This type provides collection access semantics
    as well as dictionary access semantics through TryGetValue, ContainsKey, and this[symbol]
    """

    @property
    def Count(self) -> int:
        """Gets the number of elements contained in the System.Collections.Generic.ICollection`1."""
        ...

    @property
    def IsReadOnly(self) -> bool:
        """Gets a value indicating whether the System.Collections.Generic.ICollection`1 is read-only."""
        ...

    def __getitem__(self, symbol: typing.Union[QuantConnect.Symbol, str]) -> System.Collections.Generic.List[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Dictionary accessor returns a list of insights for the specified symbol
        
        :param symbol: The symbol key
        :returns: List of insights for the symbol.
        """
        ...

    def __setitem__(self, symbol: typing.Union[QuantConnect.Symbol, str], value: System.Collections.Generic.List[QuantConnect.Algorithm.Framework.Alphas.Insight]) -> None:
        """
        Dictionary accessor returns a list of insights for the specified symbol
        
        :param symbol: The symbol key
        :returns: List of insights for the symbol.
        """
        ...

    def Add(self, item: QuantConnect.Algorithm.Framework.Alphas.Insight) -> None:
        """
        Adds an item to the System.Collections.Generic.ICollection`1.
        
        :param item: The object to add to the System.Collections.Generic.ICollection`1.
        """
        ...

    def AddRange(self, insights: System.Collections.Generic.IEnumerable[QuantConnect.Algorithm.Framework.Alphas.Insight]) -> None:
        """
        Adds each item in the specified enumerable of insights to this collection
        
        :param insights: The insights to add to this collection
        """
        ...

    @typing.overload
    def Clear(self) -> None:
        """Removes all items from the System.Collections.Generic.ICollection`1."""
        ...

    @typing.overload
    def Clear(self, symbols: typing.List[QuantConnect.Symbol]) -> None:
        """
        Removes the symbol and its insights
        
        :param symbols: List of symbols that will be removed
        """
        ...

    def Contains(self, item: QuantConnect.Algorithm.Framework.Alphas.Insight) -> bool:
        """
        Determines whether the System.Collections.Generic.ICollection`1 contains a specific value.
        
        :param item: The object to locate in the System.Collections.Generic.ICollection`1.
        :returns: true if  is found in the System.Collections.Generic.ICollection`1; otherwise, false.
        """
        ...

    def ContainsKey(self, symbol: typing.Union[QuantConnect.Symbol, str]) -> bool:
        """
        Determines whether insights exist in this collection for the specified symbol
        
        :param symbol: The symbol key
        :returns: True if there are insights for the symbol in this collection.
        """
        ...

    def CopyTo(self, array: typing.List[QuantConnect.Algorithm.Framework.Alphas.Insight], arrayIndex: int) -> None:
        """
        Copies the elements of the System.Collections.Generic.ICollection`1 to an System.Array, starting at a particular System.Array index.
        
        :param array: The one-dimensional System.Array that is the destination of the elements copied from System.Collections.Generic.ICollection`1. The System.Array must have zero-based indexing.
        :param arrayIndex: The zero-based index in  at which copying begins.
        """
        ...

    def GetActiveInsights(self, utcTime: typing.Union[datetime.datetime, datetime.date]) -> System.Collections.Generic.ICollection[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Gets the last generated active insight
        
        :returns: Collection of insights that are active.
        """
        ...

    @typing.overload
    def GetEnumerator(self) -> System.Collections.Generic.IEnumerator[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Returns an enumerator that iterates through the collection.
        
        :returns: A System.Collections.Generic.IEnumerator`1 that can be used to iterate through the collection.
        """
        ...

    @typing.overload
    def GetEnumerator(self) -> System.Collections.IEnumerator:
        """
        Returns an enumerator that iterates through a collection.
        
        :returns: An System.Collections.IEnumerator object that can be used to iterate through the collection.
        """
        ...

    def GetNextExpiryTime(self) -> typing.Optional[datetime.datetime]:
        """Gets the next expiry time UTC"""
        ...

    def HasActiveInsights(self, symbol: typing.Union[QuantConnect.Symbol, str], utcTime: typing.Union[datetime.datetime, datetime.date]) -> bool:
        """
        Returns true if there are active insights for a given symbol and time
        
        :param symbol: The symbol key
        :param utcTime: Time that determines whether the insight has expired
        """
        ...

    def Remove(self, item: QuantConnect.Algorithm.Framework.Alphas.Insight) -> bool:
        """
        Removes the first occurrence of a specific object from the System.Collections.Generic.ICollection`1.
        
        :param item: The object to remove from the System.Collections.Generic.ICollection`1.
        :returns: true if  was successfully removed from the System.Collections.Generic.ICollection`1; otherwise, false. This method also returns false if  is not found in the original System.Collections.Generic.ICollection`1.
        """
        ...

    def RemoveExpiredInsights(self, utcTime: typing.Union[datetime.datetime, datetime.date]) -> System.Collections.Generic.ICollection[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Remove all expired insights from the collection and retuns them
        
        :param utcTime: Time that determines whether the insight has expired
        :returns: Expired insights that were removed.
        """
        ...

    def TryGetValue(self, symbol: typing.Union[QuantConnect.Symbol, str], insights: typing.Optional[System.Collections.Generic.List[QuantConnect.Algorithm.Framework.Alphas.Insight]]) -> typing.Union[bool, System.Collections.Generic.List[QuantConnect.Algorithm.Framework.Alphas.Insight]]:
        """
        Attempts to get the list of insights with the specified symbol key
        
        :param symbol: The symbol key
        :param insights: The insights for the specified symbol, or null if not found
        :returns: True if insights for the specified symbol were found, false otherwise.
        """
        ...


