# generated by datamodel-codegen:
#   filename:  openapi.yaml
#   timestamp: 2023-05-31T20:26:09+00:00

from __future__ import annotations

from datetime import date, datetime
from enum import Enum
from typing import Any, Dict, List, Optional, Union

from pydantic import BaseModel, Extra, Field, StrictBool, StrictStr, conint, constr
from typing_extensions import Literal


class Role(Enum):
    data_point = "data point"
    verification = "verification"
    calculation = "calculation"
    development = "development"
    administration = "administration"


class Administrative(BaseModel):
    class Config:
        extra = Extra.forbid

    role: Role


class CalcFreq(Enum):
    Daily = "Daily"
    Daily__EOD = "Daily, EOD"
    Intraday = "Intraday"


class DisplayMonth(Enum):
    Jan = "Jan"
    Feb = "Feb"
    Mar = "Mar"
    Apr = "Apr"
    May = "May"
    Jun = "Jun"
    Jul = "Jul"
    Aug = "Aug"
    Sep = "Sep"
    Oct = "Oct"
    Nov = "Nov"
    Dec = "Dec"


class FieldModel(BaseModel):
    display_name: Optional[StrictStr] = None
    field_name: Optional[StrictStr] = None


class PortfolioDisplay(BaseModel):
    fields: Optional[List[FieldModel]] = None


class RebalFreq(Enum):
    Annual = "Annual"
    Daily = "Daily"
    Monthly = "Monthly"
    Quarterly = "Quarterly"
    Semi_Annual = "Semi-Annual"
    Weekly = "Weekly"
    Bi_Monthly = "Bi-Monthly"
    Intraday = "Intraday"
    None_ = "None"


class Stage(Enum):
    prod = "prod"
    test = "test"
    development = "development"


class WeightingMethod(Enum):
    Other = "Other"
    Equal = "Equal"


class MerqTimestamp(BaseModel):
    __root__: Union[
        datetime,
        date,
        constr(regex=r"^[0-9]{4}-[0-9]{2}-[0-9]{2}(?:[ T][0-9]{2}:[0-9]{2}:[0-9]{2})?(?:[.][0-9]{1,6})?$", strict=True),
    ] = Field(..., example=["2021-01-01", "2021-01-01T01:01:01", "2021-01-01T01:01:01.zzzzz"])


class Status(BaseModel):
    created_at: Optional[StrictStr] = None
    created_by: Optional[StrictStr] = None
    last_modified: StrictStr
    last_modified_by: Optional[StrictStr] = None
    locked_after: Optional[datetime] = Field(
        None,
        description="If this is set (non null), the manifest is locked for all edits to any other field after this timestamp. A PUT/PATCH may be used to first unlock the manifest, by setting this field (to a max of one hour in the future), or to `null` again, to make other edits.",
    )


class Condition(Enum):
    any = "any"
    all = "all"
    custom = "custom"


class WeekmaskEnum(Enum):
    Mon = "Mon"
    Tue = "Tue"
    Wed = "Wed"
    Thu = "Thu"
    Fri = "Fri"
    Sat = "Sat"
    Sun = "Sun"


class HolidayCalendarSpec(BaseModel):
    class Config:
        extra = Extra.forbid

    calendar_identifiers: Optional[List[constr(regex=r"^(FUT|MIC|FX):.+$", strict=True)]] = None
    swaps_monitor_codes: Optional[List[constr(regex=r"^[a-zA-Z]{3}$", strict=True)]] = None
    condition: Optional[Condition] = None
    holidays_to_add: Optional[List[date]] = None
    holidays_to_remove: Optional[List[date]] = None
    weekmask: Optional[List[WeekmaskEnum]] = Field(
        ["Mon", "Tue", "Wed", "Thu", "Fri"], description="weekmask of valid business days"
    )


class CommandArguments(BaseModel):
    __root__: List[List[StrictStr]]


class SubPod(BaseModel):
    class Config:
        extra = Extra.forbid

    arguments: Optional[CommandArguments] = None
    command: StrictStr
    pod_type: StrictStr
    uuid: StrictStr


class S3Bucket(BaseModel):
    class Config:
        extra = Extra.forbid

    bucket: StrictStr
    path: Optional[StrictStr] = None


class AirflowConfig(BaseModel):
    class Config:
        extra = Extra.forbid

    description: Optional[StrictStr] = Field(None, description="A short description related with the generated runner")
    s3_location: Optional[S3Bucket] = Field(
        None,
        description="Bucket and path where the generated dag should be stored. If not defined `merq-airflow-dags-airflow2` is defined in merqutil",
    )
    dag: Optional[Dict[str, Any]] = Field(None, description="use this to set kwargs for the dag")
    pod: Optional[Dict[str, Any]] = Field(None, description="use this to set kwargs for the pod")
    env: Optional[Dict[str, Any]] = Field(None, description="use this to set ENV variables in the pod")
    subpods: Optional[List[SubPod]] = None


class EmailDissapiConfig(BaseModel):
    recipient_list: List[StrictStr] = Field(..., min_items=1)
    email_list: Optional[List[StrictStr]] = None
    bcc_list: Optional[List[StrictStr]] = None
    cc_list: Optional[List[StrictStr]] = None
    subject: StrictStr
    content: Optional[StrictStr] = None
    file_keys: Optional[List[StrictStr]] = None


class SftpDissapiConfig(BaseModel):
    sftp_ids: List[StrictStr]
    file_keys: List[StrictStr]


class S3DissapiConfig(BaseModel):
    bucket: StrictStr
    key_prefix: StrictStr
    file_keys: List[StrictStr]


class DisseminationDestinations(BaseModel):
    email_dissapi_configs: Optional[List[EmailDissapiConfig]] = Field(None, min_items=1)
    sftp_dissapi_configs: Optional[List[SftpDissapiConfig]] = None
    s3_dissapi_configs: Optional[List[S3DissapiConfig]] = None


class IndexReport(BaseModel):
    uuid: StrictStr
    program_args: Optional[Dict[str, Any]] = None
    dissemination_destinations: Optional[DisseminationDestinations] = None


class RunConfigLabelAdditional(BaseModel):
    label: StrictStr = Field(..., description="unique label of this rc")


class HolidayCalendar(BaseModel):
    cal_type: Optional[StrictStr] = Field(None, example="MIC")
    mic: Optional[StrictStr] = Field(None, example="XNYS")


class Schedule(BaseModel):
    class Config:
        extra = Extra.forbid

    retries: int
    retry_interval_min: int
    schedule_start: StrictStr
    schedule_cron: Optional[StrictStr] = None
    timeout_delta: Optional[StrictStr] = Field(None, example="minutes=17")
    business_days_prior: Optional[int] = Field(None, example=1)
    holiday_calendar: Optional[HolidayCalendar] = None


class CopyFromManifest(BaseModel):
    copy_from_uuid: StrictStr = Field(..., description="the uuid of the resource to start from")
    field_deletes: Optional[List[StrictStr]] = Field(None, description="fields to delete from the from-manifest")
    field_updates: Optional[Dict[str, Any]] = Field(
        None,
        description="a dictionary of top level keys that the original manifest will be updated with (ie `manifest.update(this[field_updates])`. Top level keys can be added or replaced. To change the namespace, add namespace to the field_updates dict. The new manifest must be valid per the original resource definition.",
    )
    name: StrictStr = Field(..., description="the name of the new resource")


class CrudExtra(BaseModel):
    class Config:
        extra = Extra.forbid

    id: StrictStr
    namespace: StrictStr
    status: Status


class IndexClassDefinitionPost(BaseModel):
    class Config:
        extra = Extra.forbid

    name: StrictStr
    namespace: Optional[StrictStr] = None
    index_class_args_spec: Dict[str, Any]


class IndexClassDefinitionPatchPutGet(IndexClassDefinitionPost, CrudExtra):
    pass

    class Config:
        extra = Extra.forbid


class IndexSpec(BaseModel):
    index_class: Optional[StrictStr] = None
    index_class_args: Optional[Dict[str, Any]] = Field(
        None,
        description="should validate against index_class_args_spec field of the IndexClassDefinition identified by index_class",
    )
    index_variables: Optional[Dict[str, Any]] = Field(None, description="TODO")
    version: Optional[int] = None


class Type(Enum):
    security = "security"
    index = "index"


class Related(BaseModel):
    default_display: Optional[StrictBool] = False
    id: StrictStr
    metric: Optional[StrictStr] = None
    name: StrictStr
    type: Type


class ChartType(Enum):
    line = "line"
    spline = "spline"
    area = "area"
    bar = "bar"
    column = "column"


class CompareMode(Enum):
    absolute = "absolute"
    percent = "percent"


class ConstructorType(Enum):
    chart = "chart"
    stockChart = "stockChart"


class Value(BaseModel):
    class Config:
        extra = Extra.forbid

    display_name: StrictStr
    path: StrictStr


class Datum(BaseModel):
    class Config:
        extra = Extra.forbid

    url: StrictStr
    array_field: StrictStr
    values: List[Value]
    key_field: StrictStr


class CustomCharts(BaseModel):
    class Config:
        extra = Extra.forbid

    name: StrictStr
    xlabel: StrictStr
    ylabel: StrictStr
    chart_type: Optional[ChartType] = "line"
    compare_mode: Optional[CompareMode] = "percent"
    constructor_type: Optional[ConstructorType] = "stockChart"
    size: Optional[float] = 12
    data: Optional[List[Datum]] = None


class IndexBenchmark(BaseModel):
    class Config:
        extra = Extra.forbid

    ticker: StrictStr
    threshold: float
    index_metric: Optional[StrictStr] = Field(
        "price_return",
        description="the metric to compare against the ticker/threshold, eg can compare some other metric than price_return",
    )


class Provider(Enum):
    bloomberg = "bloomberg"
    reuters = "reuters"
    morningstar = "morningstar"
    factset = "factset"
    nasdaq = "nasdaq"
    wind = "wind"
    secapi = "secapi"


class BloombergProviderKwargsPostType(Enum):
    EOD = "EOD"
    RT = "RT"
    EOD_AND_RT = "EOD_AND_RT"


class BloombergProviderKwargs(BaseModel):
    class Config:
        extra = Extra.forbid

    post_type: BloombergProviderKwargsPostType


class ReutersProviderKwargsPostType(Enum):
    EOD = "EOD"
    RT = "RT"
    EOD_AND_RT = "EOD_AND_RT"


class ReutersProviderKwargs(BaseModel):
    class Config:
        extra = Extra.forbid

    post_type: Optional[ReutersProviderKwargsPostType] = None


class SecapiProviderKwargs(BaseModel):
    class Config:
        extra = Extra.forbid

    security_type: StrictStr
    security_name: StrictStr
    metric: StrictStr


class NasdaqEnv(Enum):
    testing = "testing"
    production = "production"


class NasdaqProviderKwargs(BaseModel):
    class Config:
        extra = Extra.forbid

    nasdaq_env: NasdaqEnv = Field(..., description="Which Nasdaq environment to send data to")
    eod_date_delta: Optional[int] = Field(
        None,
        description="How many days to offset the Nasdaq date (T if before 6:30pm EST otherwise T + 1) when getting EOD data from the Index",
    )


class Compression(Enum):
    NONE = "NONE"
    GZIP = "GZIP"


class LayoutType(Enum):
    SINGLE_FILE = "SINGLE_FILE"
    YEARLY_DIR_DAILY_FILE = "YEARLY_DIR_DAILY_FILE"


class DataCollectionsSpec(BaseModel):
    class Config:
        extra = Extra.allow

    index_dc_subtype: StrictStr = Field(
        ..., description="Index Data Collection Subtype object key moves to array after transformation"
    )
    auto_persist: Optional[StrictBool] = Field(
        False, description="Boolean to indicate whether to automatically persist the data. Default is False."
    )
    compression: Optional[Compression] = "GZIP"
    date_col: Optional[StrictStr] = "date"
    format: Optional[Literal["csv"]] = "csv"
    layout_type: Optional[LayoutType] = Field(
        "SINGLE_FILE",
        description="SINGLE_FILE: one file. YEARLY_DIR_DAILY_FILE: one directory per year, each day, a file with YYYYMMDD format.",
    )
    location: StrictStr
    name: constr(regex=r"^[A-Za-z0-9_]*$", min_length=3, max_length=128, strict=True)
    seed_file_path: Optional[StrictStr] = Field(None, description="Seed file for the data collection.")
    start_time: Optional[StrictStr] = None


class RealTimeTradeType(Enum):
    ELIGIBLE = "ELIGIBLE"
    INELIGIBLE = "INELIGIBLE"


class PortfolioUom(Enum):
    WEIGHT = "WEIGHT"
    UNITS = "UNITS"


class IdentifierType(Enum):
    RIC = "RIC"
    CURRENCY_CODE = "CURRENCY_CODE"


class AssetType(Enum):
    CASH = "CASH"
    THIRD_PARTY_INDEX = "THIRD_PARTY_INDEX"
    EQUITY = "EQUITY"


class SecurityCreationResponse(BaseModel):
    id: Optional[StrictStr] = None
    inserts: Optional[int] = None


class NewSecurity(BaseModel):
    class Config:
        extra = Extra.forbid

    name: StrictStr
    namespace: StrictStr = Field(
        ...,
        description="the calling user must have permission to this namespace to create the security in this namespace",
    )
    eff_ts: Optional[MerqTimestamp] = Field(
        None,
        description="DEPRECATED: this is no longer used for security creates, but allowed for backwards compatibility",
    )
    prov_ts: MerqTimestamp
    source: Optional[StrictStr] = None


class SecurityMetrics(BaseModel):
    eff_ts: MerqTimestamp
    id: StrictStr = Field(..., example="0000699a-fcd7-45d4-8ce4-064a4ffeced0")
    metric: StrictStr = Field(..., example="Level")
    source: Optional[StrictStr] = Field(None, example="some_gcp_feed")
    prov_ts: MerqTimestamp
    value: Union[StrictStr, float, int, StrictBool, List, Dict[str, Any]]


class SecurityMetricsDeletion(BaseModel):
    eff_ts: MerqTimestamp
    id: StrictStr = Field(..., example="0000699a-fcd7-45d4-8ce4-064a4ffeced0")
    metric: StrictStr = Field(..., example="Level")
    prov_ts: Optional[MerqTimestamp] = None
    source: Optional[StrictStr] = Field(None, example="some_gcp_feed")


class DataType(Enum):
    string = "string"
    float64 = "float64"
    datetime64 = "datetime64"
    int64 = "int64"
    bool = "bool"
    object = "object"


class MetricsSchema(BaseModel):
    data_type: DataType
    description: StrictStr = Field(..., description="a description of what this metric represents")
    name: StrictStr = Field(..., description="metric name")
    object_schema: Optional[Dict[str, Any]] = Field(
        None,
        description="optional - this supports complex objects, ie you can specify the  metric is of this schema. THis allows you to upload a json schema itself of this metric. THis is for downstream users of this metric.",
    )


class IdentifierType1(Enum):
    RIC = "RIC"
    secapi_name = "secapi_name"


class Security(BaseModel):
    class Config:
        extra = Extra.forbid

    identifier_type: IdentifierType1
    identifier_value: StrictStr = Field(..., example="AAPL.QQ")
    security_type: StrictStr = Field(..., example="equity")


class SecurityListPost(BaseModel):
    class Config:
        extra = Extra.forbid

    name: StrictStr = Field(..., description="unique name among all other security lists")
    namespace: Optional[StrictStr] = None
    realtime: Optional[StrictBool] = None
    securities: List[Security]


class SecurityListPatchPutGet(SecurityListPost, CrudExtra):
    pass

    class Config:
        extra = Extra.forbid


class OptionResponse(BaseModel):
    price: Optional[float] = Field(None, description="Option Price")
    vol: Optional[float] = Field(None, description="Implied Volatility")
    interest_rate: Optional[float] = Field(None, description="Implied Interest Rate")
    dividend_yield: Optional[float] = Field(None, description="Implied Dividend Yield for the underlying")
    spot: Optional[float] = Field(None, description="Underlying spot price")
    delta: Optional[float] = Field(None, description="Delta of this option")
    theta: Optional[float] = Field(None, description="Theta of the option being priced")
    gamma: Optional[float] = Field(None, description="Gamma of the option being priced")
    vega: Optional[float] = Field(None, description="Vega of the option being priced")
    bid_ask_spread: Optional[float] = Field(
        None, description="Spread between Bid and Ask prices of the option being priced"
    )
    request_id: Optional[StrictStr] = Field(None, description="Request ID sent in the request")


class FindStrikeResponse(BaseModel):
    strike: Optional[float] = Field(None, description="Strike that prices to the given budget.")
    spot: Optional[float] = Field(None, description="Underlying spot price.")
    strike_percentage: Optional[float] = Field(
        None, description="Strike as a percentage of the underlying spot price that prices to the given budget."
    )
    request_id: Optional[StrictStr] = Field(None, description="Request ID sent in the request")


class MetricsArrItem(BaseModel):
    id: Optional[StrictStr] = Field(None, example="price_return")
    value: Optional[float] = Field(None, example=1000.0000000000002)


class MetricsArr(BaseModel):
    __root__: List[MetricsArrItem]


class Stats(BaseModel):
    annual_volatility: Optional[float] = Field(None, example=3.717606464173326)
    annualized_return: Optional[float] = Field(None, example=6.665050717276233)
    cumulative_return: Optional[float] = Field(None, example=2.7597506251556547)
    id: Optional[StrictStr] = Field(None, example="YTD")
    max_drawdown: Optional[float] = Field(None, example=-1.3877029296510448)
    sharpe_ratio: Optional[float] = Field(None, example=1.759543308780235)
    start_date: Optional[MerqTimestamp] = None
    end_date: Optional[MerqTimestamp] = None


class MetricsDef(BaseModel):
    name: Optional[StrictStr] = Field(None, example="daily_return")
    type: Optional[StrictStr] = Field(None, example="double")


class ErrorCodes(BaseModel):
    code: Optional[StrictStr] = None
    message: Optional[StrictStr] = None


class IntradayTickFilter(BaseModel):
    class Config:
        extra = Extra.forbid

    start_date: Optional[MerqTimestamp] = None
    end_date: Optional[MerqTimestamp] = None
    start_time: Optional[StrictStr] = Field(
        None,
        description="Inclusive start time of the day to start running this intraday index. Format is %H:%M:%S.%f. This should be in the timezone of the index based on tzinfo.",
        example="20:39:00.262345",
    )
    end_time: Optional[StrictStr] = Field(
        None,
        description="Inclusive end time of the day to stop running this intraday index. Format is %H:%M:%S.%f. This should be in the timezone of the index based on tzinfo.",
        example="20:39:00.262345",
    )
    days_of_week: Optional[List[int]] = Field(
        None,
        description="Which days of the week to run the index. Each day of the week is denoted by an integer with Monday = 0 and Sunday = 6",
    )
    exclude_holidays: Optional[StrictBool] = Field(
        None,
        description="If this is True use the index holiday calendar to decide which days to run the index. It will only run on non-holidays.",
    )


class IntradayPublishConfigTargetBase(BaseModel):
    active_time_ranges: Optional[List[IntradayTickFilter]] = Field(
        None,
        description="Time ranges during which values should be published to this target. Target level active_time_ranges override publish_config metric level active_time_ranges.",
    )


class IntradayPublishConfigDbTarget(IntradayPublishConfigTargetBase):
    target: Literal["db"]


class IntradayPublishConfigSecapiTarget(IntradayPublishConfigTargetBase):
    target: Literal["secapi"]


class IntradayPublishConfigBloombergTargetParams(BaseModel):
    class Config:
        extra = Extra.forbid

    rounding_decimals: Optional[int] = None
    ticker: Optional[StrictStr] = None


class IntradayPublishConfigBloombergTarget(IntradayPublishConfigTargetBase):
    target: Literal["bloomberg"]
    params: Optional[IntradayPublishConfigBloombergTargetParams] = None


class IntradayPublishConfigReutersTargetParams(BaseModel):
    class Config:
        extra = Extra.forbid

    rounding_decimals: Optional[int] = None
    ticker: Optional[StrictStr] = None
    post_type: Optional[ReutersProviderKwargsPostType] = None


class IntradayPublishConfigReutersTarget(IntradayPublishConfigTargetBase):
    target: Literal["reuters"]
    params: Optional[IntradayPublishConfigReutersTargetParams] = None


class IntradayPublishConfigTarget(BaseModel):
    __root__: Union[
        IntradayPublishConfigDbTarget,
        IntradayPublishConfigSecapiTarget,
        IntradayPublishConfigBloombergTarget,
        IntradayPublishConfigReutersTarget,
    ]


class IntradayPublishConfigItem(BaseModel):
    class Config:
        extra = Extra.forbid

    default_active_time_ranges: Optional[List[IntradayTickFilter]] = Field(
        None,
        description="Time ranges during which values should be published for this metric. This will be overriden if a target level active_time_ranges is set.",
    )
    targets: List[IntradayPublishConfigTarget] = Field(..., description="List of targets to send this index metric too")


class IntradayPublishConfig(BaseModel):
    __root__: Optional[Dict[str, Union[IntradayPublishConfigItem, List[IntradayPublishConfigTarget]]]] = None


class Intraday(BaseModel):
    class Config:
        extra = Extra.forbid

    enabled: StrictBool = Field(..., description="If the intraday process should be run or not")
    security_id: Optional[StrictStr] = Field(
        None, description="Security ID of the intraday_index security where ticker data is served"
    )
    ticker_period: Optional[float] = Field(None, description="Duration between ticker datapoints. In seconds")
    tzinfo: Optional[StrictStr] = Field(None, description="Timezone of intraday tick timestamp comparisons")
    active_time_ranges: Optional[List[IntradayTickFilter]] = None
    publish_config: Optional[IntradayPublishConfig] = None
    calculation_max_retry_delay: Optional[conint(ge=0)] = Field(
        None,
        description="How many seconds to keep retrying the real time calculation before setting the force flag. Defalts to 0 which means retry forever.",
    )
    resource_cpu_request: Optional[conint(ge=1)] = Field(
        None, description="Minimum cpu resources requested in milliCPU"
    )
    resource_memory_request: Optional[conint(ge=0)] = Field(
        None, description="Minimum memory resources requested in mebibytes."
    )
    heartbeat_timeout: Optional[conint(ge=1)] = Field(
        None, description="Max number of seconds between heartbeats before the rtindex pod is considered unhealthy"
    )
    startup_failure_timeout: Optional[conint(ge=1)] = Field(
        None,
        description="Max number of seconds to wait for the first heartbeat from the rtindex pod before considering it a failed startup. By default it will wait 40sec",
    )
    data_refresh_period: Optional[conint(ge=0)] = Field(
        None,
        description="After the rtindex refreshes its data this is the number of seconds to wait before refreshing again. 0 means do not refresh. Defaults to 3600 seconds (60min)",
    )


class RunConfig(BaseModel):
    class Config:
        extra = Extra.allow

    airflow_config: Optional[AirflowConfig] = None
    command: Optional[StrictStr] = None
    command_arguments: Optional[CommandArguments] = None
    index_report_uuids: Optional[List[StrictStr]] = None
    index_reports: Optional[Union[List[StrictStr], List[IndexReport]]] = None
    job_enabled: StrictBool
    holiday_calendar: Optional[HolidayCalendarSpec] = None
    pod_image_and_tag: Optional[StrictStr] = Field(None, description="overrides the image")
    schedule: Schedule
    tzinfo: Optional[StrictStr] = None


class RunConfigLabel(RunConfig, RunConfigLabelAdditional):
    pass

    class Config:
        extra = Extra.allow


class Webpage(BaseModel):
    custom_charts: Optional[List[CustomCharts]] = None
    visible: Optional[StrictBool] = True


class IdentifierUUIDPost(BaseModel):
    class Config:
        extra = Extra.forbid

    display_name: Optional[StrictStr] = None
    index_name: StrictStr
    metric: Optional[StrictStr] = None
    name: StrictStr = Field(..., description="unique name among all other Identifiers of the provider resource type.")
    namespace: Optional[StrictStr] = None
    rounding_decimals: Optional[int] = None
    provider_kwargs: Optional[
        Union[BloombergProviderKwargs, ReutersProviderKwargs, SecapiProviderKwargs, NasdaqProviderKwargs]
    ] = None
    start_date: Optional[date] = None
    ticker: StrictStr


class IdentifierUUIDPatchPutGet(IdentifierUUIDPost, CrudExtra):
    pass

    class Config:
        extra = Extra.forbid


class IdentifierUUIDRef(BaseModel):
    class Config:
        extra = Extra.forbid

    name: StrictStr
    provider: Provider


class BasketPosition(BaseModel):
    class Config:
        extra = Extra.forbid

    amount: float = Field(..., title="Amount")
    asset_type: AssetType
    identifier: StrictStr = Field(..., title="Identifier")
    identifier_type: IdentifierType = Field(..., title="Identifier Type")
    position_id: Optional[StrictStr] = Field(None, title="Position Id")


class RicEquityPosition(BasketPosition):
    class Config:
        extra = Extra.forbid

    real_time_trade_types: Optional[List[RealTimeTradeType]] = None
    use_primary_listing: Optional[StrictBool] = Field(
        False,
        description="use the security's primary listing rather than the one from the identifier",
        title="Use Primary Listing",
    )


class Metrics(BaseModel):
    ts: Optional[datetime] = Field(None, description="iso8601 format")
    metrics: Optional[MetricsArr] = None


class IndexDefinitionPost(BaseModel):
    class Config:
        extra = Extra.forbid

    administrative: Administrative
    base_date: Optional[StrictStr] = None
    base_year: Optional[int] = None
    benchmark: Optional[Union[IndexBenchmark, List[IndexBenchmark]]] = None
    buffer_end: Optional[float] = None
    buffer_start: Optional[float] = None
    calc_freq: Optional[CalcFreq] = None
    currency: Optional[StrictStr] = None
    custom_metrics: Optional[List[MetricsSchema]] = None
    description: StrictStr
    display_month: Optional[DisplayMonth] = None
    documents: Optional[Dict[str, Any]] = None
    excess_strategy: Optional[Literal["keep_in_cash"]] = None
    family: StrictStr
    family_description: Optional[StrictStr] = None
    identifiers: Optional[List[IdentifierUUIDRef]] = Field(None, min_items=0)
    index_class_uuid: Optional[StrictStr] = None
    intraday: Optional[Intraday] = Field(
        None, description="Only available for indexes with intraday tick computation", title="Intraday Details"
    )
    launch_date: StrictStr
    methodology: Optional[StrictStr] = None
    month: Optional[int] = None
    name: constr(regex=r"^[a-zA-Z][a-zA-Z0-9-_]{0,99}$", strict=True)
    namespace: Optional[StrictStr] = None
    plot_metric: Optional[StrictStr] = None
    portfolio_allocation_display: Optional[StrictBool] = Field(
        None, description="whether or not portfolio_allocations are shown on the website. False by default"
    )
    portfolio_display: Optional[PortfolioDisplay] = None
    rebal_freq: Optional[RebalFreq] = None
    related: Optional[List[Related]] = None
    run_configuration: Optional[RunConfig] = None
    run_configurations: Optional[List[RunConfigLabel]] = None
    spec: Optional[IndexSpec] = None
    stage: Stage
    tags: Optional[StrictStr] = None
    title: StrictStr
    webpage: Optional[Webpage] = None
    weighting_method: Optional[WeightingMethod] = None


class IndexDefinitionPatchPutGet(IndexDefinitionPost, CrudExtra):
    pass

    class Config:
        extra = Extra.forbid


class EquityBasketPortfolio(BaseModel):
    class Config:
        extra = Extra.forbid

    positions: List[Union[BasketPosition, RicEquityPosition]] = Field(..., title="Positions")
    timestamp: MerqTimestamp = Field(
        ..., description="the time at which the portfolio should take effect", title="Timestamp"
    )
    unit_of_measure: PortfolioUom = Field(
        ...,
        description="indicates if the quantities in positions are absolute values, e.g. shares of equity positions, or relative weights of the total portfolio.",
    )
