# generated by datamodel-codegen:
#   filename:  https://static.tradingview.com/static/bundles/broker-rest-api.be05513c026d4c75f324.yaml
#   timestamp: 2025-01-06T17:40:49+00:00

from __future__ import annotations

from enum import Enum
from typing import Any, List, Optional, Union

from pydantic import BaseModel, ConfigDict, Field, RootModel, confloat


class AccessToken(BaseModel):
    """
    Access token.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    access_token: str = Field(
        ...,
        description=(
            "Access token acts as a session ID that the application uses for"
            " making\nrequests. This token should be protected as if it were"
            " user\ncredentials.\n"
        ),
        examples=["7133au-cba5a72-842029c"],
    )
    expiration: float = Field(
        ...,
        description=(
            "The time when the token is expired is represented as the number"
            " of\nseconds since the Unix epoch (00:00:00 UTC on 1 January 1970).\n"
        ),
        examples=[1548661401],
    )


class Type(Enum):
    """
    Account type
    """

    live = "live"
    demo = "demo"


class AccountFlags(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    supportBrackets: Optional[bool] = Field(
        None,
        description=(
            "Whether the integration supports brackets. Deprecated. Use"
            " supportOrderBrackets and supportPositionBrackets instead."
        ),
    )
    supportOrderBrackets: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports brackets (take profit and stop loss) for"
            " orders."
        ),
    )
    supportAddBracketsToExistingOrder: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports adding brackets to an already placed"
            " order"
        ),
    )
    supportMarketBrackets: Optional[bool] = Field(
        True, description="Whether the integration supports brackets for market orders."
    )
    supportPositionBrackets: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports adding (or modifying) stop loss and take"
            " profit to positions."
        ),
    )
    supportPositions: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports the Positions tab. If you set it to"
            " `false`, the `/positions` endpoint will not be used."
        ),
    )
    supportMultiposition: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports multiple positions at one instrument at"
            " the same time."
        ),
    )
    supportClosePosition: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports closing of a position without a need for"
            " a user to fill an order."
        ),
    )
    supportPartialClosePosition: Optional[bool] = Field(
        False,
        description="Whether the integration supports partial closing of a position.",
    )
    supportReversePosition: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports reversing of a position. If this flag is"
            " set to `false` the reverse position button will be hidden."
        ),
    )
    supportNativeReversePosition: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration natively supports reversing of a position. If it"
            " is natively supported then TradingView will send a request to the [Modify"
            " Position endpoint](#operation/modifyPosition) with the `side` parameter"
            " set. If it is not natively supported then a reversing order will be"
            " placed."
        ),
    )
    supportMarketOrders: Optional[bool] = Field(
        True, description="Whether the integration supports market orders."
    )
    supportLimitOrders: Optional[bool] = Field(
        True, description="Whether the integration supports limit orders."
    )
    supportStopOrders: Optional[bool] = Field(
        True, description="Whether the integration supports stop orders."
    )
    supportStopLimitOrders: Optional[bool] = Field(
        False, description="Whether the integration supports StopLimit orders."
    )
    supportStopLoss: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports stop loss orders. If this flag is set to"
            " `false`, the `supportTrailingStop` and / or `supportGuaranteedStop` flag"
            " should be set to `true`. If the `supportStopLoss`, `supportTrailingStop`"
            " and `supportGuaranteedStop` flags are set to `false`, the default value"
            " will be used."
        ),
    )
    supportTrailingStop: Optional[bool] = Field(
        False, description="Whether the integration supports trailing stop orders."
    )
    supportGuaranteedStop: Optional[bool] = Field(
        False, description="Whether the integration supports guaranteed stop orders."
    )
    supportStopOrdersInBothDirections: Optional[bool] = Field(
        False,
        description=(
            "Whether Stop orders should behave like Market-if-touched in both"
            " directions. Enabling this flag removes the direction check from the order"
            " dialog."
        ),
    )
    supportStopLimitOrdersInBothDirections: Optional[bool] = Field(
        False,
        description=(
            "Whether StopLimit orders should behave like Limit-if-touched in both"
            " directions. Enabling this flag removes the direction check from the order"
            " dialog."
        ),
    )
    supportPartialOrderExecution: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports partial order's execution. If this flag"
            " is set to `true`, then the 'Filled Qty' column will be displayed on the"
            " Orders tab."
        ),
    )
    supportModifyOrder: Optional[bool] = Field(
        None,
        description=(
            "Whether the integration supports the modification of the existing order."
            " Deprecated. Use supportModifyOrderPrice, supportEditAmount and"
            " supportModifyBrackets instead."
        ),
    )
    supportModifyOrderPrice: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports order price editing. If you set it to"
            " `false`, the price control in the order ticket will be disabled when"
            " modifying an order."
        ),
    )
    supportEditAmount: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports editing orders quantity. If you set it to"
            " `false`, the quantity control in the order ticket will be disabled when"
            " modifying an order."
        ),
    )
    supportModifyBrackets: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports order brackets editing. If you set it to"
            " `false`, the bracket's control in the order ticket will be disabled when"
            " modifying an order, and 'Modify' button will be hidden on a chart and in"
            " the Account Manager."
        ),
    )
    supportModifyDuration: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports the modification of the duration of the"
            " existing order."
        ),
    )
    supportCryptoExchangeOrderTicket: Optional[bool] = Field(
        False,
        description=(
            "Whether the account is used to exchange(trade) crypto currencies. This"
            " flag switches the Order Ticket to the Crypto Exchange mode. It adds"
            " second currency quantity control, currency labels etc."
        ),
    )
    supportDigitalSignature: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports Digital signature input field in the"
            " Order Ticket."
        ),
    )
    supportPlaceOrderPreview: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports providing and displaying information"
            " (such as commission, margin, value, etc.) about the order being placed"
            " before submitting it."
        ),
    )
    supportModifyOrderPreview: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports providing and displaying information"
            " (such as commission, margin, value, etc.) about the order being modified"
            " before submitting it."
        ),
    )
    showQuantityInsteadOfAmount: Optional[bool] = Field(
        False, description="Renames Amount to Quantity in the Order Ticket."
    )
    supportBalances: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports"
            " [/balances](/rest-api-spec/#operation/getBalances) request."
        ),
    )
    supportOrdersHistory: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports"
            " [/ordersHistory](/rest-api-spec/#operation/getOrdersHistory) request."
        ),
    )
    supportLeverage: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports leverage. If the flag is set to `true`,"
            " broker will calculate leverage using"
            " [/getLeverage](/rest-api-spec/#operation/getLeverage) endpoint."
        ),
    )
    supportLeverageButton: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports leverage button. If the flag is set to"
            " `true`, a leverage input field will appear in the Order Widget. Click on"
            " the input field will activate a dedicated Leverage Dialog. Please note,"
            " that the flag `supportLeverage` should be enabled for the button to"
            " display."
        ),
    )
    supportDOM: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports DOM (Depth of market) widget to be"
            " available."
        ),
    )
    supportLevel2Data: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports Level 2 data. It is required to display"
            " DOM levels. You must implement"
            " [/depth](/rest-api-spec/#operation/getDepth) endpoint to display DOM."
        ),
    )
    supportPLUpdate: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration provide `unrealizedPl` for positions. Otherwise"
            " P&L will be calculated automatically based on a simple algorithm."
        ),
    )
    supportDisplayBrokerNameInSymbolSearch: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration involves displaying broker instrument names in the"
            " Symbol Search. You may usually want to disable it if broker symbols are"
            " the same or you are using internal numbers as broker symbol names."
        ),
    )
    supportLogout: Optional[bool] = Field(
        False, description="Whether the integration supports logout."
    )
    supportCustomAccountSummaryRow: Optional[bool] = Field(
        False,
        description="Whether the integration supports custom Account Summary Row.",
    )
    supportPositionCustomFields: Optional[bool] = Field(
        False,
        description="Whether the integration supports custom fields for position.",
    )
    supportOrderCustomFields: Optional[bool] = Field(
        False, description="Whether the integration supports custom fields for order."
    )
    supportOrderHistoryCustomFields: Optional[bool] = Field(
        False,
        description="Whether the integration supports custom fields for order history.",
    )
    supportTrackLatency: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports latency tracking. See the"
            " [/trackLatency](#operation/trackLatency) endpoint."
        ),
    )
    supportPositionNetting: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports individual and net positions.\nInstead of"
            " requesting positions from the [/positions](#operation/getPositions)"
            " endpoint, the client will request individual and net positions"
            " separately.\n'Positions' tab in the Account Manager will be divided into"
            " two subcategories: 'Individual Positions' and 'Net Positions'.\n\nEnables"
            " the [/individualPositions](#operation/getIndividualPositions) and"
            " [/netPositions](#operation/getNetPositions) endpoints\nas well as"
            " [/modifyIndividualPosition](#operation/modifyIndividualPosition),"
            " [/closeIndividualPosition](#operation/closeIndividualPosition),"
            " [/closeNetPosition](#operation/closeNetPosition).\n\nDisables the"
            " [/positions](#operation/getPositions),"
            " [/modifyPosition](#operation/modifyPosition) and"
            " [/closePosition](#operation/closePosition) endpoints.\n"
        ),
    )
    supportIndividualPositionBrackets: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports adding (or modifying) stop loss and take"
            " profit to individual positions."
        ),
    )
    supportCloseIndividualPosition: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports closing of an individual position."
        ),
    )
    supportPartialCloseIndividualPosition: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports partial closing of an individual"
            " position."
        ),
    )
    supportStrictCheckingLimitOrderPrice: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports limit price validation in the order"
            " ticket to eliminate the possibility to place an order on the wrong side"
            " of the market that will most likely trigger and get filled immediately."
        ),
    )
    supportRiskControlsAndInfo: Optional[bool] = Field(
        True,
        description=(
            "Whether the integration supports risk controls.\nIf the flag is set to"
            " true, risk controls will appear in Order Ticket when they are"
            " applicable.\nRisk control related information, such as trade value, will"
            " be shown in Order Ticket and on the Chart.\n"
        ),
    )
    supportCustomOrderInfo: Optional[bool] = Field(
        False,
        description=(
            "Whether the integration supports displaying custom data in the Order Info"
            " section. If the flag is set to `true`, the Order Ticket retrieves"
            " additional order data displayed in the Order Ticket. Enables the"
            " [/orderInfo](#operation/orderInfo) endpoint."
        ),
    )


class Alignment(Enum):
    """
    The cell value alignment. Default value is `left`
    """

    left = "left"
    right = "right"


class AccountManagerColumn(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., examples=["balance"])
    title: str = Field(
        ..., description="Localized title of a column.", examples=["Balance"]
    )
    tooltip: Optional[str] = Field(
        None,
        description="Tooltip that is shown on mouse hover.",
        examples=["Balance column"],
    )
    alignment: Optional[Alignment] = Field(
        "left",
        description="The cell value alignment. Default value is `left`",
        examples=["right"],
    )
    isCapitalize: Optional[bool] = Field(
        True,
        description=(
            "The first character of each word in the sentence will be capitalized. The"
            " rest of the symbols appearance does not change."
        ),
    )


class AccountManagerTable(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., examples=["accountSummary"])
    title: Optional[str] = Field(
        None, description="Localized title of a table.", examples=["Account Summary"]
    )
    columns: List[AccountManagerColumn] = Field(..., min_length=1)


class UserInfo(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    userId: str = Field(
        ...,
        description="Unique identifier for the user.",
        examples=["1466320d-7bdb-479f-aa26-fa1b99c8b2a6"],
    )
    promotionId: Optional[str] = Field(
        None,
        description=(
            "Identifier for a promotion linked to the user account. Prior coordination"
            " with the TradingView team is required to use this field."
        ),
    )


class AccountState(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    balance: float = Field(..., description="Account Balance.")
    unrealizedPl: float = Field(..., description="Unrealized profit/loss.")
    equity: Optional[float] = Field(
        None,
        description=(
            "Equity. If this field is not specified, then it is calculated as balance +"
            " unrealizedPl."
        ),
    )
    amData: Optional[List[List[List[str]]]] = Field(
        None,
        description=(
            "Account manager data. Structure of Account manager is defined by"
            " the\n[/config](#operation/getConfiguration) endpoint. Each element of"
            " this array is a table.\n"
        ),
        min_length=1,
    )
    accountSummaryRowData: Optional[List[str]] = Field(
        None,
        description=(
            "Account Summary Row data. Structure of Account Summary Row is defined by"
            " the\n[/config](#operation/getConfiguration) endpoint.\n"
        ),
        min_length=1,
    )
    marginAvailable: Optional[float] = Field(
        None, description="Current available margin for account."
    )


class AccountStateMessage(RootModel[AccountState]):
    root: AccountState = Field(..., title="AccountStateMessage")


class AccountSummaryRowItem(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., description="Unique Account Summary Row item identifier.")
    title: str = Field(..., description="Localized Account Summary Row item title.")


class BarsArrays(BaseModel):
    """
    Bars data.
    """

    t: List[float] = Field(
        ...,
        description=(
            "Bar time, Unix timestamp (UTC). Daily bars should only have the"
            " date\npart, time should be 0.\n"
        ),
        examples=[[1547942400, 1547942460, 1547942520]],
    )
    o: List[float] = Field(
        ..., description="Open price.", examples=[[3667, 3662.25, 3664.29]]
    )
    h: List[float] = Field(
        ..., description="High price.", examples=[[3667.24, 3664.47, 3664.3]]
    )
    l: List[float] = Field(
        ..., description="Low price.", examples=[[3661.55, 3661.9, 3662.43]]
    )
    c: List[float] = Field(
        ..., description="Close price.", examples=[[3662.25, 3663.13, 3664.01]]
    )
    v: List[float] = Field(
        ..., description="Volume.", examples=[[34.7336, 2.4413, 11.7075]]
    )


class CheckBoxMetainfo(BaseModel):
    id: str = Field(
        ..., description="Unique field identifier.", examples=["customInputFieldId"]
    )
    title: str = Field(
        ...,
        description="Localized checkbox display name.",
        examples=["Additional parameter"],
    )
    saveToSettings: Optional[bool] = Field(
        False,
        description=(
            "Whether the value should be stored in the user settings and preserved for"
            " the next time the dialog is displayed."
        ),
        examples=[True],
    )
    help: Optional[str] = Field(
        None,
        description="Help text displayed when hovering over the checkbox.",
        examples=["Brief help text"],
    )
    checked: Optional[bool] = Field(
        False, description="Initial checkbox value.", examples=[False]
    )
    mutable: Optional[bool] = Field(
        True,
        description="Whether this field can be changed during the order modification.",
        examples=[False],
    )


class TextFieldMetaInfo(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(
        ..., description="Unique field identifier.", examples=["customInputFieldId"]
    )
    title: str = Field(
        ...,
        description="Localized field display name for text input.",
        examples=["Additional parameters"],
    )
    saveToSettings: Optional[bool] = Field(
        False,
        description=(
            "Whether the value should be stored in the user settings and preserved for"
            " the next time the dialog is displayed."
        ),
        examples=[True],
    )
    mutable: Optional[bool] = Field(
        True,
        description="Whether this field can be changed during the order modification.",
        examples=[False],
    )
    forceUserEnterInitialValue: Optional[bool] = Field(
        False,
        description=(
            "If this flag is set to true, the user will not be able to place an order"
            " without explicitly entering a value, so instant order placement is not"
            " available."
        ),
        examples=[True],
    )
    placeholder: Optional[str] = Field(
        None, description="Localized placeholder for the field."
    )
    maskWithAsterisk: Optional[bool] = Field(
        False,
        description=(
            "If the value is set to true, the entered text will be masked with dots."
        ),
    )


class ComboBoxValue(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    text: str = Field(..., description="Localized display name.", examples=["text"])
    value: str = Field(
        ...,
        description="Value that is sent back to the server if the item is selected.",
        examples=["value"],
    )


class ConfirmId(RootModel[str]):
    root: str = Field(
        ...,
        description=(
            "An optional order identifier, which was received in the"
            " [/previewOrder](#operation/previewOrder) response."
        ),
        examples=["112358"],
    )


class CryptoBalance(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    symbol: str = Field(..., description="Crypto currency symbol.", examples=["BTC"])
    longName: Optional[str] = Field(
        None, description="Crypto currency name.", examples=["Bitcoin"]
    )
    total: float = Field(
        ..., description="Total amount of the balance.", examples=[1000]
    )
    available: float = Field(
        ..., description="The balance available to the user.", examples=[10]
    )
    reserved: Optional[float] = Field(
        None,
        description=(
            "Reserved balance amount that can't be used at the moment for any reasons."
        ),
        examples=[90],
    )
    btcValue: Optional[float] = Field(
        None, description="Total balance amount in BTC.", examples=[1000]
    )
    value: Optional[float] = Field(
        None, description="Balance amount in additional currency.", examples=[100000]
    )
    valueCurrency: Optional[str] = Field(
        None,
        description="Currency of the value. It can be either code, or symbol.",
        examples=["USD"],
    )


class CustomFieldsValueItem(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(
        ...,
        description=(
            "Column identifier as defined in [/config](#operation/getConfiguration)"
            " response."
        ),
    )
    value: str = Field(..., description="Localized column value")


class SupportedOrderType(Enum):
    market = "market"
    stop = "stop"
    limit = "limit"
    stoplimit = "stoplimit"


class Duration(BaseModel):
    """
    Single duration option.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., description="Duration identifier.", examples=["GTT"])
    title: str = Field(..., description="Localized title.", examples=["Good Till Time"])
    hasDatePicker: Optional[bool] = Field(
        False,
        description="Display date control in Order Ticket for this duration type.",
        examples=[True],
    )
    hasTimePicker: Optional[bool] = Field(
        False,
        description="Display time control in Order Ticket for this duration type.",
        examples=[True],
    )
    default: Optional[bool] = Field(
        False,
        description=(
            "Default duration. Only one duration object in the durations array can have"
            " a `true` value for this field. The default duration will be used when the"
            " user places orders in the silent mode and it will be the selected one"
            " when the user opens the Order dialog for the first time."
        ),
        examples=[True],
    )
    supportedOrderTypes: Optional[List[SupportedOrderType]] = Field(
        ["limit", "stop", "stoplimit"],
        description=(
            "An optional array of order types to which the duration will be applied."
        ),
        examples=[["stop", "stoplimit"]],
        min_length=1,
    )


class EmptyBarArrays(BaseModel):
    """
    Empty Bars data.
    """

    t: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )
    o: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )
    h: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )
    l: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )
    c: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )
    v: Optional[List[float]] = Field(
        None, description="Empty array", examples=[[]], max_length=0
    )


class Side(Enum):
    """
    Side.
    """

    buy = "buy"
    sell = "sell"


class Execution(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., description="Unique identifier.", examples=["EX34567"])
    instrument: str = Field(..., description="Instrument id.", examples=["EURUSD"])
    price: float = Field(..., description="Execution price.", examples=[1.23564])
    time: float = Field(
        ..., description="Execution time, Unix timestamp (UTC).", examples=[1548406235]
    )
    qty: float = Field(..., description="Execution quantity.", examples=[1])
    side: Side = Field(..., description="Side.", examples=["buy"])
    orderId: str = Field(
        ...,
        description="Identifier of the order that has been filled.",
        examples=["1263159154"],
    )
    isClose: bool = Field(
        ..., description="Whether the execution reduces the position.", examples=[False]
    )
    positionId: Optional[str] = Field(
        None,
        description=(
            "Identifier of the position that has been opened, modified or closed."
        ),
        examples=["10098"],
    )
    commission: Optional[float] = Field(
        None, description="Commission charged for the fill.", examples=[0.004]
    )


class GetLeverage(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    title: str = Field(..., description="Title for leverage adjustment popup.")
    leverage: float = Field(..., description="Current leverage value.")
    min: float = Field(..., description="Minimum leverage value.")
    max: float = Field(..., description="Maximum leverage value.")
    step: float = Field(..., description="Leverage value change step.")


class Group(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(
        ...,
        description=(
            "All characters in a group id must be either a lowercase alphabetic"
            " character, a number, or an underscore.\nA group id should start with the"
            " same prefix related to the broker's name.\n"
        ),
    )


class GroupList(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    groups: Optional[List[Group]] = Field(
        None, description="Each element of this array is an group object.\n"
    )


class Id(Enum):
    limitPercent = "limitPercent"


class Options(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    min: float = Field(
        ...,
        description=(
            "Minimal value in percentage of the limit price relative to the current"
            " price."
        ),
        examples=[10],
    )
    max: float = Field(
        ...,
        description=(
            "Maximum value in percentage of the limit price relative to the current"
            " price."
        ),
        examples=[20],
    )


class LimitPercentValidationRule(BaseModel):
    """
    Limit Percent Price Range Rule applied to the order price field validation in the Order dialog.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: Id
    options: Options


class Locale(Enum):
    """
    Locale (language) id. This parameter is required for trading integration only.
    """

    ar_AE = "ar_AE"
    br = "br"
    cs = "cs"
    de_DE = "de_DE"
    el = "el"
    en = "en"
    es = "es"
    fr = "fr"
    he_IL = "he_IL"
    hu_HU = "hu_HU"
    id = "id"
    in_ = "in"
    it = "it"
    ja = "ja"
    kr = "kr"
    ms_MY = "ms_MY"
    nl_NL = "nl_NL"
    pl = "pl"
    ro = "ro"
    ru = "ru"
    th_TH = "th_TH"
    tr = "tr"
    uk = "uk"
    vi_VN = "vi_VN"
    zh_CN = "zh_CN"
    zh_TW = "zh_TW"


class Type1(Enum):
    """
    Message type
    """

    information = "information"
    warning = "warning"
    error = "error"


class OrderInformationalMessage(BaseModel):
    """
    Informational message description, that will be displayed for the order in the Account manager. The message will be marked
    with a color, corresponding to a message type.
    The text message will also be displayed in the notification pop-up in case the order status gets changed.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    text: str = Field(
        ...,
        description="Message text",
        examples=["This order has been rejected due to the closed market"],
    )
    type: Type1 = Field(..., description="Message type", examples=["Information"])


class PositionInformationalMessage(BaseModel):
    """
    Informational message description, that will be displayed for the position in the Account manager. The message will be marked
    with a color, corresponding to a message type.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    text: str = Field(
        ...,
        description="Message text",
        examples=["You can add brackets to this position to protect it"],
    )
    type: Type1 = Field(..., description="Message type", examples=["Information"])


class OkStatus(Enum):
    """
    Status will always be `ok`.
    """

    ok = "ok"


class Type3(Enum):
    """
    Type.
    """

    market = "market"
    stop = "stop"
    limit = "limit"
    stoplimit = "stoplimit"


class ParentType(Enum):
    """
    Type of order's parent. Should be set only for bracket orders.
    """

    order = "order"
    position = "position"


class Duration1(BaseModel):
    """
    Expiration type and Unix timestamp date/time.
    """

    type: str = Field(
        ...,
        description=(
            "Duration ID. Internal ID that you set in"
            " [/config](#operation/getConfiguration) response."
        ),
    )
    datetime: Optional[float] = Field(None, description="Unix timestamp (UTC).")


class OrderCommon(BaseModel):
    id: str = Field(..., description="Unique identifier.")
    instrument: str = Field(
        ..., description="Instrument name that is used on a broker's side."
    )
    qty: float = Field(..., description="Quantity.")
    side: Side = Field(..., description="Side.")
    type: Type3 = Field(..., description="Type.")
    filledQty: Optional[float] = Field(None, description="Filled quantity.")
    avgPrice: Optional[float] = Field(
        None,
        description=(
            "Average price of order fills. It should be provided for filled / partly"
            " filled orders.\n"
        ),
    )
    limitPrice: Optional[float] = Field(
        None,
        description=(
            "Limit Price for Limit or StopLimit orders only. You should not send this"
            " field for other order types."
        ),
    )
    stopPrice: Optional[float] = Field(
        None,
        description=(
            "Stop Price for Stop or StopLimit orders only. You should not send this"
            " field for other order types."
        ),
    )
    trailingStopPips: Optional[float] = Field(
        None,
        description=(
            "Distance from the stop loss level to the current market price in pips for"
            " a position or to the order price if the parent is a stop or limit order."
        ),
    )
    isTrailingStop: Optional[bool] = Field(
        None,
        description=(
            "If this flag is set to `true`, then the stop order is a trailing stop."
        ),
    )
    isGuaranteedStop: Optional[bool] = Field(
        None,
        description=(
            "If this flag is set to `true`, then the stop order is a guaranteed stop."
        ),
    )
    parentId: Optional[str] = Field(
        None,
        description=(
            "Identifier of a parent order or a parent position (for position brackets)"
            " depending on `parentType`.\nShould be set only for bracket orders.\n"
        ),
    )
    parentType: Optional[ParentType] = Field(
        None,
        description="Type of order's parent. Should be set only for bracket orders.",
    )
    duration: Optional[Duration1] = Field(
        None, description="Expiration type and Unix timestamp date/time."
    )
    lastModified: Optional[float] = Field(
        None,
        description=(
            "Indicates the time when the order was last modified, Unix timestamp (UTC)."
        ),
    )
    customFields: Optional[List[CustomFieldsValueItem]] = Field(
        None,
        description=(
            "Localized order custom fields values data.\nCustom fields are configured"
            " in the [/config](#operation/getConfiguration) endpoint response.\nCustom"
            " `Order dialog` fields are to be sent along with the standard fields in"
            " the order object.\n"
        ),
        min_length=1,
    )
    message: Optional[OrderInformationalMessage] = None


class Status(Enum):
    """
    String constants to describe a final order status.

    `Status`  | Description
    ----------|-------------
    rejected  | order is rejected for some reason
    filled    | order is fully executed
    cancelled  | order is cancelled

    """

    rejected = "rejected"
    filled = "filled"
    cancelled = "cancelled"


class OrderHistoryStatus(BaseModel):
    status: Status = Field(
        ...,
        description=(
            "String constants to describe a final order status.\n\n`Status`  |"
            " Description\n----------|-------------\nrejected  | order is rejected for"
            " some reason\nfilled    | order is fully executed\ncancelled  | order is"
            " cancelled\n"
        ),
    )


class OrderPreviewSectionRow(BaseModel):
    """
    Describes a single row of a section table of the order preview.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    title: str = Field(..., description="Description of the item.")
    value: str = Field(..., description="Formatted value of the item.")


class OrderInfoRow(BaseModel):
    """
    Defines a single row in the table displayed within the Order Info section of the Order Ticket, providing additional details about the order.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    title: str = Field(..., description="Title of the row.")
    value: Optional[str] = Field(None, description="Value to display.")
    currency: Optional[Any] = Field(
        None, description="Currency code for value.", examples=["USD"]
    )


class Type4(Enum):
    """
    Indicates that it is a separator.
    """

    separator = "separator"


class OrderInfoDivider(BaseModel):
    """
    Defines a separator in the table displayed within the Order Info section of the Order Ticket.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    type: Type4 = Field(..., description="Indicates that it is a separator.")


class Hyperlink(BaseModel):
    """
    Describes a hyperlink that will be shown in UI.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    text: str = Field(..., description="The text that will be showed to user.")
    url: str = Field(
        ..., description="The url address to which the link should direct to."
    )


class Status1(Enum):
    """
    String constants to describe an order status.

    `Status`  | Description
    ----------|-------------
    placing   | order is not created on a broker's side yet
    inactive  | bracket order is created but waiting for a base order to be filled
    working   | order is created but not fully executed yet
    rejected  | order is rejected for some reason
    filled    | order is fully executed
    cancelled  | order is cancelled

    """

    placing = "placing"
    inactive = "inactive"
    working = "working"
    rejected = "rejected"
    filled = "filled"
    cancelled = "cancelled"


class OrderStatus(BaseModel):
    status: Status1 = Field(
        ...,
        description=(
            "String constants to describe an order status.\n\n`Status`  |"
            " Description\n----------|-------------\nplacing   | order is not created"
            " on a broker's side yet\ninactive  | bracket order is created but waiting"
            " for a base order to be filled\nworking   | order is created but not fully"
            " executed yet\nrejected  | order is rejected for some reason\nfilled    |"
            " order is fully executed\ncancelled  | order is cancelled\n"
        ),
    )


class PermissionGroups(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    groups: List[str] = Field(
        ...,
        description="Groups list. Each element of this array is a group identifier.",
    )


class PermissionsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: PermissionGroups


class PlaceModifyPreviewOrderCommon(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    qty: Optional[float] = Field(None, description="The number of units.", examples=[1])
    limitPrice: Optional[float] = Field(
        None,
        description="Limit Price for Limit or StopLimit order.",
        examples=[1.23456],
    )
    stopPrice: Optional[float] = Field(
        None, description="Stop Price for Stop or StopLimit order."
    )
    durationType: Optional[str] = Field(
        None, description="Duration ID (if supported).", examples=["gtt"]
    )
    durationDateTime: Optional[float] = Field(
        None,
        description=(
            "Expiration datetime Unix timestamp (if supported by duration type)."
        ),
        examples=[1548406235],
    )
    stopLoss: Optional[float] = Field(
        None, description="StopLoss price (if supported)."
    )
    trailingStopPips: Optional[float] = Field(
        None,
        description=(
            "Distance from the stop loss level to the current market price in pips (if"
            " supported by the broker)."
        ),
    )
    guaranteedStop: Optional[float] = Field(
        None, description="Stop price of Guaranteed Stop bracket (if supported)."
    )
    takeProfit: Optional[float] = Field(
        None, description="TakeProfit price (if supported)."
    )
    digitalSignature: Optional[str] = Field(
        None, description="Digital signature (if supported).", examples=[954345868]
    )
    currentAsk: Optional[float] = Field(
        None,
        description=(
            "Current ask price for the instrument that the user sees in the order"
            " panel."
        ),
        examples=[1.25],
    )
    currentBid: Optional[float] = Field(
        None,
        description=(
            "Current bid price for the instrument that the user sees in the order"
            " panel."
        ),
        examples=[1.23],
    )


class PlacePreviewOrderCommon(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    instrument: Optional[str] = Field(
        None, description="Instrument.", examples=["EURUSD"]
    )
    side: Optional[Side] = Field(None, description="Side.", examples=["buy"])
    type: Optional[Type3] = Field(None, description="Type.", examples=["limit"])


class Position(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., description="Unique identifier.", examples=["1"])
    instrument: str = Field(
        ...,
        description="Instrument name that is used on a broker's side.",
        examples=["EURUSD"],
    )
    qty: float = Field(..., description="Quantity.", examples=[1])
    side: Side = Field(..., description="Side.", examples=["buy"])
    avgPrice: float = Field(
        ..., description="Average price of position trades.", examples=[1.1347091]
    )
    unrealizedPl: Optional[float] = Field(
        None, description="Unrealized (open) profit/loss.", examples=[19.4739]
    )
    message: Optional[PositionInformationalMessage] = None
    customFields: Optional[List[CustomFieldsValueItem]] = Field(
        None,
        description=(
            "Localized position custom fields values data.\nCustom fields are"
            " configured in the [/config](#operation/getConfiguration) endpoint"
            " response.\n"
        ),
        min_length=1,
    )


class NetPosition(BaseModel):
    id: str = Field(..., description="Unique identifier.", examples=["1"])
    instrument: str = Field(
        ...,
        description="Instrument name that is used on a broker's side.",
        examples=["EURUSD"],
    )
    qty: float = Field(..., description="Net quantity.", examples=[1])
    longQty: Optional[float] = Field(
        None, description="Net quantity of long positions.", examples=[2]
    )
    shortQty: Optional[float] = Field(
        None, description="Net quantity of short positions.", examples=[1]
    )
    avgPrice: Optional[float] = Field(
        None, description="Average price of net position trades.", examples=[1.23]
    )
    customFields: Optional[List[CustomFieldsValueItem]] = Field(
        None,
        description=(
            "Localized net position custom fields values data.\nCustom fields are"
            " configured in the [/config](#operation/getConfiguration) endpoint"
            " response.\n"
        ),
        min_length=1,
    )
    message: Optional[PositionInformationalMessage] = None


class IndividualPosition(BaseModel):
    id: str = Field(..., description="Unique identifier.", examples=["1"])
    instrument: str = Field(
        ...,
        description="Instrument name that is used on a broker's side.",
        examples=["EURUSD"],
    )
    date: str = Field(
        ...,
        description=(
            "The date when the individual position was opened. UNIX timestamp in"
            " milliseconds."
        ),
        examples=["1683818630353"],
    )
    qty: float = Field(..., description="Quantity.", examples=[1])
    side: Side = Field(..., description="Side.", examples=["buy"])
    price: float = Field(
        ..., description="Individual position's price.", examples=[23.274]
    )
    unrealizedPl: Optional[float] = Field(
        None, description="Individual position's profit/loss.", examples=[3.094]
    )
    customFields: Optional[List[CustomFieldsValueItem]] = Field(
        None,
        description=(
            "Localized individual position custom fields values data.\nCustom fields"
            " are configured in the [/config](#operation/getConfiguration) endpoint"
            " response.\n"
        ),
        min_length=1,
    )
    message: Optional[PositionInformationalMessage] = None


class StreamClosedPosition(BaseModel):
    id: str = Field(..., description="Unique identifier.", examples=["1"])
    qty: float = Field(
        ..., description="Quantity. Should be equal to `0`.", examples=[0]
    )


class DeletePositionRequestBody(BaseModel):
    amount: Optional[float] = Field(
        None,
        description=(
            "Amount to close. This property is used if supportPartialClosePosition flag"
            " is `true`."
        ),
    )


class DeleteIndividualPositionRequestBody(BaseModel):
    amount: Optional[float] = Field(
        None,
        description=(
            "Amount to close. This property is used if"
            " supportPartialCloseIndividualPosition flag is `true`."
        ),
    )


class PositionsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Position]


class StreamPositionsMessage(RootModel[List[Union[Position, StreamClosedPosition]]]):
    root: List[Union[Position, StreamClosedPosition]] = Field(
        ...,
        examples=[
            [
                {
                    "id": "1",
                    "instrument": "EURUSD",
                    "qty": 1,
                    "side": "buy",
                    "avgPrice": 1.1347091,
                    "unrealizedPl": 19.4739,
                    "message": {
                        "text": "You can add brackets to this position to protect it",
                        "type": "Information",
                    },
                    "customFields": [
                        {"id": "customField1", "value": "Value of custom field"}
                    ],
                },
                {"id": "2", "qty": 0},
            ]
        ],
        title="StreamPositionsMessage",
    )


class PingMessage(BaseModel):
    """
    A ping message to ensure that the connection persists. Must be sent every 5 seconds if there were no entity updates.
    """

    s: OkStatus


class S(Enum):
    """
    Status will always be `error`.
    """

    error = "error"


class Error(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: S = Field(..., description="Status will always be `error`.", examples=["error"])
    errmsg: str = Field(
        ..., description="Error message.", examples=["An error occurred."]
    )


class NetPositionsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[NetPosition]


class IndividualPositionsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[IndividualPosition]


class ModifyPositionCommonRequestBody(BaseModel):
    stopLoss: Optional[float] = Field(
        None, description="StopLoss price.", examples=[1.283568]
    )
    trailingStopPips: Optional[float] = Field(
        None,
        description=(
            "Distance from the stop loss level to the order price in pips (if"
            " supported)."
        ),
    )
    guaranteedStop: Optional[float] = Field(
        None, description="Stop price of Guaranteed Stop bracket (if supported)."
    )
    takeProfit: Optional[float] = Field(
        None, description="TakeProfit price.", examples=[1.294436]
    )
    currentAsk: Optional[float] = Field(
        None,
        description=(
            "Current ask price for the instrument that the user sees in the order"
            " panel."
        ),
        examples=[1.287367],
    )
    currentBid: Optional[float] = Field(
        None,
        description=(
            "Current bid price for the instrument that the user sees in the order"
            " panel."
        ),
        examples=[1.28554],
    )


class Side5(Enum):
    """
    New side of the position. This parameter is used to reverse the position,
    if the `supportNativeReversePosition` flag is enabled in the account config.
    Please see the [/accounts](#operation/getAccounts) endpoint.

    """

    buy = "buy"
    sell = "sell"


class ModifyPositionRequestBody(ModifyPositionCommonRequestBody):
    side: Optional[Side5] = Field(
        None,
        description=(
            "New side of the position. This parameter is used to reverse the"
            " position,\nif the `supportNativeReversePosition` flag is enabled in the"
            " account config.\nPlease see the [/accounts](#operation/getAccounts)"
            " endpoint.\n"
        ),
    )


class ModifyIndividualPositionRequestBody(ModifyPositionCommonRequestBody):
    pass


class PreviewLeverage(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    infos: Optional[List[str]] = Field(
        None, description="An array of information messages if any.", min_length=1
    )
    warnings: Optional[List[str]] = Field(
        None, description="An array of warning messages if any.", min_length=1
    )
    errors: Optional[List[str]] = Field(
        None, description="An array of error messages if any.", min_length=1
    )


class PreviewLeverageResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: PreviewLeverage


class PullingInterval(BaseModel):
    """
    Time intervals in milliseconds to pull data from the server.
    Please note: if the pulling interval is set above the maximum value then the maximum value will be used explicitly.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    quotes: Optional[confloat(le=1000.0)] = Field(
        500,
        description=(
            "Time interval in milliseconds to request quote and level 2 depth updates."
        ),
        examples=[500],
    )
    orders: Optional[confloat(le=1000.0)] = Field(
        500,
        description="Time interval in milliseconds to request orders.",
        examples=[500],
    )
    positions: Optional[confloat(le=1500.0)] = Field(
        1000,
        description="Time interval in milliseconds to request positions.",
        examples=[1000],
    )
    accountManager: Optional[confloat(le=1500.0)] = Field(
        500,
        description="Time interval in milliseconds to update Account manager tables.",
        examples=[1000],
    )
    balances: Optional[confloat(le=1500.0)] = Field(
        1000,
        description="Time interval in milliseconds to request balances.",
        examples=[1000],
    )


class SetLeverage(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    leverage: float = Field(..., description="Leverage value confirmed by broker.")


class SetLeverageResponse(BaseModel):
    s: OkStatus
    d: SetLeverage


class SingleField(Enum):
    """
    Constant. Set it to `brokerSymbol`.
    """

    brokerSymbol = "brokerSymbol"


class SingleMapping(BaseModel):
    """
    Map of Broker instrument name to TradingView instrument name.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    f: List[str] = Field(
        ...,
        description=(
            "An array with the only one string element &ndash; broker symbol name."
        ),
        min_length=1,
    )
    s: str = Field(
        ...,
        description="TradingView symbol name with a prefix (AA:XXXX).",
        examples=["FX_IDC:EURUSD"],
    )


class SingleQuote(BaseModel):
    """
    Price and restriction data for an instrument.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    ask: float = Field(..., description="Ask price.", examples=[1.13836])
    bid: float = Field(..., description="Bid price.", examples=[1.13834])
    buyPipValue: Optional[float] = Field(
        None,
        description=(
            "Value of 1 pip in the account currency, used for calculating risks and"
            " trade value in the Order dialog for buy orders."
        ),
        examples=[1],
    )
    sellPipValue: Optional[float] = Field(
        None,
        description=(
            "Value of 1 pip in the account currency, used for calculating risks and"
            " trade value in the Order dialog for sell orders."
        ),
        examples=[1],
    )
    hardToBorrow: Optional[bool] = Field(
        False, description="Specify if the instrument is hard to borrow."
    )
    notShortable: Optional[bool] = Field(
        False, description="Specify if the instrument is not shortable."
    )
    halted: Optional[bool] = Field(
        False, description="Specify if the instrument is halted."
    )


class StatusModel(Enum):
    ok = "ok"
    error = "error"


class Id1(Enum):
    slPercent = "slPercent"


class Options1(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    min: float = Field(
        ...,
        description=(
            "Minimal value in percentage of the stop loss price relative to the parent"
            " order price."
        ),
        examples=[10],
    )
    max: float = Field(
        ...,
        description=(
            "Maximum value in percentage of the stop loss price relative to the parent"
            " order price."
        ),
        examples=[90],
    )


class StopLossPercentValidationRule(BaseModel):
    """
    Stop Loss Percent Price Range Rule applied to field validation in the Order dialog.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: Id1
    options: Options1


class Id2(Enum):
    stopPercent = "stopPercent"


class Options2(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    min: float = Field(
        ...,
        description=(
            "Minimal value in percentage of the stop price relative to the current"
            " price.\n"
        ),
        examples=[10],
    )
    max: float = Field(
        ...,
        description=(
            "Maximum value in percentage of the stop price relative to the current"
            " price.\n"
        ),
        examples=[20],
    )


class StopPercentValidationRule(BaseModel):
    """
    Stop Percent Price Range Rule applied to the order price field validation in the Order dialog.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: Id2
    options: Options2


class Id3(Enum):
    gsPercent = "gsPercent"


class Options3(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    min: float = Field(
        ...,
        description=(
            "Minimal value in percentage of the guaranteed stop price relative to the"
            " current price.\n"
        ),
        examples=[10],
    )
    max: float = Field(
        ...,
        description=(
            "Maximum value in percentage of the guaranteed stop price relative to the"
            " current price.\n"
        ),
        examples=[20],
    )


class GuaranteedStopPercentValidationRule(BaseModel):
    """
    Guaranteed Stop Percent Price Range Rule applied to the order price field validation in the Order dialog.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: Id3
    options: Options3


class StreamingAskBidTradeItem(BaseModel):
    """
    Ask or Bid.
    """

    id: str = Field(..., description="Symbol", examples=["EURUSD"])
    p: float = Field(..., description="Price.", examples=[1.47245])
    s: float = Field(..., description="Size.", examples=[100])
    t: float = Field(..., description="Unix time UTC.", examples=[1547942400])


class StreamingAskItemType(BaseModel):
    """
    Ask
    """

    f: Optional[str] = Field(None, description="Should always be `a`.", examples=["a"])


class StreamingAskResponseDeprecated(StreamingAskItemType, StreamingAskBidTradeItem):
    pass


class StreamingBidItemType(BaseModel):
    """
    Bid
    """

    f: Optional[str] = Field(None, description="Should always be `b`.", examples=["b"])


class StreamingBidResponseDeprecated(StreamingBidItemType, StreamingAskBidTradeItem):
    pass


class StreamingDailyBarType(BaseModel):
    """
    Daily Bar
    """

    f: str = Field(..., description="Should always be `d`.", examples=["d"])


class StreamingHeartbeatResponse(BaseModel):
    heartbeat: Optional[int] = Field(
        None, description="Current Unix timestamp in seconds."
    )


class StreamingQuoteResponse(BaseModel):
    f: str = Field(..., description="Should always be `q`.")
    id: str = Field(..., description="Symbol.")
    t: float = Field(..., description="Unix time UTC.")
    ap: float = Field(..., description="Best ask price.")
    as_: float = Field(..., alias="as", description="Best ask size.")
    bp: float = Field(..., description="Best bid price.")
    bs: float = Field(..., description="Best bid size.")


class StreamingTradeItemType(BaseModel):
    """
    Trade
    """

    f: str = Field(..., description="Should always be `t`.", examples=["t"])


class StreamingTradeResponse(StreamingTradeItemType, StreamingAskBidTradeItem):
    pass


class SuccessResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus = Field(..., description="Status will always be `ok`.", examples=["ok"])


class VolumeTypeEnum(Enum):
    base = "base"
    quote = "quote"
    tick = "tick"
    contract = "contract"


class TimezoneEnum(Enum):
    America_New_York = "America/New_York"
    America_Los_Angeles = "America/Los_Angeles"
    America_Chicago = "America/Chicago"
    America_Phoenix = "America/Phoenix"
    America_Toronto = "America/Toronto"
    America_Vancouver = "America/Vancouver"
    America_Argentina_Buenos_Aires = "America/Argentina/Buenos_Aires"
    America_El_Salvador = "America/El_Salvador"
    America_Sao_Paulo = "America/Sao_Paulo"
    America_Bogota = "America/Bogota"
    Europe_Moscow = "Europe/Moscow"
    Europe_Athens = "Europe/Athens"
    Europe_Berlin = "Europe/Berlin"
    Europe_London = "Europe/London"
    Europe_Madrid = "Europe/Madrid"
    Europe_Paris = "Europe/Paris"
    Europe_Warsaw = "Europe/Warsaw"
    Australia_Sydney = "Australia/Sydney"
    Australia_Brisbane = "Australia/Brisbane"
    Australia_Adelaide = "Australia/Adelaide"
    Australia_ACT = "Australia/ACT"
    Asia_Almaty = "Asia/Almaty"
    Asia_Ashkhabad = "Asia/Ashkhabad"
    Asia_Tokyo = "Asia/Tokyo"
    Asia_Taipei = "Asia/Taipei"
    Asia_Singapore = "Asia/Singapore"
    Asia_Shanghai = "Asia/Shanghai"
    Asia_Seoul = "Asia/Seoul"
    Asia_Tehran = "Asia/Tehran"
    Asia_Dubai = "Asia/Dubai"
    Asia_Kolkata = "Asia/Kolkata"
    Asia_Hong_Kong = "Asia/Hong_Kong"
    Asia_Bangkok = "Asia/Bangkok"
    Pacific_Auckland = "Pacific/Auckland"
    Pacific_Chatham = "Pacific/Chatham"
    Pacific_Fakaofo = "Pacific/Fakaofo"
    Pacific_Honolulu = "Pacific/Honolulu"
    America_Mexico_City = "America/Mexico_City"
    Africa_Johannesburg = "Africa/Johannesburg"
    Asia_Kathmandu = "Asia/Kathmandu"
    US_Mountain = "US/Mountain"
    Etc_UTC = "Etc/UTC"


class BarSourceEnum(Enum):
    bid = "bid"
    ask = "ask"
    mid = "mid"
    trade = "trade"


class BarTransformEnum(Enum):
    none = "none"
    openprev = "openprev"
    prevopen = "prevopen"


class SymbolMapping(BaseModel):
    """
    Map of Broker instrument names and TradingView instrument names.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    symbols: Optional[List[SingleMapping]] = None
    fields: Optional[List[SingleField]] = Field(
        None,
        description="Array with the only one element `['brokerSymbol']`.",
        max_length=1,
        min_length=1,
    )


class SymbolType(Enum):
    """
    Symbol type (forex, stock, etc.).
    **Deprecated values**: crypto, cfd

    """

    stock = "stock"
    dr = "dr"
    right = "right"
    bond = "bond"
    warrant = "warrant"
    structured = "structured"
    index = "index"
    forex = "forex"
    futures = "futures"
    spot = "spot"
    swap = "swap"
    commodity = "commodity"
    crypto = "crypto"
    cfd = "cfd"
    option = "option"


class Id4(Enum):
    tpPercent = "tpPercent"


class Options4(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    min: float = Field(
        ...,
        description=(
            "Minimal value in percentage of the take profit price relative to the"
            " parent order price."
        ),
        examples=[10],
    )
    max: float = Field(
        ...,
        description=(
            "Maximum value in percentage of the take profit price relative to the"
            " parent order price."
        ),
        examples=[90],
    )


class TakeProfitPercentValidationRule(BaseModel):
    """
    Take Profit Percent Price Range Rule applied to field validation in the Order dialog.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    id: Id4
    options: Options4


class ConnectWarningConfig(BaseModel):
    """
    A message that is displayed to users right after the authentication process is finished.
    One of the use cases is displaying regulatory required message.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    key: str = Field(
        ...,
        description=(
            "Predefined key associated with a combination of a title and a message that"
            " must be shown.\nThe list of keys, titles and messages must be negotiated"
            " with TradingView beforehand.\n"
        ),
    )
    skippable: Optional[bool] = Field(
        False, description="Whether the message may be disabled by the user."
    )


class Dependency(Enum):
    qty = "qty"
    side = "side"
    price = "price"
    duration = "duration"
    brackets = "brackets"


class OrderInfoConfig(BaseModel):
    """
    Config for the Order Info section of the Order Ticket.
    """

    dependencies: List[Dependency] = Field(
        ...,
        description=(
            "List of fields that trigger an update to the data in the Order Info"
            " section whenever its values change."
        ),
        min_length=1,
    )


class UserInfoResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: UserInfo


class AccountStateResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: AccountState


class AuthorizeResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: AccessToken


class ComboBoxMetaInfo(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(
        ..., description="Unique field identifier.", examples=["customInputFieldId"]
    )
    title: str = Field(
        ...,
        description="Localized field display name.",
        examples=["Additional parameters"],
    )
    saveToSettings: Optional[bool] = Field(
        False,
        description=(
            "Whether the value should be stored in the user settings and preserved for"
            " the next time the dialog is displayed."
        ),
        examples=[True],
    )
    mutable: Optional[bool] = Field(
        True,
        description="Whether this field can be changed during the order modification.",
        examples=[False],
    )
    forceUserEnterInitialValue: Optional[bool] = Field(
        False,
        description=(
            "If this flag is set to true, the user will not be able to place an order"
            " without explicitly entering a value, so instant order placement is not"
            " available."
        ),
        examples=[True],
    )
    items: List[ComboBoxValue] = Field(..., min_length=1)


class Config(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    accountSummaryRow: Optional[List[AccountSummaryRowItem]] = Field(
        None,
        description=(
            "Localized Account Summary Row configuration.\nAccount Summary Row is a"
            " panel at the top of the bottom widget with the key account indicators."
            " The `supportCustomAccountSummaryRow` flag should be enabled in the"
            " account config, see the [/accounts](#operation/getAccounts) endpoint."
            " Data of the Account Summary Row is filled using the"
            " [/state](/rest-api-spec/#operation/getState) endpoint."
        ),
        examples=[
            [
                {"id": "accountBalance", "title": "Account Balance"},
                {"id": "Equity", "title": "Realized P/L"},
                {"id": "Open Profit", "title": "Unrealized P/L"},
            ]
        ],
        title="AccountSummaryRow",
    )
    accountManager: Optional[List[AccountManagerTable]] = Field(
        None,
        description=(
            "Localized Account manager's tables configuration. Account manager is"
            " a\npage in the bottom widget. This page can have multiple tables. Data"
            " of\nthe tables is filled using the"
            " [/state](/rest-api-spec/#operation/getState) endpoint.\n"
        ),
        examples=[
            [
                {
                    "id": "accountSummary",
                    "title": "",
                    "columns": [
                        {"id": "todayPL", "title": "Today's P&L"},
                        {"id": "accountValue", "title": "Account Value"},
                        {"id": "balance", "title": "Balance"},
                        {"id": "totalMargin", "title": "Margin"},
                        {"id": "held", "title": "Held"},
                        {"id": "buyingPower", "title": "Buying Power"},
                    ],
                }
            ]
        ],
        title="AccountManager",
    )
    durations: Optional[List[Duration]] = Field(
        None,
        description="Localized array of durations displayed in Order Ticket.",
        title="Durations",
    )
    orderCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional order columns to be displayed in the orders table of the"
            " Account manager.\nThe orders table has a default set of columns that can"
            " be extended using this configuration.\nThe `supportOrderCustomFields`"
            " flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/orders](https://www.tradingview.com/rest-api-spec/#operation/getOrders)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "commission",
                    "title": "Commission",
                    "tooltip": "Commission Fees",
                    "alignment": "right",
                }
            ]
        ],
        title="OrderCustomFields",
    )
    orderHistoryCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional history columns to be displayed in the history table of the"
            " Account manager.\nThe history table has a default set of columns that can"
            " be extended using this configuration.\nThe"
            " `supportOrderHistoryCustomFields` and `supportOrdersHistory` flags should"
            " be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/ordersHistory](/rest-api-spec/#operation/getOrdersHistory)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "commission",
                    "title": "Commission",
                    "tooltip": "Commission Fees",
                    "alignment": "right",
                }
            ]
        ],
        title="OrderHistoryCustomFields",
    )
    positionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    netPositionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    individualPositionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    pullingInterval: Optional[PullingInterval] = None
    orderInfoConfig: Optional[OrderInfoConfig] = None


class ConfigResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: Config


class CryptoBalancesResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[CryptoBalance]


class Depth(BaseModel):
    """
    Depth of market for an instrument.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    asks: List[List[float]] = Field(
        ...,
        description=(
            "Array of arrays with two numeric elements - price and volume. Must be"
            " sorted by `price` in ascending order."
        ),
    )
    bids: List[List[float]] = Field(
        ...,
        description=(
            "Array of arrays with two numeric elements - price and volume. Must be"
            " sorted by `price` in ascending order."
        ),
    )


class DepthResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: Depth


class ErrorResponse(RootModel[Error]):
    root: Error = Field(..., title="ErrorResponse")


class ExecutionsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Execution]


class GetLeverageResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: GetLeverage


class GroupListResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: GroupList


class HistoryEmptyBarResponse(SuccessResponse, EmptyBarArrays):
    pass


class HistorySuccessResponse(SuccessResponse, BarsArrays):
    pass


class MappingResponse(RootModel[SymbolMapping]):
    root: SymbolMapping = Field(..., title="MappingResponse")


class Order(OrderCommon, OrderStatus):
    pass


class OrderDialogCustomFields(BaseModel):
    """
    Additional custom controls to be displayed in the Order dialog. At the moment, the only possible control types are combobox and checkbox. Data of the additional fields is filled from the [/orders](#operation/getOrders) endpoint.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    comboBox: Optional[List[ComboBoxMetaInfo]] = Field(None, min_length=1)
    checkbox: Optional[List[CheckBoxMetainfo]] = None
    textField: Optional[List[TextFieldMetaInfo]] = None


class OrderHistory(OrderCommon, OrderHistoryStatus):
    pass


class OrdersHistoryResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[OrderHistory] = Field(
        ...,
        examples=[
            [
                {
                    "id": "1",
                    "instrument": "EURUSD",
                    "qty": 100,
                    "side": "buy",
                    "type": "limit",
                    "avgPrice": 0,
                    "limitPrice": 1.14344,
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "filled",
                },
                {
                    "id": "2",
                    "instrument": "EURUSD",
                    "qty": 100,
                    "side": "sell",
                    "type": "limit",
                    "filledQty": 50,
                    "avgPrice": 0,
                    "limitPrice": 1.15094,
                    "parentId": "1",
                    "parentType": "order",
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "cancelled",
                },
            ]
        ],
    )


class OrderPreviewSection(BaseModel):
    """
    Describes a single order preview section. Order preview can have multiple sections that are divided by separators and may have titles.
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    rows: List[OrderPreviewSectionRow] = Field(
        ...,
        description=(
            "Array of order preview items. Each item is a row of the section table."
        ),
    )
    header: Optional[str] = Field(None, description="Optional title of the section.")


class OrdersResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Order] = Field(
        ...,
        examples=[
            [
                {
                    "id": "1",
                    "instrument": "EURUSD",
                    "qty": 100,
                    "side": "buy",
                    "type": "limit",
                    "avgPrice": 0,
                    "limitPrice": 1.14344,
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "working",
                    "customFields": [{"id": "commission", "value": "1.25"}],
                },
                {
                    "id": "2",
                    "instrument": "EURUSD",
                    "qty": 100,
                    "side": "sell",
                    "type": "limit",
                    "filledQty": 50,
                    "avgPrice": 0,
                    "limitPrice": 1.15094,
                    "parentId": "1",
                    "parentType": "order",
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "inactive",
                    "customFields": [{"id": "commission", "value": ""}],
                },
                {
                    "id": "3",
                    "instrument": "EURUSD",
                    "qty": 1000000,
                    "side": "sell",
                    "type": "limit",
                    "filledQty": 0,
                    "avgPrice": 0,
                    "limitPrice": 1.15094,
                    "parentId": "1",
                    "parentType": "order",
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "rejected",
                    "message": {
                        "text": "This order has been rejected due to the closed market",
                        "type": "error",
                    },
                },
            ]
        ],
    )


class OrdersMessage(RootModel[List[Order]]):
    root: List[Order] = Field(
        ...,
        examples=[
            [
                {
                    "id": "1",
                    "instrument": "EURUSD",
                    "qty": 101,
                    "side": "buy",
                    "type": "limit",
                    "avgPrice": 0,
                    "limitPrice": 1.2093,
                    "duration": {"type": "gtt", "datetime": 1548406235},
                    "status": "working",
                    "customFields": [{"id": "commission", "value": "1.25"}],
                }
            ]
        ],
        title="OrdersMessage",
    )


class StreamIndividualPositionsMessage(
    RootModel[List[Union[IndividualPosition, StreamClosedPosition]]]
):
    root: List[Union[IndividualPosition, StreamClosedPosition]] = Field(
        ...,
        examples=[
            [
                {
                    "id": "ip1",
                    "instrument": "EUR/USD",
                    "qty": 50,
                    "side": "buy",
                    "price": 1.1347,
                    "pl": 555.44,
                },
                {
                    "id": "ip2",
                    "instrument": "EUR/USD",
                    "qty": 40,
                    "side": "buy",
                    "price": 1.12,
                    "pl": 405.44,
                },
                {"id": "ip3", "qty": 0},
            ]
        ],
        title="StreamIndividualPositionsMessage",
    )


class StreamNetPositionsMessage(
    RootModel[List[Union[NetPosition, StreamClosedPosition]]]
):
    root: List[Union[NetPosition, StreamClosedPosition]] = Field(
        ...,
        examples=[
            [
                {
                    "id": "np1",
                    "instrument": "EUR/USD",
                    "qty": 90,
                    "side": "buy",
                    "longQty": 90,
                    "shortQty": 0,
                    "avgPrice": 1.1247,
                },
                {"id": "np2", "qty": 0},
            ]
        ],
        title="StreamNetPositionsMessage",
    )


class ErrorMessage(RootModel[Error]):
    root: Error = Field(..., title="ErrorMessage")


class D(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    orderId: Optional[str] = Field(
        None, description="New order identifier.", examples=["441fdB023"]
    )
    transactionId: Optional[str] = Field(
        None,
        description=(
            "An unique transaction id is used in these endpoints as an identifier for"
            " latency tracking using"
            " [/trackLatency](#operation/trackLatency):\n[/placeOrder](#operation/placeOrder),\n[/modifyOrder](operation/#operation/modifyOrder),\n[/cancelOrder](#operation/cancelOrder),\n[/modifyPosition](#operation/modifyPosition),\n[/closePosition](#operation/closePosition)\nThis"
            " field is used only if `supportTrackLatency` flag is set to true.\n"
        ),
        examples=["1adf4578-cdf"],
        title="TransactionId",
    )


class PostOrderResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: D


class PreviewOrder(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    confirmId: Optional[str] = Field(
        None,
        description=(
            "An optional order identifier. It is sent back to the server in the"
            " [/placeOrder](#operation/placeOrder) and"
            " [/modifyOrder](#operation/modifyOrder) requests."
        ),
        examples=["112358"],
    )
    sections: List[OrderPreviewSection]
    warnings: Optional[List[Union[str, List[Union[str, Hyperlink]]]]] = Field(
        None, description="Optional array of text warnings."
    )
    errors: Optional[List[Union[str, List[Union[str, Hyperlink]]]]] = Field(
        None, description="Optional array of text errors."
    )


class PreviewOrderResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: PreviewOrder


class OrderInfo(BaseModel):
    rows: List[Union[OrderInfoRow, OrderInfoDivider]] = Field(
        ...,
        description=(
            "Defines rows in the table displayed within the Order Info section of the"
            " Order Ticket."
        ),
    )
    disclaimer: Optional[Union[str, List[Union[str, Hyperlink]]]] = Field(
        None,
        description=(
            "Disclaimer, which will be shown in the bottom of the Order Info section of"
            " the Order Ticket."
        ),
    )


class Quote(BaseModel):
    """
    Price response for an instrument
    """

    model_config = ConfigDict(
        extra="forbid",
    )
    s: Optional[StatusModel] = None
    n: str = Field(
        ...,
        description="Symbol name. Should be equal to the requested one.",
        examples=["EURUSD"],
    )
    v: SingleQuote


class StreamingDailyBarResponse(StreamingDailyBarType):
    id: str = Field(..., description="Symbol", examples=["EURUSD"])
    o: float = Field(..., description="Open.", examples=[3667])
    h: float = Field(..., description="High.", examples=[3667.24])
    l: float = Field(..., description="Low.", examples=[3661.55])
    c: float = Field(..., description="Close.", examples=[3662.25])
    v: float = Field(..., description="Volume.", examples=[34])
    t: float = Field(
        ...,
        description=(
            "Unix timestamp in seconds. Timestamp time should be always 00:00 at the"
            " start of the day."
        ),
        examples=[1547931600],
    )


class D1(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    transactionId: Optional[str] = Field(
        None,
        description=(
            "An unique transaction id is used in these endpoints as an identifier for"
            " latency tracking using"
            " [/trackLatency](#operation/trackLatency):\n[/placeOrder](#operation/placeOrder),\n[/modifyOrder](operation/#operation/modifyOrder),\n[/cancelOrder](#operation/cancelOrder),\n[/modifyPosition](#operation/modifyPosition),\n[/closePosition](#operation/closePosition)\nThis"
            " field is used only if `supportTrackLatency` flag is set to true.\n"
        ),
        examples=["1adf4578-cdf"],
        title="TransactionId",
    )


class SuccessResponseWithTransactionId(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: Optional[D1] = None


class SymbolInfoArrays(BaseModel):
    """
    SymbolInfo is an object containing symbols metadata. Each value of this  object is an array of values which
    size is equal to symbols count or a single value that is applied to all symbols.

    """

    symbol: List[str] = Field(
        ...,
        description=(
            "It is a symbol name which is a string that users see. Also, the symbol"
            " name is used for data requests\nif you are not using tickers. `symbol`"
            " must contain uppercase letters and can optionally contain numbers,\ndots,"
            " or underscores. Learn more about `symbol`\nin the"
            " [manual](https://www.tradingview.com/broker-api-docs/data/Symbol_info.html#symbol-naming-rules).\n"
        ),
        examples=[["VIXG2019", "AAPLE", "EURUSD", "BTCUSD"]],
        min_length=1,
    )
    description: List[str] = Field(
        ...,
        description=(
            "Description of a symbol. Will be displayed in the chart legend for this"
            " symbol.\n"
        ),
        examples=[["Volatility Index", "Apple Inc", "EUR/USD", "Bitcoin / US Dollar"]],
    )
    currency: List[str] = Field(
        ...,
        description=(
            "Symbol currency, also named as counter currency. If a symbol is a currency"
            " pair, then the currency field has\nto contain the second currency of this"
            " pair. For example, `USD` is a currency for `EURUSD` ticker.\nFiat"
            " currency must meet the ISO 4217 standard.\n"
        ),
        examples=[["USD", "USD", "USD", "USD"]],
    )
    base_currency: Optional[List[str]] = Field(
        None,
        alias="base-currency",
        description=(
            "For currency pairs only. This field contains the first currency of the"
            " pair. For example, base currency for\n`EURUSD` ticker is `EUR`. Fiat"
            " currency must meet the ISO 4217 standard.\n"
        ),
        examples=[[None, None, "EUR", "BTC"]],
    )
    exchange_listed: List[str] = Field(
        ...,
        alias="exchange-listed",
        description="Short name of exchange where this symbol is listed.",
        examples=[["CBOE", "NASDAQ", "FOREX", "CRYPTO"]],
    )
    exchange_traded: List[str] = Field(
        ...,
        alias="exchange-traded",
        description="Short name of exchange where this symbol is traded.",
        examples=[["CBOE", "NASDAQ", "FOREX", "CRYPTO"]],
    )
    minmovement: List[float] = Field(
        ...,
        description="Minimal integer price change.",
        examples=[[1.0, 1.0, 1.0, 1.0]],
    )
    minmovement2: Optional[List[float]] = Field(
        None,
        description=(
            "This is a number for complex price formatting cases. The default value is"
            " `0`."
        ),
        examples=[[0, 0, 0, 0]],
    )
    fractional: Optional[List[bool]] = Field(
        None,
        description=(
            "Boolean showing whether this symbol wants to have complex"
            " price\nformatting (see `minmovement2`) or not. The default value is"
            " `false`.\n"
        ),
        examples=[[False, False, False, False]],
    )
    pricescale: List[float] = Field(
        ...,
        description=(
            "Indicates how many decimal points the price has. For example, if the price"
            " has 2 decimal points (ex., 300.01),\nthen `pricescale` is `100`. If it"
            " has 3 decimals, then `pricescale` is `1000` etc. If the price doesn't"
            " have decimals,\nset `pricescale` to `1`.\n"
        ),
        examples=[[100, 100, 100000, 100]],
    )
    root: Optional[List[str]] = Field(
        None,
        description=(
            "Root of the features. It's required for futures symbol types"
            " only.\nProvide a null value for other symbol types.\n"
        ),
        examples=[["VIX", None, None, None]],
    )
    root_description: Optional[List[str]] = Field(
        None,
        alias="root-description",
        description=(
            "Short description of the futures root that will be displayed in the symbol"
            " search.\nIt's required for futures only. Provide a null value for other"
            " symbol types.\n"
        ),
        examples=[["Volatility Index", None, None, None]],
    )
    has_intraday: Optional[List[bool]] = Field(
        None,
        alias="has-intraday",
        description=(
            "Boolean value showing whether the symbol includes intraday"
            " (minutes)\nhistorical data. If it's `false` then all buttons for intraday"
            " resolutions\nwill be disabled for this particular symbol.\n"
        ),
        examples=[[True, True, True, True]],
    )
    has_no_volume: Optional[List[bool]] = Field(
        None,
        alias="has-no-volume",
        description=(
            "Boolean showing whether the symbol includes volume data or not. The"
            " default value is `false`."
        ),
        examples=[[False, False, True, False]],
    )
    type: List[SymbolType] = Field(
        ...,
        description=(
            "Symbol type (forex/stock etc.).\n**Deprecated values**: crypto, cfd\n"
        ),
        examples=[["futures", "stock", "forex", "spot"]],
    )
    typespecs: Optional[List[str]] = Field(
        None,
        description=(
            "An array of strings. Each element can be a list of comma separated"
            " values.\n**Applicable values**:\n  - cfd\n  - spreadbet\n  - crypto\n"
        ),
        examples=[["cfd", "cfd", None, "crypto,cfd"]],
    )
    volume_type: Optional[List[VolumeTypeEnum]] = Field(
        None,
        alias="volume-type",
        description=(
            "The volume type of the symbol.\nRequired if the `typespecs` field includes"
            " 'crypto' and the `has-no-volume` field is set to `false`.\n"
        ),
        examples=[["base", "quote", "tick", None]],
    )
    is_cfd: Optional[List[bool]] = Field(
        None,
        alias="is-cfd",
        description=(
            "Boolean value showing whether the symbol is CFD. The base instrument type"
            " is set using the type field.\nDeprecated. Use `typespecs` instead.\n"
        ),
        examples=[[True, True, False, True]],
    )
    ticker: Optional[List[str]] = Field(
        None,
        description=(
            "This is a unique identifier for this particular symbol in your"
            " symbology.\nIf you specify this property then its value will be used for"
            " all data requests for this symbol.\n"
        ),
        examples=[["VIXG2019", "AAPLE", "EURUSD", "BTCUSD"]],
    )
    timezone: List[TimezoneEnum] = Field(
        ...,
        description=(
            "Timezone of the exchange for this symbol. We expect to get the name of the"
            " time zone in olsondb format.\n"
        ),
        examples=[
            ["America/New_York", "America/New_York", "America/New_York", "Etc/UTC"]
        ],
    )
    session_regular: List[str] = Field(
        ...,
        alias="session-regular",
        description=(
            "Session time format is HHMM-HHMM. E.g., a session that starts at 9:30 am"
            " and ends at 4:00 pm should look like `0930-1600`.\nThere is a special"
            " case for symbols traded 24/7 (e.g., Bitcoin and other cryptocurrencies):"
            " the session string should be `24x7`.\nTo specify an overnight session set"
            " start time greater than end time (ie, `1700-0900`).\nSession time is"
            " expected to be in exchange time zone.\n"
        ),
        examples=[["0000-2359:23456", "0930-1600", "1700-1700", "24x7"]],
    )
    session_extended: Optional[List[str]] = Field(
        None,
        alias="session-extended",
        description=(
            "An extended session, includes `session-premarket` and"
            " `session-postmarket`.\nThe start time should be earlier or be equal to"
            " the start time of the `session-regular`\nand be equal to the start time"
            " of the `session-premarket` if it exists.\n"
        ),
        examples=[["0000-2359:23456", "0400-2000", "1700-1700", "24x7"]],
    )
    session_premarket: Optional[List[str]] = Field(
        None,
        alias="session-premarket",
        description=(
            "An additional session before `session-regular`. The start time should be"
            " equal to the start time of the `session-extended`.\nThe end time should"
            " be equal or less than the start time of the `session-regular`.\n"
        ),
        examples=[[None, "0400-0930", None, None]],
    )
    session_postmarket: Optional[List[str]] = Field(
        None,
        alias="session-postmarket",
        description=(
            "An additional session after the `session-regular`. The start time should"
            " be equal or greater\nthan the end time of the `session-regular`. The end"
            " time should be equal to the end time of the `session-extended`.\n"
        ),
        examples=[[None, "1600-2000", None, None]],
    )
    has_daily: Optional[List[bool]] = Field(
        None,
        alias="has-daily",
        description=(
            "The boolean value showing whether data feed has its own daily\nresolution"
            " bars or not. If `has-daily` = `false` then Charting Library\nwill build"
            " the respective resolutions using 1-minute bars by itself.\nIf not, then"
            " it will request those bars from the data feed.\nThe default value is"
            " `true`.\n"
        ),
        examples=[[True, True, True, False]],
    )
    has_weekly_and_monthly: Optional[List[bool]] = Field(
        None,
        alias="has-weekly-and-monthly",
        description=(
            "The boolean value showing whether data feed has its own weekly\nand"
            " monthly resolution bars or not. If `has-weekly-and-monthly` ="
            " `false`\nthen Charting Library will build the respective resolutions"
            " using daily\nbars by itself. If not, then it will request those bars from"
            " the data feed.\nThe default value is `false`.\n"
        ),
        examples=[[False, False, False, False]],
    )
    pointvalue: Optional[List[float]] = Field(
        None,
        description=(
            "The currency value of a single whole unit price change in the instrument's"
            " currency.\nIf the value is not provided it is assumed to be `1`.\n"
        ),
        examples=[[10, 1, 1e-05, 1]],
    )
    expiration: Optional[List[float]] = Field(
        None,
        description=(
            "Expiration of the futures in the following format: YYYYMMDD. Required for"
            " futures type symbols only.\n"
        ),
        examples=[[20190213, None, None, None]],
    )
    bar_source: Optional[List[BarSourceEnum]] = Field(
        None,
        alias="bar-source",
        description="The principle of building bars. The default value is `trade`.",
        examples=[["trade", "bid", "ask", "trade"]],
    )
    bar_transform: Optional[List[BarTransformEnum]] = Field(
        None,
        alias="bar-transform",
        description="The principle of bar alignment. The default value is `none`.",
        examples=[["openprev", "openprev", "none", "none"]],
    )
    bar_fillgaps: Optional[List[bool]] = Field(
        None,
        alias="bar-fillgaps",
        description=(
            "Is used to create the zero-volume bars in the absence of any trades\n(i.e."
            " bars with zero volume and equal OHLC values ).\nThe default value is"
            " `false`.\n"
        ),
        examples=[["true", "true", "false", "false"]],
    )
    isin: Optional[List[str]] = Field(
        None,
        description=(
            "International Securities Identification Number. It's needed for classic"
            " stock instruments only."
        ),
        examples=[["ZAE000190252", "ZAE0001201977", "ZAE000567432", None]],
    )
    wkn: Optional[List[str]] = Field(
        None,
        description=(
            "German Securities Identification Code. It's needed for classic German"
            " stock instruments only."
        ),
        examples=[["A12ABB", "A66RTT", "A13DDE", None]],
    )


class SymbolInfoResponse(SuccessResponse, SymbolInfoArrays):
    pass


class Ui(BaseModel):
    """
    Account manager and Order dialog configuration for the account.
    The Account manager configuration will override configuration, specified in the [/config](#operation/getConfiguration) endpoint.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    accountSummaryRow: Optional[List[AccountSummaryRowItem]] = Field(
        None,
        description=(
            "Localized Account Summary Row configuration.\nAccount Summary Row is a"
            " panel at the top of the bottom widget with the key account indicators."
            " The `supportCustomAccountSummaryRow` flag should be enabled in the"
            " account config, see the [/accounts](#operation/getAccounts) endpoint."
            " Data of the Account Summary Row is filled using the"
            " [/state](/rest-api-spec/#operation/getState) endpoint."
        ),
        examples=[
            [
                {"id": "accountBalance", "title": "Account Balance"},
                {"id": "Equity", "title": "Realized P/L"},
                {"id": "Open Profit", "title": "Unrealized P/L"},
            ]
        ],
        title="AccountSummaryRow",
    )
    accountManager: Optional[List[AccountManagerTable]] = Field(
        None,
        description=(
            "Localized Account manager's tables configuration. Account manager is"
            " a\npage in the bottom widget. This page can have multiple tables. Data"
            " of\nthe tables is filled using the"
            " [/state](/rest-api-spec/#operation/getState) endpoint.\n"
        ),
        examples=[
            [
                {
                    "id": "accountSummary",
                    "title": "",
                    "columns": [
                        {"id": "todayPL", "title": "Today's P&L"},
                        {"id": "accountValue", "title": "Account Value"},
                        {"id": "balance", "title": "Balance"},
                        {"id": "totalMargin", "title": "Margin"},
                        {"id": "held", "title": "Held"},
                        {"id": "buyingPower", "title": "Buying Power"},
                    ],
                }
            ]
        ],
        title="AccountManager",
    )
    orderCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional order columns to be displayed in the orders table of the"
            " Account manager.\nThe orders table has a default set of columns that can"
            " be extended using this configuration.\nThe `supportOrderCustomFields`"
            " flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/orders](https://www.tradingview.com/rest-api-spec/#operation/getOrders)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "commission",
                    "title": "Commission",
                    "tooltip": "Commission Fees",
                    "alignment": "right",
                }
            ]
        ],
        title="OrderCustomFields",
    )
    orderHistoryCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional history columns to be displayed in the history table of the"
            " Account manager.\nThe history table has a default set of columns that can"
            " be extended using this configuration.\nThe"
            " `supportOrderHistoryCustomFields` and `supportOrdersHistory` flags should"
            " be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/ordersHistory](/rest-api-spec/#operation/getOrdersHistory)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "commission",
                    "title": "Commission",
                    "tooltip": "Commission Fees",
                    "alignment": "right",
                }
            ]
        ],
        title="OrderHistoryCustomFields",
    )
    positionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    netPositionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    individualPositionCustomFields: Optional[List[AccountManagerColumn]] = Field(
        None,
        description=(
            "Additional position columns to be displayed in the positions table of the"
            " Account manager.\nThe positions table has a default set of columns that"
            " can be extended using this configuration.\nThe"
            " `supportPositionCustomFields` flag should be enabled in the [account"
            " configuration](https://www.tradingview.com/rest-api-spec/#operation/getAccounts).\nData"
            " of the additional fields is filled from"
            " the\n[/positions](https://www.tradingview.com/rest-api-spec/#operation/getPositions)"
            " `customFields` value.\n"
        ),
        examples=[
            [
                {
                    "id": "exchangeFee",
                    "title": "Exchange fee",
                    "tooltip": "Exchange fee for the position",
                    "alignment": "right",
                },
                {
                    "id": "routeFee",
                    "title": "Route fee",
                    "tooltip": "Route fee for the position",
                    "alignment": "right",
                },
            ]
        ],
        title="PositionCustomFields",
    )
    orderDialogCustomFields: Optional[OrderDialogCustomFields] = None
    orderDialogLinks: Optional[List[Hyperlink]] = Field(
        None,
        description=(
            "Optional array of hyperlinks displayed to the user in the order ticket."
            " Needs to be coordinated with TradingView team before enabling."
        ),
    )


class Account(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    id: str = Field(..., description="Unique account identifier.", examples=["ACC-001"])
    name: str = Field(
        ...,
        description="Account title that is displayed to a user.",
        examples=["Demo trading account"],
    )
    type: Type = Field(..., description="Account type", examples=["demo"])
    currency: Optional[str] = Field(
        None, description="Abbreviation of account currency.", examples=["JPY"]
    )
    currencySign: Optional[str] = Field(
        None, description="Account currency symbol.", examples=["¥"]
    )
    config: AccountFlags
    ui: Optional[Ui] = Field(
        None,
        description=(
            "Account manager and Order dialog configuration for the account.\nThe"
            " Account manager configuration will override configuration, specified in"
            " the [/config](#operation/getConfiguration) endpoint.\n"
        ),
    )
    durations: Optional[List[Duration]] = Field(
        None,
        description=(
            "Localized array of durations displayed in Order Ticket.\nIt will override"
            " values, specified in the [/config](#operation/getConfiguration)"
            " endpoint.\n"
        ),
        title="AccountDurations",
    )
    prefix: Optional[str] = Field(
        None, description="Prefix for instruments.", examples=["NASDAQ"]
    )
    isVerified: Optional[bool] = Field(
        False,
        description=(
            "Used to confirm that the account has been verified (for example, KYC is"
            " passed). Only verified account users can leave reviews in the broker"
            " profile."
        ),
        examples=[True],
    )
    connectWarningConfig: Optional[ConnectWarningConfig] = None


class AccountResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Account] = Field(..., min_length=1)


class Ui1(BaseModel):
    """
    Order dialog configuration for the symbol. It will override configuration,
    specified in the [/accounts](#operation/getAccounts) endpoint.

    """

    model_config = ConfigDict(
        extra="forbid",
    )
    orderDialogCustomFields: Optional[OrderDialogCustomFields] = None
    validationRules: Optional[
        List[
            Union[
                StopPercentValidationRule,
                LimitPercentValidationRule,
                StopLossPercentValidationRule,
                TakeProfitPercentValidationRule,
                GuaranteedStopPercentValidationRule,
            ]
        ]
    ] = Field(
        None,
        description=(
            "Rules applied to field validation in the Order dialog.\nPlease note:"
            " `stopPercent` and `limitPercent` validation rules are not applied\nif the"
            " `supportStopOrdersInBothDirections` or"
            " `supportStopLimitOrdersInBothDirections` flag is set to `true`.\n"
        ),
        examples=[
            [
                {"id": "slPercent", "options": {"min": 10, "max": 90}},
                {"id": "tpPercent", "options": {"min": 10, "max": 90}},
                {"id": "limitPercent", "options": {"min": 10, "max": 20}},
                {"id": "stopPercent", "options": {"min": 10, "max": 20}},
                {"id": "gsPercent", "options": {"min": 10, "max": 20}},
            ]
        ],
        min_length=1,
    )


class Instrument(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    name: str = Field(..., description="Broker instrument name.", examples=["EURUSD"])
    description: str = Field(
        ..., description="Instrument description.", examples=["EUR/USD"]
    )
    minQty: Optional[float] = Field(
        None,
        description=(
            "Minimum quantity for trading. If `lotSize` is set, then the specified"
            " value must be in lots."
        ),
        examples=[1],
    )
    maxQty: Optional[float] = Field(
        1000000000,
        description=(
            "Maximum quantity for trading. If `lotSize` is set, then the specified"
            " value must be in lots. This field is required if the minQty value exceeds"
            " the default value."
        ),
        examples=[100000000],
    )
    qtyStep: Optional[float] = Field(
        None,
        description=(
            "Quantity step. If `lotSize` is set, then the specified value must be in"
            " lots."
        ),
        examples=[100],
    )
    pipSize: float = Field(
        ...,
        description=(
            "Size of 1 pip.\nIt is equal to `minTick` for non-forex symbols. For forex"
            " pairs it equals either the `minTick`,\nor the `minTick` multiplied by"
            " `10`. For example, for IBM `minTick` it is 0.01, for EURCAD `minTick` it"
            " is 0.00001.\n"
        ),
        examples=[0.0001],
    )
    pipValue: float = Field(
        ...,
        description="Value of 1 pip in the account currency.\n",
        examples=[8.845e-05],
    )
    minTick: float = Field(
        ...,
        description=(
            "Minimum price movement. For example, for IBM `minTick` is 0.01, for EURCAD"
            " `minTick` is 0.00001."
        ),
        examples=[1e-05],
    )
    lotSize: Optional[float] = Field(
        None,
        description=(
            "Financial instrument units standardized number as set by the exchange or"
            " broker for buying or selling."
        ),
        examples=[10],
    )
    currency: Optional[str] = Field(
        None,
        description=(
            "Instrument currency. Used to display position pl in instrument currency."
        ),
        examples=["EUR"],
    )
    baseCurrency: Optional[str] = Field(
        None,
        description=(
            "The first currency quoted in a currency pair. Used for crypto currencies"
            " only."
        ),
        examples=["LTC"],
    )
    quoteCurrency: Optional[str] = Field(
        None,
        description=(
            "A quote currency is the second currency quoted in a currency pair. Used"
            " for crypto currencies only.\n"
        ),
        examples=["BTC"],
    )
    marginRate: Optional[float] = Field(
        None, description="Margin rate for this instrument.", examples=[0.05]
    )
    hasQuotes: Optional[bool] = Field(
        True,
        description=(
            "Indicates if your API provides quotes for this instrument. Assigning"
            " `false` to this field prevents `/quotes` request and makes ask/bid"
            " displayed from a TradingView server depending on users data subscriptions"
            " on TradingView. Use of this flag must be agreed with TradingView"
        ),
        examples=[False],
    )
    units: Optional[str] = Field(
        None,
        description=(
            "Units of quantity or amount. Displayed instead of the `Units` label in the"
            " Quantity/Amount field"
        ),
    )
    variableMinTick: Optional[str] = Field(
        None,
        description=(
            "Dynamic minimum price movement. It is used if the instrument's minimum"
            " price movement changes depending on the price range. For example, '0.01"
            " 10 0.02 25 0.05', where `minTick` is 0.01 for a price less than 10,"
            " `minTick` is 0.02 for a price less than 25, `minTick` is 0.05 for a price"
            " more and equal than 25."
        ),
        examples=["0.01 10 0.02 25 0.05"],
    )
    type: SymbolType
    typespecs: Optional[str] = Field(
        None,
        description=(
            "Additional symbol type information (crypto, cfd, etc.).\nA string of comma"
            " separated values.\n**Applicable values**:\n  - cfd\n  - spreadbet\n  -"
            " crypto\n"
        ),
        examples=["crypto,cfd"],
    )
    ui: Optional[Ui1] = Field(
        None,
        description=(
            "Order dialog configuration for the symbol. It will override"
            " configuration,\nspecified in the [/accounts](#operation/getAccounts)"
            " endpoint.\n"
        ),
    )


class InstrumentsResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Instrument]


class OrderInfoResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: OrderInfo


class QuotesResponse(BaseModel):
    model_config = ConfigDict(
        extra="forbid",
    )
    s: OkStatus
    d: List[Quote] = Field(..., title="Quotes")


class QuotesMessage(RootModel[List[Quote]]):
    root: List[Quote] = Field(..., title="QuotesMessage")
