
    i"                       d dl mZ d dlZd dlmZ d dlmZmZ d dlZ	d dl
mZ d dlmc mc mZ d dlmZ d dlmZmZ d dlmZ d d	lmZ d d
lmZ d dlmZ d dlmZ d dl m!Z!m"Z"m#Z# d dl$m%Z%m&Z& d dl'm(Z( d dl)m*Z*m+Z+ d dl,m-Z-m.Z. d dl/m0Z0m1Z1 erd dl2m3Z3m4Z4m5Z5 d dl6m7Z7m8Z8 d dl9m:Z: 	 	 	 	 	 	 	 	 	 	 ddZ;	 	 	 	 	 	 d dZ< ed       G d de0             Z= ed       G d de1e=             Z> G d de=      Z?y)!    )annotationsN)partial)TYPE_CHECKINGcast)	Timedelta)
set_module)is_datetime64_dtypeis_numeric_dtype)DatetimeTZDtype)	ABCSeries)isna)common)dtype_to_unit)BaseIndexerExponentialMovingWindowIndexerGroupbyIndexer)get_jit_argumentsmaybe_use_numba)zsqrt)generate_numba_ewm_funcgenerate_numba_ewm_table_func)EWMMeanStategenerate_online_numba_ewma_func)
BaseWindowBaseWindowGroupby)TimedeltaConvertibleTypesTimeUnitnpt)	DataFrameSeries)NDFramec                   t        j                  | |||      }|dkD  rt        d      | | dk  rt        d      |#|dk  rt        d      |dz
  dz  } t        |       S |Q|dk  rt        d      dt        j                  t        j
                  d      |z        z
  }d|z  dz
  } t        |       S |(|dk  s|dkD  rt        d	      d|z
  |z  } t        |       S t        d
      t        |       S )N   z8comass, span, halflife, and alpha are mutually exclusiver   z comass must satisfy: comass >= 0zspan must satisfy: span >= 1   z#halflife must satisfy: halflife > 0g      ?z"alpha must satisfy: 0 < alpha <= 1z1Must pass one of comass, span, halflife, or alpha)r   count_not_none
ValueErrornpexplogfloat)comassspanhalflifealphavalid_countdecays         S/app/cer_product_mecsu/.venv/lib/python3.12/site-packages/pandas/core/window/ewm.pyget_center_of_massr2   ?   s!    ''hFKQSTT A:?@@		!8;<<(a = 
	q=BCCBFF266#;122UQ = 
	A:ABBe)u$ = LMM=    c                   t        | j                        }t        d|      }t        | t              r| j
                  } t        j                  | j                  t        j                        t        j                        }t        t        |      j                  |      j                        }t        j                  |      |z  S )a  
    Return the diff of the times divided by the half-life. These values are used in
    the calculation of the ewm mean.

    Parameters
    ----------
    times : np.ndarray, Series
        Times corresponding to the observations. Must be monotonically increasing
        and ``datetime64[ns]`` dtype.
    halflife : float, str, timedelta, optional
        Half-life specifying the decay

    Returns
    -------
    np.ndarray
        Diff of the times divided by the half-life
    r   dtype)r   r6   r   
isinstancer   _valuesr'   asarrayviewint64float64r*   r   as_unit_valuediff)timesr-   unit_times	_halflifes        r1   _calculate_deltasrD   `   s    * %D
D!D%#ZZ

288,BJJ?Fi)11$7>>?I776?Y&&r3   zpandas.api.typingc                  $    e Zd ZdZg dZ	 	 	 	 	 	 	 	 	 ddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZ	 	 	 	 	 	 	 	 ddZddZ	 d	 	 	 ddZd fd		Z	e	Z
	 	 	 d	 dd
Z	 	 	 d	 ddZdddZdddZ	 	 	 	 d	 	 	 	 	 	 	 ddZ	 	 	 d	 	 	 	 	 ddZ xZS )ExponentialMovingWindowa  
    Provide exponentially weighted (EW) calculations.

    Exactly one of ``com``, ``span``, ``halflife``, or ``alpha`` must be
    provided if ``times`` is not provided. If ``times`` is provided and ``adjust=True``,
    ``halflife`` and one of ``com``, ``span`` or ``alpha`` may be provided.
    If ``times`` is provided and ``adjust=False``, ``halflife`` must be the only
    provided decay-specification parameter.

    Parameters
    ----------
    com : float, optional
        Specify decay in terms of center of mass

        :math:`\alpha = 1 / (1 + com)`, for :math:`com \geq 0`.

    span : float, optional
        Specify decay in terms of span

        :math:`\alpha = 2 / (span + 1)`, for :math:`span \geq 1`.

    halflife : float, str, timedelta, optional
        Specify decay in terms of half-life

        :math:`\alpha = 1 - \exp\left(-\ln(2) / halflife\right)`, for
        :math:`halflife > 0`.

        If ``times`` is specified, a timedelta convertible unit over which an
        observation decays to half its value. Only applicable to ``mean()``,
        and halflife value will not apply to the other functions.

    alpha : float, optional
        Specify smoothing factor :math:`\alpha` directly

        :math:`0 < \alpha \leq 1`.

    min_periods : int, default 0
        Minimum number of observations in window required to have a value;
        otherwise, result is ``np.nan``.

    adjust : bool, default True
        Divide by decaying adjustment factor in beginning periods to account
        for imbalance in relative weightings (viewing EWMA as a moving average).

        - When ``adjust=True`` (default), the EW function is calculated using weights
          :math:`w_i = (1 - \alpha)^i`. For example, the EW moving average of the series
          [:math:`x_0, x_1, ..., x_t`] would be:

        .. math::
            y_t = \frac{x_t + (1 - \alpha)x_{t-1} + (1 - \alpha)^2 x_{t-2} + ... + (1 -
            \alpha)^t x_0}{1 + (1 - \alpha) + (1 - \alpha)^2 + ... + (1 - \alpha)^t}

        - When ``adjust=False``, the exponentially weighted function is calculated
          recursively:

        .. math::
            \begin{split}
                y_0 &= x_0\\
                y_t &= (1 - \alpha) y_{t-1} + \alpha x_t,
            \end{split}
    ignore_na : bool, default False
        Ignore missing values when calculating weights.

        - When ``ignore_na=False`` (default), weights are based on absolute positions.
          For example, the weights of :math:`x_0` and :math:`x_2` used in calculating
          the final weighted average of [:math:`x_0`, None, :math:`x_2`] are
          :math:`(1-\alpha)^2` and :math:`1` if ``adjust=True``, and
          :math:`(1-\alpha)^2` and :math:`\alpha` if ``adjust=False``.

        - When ``ignore_na=True``, weights are based
          on relative positions. For example, the weights of :math:`x_0` and :math:`x_2`
          used in calculating the final weighted average of
          [:math:`x_0`, None, :math:`x_2`] are :math:`1-\alpha` and :math:`1` if
          ``adjust=True``, and :math:`1-\alpha` and :math:`\alpha` if ``adjust=False``.

    times : np.ndarray, Series, default None

        Only applicable to ``mean()``.

        Times corresponding to the observations. Must be monotonically increasing and
        ``datetime64[ns]`` dtype.

        If 1-D array like, a sequence with the same shape as the observations.

    method : str {'single', 'table'}, default 'single'
        Execute the rolling operation per single column or row (``'single'``)
        or over the entire object (``'table'``).

        This argument is only implemented when specifying ``engine='numba'``
        in the method call.

        Only applicable to ``mean()``

    Returns
    -------
    pandas.api.typing.ExponentialMovingWindow
        An instance of ExponentialMovingWindow for further exponentially weighted (EW)
        calculations, e.g. using the ``mean`` method.

    See Also
    --------
    rolling : Provides rolling window calculations.
    expanding : Provides expanding transformations.

    Notes
    -----
    See :ref:`Windowing Operations <window.exponentially_weighted>`
    for further usage details and examples.

    Examples
    --------
    >>> df = pd.DataFrame({'B': [0, 1, 2, np.nan, 4]})
    >>> df
         B
    0  0.0
    1  1.0
    2  2.0
    3  NaN
    4  4.0

    >>> df.ewm(com=0.5).mean()
              B
    0  0.000000
    1  0.750000
    2  1.615385
    3  1.615385
    4  3.670213
    >>> df.ewm(alpha=2 / 3).mean()
              B
    0  0.000000
    1  0.750000
    2  1.615385
    3  1.615385
    4  3.670213

    **adjust**

    >>> df.ewm(com=0.5, adjust=True).mean()
              B
    0  0.000000
    1  0.750000
    2  1.615385
    3  1.615385
    4  3.670213
    >>> df.ewm(com=0.5, adjust=False).mean()
              B
    0  0.000000
    1  0.666667
    2  1.555556
    3  1.555556
    4  3.650794

    **ignore_na**

    >>> df.ewm(com=0.5, ignore_na=True).mean()
              B
    0  0.000000
    1  0.750000
    2  1.615385
    3  1.615385
    4  3.225000
    >>> df.ewm(com=0.5, ignore_na=False).mean()
              B
    0  0.000000
    1  0.750000
    2  1.615385
    3  1.615385
    4  3.670213

    **times**

    Exponentially weighted mean with weights calculated with a timedelta ``halflife``
    relative to ``times``.

    >>> times = ['2020-01-01', '2020-01-03', '2020-01-10', '2020-01-15', '2020-01-17']
    >>> df.ewm(halflife='4 days', times=pd.DatetimeIndex(times)).mean()
              B
    0  0.000000
    1  0.585786
    2  1.523889
    3  1.523889
    4  3.233686
    )	comr,   r-   r.   min_periodsadjust	ignore_nar@   methodN	selectionc          	        t         |   ||dnt        t        |      d      d dd |
|       || _        || _        || _        || _        || _        || _	        |	| _
        | j                  t        | j                  dd       }t        |      st        |t              st        d      t!        | j                        t!        |      k7  rt        d      t        | j                  t"        t$        j&                  t(        j*                  f      st        d      t-        | j                        j/                         rt        d      t1        | j                  | j                        | _        t5        j6                  | j                  | j
                  | j                        d	kD  rI| j                  st9        d
      t;        | j                  | j
                  d | j                        | _        y d| _        y | j                  Dt        | j                  t"        t$        j&                  t(        j*                  f      rt        d      t)        j>                  t        | j@                  jB                  d	   dz
  d	      t(        jD                        | _        t;        | j                  | j
                  | j                  | j                        | _        y )Nr#   F)objrH   oncenterclosedrK   rM   r6   ztimes must be datetime64 dtype.z,times must be the same length as the object.z/halflife must be a timedelta convertible objectz$Cannot convert NaT values to integerr   zRNone of com, span, or alpha can be specified if times is provided and adjust=Falseg      ?zKhalflife can only be a timedelta convertible argument if times is not None.r5   )#super__init__maxintrG   r,   r-   r.   rI   rJ   r@   getattrr	   r7   r   r&   lenstrdatetime	timedeltar'   timedelta64r   anyrD   _deltasr   r%   NotImplementedErrorr2   _comonesrO   shaper<   )selfrO   rG   r,   r-   r.   rH   rI   rJ   r@   rK   rM   times_dtype	__class__s                r1   rT   z ExponentialMovingWindow.__init__D  s-    	(0c#k:JA6N 	 	
 	 
"
::!!$**gt<K#K0k?; !BCC4::#c(* !OPPdmmc83E3Er~~-VW !RSSDJJ##% !GHH,TZZGDL $$TXXtyy$**EI{{-=  /txxD$**U		}}(ZX%7%7H. !) 
 773txx~~a'81'<a#@

SDL* 		

DIr3   c                     y N )rc   startendnum_valss       r1   _check_window_boundsz,ExponentialMovingWindow._check_window_bounds  s    
 	r3   c                    t               S )z[
        Return an indexer class that will compute the window start and end bounds
        )r   rc   s    r1   _get_window_indexerz+ExponentialMovingWindow._get_window_indexer  s     .//r3   c                    t        | j                  | j                  | j                  | j                  | j
                  | j                  | j                  | j                  | j                  ||| j                        S )a  
        Return an ``OnlineExponentialMovingWindow`` object to calculate
        exponentially moving window aggregations in an online method.

        Parameters
        ----------
        engine: str, default ``'numba'``
            Execution engine to calculate online aggregations.
            Applies to all supported aggregation methods.

        engine_kwargs : dict, default None
            Applies to all supported aggregation methods.

            * For ``'numba'`` engine, the engine can accept ``nopython``, ``nogil``
              and ``parallel`` dictionary keys. The values must either be ``True`` or
              ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
              ``{'nopython': True, 'nogil': False, 'parallel': False}`` and will be
              applied to the function

        Returns
        -------
        OnlineExponentialMovingWindow
        )rO   rG   r,   r-   r.   rH   rI   rJ   r@   engineengine_kwargsrM   )OnlineExponentialMovingWindowrO   rG   r,   r-   r.   rH   rI   rJ   r@   
_selection)rc   rq   rr   s      r1   onlinezExponentialMovingWindow.online  s_    4 -]]**((;;nn**'oo
 	
r3   c                *    t        |   |g|i |S )a[	  
        Aggregate using one or more operations over the specified axis.

        Parameters
        ----------
        func : function, str, list or dict
            Function to use for aggregating the data. If a function, must either
            work when passed a Series/Dataframe or when passed to
            Series/Dataframe.apply.

            Accepted combinations are:

            - function
            - string function name
            - list of functions and/or function names, e.g. ``[np.sum, 'mean']``
            - dict of axis labels -> functions, function names or list of such.
        *args
            Positional arguments to pass to `func`.
        **kwargs
            Keyword arguments to pass to `func`.

        Returns
        -------
        scalar, Series or DataFrame

            The return can be:

            * scalar : when Series.agg is called with single function
            * Series : when DataFrame.agg is called with a single function
            * DataFrame : when DataFrame.agg is called with several functions

        See Also
        --------
        pandas.DataFrame.rolling.aggregate

        Notes
        -----
        The aggregation operations are always performed over an axis, either the
        index (default) or the column axis. This behavior is different from
        `numpy` aggregation functions (`mean`, `median`, `prod`, `sum`, `std`,
        `var`), where the default is to compute the aggregation of the flattened
        array, e.g., ``numpy.mean(arr_2d)`` as opposed to
        ``numpy.mean(arr_2d, axis=0)``.

        `agg` is an alias for `aggregate`. Use the alias.

        Functions that mutate the passed object can produce unexpected
        behavior or errors and are not supported. See :ref:`gotchas.udf-mutation`
        for more details.

        A passed user-defined-function will be passed a Series for evaluation.

        If ``func`` defines an index relabeling, ``axis`` must be ``0`` or ``index``.

        Examples
        --------
        >>> df = pd.DataFrame({"A": [1, 2, 3], "B": [4, 5, 6], "C": [7, 8, 9]})
        >>> df
           A  B  C
        0  1  4  7
        1  2  5  8
        2  3  6  9

        >>> df.ewm(alpha=0.5).mean()
                  A         B         C
        0  1.000000  4.000000  7.000000
        1  1.666667  4.666667  7.666667
        2  2.428571  5.428571  8.428571
        )rS   	aggregate)rc   funcargskwargsre   s       r1   rw   z!ExponentialMovingWindow.aggregate  s     L w 7777r3   c           
        t        |      ry| j                  dk(  rt        }nt        } |di t	        |      | j
                  | j                  | j                  t        | j                        dd}| j                  |d      S |dv rx|t        d      | j                  dn| j                  }t        t        j                  | j
                  | j                  | j                  |d      }| j                  |d|	      S t        d
      )a  
        Calculate the ewm (exponential weighted moment) mean.

        Parameters
        ----------
        numeric_only : bool, default False
            Include only float, int, boolean columns.

        engine : str, default None
            * ``'cython'`` : Runs the operation through C-extensions from cython.
            * ``'numba'`` : Runs the operation through JIT compiled code from numba.
            * ``None`` : Defaults to ``'cython'`` or globally setting
              ``compute.use_numba``

        engine_kwargs : dict, default None
            * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
            * For ``'numba'`` engine, the engine can accept ``nopython``, ``nogil``
              and ``parallel`` dictionary keys. The values must either be ``True`` or
              ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
              ``{'nopython': True, 'nogil': False, 'parallel': False}``

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.mean : Aggregating mean for Series.
        DataFrame.mean : Aggregating mean for DataFrame.

        Notes
        -----
        See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for
        extended documentation and performance considerations for the Numba engine.

        Examples
        --------
        >>> ser = pd.Series([1, 2, 3, 4])
        >>> ser.ewm(alpha=0.2).mean()
        0    1.000000
        1    1.555556
        2    2.147541
        3    2.775068
        dtype: float64
        singleTrG   rI   rJ   deltas	normalizemeannamecythonNN+cython engine does not accept engine_kwargsr   numeric_only)engine must be either 'numba' or 'cython'rh   )r   rK   r   r   r   r`   rI   rJ   tupler^   _applyr&   r@   r   window_aggregationsewmrc   r   rq   rr   rx   ewm_funcr~   window_funcs           r1   r   zExponentialMovingWindow.mean  s    l 6"{{h&.4 #M2II{{..T\\*H ;;xf;55''( !NOO!ZZ/TT\\F!#''II{{..K ;;{l;SSHIIr3   c           
     t   | j                   st        d      | j                  t        d      t        |      ry| j                  dk(  rt
        }nt        } |di t        |      | j                  | j                   | j                  t        | j                        dd}| j                  |d      S |d	v rx|t        d
      | j                  dn| j                  }t        t        j                   | j                  | j                   | j                  |d      }| j                  |d|      S t        d      )a  
        Calculate the ewm (exponential weighted moment) sum.

        Parameters
        ----------
        numeric_only : bool, default False
            Include only float, int, boolean columns.
        engine : str, default None
            * ``'cython'`` : Runs the operation through C-extensions from cython.
            * ``'numba'`` : Runs the operation through JIT compiled code from numba.
            * ``None`` : Defaults to ``'cython'`` or globally setting
              ``compute.use_numba``
        engine_kwargs : dict, default None
            * For ``'cython'`` engine, there are no accepted ``engine_kwargs``
            * For ``'numba'`` engine, the engine can accept ``nopython``, ``nogil``
              and ``parallel`` dictionary keys. The values must either be ``True`` or
              ``False``. The default ``engine_kwargs`` for the ``'numba'`` engine is
              ``{'nopython': True, 'nogil': False, 'parallel': False}``

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.sum : Aggregating sum for Series.
        DataFrame.sum : Aggregating sum for DataFrame.

        Notes
        -----
        See :ref:`window.numba_engine` and :ref:`enhancingperf.numba` for extended
        documentation and performance considerations for the Numba engine.

        Examples
        --------
        >>> ser = pd.Series([1, 2, 3, 4])
        >>> ser.ewm(alpha=0.2).sum()
        0    1.000
        1    2.800
        2    5.240
        3    8.192
        dtype: float64
        z(sum is not implemented with adjust=FalseNz!sum is not implemented with timesr|   Fr}   sumr   r   r   r   r   rh   )rI   r_   r@   r   rK   r   r   r   r`   rJ   r   r^   r   r&   r   r   r   r   s           r1   r   zExponentialMovingWindow.sume  s!   h {{%&PQQ::!%&IJJ6"{{h&.4 #M2II{{..T\\*H ;;xe;44''( !NOO!ZZ/TT\\F!#''II{{..K ;;{\;RRHIIr3   c                   |rY| j                   j                  dk(  r@t        | j                   j                        s!t	        t        |       j                   d      | j                  t	        d      t        | j                  ||            S )a  
        Calculate the ewm (exponential weighted moment) standard deviation.

        Parameters
        ----------
        bias : bool, default False
            Use a standard estimation bias correction.
        numeric_only : bool, default False
            Include only float, int, boolean columns.

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.std : Aggregating std for Series.
        DataFrame.std : Aggregating std for DataFrame.

        Examples
        --------
        >>> ser = pd.Series([1, 2, 3, 4])
        >>> ser.ewm(alpha=0.2).std()
        0         NaN
        1    0.707107
        2    0.995893
        3    1.277320
        dtype: float64
        r#   z$.std does not implement numeric_onlyz!std is not implemented with times)biasr   )
_selected_objndimr
   r6   r_   type__name__r@   r   varrc   r   r   s      r1   stdzExponentialMovingWindow.std  s    D ""''1,$T%7%7%=%=> &:&&''KL  ::!%&IJJTXX4lXCDDr3   c                    | j                   t        d      t        j                  }t	        || j
                  | j                  | j                  |      fd}| j                  |d|      S )a  
        Calculate the ewm (exponential weighted moment) variance.

        Parameters
        ----------
        bias : bool, default False
            Use a standard estimation bias correction.
        numeric_only : bool, default False
            Include only float, int, boolean columns.

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.var : Aggregating var for Series.
        DataFrame.var : Aggregating var for DataFrame.

        Examples
        --------
        >>> ser = pd.Series([1, 2, 3, 4])
        >>> ser.ewm(alpha=0.2).var()
        0         NaN
        1    0.500000
        2    0.991803
        3    1.631547
        dtype: float64
        z!var is not implemented with times)rG   rI   rJ   r   c                     | ||||       S rg   rh   )valuesbeginrj   rH   wfuncs       r1   var_funcz-ExponentialMovingWindow.var.<locals>.var_func  s    [&AAr3   r   r   )	r@   r_   r   ewmcovr   r`   rI   rJ   r   )rc   r   r   r   r   r   s        @r1   r   zExponentialMovingWindow.var  si    B ::!%&IJJ)00		;;nn
	B {{8%l{KKr3   c                      j                   t        d      ddlm  j	                  d|        fd} j                   j                  ||||      S )a  
        Calculate the ewm (exponential weighted moment) sample covariance.

        Parameters
        ----------
        other : Series or DataFrame , optional
            If not supplied then will default to self and produce pairwise
            output.
        pairwise : bool, default None
            If False then only matching columns between self and other will be
            used and the output will be a DataFrame.
            If True then all pairwise combinations will be calculated and the
            output will be a MultiIndex DataFrame in the case of DataFrame
            inputs. In the case of missing elements, only complete pairwise
            observations will be used.
        bias : bool, default False
            Use a standard estimation bias correction.
        numeric_only : bool, default False
            Include only float, int, boolean columns.

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.cov : Aggregating cov for Series.
        DataFrame.cov : Aggregating cov for DataFrame.

        Examples
        --------
        >>> ser1 = pd.Series([1, 2, 3, 4])
        >>> ser2 = pd.Series([10, 11, 13, 16])
        >>> ser1.ewm(alpha=0.2).cov(ser2)
        0         NaN
        1    0.500000
        2    1.524590
        3    3.408836
        dtype: float64
        z!cov is not implemented with timesr   r    covc                   j                  |       }j                  |      }j                         }j                  j                  n|j                  }|j	                  t        |      |j                  j                  j                        \  }}t        j                  |||j                  |j                  j                  j                  
	      } 	|| j                  | j                  d      S )N
num_valuesrH   rQ   rR   stepFindexr   copy)_prep_valuesro   rH   window_sizeget_window_boundsrX   rQ   rR   r   r   r   r`   rI   rJ   r   r   )xyx_arrayy_arraywindow_indexerrH   ri   rj   resultr    r   rc   s            r1   cov_funcz-ExponentialMovingWindow.cov.<locals>.cov_funcT  s    ''*G''*G!557N ##/   #// 
 (99w<'{{{{YY : JE3 )//   		F &aff5IIr3   r@   r_   pandasr    _validate_numeric_only_apply_pairwiser   )rc   otherpairwiser   r   r   r    s   `  `  @r1   r   zExponentialMovingWindow.cov  s[    d ::!%&IJJ!##E<8	J> ##x<
 	
r3   c                      j                   t        d      ddlm  j	                  d|        fd} j                   j                  ||||      S )a  
        Calculate the ewm (exponential weighted moment) sample correlation.

        Parameters
        ----------
        other : Series or DataFrame, optional
            If not supplied then will default to self and produce pairwise
            output.
        pairwise : bool, default None
            If False then only matching columns between self and other will be
            used and the output will be a DataFrame.
            If True then all pairwise combinations will be calculated and the
            output will be a MultiIndex DataFrame in the case of DataFrame
            inputs. In the case of missing elements, only complete pairwise
            observations will be used.
        numeric_only : bool, default False
            Include only float, int, boolean columns.

        Returns
        -------
        Series or DataFrame
            Return type is the same as the original object with ``np.float64`` dtype.

        See Also
        --------
        Series.ewm : Calling ewm with Series data.
        DataFrame.ewm : Calling ewm with DataFrames.
        Series.corr : Aggregating corr for Series.
        DataFrame.corr : Aggregating corr for DataFrame.

        Examples
        --------
        >>> ser1 = pd.Series([1, 2, 3, 4])
        >>> ser2 = pd.Series([10, 11, 13, 16])
        >>> ser1.ewm(alpha=0.2).corr(ser2)
        0         NaN
        1    1.000000
        2    0.982821
        3    0.977802
        dtype: float64
        z"corr is not implemented with timesr   r   corrc                4  
 j                  |       }j                  |      }j                         }j                  j                  n|j                  |j	                  t        |      j                  j                  j                        \  

fd}t        j                  d      5   |||      } |||      } |||      }|t        ||z        z  }	d d d         	| j                  | j                  d      S # 1 sw Y   )xY w)Nr   c                z    t        j                  | |j                  j                  j                  d	      S )NT)r   r   r`   rI   rJ   )XYrj   rH   rc   ri   s     r1   _covz<ExponentialMovingWindow.corr.<locals>.cov_func.<locals>._cov  s=    *11IIKKNN
 
r3   ignore)allFr   )r   ro   rH   r   r   rX   rQ   rR   r   r'   errstater   r   r   )r   r   r   r   r   r   r   x_vary_varr   rj   rH   ri   r    rc   s             @@@r1   r   z.ExponentialMovingWindow.corr.<locals>.cov_func  s   ''*G''*G!557N ##/   #// 
 (99w<'{{{{YY : JE3 * 47G,Wg.Wg.uUU]33	4
 &aff5II4 4s   9-DDr   )rc   r   r   r   r   r    s   `    @r1   r   zExponentialMovingWindow.corrw  s\    ^ ::!%&JKK!##FL9#	JJ ##x<
 	
r3   )	NNNNr   TFNr|   )rO   r!   rG   float | Noner,   r   r-   (float | TimedeltaConvertibleTypes | Noner.   r   rH   
int | NonerI   boolrJ   r   r@   np.ndarray | NDFrame | NonerK   rY   returnNone)ri   
np.ndarrayrj   r   rk   rV   r   r   )r   r   )numbaN)rq   rY   r   rs   rg   )FNN)r   r   FFr   r   r   r   NNFFr   DataFrame | Series | Noner   bool | Noner   r   r   r   NNFr   r   r   r   r   r   )r   
__module____qualname____doc___attributesrT   rl   ro   ru   rw   aggr   r   r   r   r   r   __classcell__re   s   @r1   rF   rF   ~   s   vp
K !!=A""#-1J JJ J 	J
 ;J J  J J J +J J 
JX&0<?	0 48'
'
	&'
RF8P C #	SJSJn #	UJUJn,E\/Lf ,0 $"Z
(Z
 Z
 	Z

 Z
| ,0 $"	]
(]
 ]
 	]
r3   rF   c                  d     e Zd ZdZej
                  ej
                  z   Zddd fdZddZ xZ	S )ExponentialMovingWindowGroupbyzF
    Provide an exponential moving window groupby implementation.
    N)_grouperc               L   t        |   |g|d|i| |j                  s| j                  ut	        j
                  t        | j                  j                  j                                     }t        | j                  j                  |      | j                        | _        y y y )Nr   )rS   rT   emptyr@   r'   concatenatelistr   indicesr   rD   taker-   r^   )rc   rO   r   ry   rz   groupby_orderre   s         r1   rT   z'ExponentialMovingWindowGroupby.__init__  s    AtAhA&AyyTZZ3NN40E0E0L0L0N+OPM,

.DL 4yr3   c                P    t        | j                  j                  t              }|S )z
        Return an indexer class that will compute the window start and end bounds

        Returns
        -------
        GroupbyIndexer
        )groupby_indicesr   )r   r   r   r   )rc   r   s     r1   ro   z2ExponentialMovingWindowGroupby._get_window_indexer  s&     ( MM119
 r3   r   r   )r   r   )
r   r   r   r   rF   r   r   rT   ro   r   r   s   @r1   r   r     s.     *558I8U8UUK,0 	r3   r   c                       e Zd Z	 	 	 	 	 	 	 	 	 	 ddd	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 d fdZddZddZdddZ	 	 	 d	 	 	 	 	 ddZ	 	 	 	 d	 	 	 	 	 	 	 ddZddd	Z	ddd
dZ
 xZS )rs   NrL   c                  |	t        d      t        | 	  |||||||||	|
       t        | j                  | j
                  | j                  |j                        | _        t        |
      r|
| _
        || _        y t        d      )Nz0times is not implemented with online operations.)
rO   rG   r,   r-   r.   rH   rI   rJ   r@   rM   z$'numba' is the only supported engine)r_   rS   rT   r   r`   rI   rJ   rb   _meanr   rq   rr   r&   )rc   rO   rG   r,   r-   r.   rH   rI   rJ   r@   rq   rr   rM   re   s                r1   rT   z&OnlineExponentialMovingWindow.__init__  s      %B  	# 	 	
 "$))T[[$..#))T
6" DK!.DCDDr3   c                8    | j                   j                          y)z=
        Reset the state captured by `update` calls.
        N)r   resetrn   s    r1   r   z#OnlineExponentialMovingWindow.reset!  s     	

r3   c                    t        d      )Nzaggregate is not implemented.r_   )rc   rx   ry   rz   s       r1   rw   z'OnlineExponentialMovingWindow.aggregate'  s    !"ABBr3   c                    t        d      )Nzstd is not implemented.r   )rc   r   ry   rz   s       r1   r   z!OnlineExponentialMovingWindow.std*      !";<<r3   c                    t        d      )Nzcorr is not implemented.r   )rc   r   r   r   s       r1   r   z"OnlineExponentialMovingWindow.corr-  s     ""<==r3   c                    t        d      )Nzcov is not implemented.r   )rc   r   r   r   r   s        r1   r   z!OnlineExponentialMovingWindow.cov5  s     "";<<r3   c                    t        d      )Nzvar is not implemented.r   r   s      r1   r   z!OnlineExponentialMovingWindow.var>  r   r3   )updateupdate_timesc                  i }| j                   j                  dk(  }|t        d      t        j                  t        | j                   j                  d   dz
  d      t        j                        }|| j                  j                  t        d      d}|j                  |d	<   |r;| j                  j                  t        j                  ddf   }	|j                  |d
<   n%| j                  j                  }	|j                  |d<   t        j                  |	|j!                         f      }
nd}| j                   j                  |d	<   |r| j                   j                  |d
<   n| j                   j                  |d<   | j                   j#                  t        j                        j!                         }
t%        di t'        | j(                        }| j                  j+                  |r|
n|
ddt        j                  f   || j,                  |      }|s|j/                         }||d } | j                   j0                  |fi |}|S )a[  
        Calculate an online exponentially weighted mean.

        Parameters
        ----------
        update: DataFrame or Series, default None
            New values to continue calculating the
            exponentially weighted mean from the last values and weights.
            Values should be float64 dtype.

            ``update`` needs to be ``None`` the first time the
            exponentially weighted mean is calculated.

        update_times: Series or 1-D np.ndarray, default None
            New times to continue calculating the
            exponentially weighted mean from the last values and weights.
            If ``None``, values are assumed to be evenly spaced
            in time.
            This feature is currently unsupported.

        Returns
        -------
        DataFrame or Series

        Examples
        --------
        >>> df = pd.DataFrame({"a": range(5), "b": range(5, 10)})
        >>> online_ewm = df.head(2).ewm(0.5).online()
        >>> online_ewm.mean()
              a     b
        0  0.00  5.00
        1  0.75  5.75
        >>> online_ewm.mean(update=df.tail(3))
                  a         b
        2  1.615385  6.615385
        3  2.550000  7.550000
        4  3.520661  8.520661
        >>> online_ewm.reset()
        >>> online_ewm.mean()
              a     b
        0  0.00  5.00
        1  0.75  5.75
        r$   Nz update_times is not implemented.r#   r   r5   z;Must call mean with update=None first before passing updater   columnsr   rh   )r   r   r_   r'   ra   rU   rb   r<   r   last_ewmr&   r   newaxisr   r   r   to_numpyastyper   r   rr   run_ewmrH   squeeze_constructor)rc   r   r   ry   rz   result_kwargsis_frameupdate_deltasresult_from
last_valuenp_array	ewma_funcr   s                r1   r   z"OnlineExponentialMovingWindow.meanA  s	   X %%**a/#%&HII""((,q0!4BJJ
 zz""* Q  K%+\\M'"!ZZ00Q?
+1>>i(!ZZ00
(.f%~~z6??3D&EFHK%)%7%7%=%=M'"+/+=+=+E+Ei((,(:(:(?(?f%))00<EEGH3 
 2 23
	 ## Hhq"**}&=	
 ^^%F%0##00I=Ir3   )
NNNNr   TFNr   N)rO   r!   rG   r   r,   r   r-   r   r.   r   rH   r   rI   r   rJ   r   r@   r   rq   rY   rr   zdict[str, bool] | Noner   r   r   rg   )F)r   r   r   r   r   r   r   r   )r   r   r   rT   r   rw   r   r   r   r   r   r   r   s   @r1   rs   rs     sD    !!=A""#-104%E %E%E %E 	%E
 ;%E %E  %E %E %E +%E %E .%E 
%ENC=
 ,0 $"	>(> > 	> ,0 $"=(= = 	=
 == "&D V Vr3   rs   )
r+   r   r,   r   r-   r   r.   r   r   r*   )r@   znp.ndarray | NDFramer-   r   r   znpt.NDArray[np.float64])@
__future__r   rZ   	functoolsr   typingr   r   numpyr'   pandas._libs.tslibsr    pandas._libs.window.aggregations_libswindowaggregationsr   pandas.util._decoratorsr   pandas.core.dtypes.commonr	   r
   pandas.core.dtypes.dtypesr   pandas.core.dtypes.genericr   pandas.core.dtypes.missingr   pandas.corer   pandas.core.arrays.datetimeliker   pandas.core.indexers.objectsr   r   r   pandas.core.util.numba_r   r   pandas.core.window.commonr   pandas.core.window.numba_r   r   pandas.core.window.onliner   r   pandas.core.window.rollingr   r   pandas._typingr   r   r   r   r   r    pandas.core.genericr!   r2   rD   rF   r   rs   rh   r3   r1   <module>r$     s#   "  
  ) > > . 6 0 +  9 
 ,
   ,
  	
 B''6' '<  U
j U
 !U
p  %68O  !B^$; ^r3   