"""
Bonds API namespace.

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

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

from ._base import AsyncBaseAPI, BaseAPI


class BondsAPI(BaseAPI):
    """Bonds namespace: analyze, curve, ladder, lookup, maturity_profile, metrics, portfolio, screen, spread."""

    def analyze(
        self,
        *,
        identifier: str,
        face_value: Optional[float] = 1000,
        coupon_rate: Optional[float] = None,
        maturity_date: Optional[str] = None,
        frequency: Optional[int] = None,
        day_count: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Analyze bond

        Calculate YTM, duration, convexity. coupon_rate and maturity_date auto-populated from metadata if missing.

        Args:
        identifier: TepiloraCode or ISIN
        face_value: Face/par value
        coupon_rate: Coupon rate (decimal). Auto-populated from metadata if missing
        maturity_date: Maturity date YYYY-MM-DD. Auto-populated from metadata if missing
        frequency: Coupon frequency (1,2,4,12). Auto-populated from metadata if missing
        day_count: Day count convention. Auto-populated from metadata if missing"""
        params: Dict[str, Any] = {}
        params["identifier"] = identifier
        if face_value is not None:
            params["face_value"] = face_value
        if coupon_rate is not None:
            params["coupon_rate"] = coupon_rate
        if maturity_date is not None:
            params["maturity_date"] = maturity_date
        if frequency is not None:
            params["frequency"] = frequency
        if day_count is not None:
            params["day_count"] = day_count
        return self._call("bonds.analyze", params=params, options=options, context=context)

    def curve(
        self,
        *,
        currency: Optional[str] = "EUR",
        date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Yield curve

        Get yield curve data.

        Args:
        currency: Currency
        date: As of date"""
        params: Dict[str, Any] = {}
        if currency is not None:
            params["currency"] = currency
        if date is not None:
            params["date"] = date
        return self._call("bonds.curve", params=params, options=options, context=context)

    def ladder(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        target_maturities: Optional[List[Any]] = None,
        investment_amount: Optional[float] = None,
        rungs: Optional[int] = 5,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Bond ladder

        Build a bond ladder.

        Args:
        identifiers: List of TepiloraCodes
        target_maturities: Target maturity years
        investment_amount: Total investment amount
        rungs: Number of rungs"""
        params: Dict[str, Any] = {}
        if identifiers is not None:
            params["identifiers"] = identifiers
        if target_maturities is not None:
            params["target_maturities"] = target_maturities
        if investment_amount is not None:
            params["investment_amount"] = investment_amount
        if rungs is not None:
            params["rungs"] = rungs
        return self._call("bonds.ladder", params=params, options=options, context=context, response_format=response_format)

    def lookup(
        self,
        *,
        identifier: Optional[str] = None,
        identifiers: Optional[Union[str, List[str]]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Fast bond metadata lookup

        Returns bond metadata from D_full.parquet without calculations

        Args:
        identifier: Single bond identifier
        identifiers: Multiple bond identifiers"""
        params: Dict[str, Any] = {}
        if identifier is not None:
            params["identifier"] = identifier
        if identifiers is not None:
            params["identifiers"] = identifiers
        return self._call("bonds.lookup", params=params, options=options, context=context, response_format=response_format)

    def maturity_profile(
        self,
        *,
        identifiers: Union[str, List[str]],
        weights: Optional[List[Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Maturity distribution by bucket

        Maturity distribution (0-1y, 1-3y, 3-5y, 5-7y, 7-10y, 10+y)

        Args:
        identifiers: Bond identifiers
        weights: Portfolio weights"""
        params: Dict[str, Any] = {}
        params["identifiers"] = identifiers
        if weights is not None:
            params["weights"] = weights
        return self._call("bonds.maturity_profile", params=params, options=options, context=context, response_format=response_format)

    def metrics(
        self,
        *,
        identifier: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Bond metrics

        Duration, convexity, etc.

        Args:
        identifier: TepiloraCode or ISIN"""
        params: Dict[str, Any] = {}
        params["identifier"] = identifier
        return self._call("bonds.metrics", params=params, options=options, context=context)

    def portfolio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        weights: Optional[List[Any]] = None,
        include_duration: Optional[bool] = True,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Bond portfolio analytics

        Portfolio-level bond analytics.

        Args:
        identifiers: List of TepiloraCodes
        weights: Portfolio weights (list of floats, same order as identifiers)
        include_duration: Include duration analysis"""
        params: Dict[str, Any] = {}
        if identifiers is not None:
            params["identifiers"] = identifiers
        if weights is not None:
            params["weights"] = weights
        if include_duration is not None:
            params["include_duration"] = include_duration
        return self._call("bonds.portfolio", params=params, options=options, context=context, response_format=response_format)

    def screen(
        self,
        *,
        criteria: Optional[Dict[str, Any]] = None,
        universe: Optional[Dict[str, Any]] = None,
        rank_by: Optional[str] = None,
        limit: Optional[int] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Screen bonds

        Screen bonds by criteria. Returns all matching bonds by default.

        Args:
        criteria: Screening criteria
        universe: Universe filter (e.g. TepiloraBondType, TepiloraBondIssuer)
        rank_by: Metric to rank by (ytm, duration, etc.)
        limit: Max results (default: all)"""
        params: Dict[str, Any] = {}
        if criteria is not None:
            params["criteria"] = criteria
        if universe is not None:
            params["universe"] = universe
        if rank_by is not None:
            params["rank_by"] = rank_by
        if limit is not None:
            params["limit"] = limit
        return self._call("bonds.screen", params=params, options=options, context=context, response_format=response_format)

    def spread(
        self,
        *,
        identifiers: Union[str, List[str]],
        benchmark: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Credit spread

        Calculate credit spread vs benchmark.

        Args:
        identifiers: List of TepiloraCodes
        benchmark: Benchmark bond identifier"""
        params: Dict[str, Any] = {}
        params["identifiers"] = identifiers
        if benchmark is not None:
            params["benchmark"] = benchmark
        return self._call("bonds.spread", params=params, options=options, context=context, response_format=response_format)



class AsyncBondsAPI(AsyncBaseAPI):
    """Bonds namespace: analyze, curve, ladder, lookup, maturity_profile, metrics, portfolio, screen, spread."""

    async def analyze(
        self,
        *,
        identifier: str,
        face_value: Optional[float] = 1000,
        coupon_rate: Optional[float] = None,
        maturity_date: Optional[str] = None,
        frequency: Optional[int] = None,
        day_count: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Analyze bond

        Calculate YTM, duration, convexity. coupon_rate and maturity_date auto-populated from metadata if missing.

        Args:
        identifier: TepiloraCode or ISIN
        face_value: Face/par value
        coupon_rate: Coupon rate (decimal). Auto-populated from metadata if missing
        maturity_date: Maturity date YYYY-MM-DD. Auto-populated from metadata if missing
        frequency: Coupon frequency (1,2,4,12). Auto-populated from metadata if missing
        day_count: Day count convention. Auto-populated from metadata if missing"""
        params: Dict[str, Any] = {}
        params["identifier"] = identifier
        if face_value is not None:
            params["face_value"] = face_value
        if coupon_rate is not None:
            params["coupon_rate"] = coupon_rate
        if maturity_date is not None:
            params["maturity_date"] = maturity_date
        if frequency is not None:
            params["frequency"] = frequency
        if day_count is not None:
            params["day_count"] = day_count
        return await self._call("bonds.analyze", params=params, options=options, context=context)

    async def curve(
        self,
        *,
        currency: Optional[str] = "EUR",
        date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Yield curve

        Get yield curve data.

        Args:
        currency: Currency
        date: As of date"""
        params: Dict[str, Any] = {}
        if currency is not None:
            params["currency"] = currency
        if date is not None:
            params["date"] = date
        return await self._call("bonds.curve", params=params, options=options, context=context)

    async def ladder(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        target_maturities: Optional[List[Any]] = None,
        investment_amount: Optional[float] = None,
        rungs: Optional[int] = 5,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Bond ladder

        Build a bond ladder.

        Args:
        identifiers: List of TepiloraCodes
        target_maturities: Target maturity years
        investment_amount: Total investment amount
        rungs: Number of rungs"""
        params: Dict[str, Any] = {}
        if identifiers is not None:
            params["identifiers"] = identifiers
        if target_maturities is not None:
            params["target_maturities"] = target_maturities
        if investment_amount is not None:
            params["investment_amount"] = investment_amount
        if rungs is not None:
            params["rungs"] = rungs
        return await self._call("bonds.ladder", params=params, options=options, context=context, response_format=response_format)

    async def lookup(
        self,
        *,
        identifier: Optional[str] = None,
        identifiers: Optional[Union[str, List[str]]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Fast bond metadata lookup

        Returns bond metadata from D_full.parquet without calculations

        Args:
        identifier: Single bond identifier
        identifiers: Multiple bond identifiers"""
        params: Dict[str, Any] = {}
        if identifier is not None:
            params["identifier"] = identifier
        if identifiers is not None:
            params["identifiers"] = identifiers
        return await self._call("bonds.lookup", params=params, options=options, context=context, response_format=response_format)

    async def maturity_profile(
        self,
        *,
        identifiers: Union[str, List[str]],
        weights: Optional[List[Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Maturity distribution by bucket

        Maturity distribution (0-1y, 1-3y, 3-5y, 5-7y, 7-10y, 10+y)

        Args:
        identifiers: Bond identifiers
        weights: Portfolio weights"""
        params: Dict[str, Any] = {}
        params["identifiers"] = identifiers
        if weights is not None:
            params["weights"] = weights
        return await self._call("bonds.maturity_profile", params=params, options=options, context=context, response_format=response_format)

    async def metrics(
        self,
        *,
        identifier: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Bond metrics

        Duration, convexity, etc.

        Args:
        identifier: TepiloraCode or ISIN"""
        params: Dict[str, Any] = {}
        params["identifier"] = identifier
        return await self._call("bonds.metrics", params=params, options=options, context=context)

    async def portfolio(
        self,
        *,
        identifiers: Optional[Union[str, List[str]]] = None,
        weights: Optional[List[Any]] = None,
        include_duration: Optional[bool] = True,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Bond portfolio analytics

        Portfolio-level bond analytics.

        Args:
        identifiers: List of TepiloraCodes
        weights: Portfolio weights (list of floats, same order as identifiers)
        include_duration: Include duration analysis"""
        params: Dict[str, Any] = {}
        if identifiers is not None:
            params["identifiers"] = identifiers
        if weights is not None:
            params["weights"] = weights
        if include_duration is not None:
            params["include_duration"] = include_duration
        return await self._call("bonds.portfolio", params=params, options=options, context=context, response_format=response_format)

    async def screen(
        self,
        *,
        criteria: Optional[Dict[str, Any]] = None,
        universe: Optional[Dict[str, Any]] = None,
        rank_by: Optional[str] = None,
        limit: Optional[int] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Screen bonds

        Screen bonds by criteria. Returns all matching bonds by default.

        Args:
        criteria: Screening criteria
        universe: Universe filter (e.g. TepiloraBondType, TepiloraBondIssuer)
        rank_by: Metric to rank by (ytm, duration, etc.)
        limit: Max results (default: all)"""
        params: Dict[str, Any] = {}
        if criteria is not None:
            params["criteria"] = criteria
        if universe is not None:
            params["universe"] = universe
        if rank_by is not None:
            params["rank_by"] = rank_by
        if limit is not None:
            params["limit"] = limit
        return await self._call("bonds.screen", params=params, options=options, context=context, response_format=response_format)

    async def spread(
        self,
        *,
        identifiers: Union[str, List[str]],
        benchmark: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Credit spread

        Calculate credit spread vs benchmark.

        Args:
        identifiers: List of TepiloraCodes
        benchmark: Benchmark bond identifier"""
        params: Dict[str, Any] = {}
        params["identifiers"] = identifiers
        if benchmark is not None:
            params["benchmark"] = benchmark
        return await self._call("bonds.spread", params=params, options=options, context=context, response_format=response_format)


