"""
Portfolio API namespace.

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

from typing import Any, Dict, List, Optional

from ._base import AsyncBaseAPI, BaseAPI


class PortfolioAPI(BaseAPI):
    """Portfolio namespace: attribution, compare, contribution, costs, create, delete, drift, exposure, get, list, optimize, rebalance, returns, share, shares, stress, tearsheet, unshare, update."""

    def attribution(
        self,
        *,
        id: str,
        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,
    ) -> Any:
        """Performance attribution

        Brinson attribution analysis.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.attribution", params=params, options=options, context=context, response_format=response_format)

    def compare(
        self,
        *,
        portfolio_ids: List[Any],
        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,
    ) -> Any:
        """Compare portfolios

        Compare multiple portfolios.

        Args:
        portfolio_ids: Portfolio IDs to compare
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["portfolio_ids"] = portfolio_ids
        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("portfolio.compare", params=params, options=options, context=context, response_format=response_format)

    def contribution(
        self,
        *,
        id: str,
        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,
    ) -> Any:
        """Return contribution

        Contribution of each holding to portfolio return.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.contribution", params=params, options=options, context=context, response_format=response_format)

    def costs(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio costs

        TER and trading costs analysis.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return self._call("portfolio.costs", params=params, options=options, context=context, response_format=response_format)

    def create(
        self,
        *,
        name: str,
        input_type: str,
        portfolio_type: Optional[str] = "Real",
        input_data: Optional[Dict[str, Any]] = None,
        benchmark: Optional[str] = None,
        description: Optional[str] = "",
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Create portfolio

        Create a new portfolio.

        Args:
        name: Portfolio name
        input_type: fixed_weights|drifting_weights|holdings|values|trades
        portfolio_type: Real|Suggested|Simulation|Backtest|Model
        input_data: Holdings/weights data
        benchmark: Benchmark TepiloraCode
        description: Description
        settings: Portfolio settings"""
        params: Dict[str, Any] = {}
        params["name"] = name
        params["input_type"] = input_type
        if portfolio_type is not None:
            params["portfolio_type"] = portfolio_type
        if input_data is not None:
            params["input_data"] = input_data
        if benchmark is not None:
            params["benchmark"] = benchmark
        if description is not None:
            params["description"] = description
        if settings is not None:
            params["settings"] = settings
        return self._call("portfolio.create", params=params, options=options, context=context)

    def delete(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Delete portfolio

        Delete portfolio.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return self._call("portfolio.delete", params=params, options=options, context=context)

    def drift(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio drift

        Weight drift from target.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return self._call("portfolio.drift", params=params, options=options, context=context, response_format=response_format)

    def exposure(
        self,
        *,
        id: str,
        dimension: Optional[str] = "sector",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio exposure

        Exposure by sector, country, currency, etc.

        Args:
        id: Portfolio ID
        dimension: sector|country|currency|asset_class"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if dimension is not None:
            params["dimension"] = dimension
        return self._call("portfolio.exposure", params=params, options=options, context=context, response_format=response_format)

    def get(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Get portfolio

        Get portfolio details.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return self._call("portfolio.get", params=params, options=options, context=context)

    def list(
        self,
        *,
        portfolio_type: Optional[str] = None,
        input_type: Optional[str] = None,
        search: Optional[str] = None,
        limit: Optional[int] = 50,
        offset: Optional[int] = 0,
        include_shared: Optional[bool] = True,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """List portfolios

        List user's portfolios.

        Args:
        portfolio_type: Filter by type
        input_type: Filter by input type
        search: Search in name
        limit: Maximum results
        offset: Pagination offset
        include_shared: Include shared portfolios"""
        params: Dict[str, Any] = {}
        if portfolio_type is not None:
            params["portfolio_type"] = portfolio_type
        if input_type is not None:
            params["input_type"] = input_type
        if search is not None:
            params["search"] = search
        if limit is not None:
            params["limit"] = limit
        if offset is not None:
            params["offset"] = offset
        if include_shared is not None:
            params["include_shared"] = include_shared
        return self._call("portfolio.list", params=params, options=options, context=context)

    def optimize(
        self,
        *,
        id: str,
        objective: Optional[str] = "max_sharpe",
        constraints: Optional[Dict[str, Any]] = None,
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Optimize portfolio

        Portfolio optimization (Julia backend).

        Args:
        id: Portfolio ID
        objective: Optimization objective
        constraints: Constraints
        settings: Optimizer settings"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if objective is not None:
            params["objective"] = objective
        if constraints is not None:
            params["constraints"] = constraints
        if settings is not None:
            params["settings"] = settings
        return self._call("portfolio.optimize", params=params, options=options, context=context)

    def rebalance(
        self,
        *,
        id: str,
        target_weights: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Rebalance portfolio

        Calculate rebalancing trades.

        Args:
        id: Portfolio ID
        target_weights: Target weights"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if target_weights is not None:
            params["target_weights"] = target_weights
        return self._call("portfolio.rebalance", params=params, options=options, context=context, response_format=response_format)

    def returns(
        self,
        *,
        id: str,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        return_method: Optional[str] = "twr",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Get portfolio returns

        Time series of portfolio returns.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        return_method: twr|mwr|modified_dietz"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if return_method is not None:
            params["return_method"] = return_method
        return self._call("portfolio.returns", params=params, options=options, context=context, response_format=response_format)

    def share(
        self,
        *,
        id: str,
        target_apikey: str,
        permission: Optional[str] = "read",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Share portfolio

        Share portfolio with another user.

        Args:
        id: Portfolio ID
        target_apikey: Target user apikey
        permission: read|write"""
        params: Dict[str, Any] = {}
        params["id"] = id
        params["target_apikey"] = target_apikey
        if permission is not None:
            params["permission"] = permission
        return self._call("portfolio.share", params=params, options=options, context=context)

    def shares(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """List shares

        List users with access to portfolio.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return self._call("portfolio.shares", params=params, options=options, context=context)

    def stress(
        self,
        *,
        id: str,
        scenarios: Optional[List[Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Stress test

        Portfolio stress testing.

        Args:
        id: Portfolio ID
        scenarios: Custom scenarios"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if scenarios is not None:
            params["scenarios"] = scenarios
        return self._call("portfolio.stress", params=params, options=options, context=context)

    def tearsheet(
        self,
        *,
        id: str,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Portfolio tearsheet

        Comprehensive portfolio report.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.tearsheet", params=params, options=options, context=context)

    def unshare(
        self,
        *,
        id: str,
        target_apikey: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Unshare portfolio

        Revoke portfolio sharing.

        Args:
        id: Portfolio ID
        target_apikey: User to remove"""
        params: Dict[str, Any] = {}
        params["id"] = id
        params["target_apikey"] = target_apikey
        return self._call("portfolio.unshare", params=params, options=options, context=context)

    def update(
        self,
        *,
        id: str,
        name: Optional[str] = None,
        input_data: Optional[Dict[str, Any]] = None,
        benchmark: Optional[str] = None,
        description: Optional[str] = None,
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Update portfolio

        Update portfolio details.

        Args:
        id: Portfolio ID
        name: New name
        input_data: New holdings/weights
        benchmark: New benchmark
        description: New description
        settings: New settings"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if name is not None:
            params["name"] = name
        if input_data is not None:
            params["input_data"] = input_data
        if benchmark is not None:
            params["benchmark"] = benchmark
        if description is not None:
            params["description"] = description
        if settings is not None:
            params["settings"] = settings
        return self._call("portfolio.update", params=params, options=options, context=context)



class AsyncPortfolioAPI(AsyncBaseAPI):
    """Portfolio namespace: attribution, compare, contribution, costs, create, delete, drift, exposure, get, list, optimize, rebalance, returns, share, shares, stress, tearsheet, unshare, update."""

    async def attribution(
        self,
        *,
        id: str,
        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,
    ) -> Any:
        """Performance attribution

        Brinson attribution analysis.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.attribution", params=params, options=options, context=context, response_format=response_format)

    async def compare(
        self,
        *,
        portfolio_ids: List[Any],
        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,
    ) -> Any:
        """Compare portfolios

        Compare multiple portfolios.

        Args:
        portfolio_ids: Portfolio IDs to compare
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["portfolio_ids"] = portfolio_ids
        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("portfolio.compare", params=params, options=options, context=context, response_format=response_format)

    async def contribution(
        self,
        *,
        id: str,
        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,
    ) -> Any:
        """Return contribution

        Contribution of each holding to portfolio return.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.contribution", params=params, options=options, context=context, response_format=response_format)

    async def costs(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio costs

        TER and trading costs analysis.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return await self._call("portfolio.costs", params=params, options=options, context=context, response_format=response_format)

    async def create(
        self,
        *,
        name: str,
        input_type: str,
        portfolio_type: Optional[str] = "Real",
        input_data: Optional[Dict[str, Any]] = None,
        benchmark: Optional[str] = None,
        description: Optional[str] = "",
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Create portfolio

        Create a new portfolio.

        Args:
        name: Portfolio name
        input_type: fixed_weights|drifting_weights|holdings|values|trades
        portfolio_type: Real|Suggested|Simulation|Backtest|Model
        input_data: Holdings/weights data
        benchmark: Benchmark TepiloraCode
        description: Description
        settings: Portfolio settings"""
        params: Dict[str, Any] = {}
        params["name"] = name
        params["input_type"] = input_type
        if portfolio_type is not None:
            params["portfolio_type"] = portfolio_type
        if input_data is not None:
            params["input_data"] = input_data
        if benchmark is not None:
            params["benchmark"] = benchmark
        if description is not None:
            params["description"] = description
        if settings is not None:
            params["settings"] = settings
        return await self._call("portfolio.create", params=params, options=options, context=context)

    async def delete(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Delete portfolio

        Delete portfolio.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return await self._call("portfolio.delete", params=params, options=options, context=context)

    async def drift(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio drift

        Weight drift from target.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return await self._call("portfolio.drift", params=params, options=options, context=context, response_format=response_format)

    async def exposure(
        self,
        *,
        id: str,
        dimension: Optional[str] = "sector",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Portfolio exposure

        Exposure by sector, country, currency, etc.

        Args:
        id: Portfolio ID
        dimension: sector|country|currency|asset_class"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if dimension is not None:
            params["dimension"] = dimension
        return await self._call("portfolio.exposure", params=params, options=options, context=context, response_format=response_format)

    async def get(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Get portfolio

        Get portfolio details.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return await self._call("portfolio.get", params=params, options=options, context=context)

    async def list(
        self,
        *,
        portfolio_type: Optional[str] = None,
        input_type: Optional[str] = None,
        search: Optional[str] = None,
        limit: Optional[int] = 50,
        offset: Optional[int] = 0,
        include_shared: Optional[bool] = True,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """List portfolios

        List user's portfolios.

        Args:
        portfolio_type: Filter by type
        input_type: Filter by input type
        search: Search in name
        limit: Maximum results
        offset: Pagination offset
        include_shared: Include shared portfolios"""
        params: Dict[str, Any] = {}
        if portfolio_type is not None:
            params["portfolio_type"] = portfolio_type
        if input_type is not None:
            params["input_type"] = input_type
        if search is not None:
            params["search"] = search
        if limit is not None:
            params["limit"] = limit
        if offset is not None:
            params["offset"] = offset
        if include_shared is not None:
            params["include_shared"] = include_shared
        return await self._call("portfolio.list", params=params, options=options, context=context)

    async def optimize(
        self,
        *,
        id: str,
        objective: Optional[str] = "max_sharpe",
        constraints: Optional[Dict[str, Any]] = None,
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Optimize portfolio

        Portfolio optimization (Julia backend).

        Args:
        id: Portfolio ID
        objective: Optimization objective
        constraints: Constraints
        settings: Optimizer settings"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if objective is not None:
            params["objective"] = objective
        if constraints is not None:
            params["constraints"] = constraints
        if settings is not None:
            params["settings"] = settings
        return await self._call("portfolio.optimize", params=params, options=options, context=context)

    async def rebalance(
        self,
        *,
        id: str,
        target_weights: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Rebalance portfolio

        Calculate rebalancing trades.

        Args:
        id: Portfolio ID
        target_weights: Target weights"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if target_weights is not None:
            params["target_weights"] = target_weights
        return await self._call("portfolio.rebalance", params=params, options=options, context=context, response_format=response_format)

    async def returns(
        self,
        *,
        id: str,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        return_method: Optional[str] = "twr",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
        response_format: Optional[str] = None,
    ) -> Any:
        """Get portfolio returns

        Time series of portfolio returns.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)
        return_method: twr|mwr|modified_dietz"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if start_date is not None:
            params["start_date"] = start_date
        if end_date is not None:
            params["end_date"] = end_date
        if return_method is not None:
            params["return_method"] = return_method
        return await self._call("portfolio.returns", params=params, options=options, context=context, response_format=response_format)

    async def share(
        self,
        *,
        id: str,
        target_apikey: str,
        permission: Optional[str] = "read",
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Share portfolio

        Share portfolio with another user.

        Args:
        id: Portfolio ID
        target_apikey: Target user apikey
        permission: read|write"""
        params: Dict[str, Any] = {}
        params["id"] = id
        params["target_apikey"] = target_apikey
        if permission is not None:
            params["permission"] = permission
        return await self._call("portfolio.share", params=params, options=options, context=context)

    async def shares(
        self,
        *,
        id: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """List shares

        List users with access to portfolio.

        Args:
        id: Portfolio ID"""
        params: Dict[str, Any] = {}
        params["id"] = id
        return await self._call("portfolio.shares", params=params, options=options, context=context)

    async def stress(
        self,
        *,
        id: str,
        scenarios: Optional[List[Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Stress test

        Portfolio stress testing.

        Args:
        id: Portfolio ID
        scenarios: Custom scenarios"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if scenarios is not None:
            params["scenarios"] = scenarios
        return await self._call("portfolio.stress", params=params, options=options, context=context)

    async def tearsheet(
        self,
        *,
        id: str,
        start_date: Optional[str] = None,
        end_date: Optional[str] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Portfolio tearsheet

        Comprehensive portfolio report.

        Args:
        id: Portfolio ID
        start_date: Start date (YYYY-MM-DD)
        end_date: End date (YYYY-MM-DD)"""
        params: Dict[str, Any] = {}
        params["id"] = id
        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("portfolio.tearsheet", params=params, options=options, context=context)

    async def unshare(
        self,
        *,
        id: str,
        target_apikey: str,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Unshare portfolio

        Revoke portfolio sharing.

        Args:
        id: Portfolio ID
        target_apikey: User to remove"""
        params: Dict[str, Any] = {}
        params["id"] = id
        params["target_apikey"] = target_apikey
        return await self._call("portfolio.unshare", params=params, options=options, context=context)

    async def update(
        self,
        *,
        id: str,
        name: Optional[str] = None,
        input_data: Optional[Dict[str, Any]] = None,
        benchmark: Optional[str] = None,
        description: Optional[str] = None,
        settings: Optional[Dict[str, Any]] = None,
        options: Optional[Dict[str, Any]] = None,
        context: Optional[Dict[str, Any]] = None,
    ) -> Any:
        """Update portfolio

        Update portfolio details.

        Args:
        id: Portfolio ID
        name: New name
        input_data: New holdings/weights
        benchmark: New benchmark
        description: New description
        settings: New settings"""
        params: Dict[str, Any] = {}
        params["id"] = id
        if name is not None:
            params["name"] = name
        if input_data is not None:
            params["input_data"] = input_data
        if benchmark is not None:
            params["benchmark"] = benchmark
        if description is not None:
            params["description"] = description
        if settings is not None:
            params["settings"] = settings
        return await self._call("portfolio.update", params=params, options=options, context=context)


