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

from __future__ import annotations
from .executedprice import ExecutedPrice, ExecutedPriceTypedDict
from .executions import Executions, ExecutionsTypedDict
from .fee import Fee, FeeTypedDict
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 List, Optional
from typing_extensions import Annotated, NotRequired, TypedDict


class OrderAssetType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of the asset in this order"""

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


class OrderBrokerCapacity(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Defaults to \"AGENCY\" if not specified. For Equities: Only \"AGENCY\" is allowed. For Mutual Funds: Only \"AGENCY\" is allowed. For Fixed Income: Either \"AGENCY\" or \"PRINCIPAL\" are allowed."""

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


class CancelRejectedReason(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Used to denote when a cancel request has been rejected."""

    CANCEL_REJECT_REASON_UNSPECIFIED = "CANCEL_REJECT_REASON_UNSPECIFIED"
    TOO_LATE_TO_CANCEL = "TOO_LATE_TO_CANCEL"
    CANCELLATION_UNKNOWN_ORDER = "CANCELLATION_UNKNOWN_ORDER"
    BROKER_EXCHANGE_OPTION = "BROKER_EXCHANGE_OPTION"
    ORDER_ALREADY_IN_PENDING_CANCEL_OR_PENDING_REPLACE_STATUS = (
        "ORDER_ALREADY_IN_PENDING_CANCEL_OR_PENDING_REPLACE_STATUS"
    )
    DUPLICATE = "DUPLICATE"
    CANCELLATION_SYSTEM_ERROR = "CANCELLATION_SYSTEM_ERROR"
    ORDER_ALREADY_CANCELED = "ORDER_ALREADY_CANCELED"
    CANCELLATION_MISCONFIGURED_CLIENT = "CANCELLATION_MISCONFIGURED_CLIENT"


class OrderCommissionType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of commission value being specified. Only the type of \"AMOUNT\" is supported."""

    COMMISSION_TYPE_UNSPECIFIED = "COMMISSION_TYPE_UNSPECIFIED"
    AMOUNT = "AMOUNT"


class ValueTypedDict(TypedDict):
    r"""The value of this commission. If type = `AMOUNT`, then this expresses a monetary value in same currency denoted on the order itself."""

    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 Value(BaseModel):
    r"""The value of this commission. If type = `AMOUNT`, then this expresses a monetary value in same currency denoted on the order itself."""

    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 OrderCommissionTypedDict(TypedDict):
    r"""A custom commission to be applied to this order. When specifying an AMOUNT type, the value represents a notional amount measured in the currency of the order."""

    type: NotRequired[OrderCommissionType]
    r"""The type of commission value being specified. Only the type of \"AMOUNT\" is supported."""
    value: NotRequired[Nullable[ValueTypedDict]]
    r"""The value of this commission. If type = `AMOUNT`, then this expresses a monetary value in same currency denoted on the order itself."""


class OrderCommission(BaseModel):
    r"""A custom commission to be applied to this order. When specifying an AMOUNT type, the value represents a notional amount measured in the currency of the order."""

    type: Annotated[
        Optional[OrderCommissionType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type of commission value being specified. Only the type of \"AMOUNT\" is supported."""

    value: OptionalNullable[Value] = UNSET
    r"""The value of this commission. If type = `AMOUNT`, then this expresses a monetary value in same currency denoted on the order itself."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["type", "value"]
        nullable_fields = ["value"]
        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 CumulativeNotionalValueTypedDict(TypedDict):
    r"""The sum of order quantity & price, across all fills, reported in the currency specified in the order. (This will be rounded to 2 decimal places for USD currencies). Will be absent if an order has no fill information."""

    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 CumulativeNotionalValue(BaseModel):
    r"""The sum of order quantity & price, across all fills, reported in the currency specified in the order. (This will be rounded to 2 decimal places for USD currencies). Will be absent if an order has no fill information."""

    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 FilledQuantityTypedDict(TypedDict):
    r"""The summed quantity value across all fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no fill information."""

    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 FilledQuantity(BaseModel):
    r"""The summed quantity value across all fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no fill information."""

    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 OrderIdentifierType(str, Enum):
    r"""The identifier type of the asset being ordered. For Equities: only SYMBOL is supported For Mutual Funds: only SYMBOL and CUSIP are supported For Fixed Income: only CUSIP and ISIN are supported"""

    SYMBOL = "SYMBOL"
    CUSIP = "CUSIP"
    ISIN = "ISIN"


class OrderAmountTypedDict(TypedDict):
    r"""The amount of the LOI. This is a monetary value in the same currency as the 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 OrderAmount(BaseModel):
    r"""The amount of the LOI. This is a monetary value in the same currency as the 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 PeriodStartDateTypedDict(TypedDict):
    r"""The period start date of the LOI."""

    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 PeriodStartDate(BaseModel):
    r"""The period start date of the LOI."""

    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 LetterOfIntentTypedDict(TypedDict):
    r"""Letter of Intent (LOI). An LOI allows investors to receive sales charge discounts based on a commitment to buy a specified monetary amount of shares over a period of time, usually 13 months."""

    amount: NotRequired[Nullable[OrderAmountTypedDict]]
    r"""The amount of the LOI. This is a monetary value in the same currency as the order."""
    period_start_date: NotRequired[Nullable[PeriodStartDateTypedDict]]
    r"""The period start date of the LOI."""


class LetterOfIntent(BaseModel):
    r"""Letter of Intent (LOI). An LOI allows investors to receive sales charge discounts based on a commitment to buy a specified monetary amount of shares over a period of time, usually 13 months."""

    amount: OptionalNullable[OrderAmount] = UNSET
    r"""The amount of the LOI. This is a monetary value in the same currency as the order."""

    period_start_date: OptionalNullable[PeriodStartDate] = UNSET
    r"""The period start date of the LOI."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["amount", "period_start_date"]
        nullable_fields = ["amount", "period_start_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 OrderPriceTypedDict(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 OrderPrice(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 OrderLimitPriceType(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 LimitPriceTypedDict(TypedDict):
    r"""The limit price for this order."""

    price: NotRequired[Nullable[OrderPriceTypedDict]]
    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[OrderLimitPriceType]
    r"""The type of this price, which must be PRICE_PER_UNIT for equity orders, or PERCENTAGE_OF_PAR for fixed income orders."""


class LimitPrice(BaseModel):
    r"""The limit price for this order."""

    price: OptionalNullable[OrderPrice] = 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[OrderLimitPriceType], 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 MaxSellQuantityTypedDict(TypedDict):
    r"""The maximum number of shares to be sold if this is a notional SELL order of an Equity asset type. (Prohibited for other side or asset_type inputs.)

    This will only be recognized for clients configured not to use OMS checks. When specified, must be greater than 0 and can't exceed 5 decimal places.
    """

    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 MaxSellQuantity(BaseModel):
    r"""The maximum number of shares to be sold if this is a notional SELL order of an Equity asset type. (Prohibited for other side or asset_type inputs.)

    This will only be recognized for clients configured not to use OMS checks. When specified, must be greater than 0 and can't exceed 5 decimal places.
    """

    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 NotionalValueTypedDict(TypedDict):
    r"""Notional quantity of the order, measured in USD. Maximum 2 decimal place precision. For Equities: This represents the maximum amount to be spent. The final order may may have a smaller notional amount. For Mutual Funds: Only supported for BUY orders. The order will be transacted at the full notional amount specified. For Fixed Income: Not supported, you must specify a `quantity` value."""

    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 NotionalValue(BaseModel):
    r"""Notional quantity of the order, measured in USD. Maximum 2 decimal place precision. For Equities: This represents the maximum amount to be spent. The final order may may have a smaller notional amount. For Mutual Funds: Only supported for BUY orders. The order will be transacted at the full notional amount specified. For Fixed Income: Not supported, you must specify a `quantity` value."""

    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 OrderDateTypedDict(TypedDict):
    r"""The date on which the order will go to the market: must either be \"today\" or the next valid trading day. If the current day is not a valid trading day, then the next valid market day must be specified. If the current time is within 5 minutes prior to market close, the next valid market day may be specified. If the current time is after market close, and before midnight Eastern, then the next valid market day must be specified. In all other cases, the current day, Eastern must be specified."""

    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 OrderDate(BaseModel):
    r"""The date on which the order will go to the market: must either be \"today\" or the next valid trading day. If the current day is not a valid trading day, then the next valid market day must be specified. If the current time is within 5 minutes prior to market close, the next valid market day may be specified. If the current time is after market close, and before midnight Eastern, then the next valid market day must be specified. In all other cases, the current day, Eastern must be specified."""

    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 OrderRejectedReason(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""When an order has the REJECTED status, this will be populated with a system code describing the rejection."""

    ORDER_REJECT_REASON_UNSPECIFIED = "ORDER_REJECT_REASON_UNSPECIFIED"
    BROKER_OPTION = "BROKER_OPTION"
    UNKNOWN_SECURITY = "UNKNOWN_SECURITY"
    EXCHANGE_CLOSED = "EXCHANGE_CLOSED"
    ORDER_EXCEEDS_LIMIT = "ORDER_EXCEEDS_LIMIT"
    TOO_LATE_TO_ENTER = "TOO_LATE_TO_ENTER"
    UNKNOWN_ORDER = "UNKNOWN_ORDER"
    DUPLICATE_ORDER = "DUPLICATE_ORDER"
    STALE_ORDER = "STALE_ORDER"
    BELOW_NOTIONAL_MINIMUM = "BELOW_NOTIONAL_MINIMUM"
    ORDER_DATE_UNAVAILABLE = "ORDER_DATE_UNAVAILABLE"
    AGGRESSIVE_LIMIT_PRICE = "AGGRESSIVE_LIMIT_PRICE"
    ACCOUNT_NOT_ENTITLED = "ACCOUNT_NOT_ENTITLED"
    SYSTEM_ERROR = "SYSTEM_ERROR"
    BLOCKING_CORPORATE_ACTION = "BLOCKING_CORPORATE_ACTION"
    UNAVAILABLE_PRICE_QUOTE = "UNAVAILABLE_PRICE_QUOTE"
    EXECUTION_MISCONFIGURED_CLIENT = "EXECUTION_MISCONFIGURED_CLIENT"
    NOTIONAL_QUANTITY_NOT_ALLOWED_FOR_SECURITY = (
        "NOTIONAL_QUANTITY_NOT_ALLOWED_FOR_SECURITY"
    )
    FRACTIONAL_QUANTITY_NOT_ALLOWED_FOR_SECURITY = (
        "FRACTIONAL_QUANTITY_NOT_ALLOWED_FOR_SECURITY"
    )
    ONLY_FRACTIONAL_SELL_OR_WHOLE_ORDERS_ALLOWED_FOR_SECURITY = (
        "ONLY_FRACTIONAL_SELL_OR_WHOLE_ORDERS_ALLOWED_FOR_SECURITY"
    )
    SYMBOL_NOT_TRADEABLE = "SYMBOL_NOT_TRADEABLE"
    ABOVE_NOTIONAL_MAXIMUM = "ABOVE_NOTIONAL_MAXIMUM"
    ABOVE_SHARE_MAXIMUM = "ABOVE_SHARE_MAXIMUM"
    FAILED_BUYING_POWER = "FAILED_BUYING_POWER"
    INSUFFICIENT_POSITION = "INSUFFICIENT_POSITION"
    MAX_SELL_QUANTITY_REQUIRED = "MAX_SELL_QUANTITY_REQUIRED"
    MAX_SELL_QUANTITY_PROHIBITED = "MAX_SELL_QUANTITY_PROHIBITED"
    STOP_PRICE_EXCEEDS_MARKET_PRICE = "STOP_PRICE_EXCEEDS_MARKET_PRICE"
    TRADES_DISABLED_FOR_ASSET_TYPE = "TRADES_DISABLED_FOR_ASSET_TYPE"
    COMMISSION_NOT_ALLOWED_FOR_NON_BROKER_DEALER = (
        "COMMISSION_NOT_ALLOWED_FOR_NON_BROKER_DEALER"
    )
    ASSET_NOT_SET_UP_TO_TRADE = "ASSET_NOT_SET_UP_TO_TRADE"
    INVALID_ORDER_QUANTITY = "INVALID_ORDER_QUANTITY"
    CLIENT_RECEIVED_TIME_REQUIRED = "CLIENT_RECEIVED_TIME_REQUIRED"


class OrderStatus(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The processing status of the order"""

    ORDER_STATUS_UNSPECIFIED = "ORDER_STATUS_UNSPECIFIED"
    PENDING_NEW = "PENDING_NEW"
    NEW = "NEW"
    PENDING_QUEUED = "PENDING_QUEUED"
    QUEUED = "QUEUED"
    PARTIALLY_FILLED = "PARTIALLY_FILLED"
    FILLED = "FILLED"
    PENDING_CANCEL = "PENDING_CANCEL"
    CANCELED = "CANCELED"
    REJECTED = "REJECTED"


class OrderOrderType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The execution type of this order. For Equities: MARKET, LIMIT, or STOP are supported. For Mutual Funds: only MARKET is supported. For Fixed Income: only LIMIT is supported."""

    ORDER_TYPE_UNSPECIFIED = "ORDER_TYPE_UNSPECIFIED"
    LIMIT = "LIMIT"
    MARKET = "MARKET"
    STOP = "STOP"


class OrderPrevailingMarketPriceTypedDict(TypedDict):
    r"""The prevailing market price, calculated as a weighted average of the fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no executions."""

    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 OrderPrevailingMarketPrice(BaseModel):
    r"""The prevailing market price, calculated as a weighted average of the fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no executions."""

    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 OrderQuantityTypedDict(TypedDict):
    r"""Numeric quantity of the order. For Equities: Represents the number of shares, must be greater than zero and may not exceed 5 decimal places. For Mutual Funds: Only supported for SELL orders. Represents the number of shares, up to a maximum of 3 decimal places. For Fixed Income: Represents the par (face-value) amount being ordered, and may not exceed two decimal places for USD-based currencies. Either a quantity or notional_value MUST be specified (but not both)."""

    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 OrderQuantity(BaseModel):
    r"""Numeric quantity of the order. For Equities: Represents the number of shares, must be greater than zero and may not exceed 5 decimal places. For Mutual Funds: Only supported for SELL orders. Represents the number of shares, up to a maximum of 3 decimal places. For Fixed Income: Represents the par (face-value) amount being ordered, and may not exceed two decimal places for USD-based currencies. Either a quantity or notional_value MUST be specified (but not both)."""

    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 OrderRightsOfAccumulationAmountTypedDict(TypedDict):
    r"""The amount of the ROA. This is a monetary value in the same currency as the order. Only 9,999,999.99 is supported."""

    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 OrderRightsOfAccumulationAmount(BaseModel):
    r"""The amount of the ROA. This is a monetary value in the same currency as the order. Only 9,999,999.99 is supported."""

    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 RightsOfAccumulationTypedDict(TypedDict):
    r"""Rights of Accumulation (ROA). An ROA allows an investor to aggregate their own fund shares with the holdings of certain related parties toward achieving the investment thresholds at which sales charge discounts become available."""

    amount: NotRequired[Nullable[OrderRightsOfAccumulationAmountTypedDict]]
    r"""The amount of the ROA. This is a monetary value in the same currency as the order. Only 9,999,999.99 is supported."""


class RightsOfAccumulation(BaseModel):
    r"""Rights of Accumulation (ROA). An ROA allows an investor to aggregate their own fund shares with the holdings of certain related parties toward achieving the investment thresholds at which sales charge discounts become available."""

    amount: OptionalNullable[OrderRightsOfAccumulationAmount] = UNSET
    r"""The amount of the ROA. This is a monetary value in the same currency as the order. Only 9,999,999.99 is supported."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = ["amount"]
        nullable_fields = ["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 OrderSide(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The side of this order."""

    SIDE_UNSPECIFIED = "SIDE_UNSPECIFIED"
    BUY = "BUY"
    SELL = "SELL"


class OrderSpecialReportingInstructions(str, Enum, metaclass=utils.OpenEnumMeta):
    SPECIAL_REPORTING_INSTRUCTIONS_UNSPECIFIED = (
        "SPECIAL_REPORTING_INSTRUCTIONS_UNSPECIFIED"
    )
    CUSTOMER_DIRECTED = "CUSTOMER_DIRECTED"
    WITH_DIVIDEND = "WITH_DIVIDEND"
    WITH_RIGHTS = "WITH_RIGHTS"
    DISCRETION_EXERCISED = "DISCRETION_EXERCISED"
    DISCRETION_NOT_EXERCISED = "DISCRETION_NOT_EXERCISED"
    BROKER_DEALER_ORDER = "BROKER_DEALER_ORDER"
    FULLY_REGISTERED = "FULLY_REGISTERED"
    ODDLOT_DIFF_ON_REQUEST = "ODDLOT_DIFF_ON_REQUEST"
    PROSPECTUS_ENCLOSED = "PROSPECTUS_ENCLOSED"
    PROSPECTUS_SEPARATE_MAIL = "PROSPECTUS_SEPARATE_MAIL"
    SOLICITED = "SOLICITED"
    UNSOLICITED = "UNSOLICITED"
    X_DIVIDEND = "X_DIVIDEND"
    ACTING_AS_PRINCIPAL = "ACTING_AS_PRINCIPAL"
    AVERAGE_PRICE = "AVERAGE_PRICE"
    BROKER_LIQUIDATION = "BROKER_LIQUIDATION"
    INTERNET_ORDER = "INTERNET_ORDER"
    MARGIN_SELLOUT = "MARGIN_SELLOUT"
    NEGATIVE_NET_PROCEED = "NEGATIVE_NET_PROCEED"
    RISKLESS_PRINCIPAL = "RISKLESS_PRINCIPAL"
    THIRD_MARKET = "THIRD_MARKET"
    SUPPRESS_TRACE_REPORTING = "SUPPRESS_TRACE_REPORTING"
    WHEN_DISTRIBUTED = "WHEN_DISTRIBUTED"


class OrderStopPricePriceTypedDict(TypedDict):
    r"""The stop 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."""

    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 OrderStopPricePrice(BaseModel):
    r"""The stop 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."""

    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 OrderStopPriceType(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""The type of this price, which must PRICE_PER_UNIT for equity orders. (Fixed income and mutual fund assets do not support stop orders.)"""

    STOP_PRICE_TYPE_UNSPECIFIED = "STOP_PRICE_TYPE_UNSPECIFIED"
    PRICE_PER_UNIT = "PRICE_PER_UNIT"


class StopPriceTypedDict(TypedDict):
    r"""The stop price for this order. Only allowed for equities, when the side is SELL."""

    price: NotRequired[Nullable[OrderStopPricePriceTypedDict]]
    r"""The stop 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."""
    type: NotRequired[OrderStopPriceType]
    r"""The type of this price, which must PRICE_PER_UNIT for equity orders. (Fixed income and mutual fund assets do not support stop orders.)"""


class StopPrice(BaseModel):
    r"""The stop price for this order. Only allowed for equities, when the side is SELL."""

    price: OptionalNullable[OrderStopPricePrice] = UNSET
    r"""The stop 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."""

    type: Annotated[
        Optional[OrderStopPriceType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type of this price, which must PRICE_PER_UNIT for equity orders. (Fixed income and mutual fund assets do not support stop 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 OrderTimeInForce(str, Enum, metaclass=utils.OpenEnumMeta):
    r"""Must be the value \"DAY\". Regulatory requirements dictate that the system capture the intended time_in_force, which is why this a mandatory field."""

    TIME_IN_FORCE_UNSPECIFIED = "TIME_IN_FORCE_UNSPECIFIED"
    DAY = "DAY"


class OrderTypedDict(TypedDict):
    r"""The message describing an order"""

    account_id: NotRequired[str]
    r"""The identifier of the account transacting this order"""
    asset_id: NotRequired[str]
    r"""Apex Asset ID for this asset. This will not be returned in the initial CreateOrder response and will be available after an order completes validation. If the provided identifier does not match any Apex asset available for trading, an OrderRejectReason of \"UNKNOWN_SECURITY\" will be returned and the asset_id will not be set."""
    asset_type: NotRequired[OrderAssetType]
    r"""The type of the asset in this order"""
    average_prices: NotRequired[List[ExecutedPriceTypedDict]]
    r"""The average prices, as weighted averages, across all executions in this order. Will be absent if an order has no executions.

    When asset_type = EQUITY or MUTUAL_FUND, there will be at most one value present, with a type of PRICE_PER_UNIT. This will have up to 4 decimal places for USD amounts less than $1, and a maximum of two for larger USD amounts.

    When asset_type = FIXED_INCOME, there may be more than one value present which would have a type other than PRICE_PER_UNIT. Price values in PERCENTAGE_OF_PAR will have up to 4 decimal places of precision, and price values measured in yields will support up to 5 decimal places.
    """
    broker_capacity: NotRequired[OrderBrokerCapacity]
    r"""Defaults to \"AGENCY\" if not specified. For Equities: Only \"AGENCY\" is allowed. For Mutual Funds: Only \"AGENCY\" is allowed. For Fixed Income: Either \"AGENCY\" or \"PRINCIPAL\" are allowed."""
    cancel_reason: NotRequired[str]
    r"""Used to explain why an order is canceled"""
    cancel_rejected_reason: NotRequired[CancelRejectedReason]
    r"""Used to denote when a cancel request has been rejected."""
    client_order_id: NotRequired[str]
    r"""User-supplied unique order ID. Cannot be more than 40 characters long."""
    client_received_time: NotRequired[Nullable[datetime]]
    r"""Required for Equity Orders for any client who is having Apex do CAT reporting on their behalf. A value may be provided for non-Equity orders, and will be remembered, but valid timestamps will have no impact on how they are processed."""
    commission: NotRequired[Nullable[OrderCommissionTypedDict]]
    r"""A custom commission to be applied to this order. When specifying an AMOUNT type, the value represents a notional amount measured in the currency of the order."""
    create_time: NotRequired[Nullable[datetime]]
    r"""Time of the order creation"""
    cumulative_notional_value: NotRequired[Nullable[CumulativeNotionalValueTypedDict]]
    r"""The sum of order quantity & price, across all fills, reported in the currency specified in the order. (This will be rounded to 2 decimal places for USD currencies). Will be absent if an order has no fill information."""
    currency_code: NotRequired[str]
    r"""Defaults to \"USD\". Only \"USD\" is supported. Full list of currency codes is defined at: https://en.wikipedia.org/wiki/ISO_4217"""
    executions: NotRequired[List[ExecutionsTypedDict]]
    r"""The execution-level details that compose this order"""
    fees: NotRequired[List[FeeTypedDict]]
    r"""Fees that will be applied to this order."""
    filled_quantity: NotRequired[Nullable[FilledQuantityTypedDict]]
    r"""The summed quantity value across all fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no fill information."""
    identifier: NotRequired[str]
    r"""Identifier of the asset (of the type specified in `identifier_type`)."""
    identifier_type: NotRequired[OrderIdentifierType]
    r"""The identifier type of the asset being ordered. For Equities: only SYMBOL is supported For Mutual Funds: only SYMBOL and CUSIP are supported For Fixed Income: only CUSIP and ISIN are supported"""
    last_update_time: NotRequired[Nullable[datetime]]
    r"""Time of the last order update"""
    letter_of_intent: NotRequired[Nullable[LetterOfIntentTypedDict]]
    r"""Letter of Intent (LOI). An LOI allows investors to receive sales charge discounts based on a commitment to buy a specified monetary amount of shares over a period of time, usually 13 months."""
    limit_price: NotRequired[Nullable[LimitPriceTypedDict]]
    r"""The limit price for this order."""
    max_sell_quantity: NotRequired[Nullable[MaxSellQuantityTypedDict]]
    r"""The maximum number of shares to be sold if this is a notional SELL order of an Equity asset type. (Prohibited for other side or asset_type inputs.)

    This will only be recognized for clients configured not to use OMS checks. When specified, must be greater than 0 and can't exceed 5 decimal places.
    """
    name: NotRequired[str]
    r"""System generated name of the order."""
    notional_value: NotRequired[Nullable[NotionalValueTypedDict]]
    r"""Notional quantity of the order, measured in USD. Maximum 2 decimal place precision. For Equities: This represents the maximum amount to be spent. The final order may may have a smaller notional amount. For Mutual Funds: Only supported for BUY orders. The order will be transacted at the full notional amount specified. For Fixed Income: Not supported, you must specify a `quantity` value."""
    order_date: NotRequired[Nullable[OrderDateTypedDict]]
    r"""The date on which the order will go to the market: must either be \"today\" or the next valid trading day. If the current day is not a valid trading day, then the next valid market day must be specified. If the current time is within 5 minutes prior to market close, the next valid market day may be specified. If the current time is after market close, and before midnight Eastern, then the next valid market day must be specified. In all other cases, the current day, Eastern must be specified."""
    order_id: NotRequired[str]
    r"""System generated unique id for the order."""
    order_rejected_reason: NotRequired[OrderRejectedReason]
    r"""When an order has the REJECTED status, this will be populated with a system code describing the rejection."""
    order_status: NotRequired[OrderStatus]
    r"""The processing status of the order"""
    order_type: NotRequired[OrderOrderType]
    r"""The execution type of this order. For Equities: MARKET, LIMIT, or STOP are supported. For Mutual Funds: only MARKET is supported. For Fixed Income: only LIMIT is supported."""
    prevailing_market_price: NotRequired[Nullable[OrderPrevailingMarketPriceTypedDict]]
    r"""The prevailing market price, calculated as a weighted average of the fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no executions."""
    quantity: NotRequired[Nullable[OrderQuantityTypedDict]]
    r"""Numeric quantity of the order. For Equities: Represents the number of shares, must be greater than zero and may not exceed 5 decimal places. For Mutual Funds: Only supported for SELL orders. Represents the number of shares, up to a maximum of 3 decimal places. For Fixed Income: Represents the par (face-value) amount being ordered, and may not exceed two decimal places for USD-based currencies. Either a quantity or notional_value MUST be specified (but not both)."""
    rights_of_accumulation: NotRequired[Nullable[RightsOfAccumulationTypedDict]]
    r"""Rights of Accumulation (ROA). An ROA allows an investor to aggregate their own fund shares with the holdings of certain related parties toward achieving the investment thresholds at which sales charge discounts become available."""
    side: NotRequired[OrderSide]
    r"""The side of this order."""
    special_reporting_instructions: NotRequired[List[OrderSpecialReportingInstructions]]
    r"""Special Reporting Instructions to be applied to this order. Can include multiple Instructions."""
    stop_price: NotRequired[Nullable[StopPriceTypedDict]]
    r"""The stop price for this order. Only allowed for equities, when the side is SELL."""
    time_in_force: NotRequired[OrderTimeInForce]
    r"""Must be the value \"DAY\". Regulatory requirements dictate that the system capture the intended time_in_force, which is why this a mandatory field."""


class Order(BaseModel):
    r"""The message describing an order"""

    account_id: Optional[str] = None
    r"""The identifier of the account transacting this order"""

    asset_id: Optional[str] = None
    r"""Apex Asset ID for this asset. This will not be returned in the initial CreateOrder response and will be available after an order completes validation. If the provided identifier does not match any Apex asset available for trading, an OrderRejectReason of \"UNKNOWN_SECURITY\" will be returned and the asset_id will not be set."""

    asset_type: Annotated[
        Optional[OrderAssetType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The type of the asset in this order"""

    average_prices: Optional[List[ExecutedPrice]] = None
    r"""The average prices, as weighted averages, across all executions in this order. Will be absent if an order has no executions.

    When asset_type = EQUITY or MUTUAL_FUND, there will be at most one value present, with a type of PRICE_PER_UNIT. This will have up to 4 decimal places for USD amounts less than $1, and a maximum of two for larger USD amounts.

    When asset_type = FIXED_INCOME, there may be more than one value present which would have a type other than PRICE_PER_UNIT. Price values in PERCENTAGE_OF_PAR will have up to 4 decimal places of precision, and price values measured in yields will support up to 5 decimal places.
    """

    broker_capacity: Annotated[
        Optional[OrderBrokerCapacity], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Defaults to \"AGENCY\" if not specified. For Equities: Only \"AGENCY\" is allowed. For Mutual Funds: Only \"AGENCY\" is allowed. For Fixed Income: Either \"AGENCY\" or \"PRINCIPAL\" are allowed."""

    cancel_reason: Optional[str] = None
    r"""Used to explain why an order is canceled"""

    cancel_rejected_reason: Annotated[
        Optional[CancelRejectedReason], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Used to denote when a cancel request has been rejected."""

    client_order_id: Optional[str] = None
    r"""User-supplied unique order ID. Cannot be more than 40 characters long."""

    client_received_time: OptionalNullable[datetime] = UNSET
    r"""Required for Equity Orders for any client who is having Apex do CAT reporting on their behalf. A value may be provided for non-Equity orders, and will be remembered, but valid timestamps will have no impact on how they are processed."""

    commission: OptionalNullable[OrderCommission] = UNSET
    r"""A custom commission to be applied to this order. When specifying an AMOUNT type, the value represents a notional amount measured in the currency of the order."""

    create_time: OptionalNullable[datetime] = UNSET
    r"""Time of the order creation"""

    cumulative_notional_value: OptionalNullable[CumulativeNotionalValue] = UNSET
    r"""The sum of order quantity & price, across all fills, reported in the currency specified in the order. (This will be rounded to 2 decimal places for USD currencies). Will be absent if an order has no fill information."""

    currency_code: Optional[str] = None
    r"""Defaults to \"USD\". Only \"USD\" is supported. Full list of currency codes is defined at: https://en.wikipedia.org/wiki/ISO_4217"""

    executions: Optional[List[Executions]] = None
    r"""The execution-level details that compose this order"""

    fees: Optional[List[Fee]] = None
    r"""Fees that will be applied to this order."""

    filled_quantity: OptionalNullable[FilledQuantity] = UNSET
    r"""The summed quantity value across all fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no fill information."""

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

    identifier_type: Optional[OrderIdentifierType] = None
    r"""The identifier type of the asset being ordered. For Equities: only SYMBOL is supported For Mutual Funds: only SYMBOL and CUSIP are supported For Fixed Income: only CUSIP and ISIN are supported"""

    last_update_time: OptionalNullable[datetime] = UNSET
    r"""Time of the last order update"""

    letter_of_intent: OptionalNullable[LetterOfIntent] = UNSET
    r"""Letter of Intent (LOI). An LOI allows investors to receive sales charge discounts based on a commitment to buy a specified monetary amount of shares over a period of time, usually 13 months."""

    limit_price: OptionalNullable[LimitPrice] = UNSET
    r"""The limit price for this order."""

    max_sell_quantity: OptionalNullable[MaxSellQuantity] = UNSET
    r"""The maximum number of shares to be sold if this is a notional SELL order of an Equity asset type. (Prohibited for other side or asset_type inputs.)

    This will only be recognized for clients configured not to use OMS checks. When specified, must be greater than 0 and can't exceed 5 decimal places.
    """

    name: Optional[str] = None
    r"""System generated name of the order."""

    notional_value: OptionalNullable[NotionalValue] = UNSET
    r"""Notional quantity of the order, measured in USD. Maximum 2 decimal place precision. For Equities: This represents the maximum amount to be spent. The final order may may have a smaller notional amount. For Mutual Funds: Only supported for BUY orders. The order will be transacted at the full notional amount specified. For Fixed Income: Not supported, you must specify a `quantity` value."""

    order_date: OptionalNullable[OrderDate] = UNSET
    r"""The date on which the order will go to the market: must either be \"today\" or the next valid trading day. If the current day is not a valid trading day, then the next valid market day must be specified. If the current time is within 5 minutes prior to market close, the next valid market day may be specified. If the current time is after market close, and before midnight Eastern, then the next valid market day must be specified. In all other cases, the current day, Eastern must be specified."""

    order_id: Optional[str] = None
    r"""System generated unique id for the order."""

    order_rejected_reason: Annotated[
        Optional[OrderRejectedReason], PlainValidator(validate_open_enum(False))
    ] = None
    r"""When an order has the REJECTED status, this will be populated with a system code describing the rejection."""

    order_status: Annotated[
        Optional[OrderStatus], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The processing status of the order"""

    order_type: Annotated[
        Optional[OrderOrderType], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The execution type of this order. For Equities: MARKET, LIMIT, or STOP are supported. For Mutual Funds: only MARKET is supported. For Fixed Income: only LIMIT is supported."""

    prevailing_market_price: OptionalNullable[OrderPrevailingMarketPrice] = UNSET
    r"""The prevailing market price, calculated as a weighted average of the fills in this order, up to a maximum of 5 decimal places. Will be absent if an order has no executions."""

    quantity: OptionalNullable[OrderQuantity] = UNSET
    r"""Numeric quantity of the order. For Equities: Represents the number of shares, must be greater than zero and may not exceed 5 decimal places. For Mutual Funds: Only supported for SELL orders. Represents the number of shares, up to a maximum of 3 decimal places. For Fixed Income: Represents the par (face-value) amount being ordered, and may not exceed two decimal places for USD-based currencies. Either a quantity or notional_value MUST be specified (but not both)."""

    rights_of_accumulation: OptionalNullable[RightsOfAccumulation] = UNSET
    r"""Rights of Accumulation (ROA). An ROA allows an investor to aggregate their own fund shares with the holdings of certain related parties toward achieving the investment thresholds at which sales charge discounts become available."""

    side: Annotated[
        Optional[OrderSide], PlainValidator(validate_open_enum(False))
    ] = None
    r"""The side of this order."""

    special_reporting_instructions: Optional[
        List[
            Annotated[
                OrderSpecialReportingInstructions,
                PlainValidator(validate_open_enum(False)),
            ]
        ]
    ] = None
    r"""Special Reporting Instructions to be applied to this order. Can include multiple Instructions."""

    stop_price: OptionalNullable[StopPrice] = UNSET
    r"""The stop price for this order. Only allowed for equities, when the side is SELL."""

    time_in_force: Annotated[
        Optional[OrderTimeInForce], PlainValidator(validate_open_enum(False))
    ] = None
    r"""Must be the value \"DAY\". Regulatory requirements dictate that the system capture the intended time_in_force, which is why this a mandatory field."""

    @model_serializer(mode="wrap")
    def serialize_model(self, handler):
        optional_fields = [
            "account_id",
            "asset_id",
            "asset_type",
            "average_prices",
            "broker_capacity",
            "cancel_reason",
            "cancel_rejected_reason",
            "client_order_id",
            "client_received_time",
            "commission",
            "create_time",
            "cumulative_notional_value",
            "currency_code",
            "executions",
            "fees",
            "filled_quantity",
            "identifier",
            "identifier_type",
            "last_update_time",
            "letter_of_intent",
            "limit_price",
            "max_sell_quantity",
            "name",
            "notional_value",
            "order_date",
            "order_id",
            "order_rejected_reason",
            "order_status",
            "order_type",
            "prevailing_market_price",
            "quantity",
            "rights_of_accumulation",
            "side",
            "special_reporting_instructions",
            "stop_price",
            "time_in_force",
        ]
        nullable_fields = [
            "client_received_time",
            "commission",
            "create_time",
            "cumulative_notional_value",
            "filled_quantity",
            "last_update_time",
            "letter_of_intent",
            "limit_price",
            "max_sell_quantity",
            "notional_value",
            "order_date",
            "prevailing_market_price",
            "quantity",
            "rights_of_accumulation",
            "stop_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
