"""Code generated by Speakeasy (https://speakeasy.com). DO NOT EDIT."""

from __future__ import annotations
from ascend_sdk import utils
from ascend_sdk.types import (
    BaseModel,
    Nullable,
    OptionalNullable,
    UNSET,
    UNSET_SENTINEL,
)
from ascend_sdk.utils import validate_open_enum
from datetime import datetime
from enum import Enum
from pydantic import model_serializer
from pydantic.functional_validators import PlainValidator
from typing import Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class OrderCostPreviewResponseAssetType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of asset referenced by the security identifier"""

    ASSET_TYPE_UNSPECIFIED = "ASSET_TYPE_UNSPECIFIED"
    EQUITY = "EQUITY"
    FIXED_INCOME = "FIXED_INCOME"
    MUTUAL_FUND = "MUTUAL_FUND"


class OrderCostPreviewResponseBrokerCapacity(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Capacity used in determining the order cost. Defaults to \"AGENCY\" if no value specified."""

    BROKER_CAPACITY_UNSPECIFIED = "BROKER_CAPACITY_UNSPECIFIED"
    AGENCY = "AGENCY"
    PRINCIPAL = "PRINCIPAL"


class EstimatedAccruedInterestTypedDict(TypedDict):
    r"""The estimated total of accrued interest that would be exchanged in an order of the given quantity"""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedAccruedInterest(BaseModel):
    r"""The estimated total of accrued interest that would be exchanged in an order of the given quantity"""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedGrossAmountTypedDict(TypedDict):
    r"""The principal amount involved, which is the notional value of the underlying assets that would be exchanged for the given quantity"""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedGrossAmount(BaseModel):
    r"""The principal amount involved, which is the notional value of the underlying assets that would be exchanged for the given quantity"""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedGrossCreditAmountTypedDict(TypedDict):
    r"""Customer disclosure of the estimated gross credit (fee / markup) amount retained by broker based given the price adjustment schedule configured for orders executed in a principal capacity for a given quantity, and limit price. This amount is priced into the estimated_gross_credit_amount and is not separately charged explicitly."""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedGrossCreditAmount(BaseModel):
    r"""Customer disclosure of the estimated gross credit (fee / markup) amount retained by broker based given the price adjustment schedule configured for orders executed in a principal capacity for a given quantity, and limit price. This amount is priced into the estimated_gross_credit_amount and is not separately charged explicitly."""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedNetAmountTypedDict(TypedDict):
    r"""The estimated net notional amount involved in an order of the given quantity, capacity, and limit price. This will be the sum of the estimated gross amount and accrued interest, rounded to two decimal places. (For orders in the principal capacity, this total will include mark-up/mark-down price adjustments.)"""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class EstimatedNetAmount(BaseModel):
    r"""The estimated net notional amount involved in an order of the given quantity, capacity, and limit price. This will be the sum of the estimated gross amount and accrued interest, rounded to two decimal places. (For orders in the principal capacity, this total will include mark-up/mark-down price adjustments.)"""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class OrderCostPreviewResponseIdentifierType(str, Enum):
    r"""The identifier type of the asset used for price calculations. This will be the same value as what was sent on the request."""

    ASSET_ID = "ASSET_ID"
    CUSIP = "CUSIP"
    ISIN = "ISIN"


class OrderCostPreviewResponsePriceTypedDict(TypedDict):
    r"""The limit price which must be greater than zero if provided. For equity orders in the USD currency, up to 2 decimal places are allowed for prices above $1 and up to 4 decimal places for prices at or below $1. For fixed income orders this is expressed as a percentage of par, which allows up to 4 decimal places in the USD currency."""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class OrderCostPreviewResponsePrice(BaseModel):
    r"""The limit price which must be greater than zero if provided. For equity orders in the USD currency, up to 2 decimal places are allowed for prices above $1 and up to 4 decimal places for prices at or below $1. For fixed income orders this is expressed as a percentage of par, which allows up to 4 decimal places in the USD currency."""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class OrderCostPreviewResponseType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of this price, which must be PRICE_PER_UNIT for equity orders, or PERCENTAGE_OF_PAR for fixed income orders."""

    LIMIT_PRICE_TYPE_UNSPECIFIED = "LIMIT_PRICE_TYPE_UNSPECIFIED"
    PRICE_PER_UNIT = "PRICE_PER_UNIT"
    PERCENTAGE_OF_PAR = "PERCENTAGE_OF_PAR"


class OrderCostPreviewResponseLimitPriceTypedDict(TypedDict):
    r"""The limit price to use in calculating costs. Only PERCENTAGE_OF_PAR will be accepted and returned."""

    price: NotRequired[Nullable[OrderCostPreviewResponsePriceTypedDict]]
    r"""The limit price which must be greater than zero if provided. For equity orders in the USD currency, up to 2 decimal places are allowed for prices above $1 and up to 4 decimal places for prices at or below $1. For fixed income orders this is expressed as a percentage of par, which allows up to 4 decimal places in the USD currency."""
    type: NotRequired[OrderCostPreviewResponseType]
    r"""The type of this price, which must be PRICE_PER_UNIT for equity orders, or PERCENTAGE_OF_PAR for fixed income orders."""


class OrderCostPreviewResponseLimitPrice(BaseModel):
    r"""The limit price to use in calculating costs. Only PERCENTAGE_OF_PAR will be accepted and returned."""

    price: OptionalNullable[OrderCostPreviewResponsePrice] = UNSET
    r"""The limit price which must be greater than zero if provided. For equity orders in the USD currency, up to 2 decimal places are allowed for prices above $1 and up to 4 decimal places for prices at or below $1. For fixed income orders this is expressed as a percentage of par, which allows up to 4 decimal places in the USD currency."""

    type: Annotated[
        Optional[OrderCostPreviewResponseType],
        PlainValidator(validate_open_enum(False)),
    ] = None
    r"""The type of this price, which must be PRICE_PER_UNIT for equity orders, or PERCENTAGE_OF_PAR for fixed income orders."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["price", "type"]
        nullable_fields = ["price"]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in self.model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m


class OrderCostPreviewResponseQuantityTypedDict(TypedDict):
    r"""The quantity of the designated asset that would be ordered. For Fixed Income: Expressed in the par (face-value) amount and may not exceed two decimal places for USD-based currencies."""

    value: NotRequired[str]
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class OrderCostPreviewResponseQuantity(BaseModel):
    r"""The quantity of the designated asset that would be ordered. For Fixed Income: Expressed in the par (face-value) amount and may not exceed two decimal places for USD-based currencies."""

    value: Optional[str] = None
    r"""The decimal value, as a string; Refer to [Google’s Decimal type protocol buffer](https://github.com/googleapis/googleapis/blob/40203ca1880849480bbff7b8715491060bbccdf1/google/type/decimal.proto#L33) for details"""


class OrderCostPreviewResponseTypedDict(TypedDict):
    r"""Preview of estimated costs for a chosen quantity, asset, capacity, and limit price"""

    account_id: NotRequired[str]
    r"""The account id used in calculating order costs"""
    asset_id: NotRequired[str]
    r"""Apex Asset ID for this asset."""
    asset_type: NotRequired[OrderCostPreviewResponseAssetType]
    r"""The type of asset referenced by the security identifier"""
    broker_capacity: NotRequired[OrderCostPreviewResponseBrokerCapacity]
    r"""Capacity used in determining the order cost. Defaults to \"AGENCY\" if no value specified."""
    estimated_accrued_interest: NotRequired[Nullable[EstimatedAccruedInterestTypedDict]]
    r"""The estimated total of accrued interest that would be exchanged in an order of the given quantity"""
    estimated_gross_amount: NotRequired[Nullable[EstimatedGrossAmountTypedDict]]
    r"""The principal amount involved, which is the notional value of the underlying assets that would be exchanged for the given quantity"""
    estimated_gross_credit_amount: NotRequired[
        Nullable[EstimatedGrossCreditAmountTypedDict]
    ]
    r"""Customer disclosure of the estimated gross credit (fee / markup) amount retained by broker based given the price adjustment schedule configured for orders executed in a principal capacity for a given quantity, and limit price. This amount is priced into the estimated_gross_credit_amount and is not separately charged explicitly."""
    estimated_net_amount: NotRequired[Nullable[EstimatedNetAmountTypedDict]]
    r"""The estimated net notional amount involved in an order of the given quantity, capacity, and limit price. This will be the sum of the estimated gross amount and accrued interest, rounded to two decimal places. (For orders in the principal capacity, this total will include mark-up/mark-down price adjustments.)"""
    identifier: NotRequired[str]
    r"""Identifier of the asset (of the type specified in `identifier_type`)."""
    identifier_type: NotRequired[OrderCostPreviewResponseIdentifierType]
    r"""The identifier type of the asset used for price calculations. This will be the same value as what was sent on the request."""
    limit_price: NotRequired[Nullable[OrderCostPreviewResponseLimitPriceTypedDict]]
    r"""The limit price to use in calculating costs. Only PERCENTAGE_OF_PAR will be accepted and returned."""
    quantity: NotRequired[Nullable[OrderCostPreviewResponseQuantityTypedDict]]
    r"""The quantity of the designated asset that would be ordered. For Fixed Income: Expressed in the par (face-value) amount and may not exceed two decimal places for USD-based currencies."""
    response_generation_time: NotRequired[Nullable[datetime]]
    r"""The time the response was generated by the system"""


class OrderCostPreviewResponse(BaseModel):
    r"""Preview of estimated costs for a chosen quantity, asset, capacity, and limit price"""

    account_id: Optional[str] = None
    r"""The account id used in calculating order costs"""

    asset_id: Optional[str] = None
    r"""Apex Asset ID for this asset."""

    asset_type: Annotated[
        Optional[OrderCostPreviewResponseAssetType],
        PlainValidator(validate_open_enum(False)),
    ] = None
    r"""The type of asset referenced by the security identifier"""

    broker_capacity: Annotated[
        Optional[OrderCostPreviewResponseBrokerCapacity],
        PlainValidator(validate_open_enum(False)),
    ] = None
    r"""Capacity used in determining the order cost. Defaults to \"AGENCY\" if no value specified."""

    estimated_accrued_interest: OptionalNullable[EstimatedAccruedInterest] = UNSET
    r"""The estimated total of accrued interest that would be exchanged in an order of the given quantity"""

    estimated_gross_amount: OptionalNullable[EstimatedGrossAmount] = UNSET
    r"""The principal amount involved, which is the notional value of the underlying assets that would be exchanged for the given quantity"""

    estimated_gross_credit_amount: OptionalNullable[EstimatedGrossCreditAmount] = UNSET
    r"""Customer disclosure of the estimated gross credit (fee / markup) amount retained by broker based given the price adjustment schedule configured for orders executed in a principal capacity for a given quantity, and limit price. This amount is priced into the estimated_gross_credit_amount and is not separately charged explicitly."""

    estimated_net_amount: OptionalNullable[EstimatedNetAmount] = UNSET
    r"""The estimated net notional amount involved in an order of the given quantity, capacity, and limit price. This will be the sum of the estimated gross amount and accrued interest, rounded to two decimal places. (For orders in the principal capacity, this total will include mark-up/mark-down price adjustments.)"""

    identifier: Optional[str] = None
    r"""Identifier of the asset (of the type specified in `identifier_type`)."""

    identifier_type: Optional[OrderCostPreviewResponseIdentifierType] = None
    r"""The identifier type of the asset used for price calculations. This will be the same value as what was sent on the request."""

    limit_price: OptionalNullable[OrderCostPreviewResponseLimitPrice] = UNSET
    r"""The limit price to use in calculating costs. Only PERCENTAGE_OF_PAR will be accepted and returned."""

    quantity: OptionalNullable[OrderCostPreviewResponseQuantity] = UNSET
    r"""The quantity of the designated asset that would be ordered. For Fixed Income: Expressed in the par (face-value) amount and may not exceed two decimal places for USD-based currencies."""

    response_generation_time: OptionalNullable[datetime] = UNSET
    r"""The time the response was generated by the system"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "account_id",
            "asset_id",
            "asset_type",
            "broker_capacity",
            "estimated_accrued_interest",
            "estimated_gross_amount",
            "estimated_gross_credit_amount",
            "estimated_net_amount",
            "identifier",
            "identifier_type",
            "limit_price",
            "quantity",
            "response_generation_time",
        ]
        nullable_fields = [
            "estimated_accrued_interest",
            "estimated_gross_amount",
            "estimated_gross_credit_amount",
            "estimated_net_amount",
            "limit_price",
            "quantity",
            "response_generation_time",
        ]
        null_default_fields = []

        serialized = handler(self)

        m = {}

        for n, f in self.model_fields.items():
            k = f.alias or n
            val = serialized.get(k)
            serialized.pop(k, None)

            optional_nullable = k in optional_fields and k in nullable_fields
            is_set = (
                self.__pydantic_fields_set__.intersection({n})
                or k in null_default_fields
            )  # pylint: disable=no-member

            if val is not None and val != UNSET_SENTINEL:
                m[k] = val
            elif val != UNSET_SENTINEL and (
                not k in optional_fields or (optional_nullable and is_set)
            ):
                m[k] = val

        return m
