"""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 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 CurrencyType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Indicates the type of currency"""

    CURRENCY_TYPE_UNSPECIFIED = "CURRENCY_TYPE_UNSPECIFIED"
    CURRENCY = "CURRENCY"
    CURRENCY_EQUIVALENT = "CURRENCY_EQUIVALENT"


class CurrencyTypedDict(TypedDict):
    r"""Currency specific asset details"""

    currency_type: NotRequired[CurrencyType]
    r"""Indicates the type of currency"""
    payment_currency: NotRequired[str]
    r"""Indicates the name of asset for the underlying payment_currency when the `currency_type` is `CURRENCY_EQUIVALENT`"""


class Currency(BaseModel):
    r"""Currency specific asset details"""

    currency_type: Annotated[
        Optional[CurrencyType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Indicates the type of currency"""

    payment_currency: Optional[str] = None
    r"""Indicates the name of asset for the underlying payment_currency when the `currency_type` is `CURRENCY_EQUIVALENT`"""


class AssetEquityType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""the code indicating the type of associated security."""

    EQUITY_TYPE_UNSPECIFIED = "EQUITY_TYPE_UNSPECIFIED"
    COMMON_STOCK = "COMMON_STOCK"
    PREFERRED_STOCK = "PREFERRED_STOCK"
    PREFERRED_ADR = "PREFERRED_ADR"
    SPECIAL_STOCK = "SPECIAL_STOCK"
    INDEX = "INDEX"
    WARRANT = "WARRANT"
    ADR = "ADR"
    RIGHTS = "RIGHTS"
    SHARES_OF_BENEFICIAL_INTEREST = "SHARES_OF_BENEFICIAL_INTEREST"
    CERTIFICATES = "CERTIFICATES"
    UNITS = "UNITS"
    DEBT_ISSUE = "DEBT_ISSUE"
    EQUITY_TYPE_OPTION = "EQUITY_TYPE_OPTION"
    ETF = "ETF"


class EquityTypedDict(TypedDict):
    r"""Equity specific asset details"""

    fractionable: NotRequired[bool]
    r"""Indicates whether the symbol is eligible for fractional or notional execution for orders at Apex"""
    liquidate: NotRequired[bool]
    r"""Indicates whether the symbol is designated as “Liquidate Only,” and, if so, the system rejects purchases"""
    type: NotRequired[AssetEquityType]
    r"""the code indicating the type of associated security."""


class Equity(BaseModel):
    r"""Equity specific asset details"""

    fractionable: Optional[bool] = None
    r"""Indicates whether the symbol is eligible for fractional or notional execution for orders at Apex"""

    liquidate: Optional[bool] = None
    r"""Indicates whether the symbol is designated as “Liquidate Only,” and, if so, the system rejects purchases"""

    type: Annotated[
        Optional[AssetEquityType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""the code indicating the type of associated security."""


class CallType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of call"""

    CALL_TYPE_UNSPECIFIED = "CALL_TYPE_UNSPECIFIED"
    ORDINARY = "ORDINARY"
    SPECIAL = "SPECIAL"
    MAKE_WHOLE = "MAKE_WHOLE"
    REGULATORY = "REGULATORY"


class CouponFrequency(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Frequency of payments"""

    COUPON_FREQUENCY_UNSPECIFIED = "COUPON_FREQUENCY_UNSPECIFIED"
    SEMI_ANNUAL = "SEMI_ANNUAL"
    MONTHLY = "MONTHLY"
    AT_MATURITY = "AT_MATURITY"
    ZERO = "ZERO"
    QUARTERLY = "QUARTERLY"
    ANNUAL = "ANNUAL"


class CouponRateTypedDict(TypedDict):
    r"""A measure of income an investor can expect to receive expressed as a percent"""

    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 CouponRate(BaseModel):
    r"""A measure of income an investor can expect to receive expressed as a percent"""

    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 CouponType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Type of coupon rate"""

    COUPON_TYPE_UNSPECIFIED = "COUPON_TYPE_UNSPECIFIED"
    COUPON_TYPE_FIXED = "COUPON_TYPE_FIXED"
    COUPON_TYPE_ZERO = "COUPON_TYPE_ZERO"


class DurationTypedDict(TypedDict):
    r"""Weighted average time until a bond’s cash flows are received in years"""

    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 Duration(BaseModel):
    r"""Weighted average time until a bond’s cash flows are received in years"""

    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 FirstCouponDateTypedDict(TypedDict):
    r"""date of first coupon"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class FirstCouponDate(BaseModel):
    r"""date of first coupon"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class FixedIncomeStatus(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The status of the fixed income"""

    FIXED_INCOME_STATUS_UNSPECIFIED = "FIXED_INCOME_STATUS_UNSPECIFIED"
    OUTSTANDING = "OUTSTANDING"
    MATURED = "MATURED"
    CALLED = "CALLED"
    UNKNOWN = "UNKNOWN"
    DEFAULTED = "DEFAULTED"
    CONVERTED = "CONVERTED"
    TENDERED = "TENDERED"
    PRE_ISSUANCE = "PRE_ISSUANCE"
    LIQUIDATED = "LIQUIDATED"
    REPURCHASED = "REPURCHASED"
    REPAID = "REPAID"
    RESTRUCTURED = "RESTRUCTURED"
    PUT = "PUT"
    FUNGED = "FUNGED"


class FixedIncomeSubtype(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of treasury"""

    FIXED_INCOME_SUBTYPE_UNSPECIFIED = "FIXED_INCOME_SUBTYPE_UNSPECIFIED"
    BOND = "BOND"
    STRIPS = "STRIPS"
    BILL = "BILL"
    NOTE = "NOTE"
    TIPS = "TIPS"


class FixedIncomeType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Type of fixed income security"""

    FIXED_INCOME_TYPE_UNSPECIFIED = "FIXED_INCOME_TYPE_UNSPECIFIED"
    MUNICIPAL = "MUNICIPAL"
    CORPORATE = "CORPORATE"
    CD = "CD"
    AGENCY = "AGENCY"
    TREASURY = "TREASURY"
    GOVERNMENT = "GOVERNMENT"
    FOREIGN_GOVERNMENT = "FOREIGN_GOVERNMENT"


class AssetIssueDateTypedDict(TypedDict):
    r"""The date of issuance"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class AssetIssueDate(BaseModel):
    r"""The date of issuance"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class IssueSizeTypedDict(TypedDict):
    r"""Total size of the bond issue in the issuing 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 IssueSize(BaseModel):
    r"""Total size of the bond issue in the issuing 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 LastCouponDateTypedDict(TypedDict):
    r"""date of last coupon"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class LastCouponDate(BaseModel):
    r"""date of last coupon"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class MaturityDateTypedDict(TypedDict):
    r"""The date the fixed income security matures"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class MaturityDate(BaseModel):
    r"""The date the fixed income security matures"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class NextCallDateTypedDict(TypedDict):
    r"""The date of the next call"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class NextCallDate(BaseModel):
    r"""The date of the next call"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class NextCouponDateTypedDict(TypedDict):
    r"""Date of next coupon payment"""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class NextCouponDate(BaseModel):
    r"""Date of next coupon payment"""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class ParValueTypedDict(TypedDict):
    r"""The amount the issuer agrees to pay the investor upon maturity"""

    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 ParValue(BaseModel):
    r"""The amount the issuer agrees to pay the investor upon maturity"""

    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 PriceAtIssuanceTypedDict(TypedDict):
    r"""The price at which fixed income security was issued as a percentage of par value in %"""

    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 PriceAtIssuance(BaseModel):
    r"""The price at which fixed income security was issued as a percentage of par value in %"""

    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 SpRating(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""

    SP_RATING_UNSPECIFIED = "SP_RATING_UNSPECIFIED"
    AAA = "AAA"
    AA_PLUS = "AA_PLUS"
    AA = "AA"
    AA_MINUS = "AA_MINUS"
    A_PLUS = "A_PLUS"
    A = "A"
    A_MINUS = "A_MINUS"
    BBB_PLUS = "BBB_PLUS"
    BBB = "BBB"
    BBB_MINUS = "BBB_MINUS"
    BB_PLUS = "BB_PLUS"
    BB = "BB"
    BB_MINUS = "BB_MINUS"
    B_PLUS = "B_PLUS"
    B = "B"
    B_MINUS = "B_MINUS"
    CCC_PLUS = "CCC_PLUS"
    CCC = "CCC"
    CCC_MINUS = "CCC_MINUS"
    CC = "CC"
    C = "C"
    D = "D"
    NR = "NR"
    SP_1_PLUS = "SP_1_PLUS"
    SP_1 = "SP_1"
    SP_1_MINUS = "SP_1_MINUS"
    A_1_PLUS = "A_1_PLUS"
    A_1 = "A_1"
    A_1_MINUS = "A_1_MINUS"


class SpRatingDateTypedDict(TypedDict):
    r"""The date of Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""

    day: NotRequired[int]
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""
    month: NotRequired[int]
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""
    year: NotRequired[int]
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class SpRatingDate(BaseModel):
    r"""The date of Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""

    day: Optional[int] = None
    r"""Day of a month. Must be from 1 to 31 and valid for the year and month, or 0 to specify a year by itself or a year and month where the day isn't significant."""

    month: Optional[int] = None
    r"""Month of a year. Must be from 1 to 12, or 0 to specify a year without a month and day."""

    year: Optional[int] = None
    r"""Year of the date. Must be from 1 to 9999, or 0 to specify a date without a year."""


class FixedIncomeTypedDict(TypedDict):
    r"""FixedIncome specific asset details"""

    call_type: NotRequired[CallType]
    r"""The type of call"""
    callable: NotRequired[bool]
    r"""Boolean that indicates whether an issuer may redeem the security before its maturity date"""
    convertible: NotRequired[bool]
    r"""Boolean that indicates whether an investor may convert to a number of shares of issuer common stock"""
    coupon_frequency: NotRequired[CouponFrequency]
    r"""Frequency of payments"""
    coupon_rate: NotRequired[Nullable[CouponRateTypedDict]]
    r"""A measure of income an investor can expect to receive expressed as a percent"""
    coupon_type: NotRequired[CouponType]
    r"""Type of coupon rate"""
    duration: NotRequired[Nullable[DurationTypedDict]]
    r"""Weighted average time until a bond’s cash flows are received in years"""
    first_coupon_date: NotRequired[Nullable[FirstCouponDateTypedDict]]
    r"""date of first coupon"""
    fixed_income_status: NotRequired[FixedIncomeStatus]
    r"""The status of the fixed income"""
    fixed_income_subtype: NotRequired[FixedIncomeSubtype]
    r"""The type of treasury"""
    fixed_income_type: NotRequired[FixedIncomeType]
    r"""Type of fixed income security"""
    insured: NotRequired[bool]
    r"""Boolean that indicates whether a security is backed by an insurance policy"""
    issue_date: NotRequired[Nullable[AssetIssueDateTypedDict]]
    r"""The date of issuance"""
    issue_size: NotRequired[Nullable[IssueSizeTypedDict]]
    r"""Total size of the bond issue in the issuing currency"""
    issuer: NotRequired[str]
    r"""Name of the bond issuer"""
    last_coupon_date: NotRequired[Nullable[LastCouponDateTypedDict]]
    r"""date of last coupon"""
    maturity_date: NotRequired[Nullable[MaturityDateTypedDict]]
    r"""The date the fixed income security matures"""
    next_call_date: NotRequired[Nullable[NextCallDateTypedDict]]
    r"""The date of the next call"""
    next_coupon_date: NotRequired[Nullable[NextCouponDateTypedDict]]
    r"""Date of next coupon payment"""
    par_value: NotRequired[Nullable[ParValueTypedDict]]
    r"""The amount the issuer agrees to pay the investor upon maturity"""
    perpetual: NotRequired[bool]
    r"""Indicates whether the bond is perpetual"""
    price_at_issuance: NotRequired[Nullable[PriceAtIssuanceTypedDict]]
    r"""The price at which fixed income security was issued as a percentage of par value in %"""
    sp_rating: NotRequired[SpRating]
    r"""Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""
    sp_rating_date: NotRequired[Nullable[SpRatingDateTypedDict]]
    r"""The date of Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""
    underlying_symbol: NotRequired[str]
    r"""The symbol for the issuer’s equity"""


class FixedIncome(BaseModel):
    r"""FixedIncome specific asset details"""

    call_type: Annotated[
        Optional[CallType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type of call"""

    callable: Optional[bool] = None
    r"""Boolean that indicates whether an issuer may redeem the security before its maturity date"""

    convertible: Optional[bool] = None
    r"""Boolean that indicates whether an investor may convert to a number of shares of issuer common stock"""

    coupon_frequency: Annotated[
        Optional[CouponFrequency], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Frequency of payments"""

    coupon_rate: OptionalNullable[CouponRate] = UNSET
    r"""A measure of income an investor can expect to receive expressed as a percent"""

    coupon_type: Annotated[
        Optional[CouponType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Type of coupon rate"""

    duration: OptionalNullable[Duration] = UNSET
    r"""Weighted average time until a bond’s cash flows are received in years"""

    first_coupon_date: OptionalNullable[FirstCouponDate] = UNSET
    r"""date of first coupon"""

    fixed_income_status: Annotated[
        Optional[FixedIncomeStatus], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The status of the fixed income"""

    fixed_income_subtype: Annotated[
        Optional[FixedIncomeSubtype], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type of treasury"""

    fixed_income_type: Annotated[
        Optional[FixedIncomeType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Type of fixed income security"""

    insured: Optional[bool] = None
    r"""Boolean that indicates whether a security is backed by an insurance policy"""

    issue_date: OptionalNullable[AssetIssueDate] = UNSET
    r"""The date of issuance"""

    issue_size: OptionalNullable[IssueSize] = UNSET
    r"""Total size of the bond issue in the issuing currency"""

    issuer: Optional[str] = None
    r"""Name of the bond issuer"""

    last_coupon_date: OptionalNullable[LastCouponDate] = UNSET
    r"""date of last coupon"""

    maturity_date: OptionalNullable[MaturityDate] = UNSET
    r"""The date the fixed income security matures"""

    next_call_date: OptionalNullable[NextCallDate] = UNSET
    r"""The date of the next call"""

    next_coupon_date: OptionalNullable[NextCouponDate] = UNSET
    r"""Date of next coupon payment"""

    par_value: OptionalNullable[ParValue] = UNSET
    r"""The amount the issuer agrees to pay the investor upon maturity"""

    perpetual: Optional[bool] = None
    r"""Indicates whether the bond is perpetual"""

    price_at_issuance: OptionalNullable[PriceAtIssuance] = UNSET
    r"""The price at which fixed income security was issued as a percentage of par value in %"""

    sp_rating: Annotated[
        Optional[SpRating], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""

    sp_rating_date: OptionalNullable[SpRatingDate] = UNSET
    r"""The date of Standard & Poor's (S&P) rating of the creditworthiness of borrowers. Correspondents must be configured to view this field."""

    underlying_symbol: Optional[str] = None
    r"""The symbol for the issuer’s equity"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "call_type",
            "callable",
            "convertible",
            "coupon_frequency",
            "coupon_rate",
            "coupon_type",
            "duration",
            "first_coupon_date",
            "fixed_income_status",
            "fixed_income_subtype",
            "fixed_income_type",
            "insured",
            "issue_date",
            "issue_size",
            "issuer",
            "last_coupon_date",
            "maturity_date",
            "next_call_date",
            "next_coupon_date",
            "par_value",
            "perpetual",
            "price_at_issuance",
            "sp_rating",
            "sp_rating_date",
            "underlying_symbol",
        ]
        nullable_fields = [
            "coupon_rate",
            "duration",
            "first_coupon_date",
            "issue_date",
            "issue_size",
            "last_coupon_date",
            "maturity_date",
            "next_call_date",
            "next_coupon_date",
            "par_value",
            "price_at_issuance",
            "sp_rating_date",
        ]
        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 LargeOrderNotificationAmountTypedDict(TypedDict):
    r"""The threshold at which Apex would need to notify the fund family of an incoming large order."""

    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 LargeOrderNotificationAmount(BaseModel):
    r"""The threshold at which Apex would need to notify the fund family of an incoming large order."""

    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 MutualFundType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Identifies type of mutual fund"""

    MUTUAL_FUND_TYPE_UNSPECIFIED = "MUTUAL_FUND_TYPE_UNSPECIFIED"
    BOND = "BOND"
    MONEY_MARKET_FUND = "MONEY_MARKET_FUND"
    EQUITY = "EQUITY"


class MutualFundTypedDict(TypedDict):
    r"""MutualFund specific asset details"""

    fund_family: NotRequired[str]
    r"""Name of the fund company"""
    large_order_notification_amount: NotRequired[
        Nullable[LargeOrderNotificationAmountTypedDict]
    ]
    r"""The threshold at which Apex would need to notify the fund family of an incoming large order."""
    mutual_fund_type: NotRequired[MutualFundType]
    r"""Identifies type of mutual fund"""
    share_class: NotRequired[str]
    r"""Indicates the type and number of fees charged for the shares in a fund"""


class MutualFund(BaseModel):
    r"""MutualFund specific asset details"""

    fund_family: Optional[str] = None
    r"""Name of the fund company"""

    large_order_notification_amount: OptionalNullable[
        LargeOrderNotificationAmount
    ] = UNSET
    r"""The threshold at which Apex would need to notify the fund family of an incoming large order."""

    mutual_fund_type: Annotated[
        Optional[MutualFundType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Identifies type of mutual fund"""

    share_class: Optional[str] = None
    r"""Indicates the type and number of fees charged for the shares in a fund"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "fund_family",
            "large_order_notification_amount",
            "mutual_fund_type",
            "share_class",
        ]
        nullable_fields = ["large_order_notification_amount"]
        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 AssetType1(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type or category of the asset"""

    TYPE_UNSPECIFIED = "TYPE_UNSPECIFIED"
    EQUITY = "EQUITY"
    OPTION = "OPTION"
    CURRENCY = "CURRENCY"
    DIGITAL = "DIGITAL"
    FDIC_SYNTHETIC = "FDIC_SYNTHETIC"
    FIXED_INCOME = "FIXED_INCOME"
    MUTUAL_FUND = "MUTUAL_FUND"


class AssetTypedDict(TypedDict):
    r"""Asset is the Apex representation of a security"""

    asset_id: NotRequired[str]
    r"""Apex internal identifier assigned upon entry to every security."""
    currency: NotRequired[Nullable[CurrencyTypedDict]]
    r"""Currency specific asset details"""
    cusip: NotRequired[str]
    r"""Identifier assigned to a security by the CUSIP Service Bureau of Standard & Poor’s Corporation"""
    description: NotRequired[str]
    r"""Name of the issuer of a security and additional descriptive information about the particular issue"""
    equity: NotRequired[Nullable[EquityTypedDict]]
    r"""Equity specific asset details"""
    fixed_income: NotRequired[Nullable[FixedIncomeTypedDict]]
    r"""FixedIncome specific asset details"""
    isin: NotRequired[str]
    r"""isin is the International Securities Identification Number"""
    issuing_region_code: NotRequired[str]
    r"""A string attribute denoting the country of issuance or where the asset is trading."""
    mutual_fund: NotRequired[Nullable[MutualFundTypedDict]]
    r"""MutualFund specific asset details"""
    name: NotRequired[str]
    r"""assets/{asset_id}"""
    originating_region_code: NotRequired[str]
    r"""ISO code identifying the region in which the entity was incorporated"""
    symbol: NotRequired[str]
    r"""An arrangement of characters—usually letters and or numbers — usually representing securities on an exchange"""
    type: NotRequired[AssetType1]
    r"""The type or category of the asset"""
    usable: NotRequired[bool]
    r"""A usable asset is active in its respective market and can be traded and/or transferred"""


class Asset(BaseModel):
    r"""Asset is the Apex representation of a security"""

    asset_id: Optional[str] = None
    r"""Apex internal identifier assigned upon entry to every security."""

    currency: OptionalNullable[Currency] = UNSET
    r"""Currency specific asset details"""

    cusip: Optional[str] = None
    r"""Identifier assigned to a security by the CUSIP Service Bureau of Standard & Poor’s Corporation"""

    description: Optional[str] = None
    r"""Name of the issuer of a security and additional descriptive information about the particular issue"""

    equity: OptionalNullable[Equity] = UNSET
    r"""Equity specific asset details"""

    fixed_income: OptionalNullable[FixedIncome] = UNSET
    r"""FixedIncome specific asset details"""

    isin: Optional[str] = None
    r"""isin is the International Securities Identification Number"""

    issuing_region_code: Optional[str] = None
    r"""A string attribute denoting the country of issuance or where the asset is trading."""

    mutual_fund: OptionalNullable[MutualFund] = UNSET
    r"""MutualFund specific asset details"""

    name: Optional[str] = None
    r"""assets/{asset_id}"""

    originating_region_code: Optional[str] = None
    r"""ISO code identifying the region in which the entity was incorporated"""

    symbol: Optional[str] = None
    r"""An arrangement of characters—usually letters and or numbers — usually representing securities on an exchange"""

    type: Annotated[
        Optional[AssetType1], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type or category of the asset"""

    usable: Optional[bool] = None
    r"""A usable asset is active in its respective market and can be traded and/or transferred"""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "asset_id",
            "currency",
            "cusip",
            "description",
            "equity",
            "fixed_income",
            "isin",
            "issuing_region_code",
            "mutual_fund",
            "name",
            "originating_region_code",
            "symbol",
            "type",
            "usable",
        ]
        nullable_fields = ["currency", "equity", "fixed_income", "mutual_fund"]
        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
