"""
Analytics endpoint mixins.

AUTO-GENERATED by scripts/generate_sdk.py - DO NOT EDIT MANUALLY!
Regenerate with: python scripts/generate_sdk.py --category analytics
"""
from __future__ import annotations

from typing import Any, Dict, List, Optional, Union


class _AnalyticsMethodsMixin:
    """annual_returns, annual_volatility, average_drawdown, batch, best_period, burke_ratio, capture_ratio, cumulative_performance, downside_capture, downside_deviation, drawdown, drawdown_duration, egarch_volatility, factor_attribution, factor_regression, gain_loss_ratio, garch_forecast, garch_volatility, hurst_exponent, info, list, log_returns, max_drawdown, momentum, monthly_returns, monthly_volatility, omega_ratio, pain_index, profit_factor, rate_of_change, relative_strength, returns, rolling_alpha, rolling_autocorrelation, rolling_beta, rolling_beta_timing, rolling_cagr, rolling_calmar, rolling_correlation, rolling_covariance, rolling_cvar, rolling_downside_beta, rolling_factor_regression, rolling_garch, rolling_information_ratio, rolling_kurtosis, rolling_r_squared, rolling_regression, rolling_residuals, rolling_sharpe, rolling_skewness, rolling_sortino, rolling_treynor, rolling_upside_beta, rolling_var, rolling_variance, rolling_volatility, semi_deviation, semi_variance, sterling_ratio, tail_ratio, tracking_error, tracking_error_volatility, ulcer_index, upside_capture, upside_deviation, win_rate, worst_period."""

    def annual_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Annualized returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("annual_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def annual_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Annualized volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("annual_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def average_drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Average drawdown

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("average_drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def batch(
        self,
        *,
        operations: List[Any],
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Batch analytics

        Execute multiple analytics functions in one call.

        Args:
        operations: List of operations [{function, params}]
        identifiers: List of TepiloraCodes
        prices: Shared prices data
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        params["operations"] = operations
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("batch", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def best_period(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Best period return

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("best_period", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def burke_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Burke ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("burke_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def capture_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Up/down capture ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("capture_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def cumulative_performance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Cumulative performance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("cumulative_performance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def downside_capture(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Downside capture

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("downside_capture", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def downside_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Downside deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("downside_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Drawdown series

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def drawdown_duration(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Drawdown duration

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("drawdown_duration", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def egarch_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """EGARCH volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("egarch_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def factor_attribution(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Factor attribution

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("factor_attribution", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def factor_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        model: Optional[str] = "FF3",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Factor regression (FF3/FF5)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        model: FF3|FF5|Carhart"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if model is not None and (not strict or model != "FF3"):
            params["model"] = model
        return self._call_analytics("factor_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def gain_loss_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Gain/loss ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("gain_loss_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def garch_forecast(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        horizon: Optional[int] = 10,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """GARCH forecast

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        horizon: Forecast horizon"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if horizon is not None and (not strict or horizon != 10):
            params["horizon"] = horizon
        return self._call_analytics("garch_forecast", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def garch_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """GARCH volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("garch_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def hurst_exponent(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Hurst exponent

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("hurst_exponent", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def info(
        self,
        *,
        function: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Get function info

        Get detailed info about an analytics function.

        Args:
        function: Function name"""
        params: Dict[str, Any] = dict(extra_params)
        params["function"] = function
        return self._call_analytics("info", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def list(
        self,
        *,
        category: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """List analytics functions

        List available analytics functions.

        Args:
        category: Filter by category"""
        params: Dict[str, Any] = dict(extra_params)
        if category is not None:
            params["category"] = category
        return self._call_analytics("list", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def log_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Log returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("log_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def max_drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Maximum drawdown

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("max_drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def momentum(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Momentum indicator

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Lookback period"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return self._call_analytics("momentum", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def monthly_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Monthly returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("monthly_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def monthly_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Monthly volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("monthly_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def omega_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        threshold: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Omega ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        threshold: Return threshold"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if threshold is not None and (not strict or threshold != 0.0):
            params["threshold"] = threshold
        return self._call_analytics("omega_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def pain_index(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Pain index

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("pain_index", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def profit_factor(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Profit factor

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("profit_factor", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rate_of_change(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rate of change

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Lookback period"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return self._call_analytics("rate_of_change", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def relative_strength(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Relative strength

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("relative_strength", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Simple returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_alpha(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling alpha

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return self._call_analytics("rolling_alpha", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_autocorrelation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        lag: Optional[int] = 1,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling autocorrelation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        lag: Autocorrelation lag"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        if lag is not None and (not strict or lag != 1):
            params["lag"] = lag
        return self._call_analytics("rolling_autocorrelation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_beta_timing(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling beta timing

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_beta_timing", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_cagr(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling CAGR

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_cagr", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_calmar(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Calmar ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_calmar", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_correlation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling correlation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return self._call_analytics("rolling_correlation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_covariance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling covariance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return self._call_analytics("rolling_covariance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_cvar(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        confidence: Optional[float] = 0.95,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling CVaR (Expected Shortfall)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        confidence: Confidence level"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if confidence is not None and (not strict or confidence != 0.95):
            params["confidence"] = confidence
        return self._call_analytics("rolling_cvar", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_downside_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling downside beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_downside_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_factor_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        model: Optional[str] = "FF3",
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling factor regression

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        model: FF3|FF5|Carhart
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if model is not None and (not strict or model != "FF3"):
            params["model"] = model
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_factor_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_garch(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling GARCH

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_garch", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_information_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling information ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_information_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_kurtosis(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling kurtosis

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return self._call_analytics("rolling_kurtosis", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_r_squared(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling R-squared

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_r_squared", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling regression

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_residuals(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling residuals

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_residuals", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_sharpe(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Sharpe ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return self._call_analytics("rolling_sharpe", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_skewness(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling skewness

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return self._call_analytics("rolling_skewness", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_sortino(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Sortino ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return self._call_analytics("rolling_sortino", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_treynor(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Treynor ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return self._call_analytics("rolling_treynor", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_upside_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling upside beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return self._call_analytics("rolling_upside_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_var(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        confidence: Optional[float] = 0.95,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Value at Risk

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        confidence: Confidence level"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if confidence is not None and (not strict or confidence != 0.95):
            params["confidence"] = confidence
        return self._call_analytics("rolling_var", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_variance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling variance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return self._call_analytics("rolling_variance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def rolling_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return self._call_analytics("rolling_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def semi_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Semi-deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("semi_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def semi_variance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Semi-variance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("semi_variance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def sterling_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Sterling ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("sterling_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def tail_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tail ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("tail_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def tracking_error(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tracking error

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("tracking_error", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def tracking_error_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tracking error volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("tracking_error_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def ulcer_index(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Ulcer index

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("ulcer_index", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def upside_capture(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Upside capture

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("upside_capture", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def upside_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Upside deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("upside_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def win_rate(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Win rate (% positive periods)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("win_rate", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    def worst_period(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Worst period return

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return self._call_analytics("worst_period", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)



class _AsyncAnalyticsMethodsMixin:
    """annual_returns, annual_volatility, average_drawdown, batch, best_period, burke_ratio, capture_ratio, cumulative_performance, downside_capture, downside_deviation, drawdown, drawdown_duration, egarch_volatility, factor_attribution, factor_regression, gain_loss_ratio, garch_forecast, garch_volatility, hurst_exponent, info, list, log_returns, max_drawdown, momentum, monthly_returns, monthly_volatility, omega_ratio, pain_index, profit_factor, rate_of_change, relative_strength, returns, rolling_alpha, rolling_autocorrelation, rolling_beta, rolling_beta_timing, rolling_cagr, rolling_calmar, rolling_correlation, rolling_covariance, rolling_cvar, rolling_downside_beta, rolling_factor_regression, rolling_garch, rolling_information_ratio, rolling_kurtosis, rolling_r_squared, rolling_regression, rolling_residuals, rolling_sharpe, rolling_skewness, rolling_sortino, rolling_treynor, rolling_upside_beta, rolling_var, rolling_variance, rolling_volatility, semi_deviation, semi_variance, sterling_ratio, tail_ratio, tracking_error, tracking_error_volatility, ulcer_index, upside_capture, upside_deviation, win_rate, worst_period."""

    async def annual_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Annualized returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("annual_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def annual_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Annualized volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("annual_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def average_drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Average drawdown

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("average_drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def batch(
        self,
        *,
        operations: List[Any],
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Batch analytics

        Execute multiple analytics functions in one call.

        Args:
        operations: List of operations [{function, params}]
        identifiers: List of TepiloraCodes
        prices: Shared prices data
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        params["operations"] = operations
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("batch", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def best_period(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Best period return

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("best_period", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def burke_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Burke ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("burke_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def capture_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Up/down capture ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("capture_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def cumulative_performance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Cumulative performance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("cumulative_performance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def downside_capture(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Downside capture

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("downside_capture", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def downside_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Downside deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("downside_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Drawdown series

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def drawdown_duration(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Drawdown duration

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("drawdown_duration", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def egarch_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """EGARCH volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("egarch_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def factor_attribution(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Factor attribution

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("factor_attribution", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def factor_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        model: Optional[str] = "FF3",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Factor regression (FF3/FF5)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        model: FF3|FF5|Carhart"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if model is not None and (not strict or model != "FF3"):
            params["model"] = model
        return await self._call_analytics("factor_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def gain_loss_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Gain/loss ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("gain_loss_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def garch_forecast(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        horizon: Optional[int] = 10,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """GARCH forecast

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        horizon: Forecast horizon"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if horizon is not None and (not strict or horizon != 10):
            params["horizon"] = horizon
        return await self._call_analytics("garch_forecast", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def garch_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """GARCH volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("garch_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def hurst_exponent(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Hurst exponent

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("hurst_exponent", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def info(
        self,
        *,
        function: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Get function info

        Get detailed info about an analytics function.

        Args:
        function: Function name"""
        params: Dict[str, Any] = dict(extra_params)
        params["function"] = function
        return await self._call_analytics("info", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def list(
        self,
        *,
        category: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """List analytics functions

        List available analytics functions.

        Args:
        category: Filter by category"""
        params: Dict[str, Any] = dict(extra_params)
        if category is not None:
            params["category"] = category
        return await self._call_analytics("list", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def log_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Log returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("log_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def max_drawdown(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Maximum drawdown

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("max_drawdown", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def momentum(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Momentum indicator

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Lookback period"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return await self._call_analytics("momentum", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def monthly_returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Monthly returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("monthly_returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def monthly_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Monthly volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("monthly_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def omega_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        threshold: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Omega ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        threshold: Return threshold"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if threshold is not None and (not strict or threshold != 0.0):
            params["threshold"] = threshold
        return await self._call_analytics("omega_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def pain_index(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Pain index

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("pain_index", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def profit_factor(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Profit factor

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("profit_factor", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rate_of_change(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rate of change

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Lookback period"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return await self._call_analytics("rate_of_change", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def relative_strength(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Relative strength

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("relative_strength", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def returns(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Simple returns

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("returns", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_alpha(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling alpha

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return await self._call_analytics("rolling_alpha", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_autocorrelation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        lag: Optional[int] = 1,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling autocorrelation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        lag: Autocorrelation lag"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        if lag is not None and (not strict or lag != 1):
            params["lag"] = lag
        return await self._call_analytics("rolling_autocorrelation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_beta_timing(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling beta timing

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_beta_timing", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_cagr(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling CAGR

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_cagr", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_calmar(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Calmar ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_calmar", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_correlation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling correlation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return await self._call_analytics("rolling_correlation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_covariance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling covariance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return await self._call_analytics("rolling_covariance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_cvar(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        confidence: Optional[float] = 0.95,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling CVaR (Expected Shortfall)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        confidence: Confidence level"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if confidence is not None and (not strict or confidence != 0.95):
            params["confidence"] = confidence
        return await self._call_analytics("rolling_cvar", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_downside_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling downside beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_downside_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_factor_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        model: Optional[str] = "FF3",
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling factor regression

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        model: FF3|FF5|Carhart
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if model is not None and (not strict or model != "FF3"):
            params["model"] = model
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_factor_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_garch(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling GARCH

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_garch", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_information_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling information ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_information_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_kurtosis(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling kurtosis

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return await self._call_analytics("rolling_kurtosis", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_r_squared(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling R-squared

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_r_squared", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_regression(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling regression

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_regression", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_residuals(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling residuals

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_residuals", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_sharpe(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Sharpe ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return await self._call_analytics("rolling_sharpe", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_skewness(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 63,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling skewness

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 63):
            params["period"] = period
        return await self._call_analytics("rolling_skewness", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_sortino(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Sortino ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return await self._call_analytics("rolling_sortino", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_treynor(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        rf: Optional[float] = 0.0,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Treynor ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        rf: Risk-free rate"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if rf is not None and (not strict or rf != 0.0):
            params["rf"] = rf
        return await self._call_analytics("rolling_treynor", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_upside_beta(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling upside beta

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        return await self._call_analytics("rolling_upside_beta", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_var(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 252,
        confidence: Optional[float] = 0.95,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling Value at Risk

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window
        confidence: Confidence level"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 252):
            params["period"] = period
        if confidence is not None and (not strict or confidence != 0.95):
            params["confidence"] = confidence
        return await self._call_analytics("rolling_var", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_variance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling variance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return await self._call_analytics("rolling_variance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def rolling_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        period: Optional[int] = 21,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Rolling volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        period: Rolling window"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if period is not None and (not strict or period != 21):
            params["period"] = period
        return await self._call_analytics("rolling_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def semi_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Semi-deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("semi_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def semi_variance(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Semi-variance

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("semi_variance", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def sterling_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Sterling ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("sterling_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def tail_ratio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tail ratio

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("tail_ratio", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def tracking_error(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tracking error

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("tracking_error", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def tracking_error_volatility(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Tracking error volatility

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("tracking_error_volatility", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def ulcer_index(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Ulcer index

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("ulcer_index", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def upside_capture(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Upside capture

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("upside_capture", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def upside_deviation(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Upside deviation

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("upside_deviation", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def win_rate(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Win rate (% positive periods)

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("win_rate", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)

    async def worst_period(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        prices: Optional[Dict[str, Any]] = None,
        prices_file: Optional[str] = None,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
        as_table: Optional[str] = None,
        strict: bool = False,
        **extra_params: Any,
    ) -> Any:
        """Worst period return

        Args:
        identifiers: List of TepiloraCodes
        prices: User-provided prices (DataFrame or dict)
        prices_file: Path to prices file
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = dict(extra_params)
        if identifiers is not None:
            params["identifiers"] = identifiers
        if prices is not None:
            params["prices"] = prices
        if prices_file is not None:
            params["prices_file"] = prices_file
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        return await self._call_analytics("worst_period", params, options=options, context=context, response_format=response_format, as_table=as_table, strict=strict)


