from typing import overload
from enum import IntEnum
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.Market
import QuantConnect.Data.UniverseSelection
import QuantConnect.Indicators
import QuantConnect.Python
import QuantConnect.Securities
import System
import System.Collections.Generic

QuantConnect_Algorithm_Framework_Alphas_AlphaModel = typing.Any


class InsightType(IntEnum):
    """Specifies the type of insight"""

    PRICE = 0
    """The insight is for a security's price (0)"""

    VOLATILITY = 1
    """The insight is for a security's price volatility (1)"""


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

    DOWN = -1
    """The value will go down (-1)"""

    FLAT = 0
    """The value will stay flat (0)"""

    UP = 1
    """The value will go up (1)"""


class InsightScoreType(IntEnum):
    """Defines a specific type of score for a insight"""

    DIRECTION = 0
    """Directional accuracy (0)"""

    MAGNITUDE = 1
    """Magnitude accuracy (1)"""


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

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

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

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

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

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

    @overload
    def __init__(self, direction: float, magnitude: float, updated_time_utc: 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 updated_time_utc: The algorithm utc time these scores were computed
        """
        ...

    def finalize(self, algorithm_utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Marks the score as finalized, preventing any further updates.
        
        :param algorithm_utc_time: The algorithm's utc time at which time these scores were finalized
        """
        ...

    def get_score(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 set_score(self, type: QuantConnect.Algorithm.Framework.Alphas.InsightScoreType, value: float, algorithm_utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Sets the specified score type with the value
        
        :param type: The score type to be set, Direction/Magnitude
        :param value: The new value for the score
        :param algorithm_utc_time: The algorithm's utc time at which time the new score was computed
        """
        ...

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


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) -> None:
        ...

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

    @group_id.setter
    def group_id(self, value: typing.Optional[System.Guid]) -> None:
        ...

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

    @source_model.setter
    def source_model(self, value: str) -> None:
        ...

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

    @generated_time_utc.setter
    def generated_time_utc(self, value: datetime.datetime) -> None:
        ...

    @property
    def close_time_utc(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
        """
        ...

    @close_time_utc.setter
    def close_time_utc(self, value: datetime.datetime) -> None:
        ...

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

    @property
    def type(self) -> QuantConnect.Algorithm.Framework.Alphas.InsightType:
        """Gets the type of insight, for example, price insight or volatility insight"""
        ...

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

    @reference_value.setter
    def reference_value(self, value: float) -> None:
        ...

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

    @reference_value_final.setter
    def reference_value_final(self, value: float) -> None:
        ...

    @property
    def direction(self) -> QuantConnect.Algorithm.Framework.Alphas.InsightDirection:
        """Gets the predicted direction, down, flat or up"""
        ...

    @property
    def period(self) -> 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)"""
        ...

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

    @property
    def weight(self) -> 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) -> None:
        ...

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

    @estimated_value.setter
    def estimated_value(self, value: float) -> None:
        ...

    @property
    def tag(self) -> str:
        """The insight's tag containing additional information"""
        ...

    @tag.setter
    def tag(self, value: str) -> None:
        ...

    @overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, tag: str = ...) -> 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 tag: The insight's tag containing additional information
        """
        ...

    @overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float], confidence: typing.Optional[float], source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 source_model: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        """
        ...

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

    @overload
    def __init__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], expiry_func: 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], source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> None:
        """
        Initializes a new instance of the Insight class
        
        :param symbol: The symbol this insight is for
        :param expiry_func: 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 source_model: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        """
        ...

    @overload
    def __init__(self, generated_time_utc: typing.Union[datetime.datetime, datetime.date], symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], period: datetime.timedelta, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float], confidence: typing.Optional[float], source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 generated_time_utc: 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 source_model: An identifier defining the model that generated this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        """
        ...

    def cancel(self, utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Cancel this insight
        
        :param utc_time: The algorithm's current time in UTC. See IAlgorithm.UtcTime
        """
        ...

    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
    @overload
    def compute_close_time(exchange_hours: QuantConnect.Securities.SecurityExchangeHours, generated_time_utc: typing.Union[datetime.datetime, datetime.date], resolution: QuantConnect.Resolution, bar_count: 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 exchange_hours: The exchange hours of the insight's security
        :param generated_time_utc: The insight's generated time in utc
        :param resolution: The resolution used to 'step-through' market hours to compute a reasonable close time
        :param bar_count: The number of resolution steps to take
        :returns: The insight's closing time in utc.
        """
        ...

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

    def expire(self, utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """
        Expire this insight
        
        :param utc_time: The algorithm's current time in UTC. See IAlgorithm.UtcTime
        """
        ...

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

    @staticmethod
    @overload
    def group(*insights: typing.Union[QuantConnect.Algorithm.Framework.Alphas.Insight, typing.Iterable[QuantConnect.Algorithm.Framework.Alphas.Insight]]) -> typing.Iterable[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
    @overload
    def group(insight: QuantConnect.Algorithm.Framework.Alphas.Insight) -> typing.Iterable[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 is_active(self, utc_time: typing.Union[datetime.datetime, datetime.date]) -> bool:
        """
        Determines whether or not this insight is considered active at the specified utc_time
        
        :param utc_time: The algorithm's current time in UTC. See IAlgorithm.UtcTime
        :returns: True if this insight is active, false otherwise.
        """
        ...

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

    @staticmethod
    @overload
    def price(symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], resolution: QuantConnect.Resolution, bar_count: int, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 bar_count: 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 source_model: The model generating this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @overload
    def price(symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], close_time_local: typing.Union[datetime.datetime, datetime.date], direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 close_time_local: 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 source_model: The model generating this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @overload
    def price(symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], period: datetime.timedelta, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 source_model: The model generating this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        :returns: A new insight object for the specified parameters.
        """
        ...

    @staticmethod
    @overload
    def price(symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], expiry_func: typing.Callable[[datetime.datetime], datetime.datetime], direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, source_model: str = None, weight: typing.Optional[float] = None, tag: str = ...) -> 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 expiry_func: 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 source_model: The model generating this insight
        :param weight: The portfolio weight of this insight
        :param tag: The insight's tag containing additional information
        :returns: A new insight object for the specified parameters.
        """
        ...

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

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

    def to_string(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) -> typing.Iterable[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(QuantConnect.Python.BasePythonWrapper[QuantConnect_Algorithm_Framework_Alphas_AlphaModel], 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) -> None:
        ...

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

    def on_securities_changed(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) -> typing.Iterable[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 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):
        """Class representing basic data of a symbol"""

        @property
        def previous_direction(self) -> typing.Optional[QuantConnect.Algorithm.Framework.Alphas.InsightDirection]:
            """Previous direction property"""
            ...

        @previous_direction.setter
        def previous_direction(self, value: typing.Optional[QuantConnect.Algorithm.Framework.Alphas.InsightDirection]) -> None:
            ...

        @property
        def security(self) -> QuantConnect.Securities.Security:
            """Security of the Symbol Data"""
            ...

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

        @property
        def macd(self) -> QuantConnect.Indicators.MovingAverageConvergenceDivergence:
            """Moving Average Convergence Divergence indicator"""
            ...

        def __init__(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, security: QuantConnect.Securities.Security, fast_period: int, slow_period: int, signal_period: int, moving_average_type: QuantConnect.Indicators.MovingAverageType, resolution: QuantConnect.Resolution) -> None:
            """Initializes an instance of the SymbolData class with the given arguments"""
            ...

    @property
    def _symbol_data(self) -> System.Collections.Generic.Dictionary[QuantConnect.Symbol, QuantConnect.Algorithm.Framework.Alphas.MacdAlphaModel.SymbolData]:
        """
        Dictionary containing basic information for each symbol present as key
        
        
        This codeEntityType is protected.
        """
        ...

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

    def on_securities_changed(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) -> typing.Iterable[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 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 on_securities_changed(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) -> typing.Iterable[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 EmaCrossAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Alpha model that uses an EMA cross to create insights"""

    class SymbolData(System.Object):
        """Contains data specific to a symbol required by this model"""

        @property
        def symbol(self) -> QuantConnect.Symbol:
            """Symbol associated with the data"""
            ...

        @property
        def fast(self) -> QuantConnect.Indicators.ExponentialMovingAverage:
            """Fast Exponential Moving Average (EMA)"""
            ...

        @property
        def slow(self) -> QuantConnect.Indicators.ExponentialMovingAverage:
            """Slow Exponential Moving Average (EMA)"""
            ...

        @property
        def fast_is_over_slow(self) -> bool:
            """
            True if the fast is above the slow, otherwise false.
            This is used to prevent emitting the same signal repeatedly
            """
            ...

        @fast_is_over_slow.setter
        def fast_is_over_slow(self, value: bool) -> None:
            ...

        @property
        def slow_is_over_fast(self) -> bool:
            """Flag indicating if the Slow EMA is over the Fast one"""
            ...

        def __init__(self, security: QuantConnect.Securities.Security, fast_period: int, slow_period: int, algorithm: QuantConnect.Algorithm.QCAlgorithm, resolution: QuantConnect.Resolution) -> None:
            """Initializes an instance of the class SymbolData with the given arguments"""
            ...

        def remove_consolidators(self) -> None:
            """Remove Fast and Slow consolidators"""
            ...

    @property
    def symbol_data_by_symbol(self) -> System.Collections.Generic.Dictionary[QuantConnect.Symbol, QuantConnect.Algorithm.Framework.Alphas.EmaCrossAlphaModel.SymbolData]:
        """
        This is made protected for testing purposes
        
        
        This codeEntityType is protected.
        """
        ...

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

    def on_securities_changed(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) -> typing.Iterable[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 has_passed_test(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, asset_1: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], asset_2: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract]) -> bool:
        """
        Check whether the assets pass a pairs trading test
        
        :param algorithm: The algorithm instance that experienced the change in securities
        :param asset_1: The first asset's symbol in the pair
        :param asset_2: The second asset's symbol in the pair
        :returns: True if the statistical test for the pair is successful.
        """
        ...

    def on_securities_changed(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) -> typing.Iterable[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 = 15, resolution: QuantConnect.Resolution = ..., threshold: float = 1, minimum_correlation: 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 minimum_correlation: The minimum correlation to consider a tradable pair
        """
        ...

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

    def on_securities_changed(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 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 on_securities_changed(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) -> typing.Iterable[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 ConstantAlphaModel(QuantConnect.Algorithm.Framework.Alphas.AlphaModel):
    """Provides an implementation of IAlphaModel that always returns the same insight for each security"""

    def __init__(self, type: QuantConnect.Algorithm.Framework.Alphas.InsightType, direction: QuantConnect.Algorithm.Framework.Alphas.InsightDirection, period: datetime.timedelta, magnitude: typing.Optional[float] = None, confidence: typing.Optional[float] = None, 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 on_securities_changed(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 should_emit_insight(self, utc_time: typing.Union[datetime.datetime, datetime.date], symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract]) -> bool:
        """
        Determine if its time to emit insight for this symbol
        
        
        This codeEntityType is protected.
        
        :param utc_time: Time of the insight
        :param symbol: The symbol to emit an insight for
        """
        ...

    def update(self, algorithm: QuantConnect.Algorithm.QCAlgorithm, data: QuantConnect.Data.Slice) -> typing.Iterable[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 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.
    """

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

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

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

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

    def on_securities_changed(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) -> typing.Iterable[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) -> typing.Iterable[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 get_model_name(model: QuantConnect.Algorithm.Framework.Alphas.IAlphaModel) -> str:
        """Gets the name of the alpha model"""
        ...


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"""
        ...

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

    def on_securities_changed(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) -> typing.Iterable[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 IInsightScoreFunction(metaclass=abc.ABCMeta):
    """Abstraction in charge of scoring insights"""

    def score(self, insight_manager: QuantConnect.Algorithm.Framework.Alphas.Analysis.InsightManager, utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """Method to evaluate and score insights for each time step"""
        ...


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

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

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

    def __init__(self, date_time_utc: typing.Union[datetime.datetime, datetime.date], insights: typing.List[QuantConnect.Algorithm.Framework.Alphas.Insight]) -> None:
        """
        Initializes a new instance of the GeneratedInsightsCollection class
        
        :param date_time_utc: The utc date time the sinals were generated
        :param insights: The generated insights
        """
        ...


class InsightScoreFunctionPythonWrapper(QuantConnect.Python.BasePythonWrapper[QuantConnect.Algorithm.Framework.Alphas.IInsightScoreFunction], QuantConnect.Algorithm.Framework.Alphas.IInsightScoreFunction):
    """A python implementation insight evaluator wrapper"""

    def __init__(self, insight_evaluator: typing.Any) -> None:
        """
        Creates a new python wrapper instance
        
        :param insight_evaluator: The python instance to wrap
        """
        ...

    def score(self, insight_manager: QuantConnect.Algorithm.Framework.Alphas.Analysis.InsightManager, utc_time: typing.Union[datetime.datetime, datetime.date]) -> None:
        """Method to evaluate and score insights for each time step"""
        ...


class InsightCollection(System.Object, 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:
        """The open insight count"""
        ...

    @property
    def total_count(self) -> int:
        """The total insight count"""
        ...

    def __contains__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract]) -> 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 __getitem__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract]) -> typing.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 __iter__(self) -> typing.Iterator[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        ...

    def __len__(self) -> int:
        ...

    def __setitem__(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], value: typing.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 add_range(self, insights: typing.List[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
        """
        ...

    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 item is found in the System.Collections.Generic.ICollection`1; otherwise, false.
        """
        ...

    def contains_key(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract]) -> 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 get_active_insights(self, utc_time: 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.
        """
        ...

    def get_enumerator(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.
        """
        ...

    @overload
    def get_insights(self, filter: typing.Any) -> typing.List[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Will return insights from the complete insight collection
        
        :param filter: The function that will determine which insight to return
        :returns: A new list containing the selected insights.
        """
        ...

    @overload
    def get_insights(self, filter: typing.Callable[[QuantConnect.Algorithm.Framework.Alphas.Insight], bool] = None) -> typing.List[QuantConnect.Algorithm.Framework.Alphas.Insight]:
        """
        Will return insights from the complete insight collection
        
        :param filter: The function that will determine which insight to return
        :returns: A new list containing the selected insights.
        """
        ...

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

    def has_active_insights(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], utc_time: 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 utc_time: 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 item was successfully removed from the System.Collections.Generic.ICollection`1; otherwise, false. This method also returns false if item is not found in the original System.Collections.Generic.ICollection`1.
        """
        ...

    def remove_expired_insights(self, utc_time: 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 utc_time: Time that determines whether the insight has expired
        :returns: Expired insights that were removed.
        """
        ...

    def remove_insights(self, filter: typing.Callable[[QuantConnect.Algorithm.Framework.Alphas.Insight], bool]) -> None:
        """
        Will remove insights from the complete insight collection
        
        :param filter: The function that will determine which insight to remove
        """
        ...

    def try_get_value(self, symbol: typing.Union[QuantConnect.Symbol, str, QuantConnect.Data.Market.BaseContract], insights: typing.Optional[typing.List[QuantConnect.Algorithm.Framework.Alphas.Insight]]) -> typing.Tuple[bool, typing.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.
        """
        ...


