class Position(Model):
    """The specification of a Position within an Account.

    Attributes:
        instrument: :class:`~async_v20.InstrumentName`
            The Position's Instrument.
        pl: :class:`~async_v20.AccountUnits`
            Profit/loss realized by the Position over the lifetime of the Account.
        unrealized_pl: :class:`~async_v20.AccountUnits`
            The unrealized profit/loss of all open Trades that contribute to this Position.
        resettable_pl: :class:`~async_v20.AccountUnits`
            Profit/loss realized by the Position since the
            Account's resettablePL was last reset by the client.
        commission: :class:`~async_v20.AccountUnits`
            The total amount of commission paid for this instrument over
            the lifetime of the Account. Represented in the Account's home currency.
        long: :class:`~async_v20.PositionSide`
            The details of the long side of the Position.
        short: :class:`~async_v20.PositionSide`
            The details of the short side of the Position.

    """

    def __init__(self, instrument: InstrumentName = sentinel, pl: AccountUnits = sentinel,
                 unrealized_pl: AccountUnits = sentinel,
                 resettable_pl: AccountUnits = sentinel, commission: AccountUnits = sentinel,
                 long: PositionSide = sentinel,
                 short: PositionSide = sentinel, financing: DecimalNumber = sentinel,
                 margin_used: AccountUnits = sentinel,
                 guaranteed_execution_fees: AccountUnits = sentinel):
        Model.__init__(**locals()) class Instrument(Model):
    """Full specification of an Instrument.

    Attributes:
        name: :class:`~async_v20.InstrumentName`
            The name of the Instrument
        type: :class:`~async_v20.InstrumentType`
            The type of the Instrument
        display_name: :class:`str` :class:`~async_v20.InstrumentName`
            The display name of the Instrument
        pip_location: :class:`int`
            The location of the "pip" for this instrument. The decimal position of the pip in this
            Instrument's price can be
            found at 10 ^ pipLocation (e.g. -4 pipLocation results in a decimal pip position of 10 ^ -4 = 0.0001).
        display_precision: :class:`int`
            The number of decimal places that should be used to display prices for this instrument.
            (e.g. a displayPrecision of 5 would result in a price of "1" being displayed as "1.00000")
        trade_units_precision: :class:`int`
            The amount of decimal places that may be provided
            when specifying the number of units traded for this instrument.
        minimum_trade_size: :class:`~async_v20.DecimalNumber`
            The smallest number of units allowed to be traded for this instrument.
        maximum_trailing_stop_distance: :class:`~async_v20.DecimalNumber`
            The maximum trailing stop distance allowed for a trailing
            stop loss created for this instrument. Specified in price units.
        minimum_trailing_stop_distance: :class:`~async_v20.DecimalNumber`
            The minimum trailing stop distance allowed for a trailing
            stop loss created for this instrument. Specified in price units.
        maximum_position_size: :class:`~async_v20.DecimalNumber`
            The maximum position size allowed for this instrument. Specified in units.
        maximum_order_units: :class:`~async_v20.DecimalNumber`
            The maximum units allowed for an Order
            placed for this instrument. Specified in units.
        margin_rate: :class:`~async_v20.DecimalNumber`
            The margin rate for this instrument.
        commission: :class:`~async_v20.InstrumentCommission`
            The commission structure for this instrument.
        guaranteed_stop_loss_order_level_restriction: :class: `~async_v20.GuaranteedStopLossOrderLevelRestriction`
            The total position size that can exist within a given price window for Trades with a guaranteed Stop Loss Orders
            attached for a specific Instrument
        guaranteed_stop_loss_order_mode:
            pass
        financing: :class:`object`

    """

    def __init__(self, name: InstrumentName = sentinel, type: InstrumentType = sentinel, display_name: str = sentinel,
                 pip_location: int = sentinel, display_precision: int = sentinel, trade_units_precision: int = sentinel,
                 minimum_trade_size: DecimalNumber = sentinel, maximum_trailing_stop_distance: DecimalNumber = sentinel,
                 minimum_trailing_stop_distance: DecimalNumber = sentinel,
                 maximum_position_size: DecimalNumber = sentinel,
                 maximum_order_units: DecimalNumber = sentinel, margin_rate: DecimalNumber = sentinel,
                 commission: InstrumentCommission = sentinel,
                 guaranteed_stop_loss_order_level_restriction: GuaranteedStopLossOrderLevelRestriction = sentinel,
                 guaranteed_stop_loss_order_mode: GuaranteedStopLossOrderMode = sentinel,
                 tags: ArrayDict = sentinel, financing: object = sentinel):
        Model.__init__(**locals()) class OrderCancelTransaction(Transaction, type=TransactionType('ORDER_CANCEL')):
    """An OrderCancelTransaction represents the cancellation of an Order in the
    client's Account.

    Attributes:
        id: :class:`~async_v20.TransactionID`
            The Transaction's Identifier.
        time: :class:`~async_v20.DateTime`
            The date/time when the Transaction was created.
        user_id: :class:`int`
            The ID of the user that initiated the creation of the Transaction.
        account_id: :class:`~async_v20.AccountID`
            The ID of the Account the Transaction was created for.
        batch_id: :class:`~async_v20.TransactionID`
            The ID of the "batch" that the Transaction belongs to.
            Transactions in the same batch are applied to the Account simultaneously.
        request_id: :class:`~async_v20.RequestID`
            The Request ID of the request which generated the transaction.
        order_id: :class:`~async_v20.TransactionID`
            The ID of the Order cancelled
        client_order_id: :class:`~async_v20.ClientID`
            The reason that the Order was cancelled.
        reason: :class:`~async_v20.OrderCancelReason`
            The reason that the Order was cancelled.
        replaced_by_order_id: :class:`~async_v20.TransactionID`
            The ID of the Order that replaced this Order
            (only provided if this Order was cancelled for replacement).

    """

    def __init__(self, id: TransactionID = sentinel, time: DateTime = sentinel, user_id: int = sentinel,
                 account_id: AccountID = sentinel, batch_id: TransactionID = sentinel, request_id: RequestID = sentinel,
                 order_id: OrderID = sentinel, client_order_id: ClientID = sentinel,
                 reason: OrderCancelReason = sentinel, replaced_by_order_id: OrderID = sentinel,
                 closed_trade_id: OrderID = sentinel, trade_close_transaction_id: TransactionID = sentinel):
        Model.__init__(**locals()) class ArrayOrder(Array, contains=Order):
    pass class Account(AccountSummary):
    """The full details of a client's Account. This includes full open Trade, open
    Position and pending Order representation.

    Attributes:
        id: :class:`~async_v20.AccountID`
            The Account's identifier
        alias: :class:`str`
            Client-assigned alias for the Account. Only provided
            if the Account has an alias set
        currency: :class:`~async_v20.Currency`
            The home currency of the Account
        balance: :class:`~async_v20.AccountUnits`
            The current balance of the Account. Represented in the Account's home currency.
        created_by_user_id: :class:`int`
            ID of the user that created the Account.
        created_time: :class:`~async_v20.DateTime`
            The date/time when the Account was created.
        pl: :class:`~async_v20.AccountUnits`
            The total profit/loss realized over the lifetime of
            the Account. Represented in the Account's home currency.
        resettable_pl: :class:`~async_v20.AccountUnits`
            The total realized profit/loss for the Account since it was
            last reset by the client. Represented in the Account's home currency.
        resettabled_pl_time: :class:`~async_v20.DateTime`
            The date/time that the Account's resettablePL was last reset.
        commission: :class:`~async_v20.AccountUnits`
            The total amount of commission paid over the lifetime
            of the Account. Represented in the Account's home currency.
        margin_rate: :class:`~async_v20.DecimalNumber`
            Client-provided margin rate override for the Account. The effective margin rate of the Account
            is the lesser of this value and
            the OANDA margin rate for the Account's division. This value is only provided if a margin rate override
            exists for the Account.
        margin_call_enter_time: :class:`~async_v20.DateTime`
            The date/time when the Account entered a margin call state.
            Only provided if the Account is in a margin call.
        margin_call_extension_count: :class:`int`
            The number of times that the Account's current margin call was extended.
        last_margin_call_extension_time: :class:`~async_v20.DateTime`
            The date/time of the Account's last margin call extension.
        open_trade_count: :class:`int`
            The number of Trades currently open in the Account.
        open_position_count: :class:`int`
            The number of Positions currently open in the Account.
        pending_order_count: :class:`int`
            The number of Orders currently pending in the Account.
        hedging_enabled: :class:`bool`
            Flag indicating that the Account has hedging enabled.
        unrealized_pl: :class:`~async_v20.AccountUnits`
            The total unrealized profit/loss for all Trades currently open
            in the Account. Represented in the Account's home currency.
        nav: :class:`~async_v20.AccountUnits`
            The net asset value of the Account. Equal to
            Account balance + unrealizedPL. Represented in the Account's home currency.
        margin_used: :class:`~async_v20.AccountUnits`
            Margin currently used for the Account.
            Represented in the Account's home currency.
        margin_available: :class:`~async_v20.AccountUnits`
            Margin available for Account. Represented in the Account's home currency.
        position_value: :class:`~async_v20.AccountUnits`
            The value of the Account's open
            positions represented in the Account's home currency.
        margin_closeout_unrealized_pl: :class:`~async_v20.AccountUnits`
            The Account's margin closeout unrealized PL.
        margin_closeout_nav: :class:`~async_v20.AccountUnits`
            The Account's margin closeout NAV.
        margin_closeout_margin_used: :class:`~async_v20.AccountUnits`
            The Account's margin closeout margin used.
        margin_closeout_percent: :class:`~async_v20.DecimalNumber`
            The Account's margin closeout percentage. When this value is 1.0
            or above the Account is in a margin closeout situation.
        margin_closeout_position_value: :class:`~async_v20.DecimalNumber`
            The value of the Account's open positions as used
            for margin closeout calculations represented in the Account's home currency.
        withdrawal_limit: :class:`~async_v20.AccountUnits`
            The current WithdrawalLimit for the account which will be zero or
            a positive value indicating how much can be withdrawn from the account.
        margin_call_margin_used: :class:`~async_v20.AccountUnits`
            The Account's margin call margin used.
        margin_call_percent: :class:`~async_v20.DecimalNumber`
            The Account's margin call percentage. When this value is 1.0
            or above the Account is in a margin call situation.
        last_transaction_id: :class:`~async_v20.TransactionID`
            The ID of the last Transaction created for the Account.
        trades: ( :class:`~async_v20.TradeSummary`, ...)
            The details of the Trades currently open in the Account.
        positions: ( :class:`~async_v20.Position`, ...)
            The details all Account Positions.
        orders: ( :class:`~async_v20.Order`, ...)
            The details of the Orders currently pending in the Account.
        dividend: :class:`~async_v20.DecimalNumber`
            Dividend
        dividendAdjustment: :class:`~async_v20.DecimalNumber`
            Undocumented
    """

    def __init__(self, id: AccountID = sentinel, alias: str = sentinel, currency: Currency = sentinel,
                 balance: AccountUnits = sentinel,
                 created_by_user_id: int = sentinel, created_time: DateTime = sentinel, pl: AccountUnits = sentinel,
                 resettable_pl: AccountUnits = sentinel, resettabled_pl_time: DateTime = sentinel,
                 commission: AccountUnits = sentinel, margin_rate: DecimalNumber = sentinel,
                 margin_call_enter_time: DateTime = sentinel, margin_call_extension_count: int = sentinel,
                 last_margin_call_extension_time: DateTime = sentinel, open_trade_count: int = sentinel,
                 open_position_count: int = sentinel, pending_order_count: int = sentinel,
                 hedging_enabled: bool = sentinel,
                 unrealized_pl: AccountUnits = sentinel, nav: AccountUnits = sentinel,
                 margin_used: AccountUnits = sentinel,
                 margin_available: AccountUnits = sentinel, position_value: AccountUnits = sentinel,
                 margin_closeout_unrealized_pl: AccountUnits = sentinel, margin_closeout_nav: AccountUnits = sentinel,
                 margin_closeout_margin_used: AccountUnits = sentinel,
                 margin_closeout_percent: DecimalNumber = sentinel,
                 margin_closeout_position_value: DecimalNumber = sentinel, withdrawal_limit: AccountUnits = sentinel,
                 margin_call_margin_used: AccountUnits = sentinel, margin_call_percent: DecimalNumber = sentinel,
                 last_transaction_id: TransactionID = sentinel, trades: ArrayTradeSummary = sentinel,
                 positions: ArrayPosition = sentinel, orders: ArrayOrder = sentinel,
                 financing: DecimalNumber = sentinel,
                 guaranteed_stop_loss_order_mode: GuaranteedStopLossOrderMode = sentinel,
                 resettable_pl_time: DateTime = sentinel,
                 dividend: DecimalNumber = sentinel,
                 dividend_adjustment: AccountUnits = sentinel,
                 guaranteed_execution_fees: AccountUnits = sentinel):
        Model.__init__(**locals()) class Order(Model):
    """The base Order definition. Contains all possible attributes an Order
    may contain

    Attributes:
        id: :class:`~async_v20.OrderID`
            The Order's identifier, unique within the Order's Account.
        create_time: :class:`~async_v20.DateTime`
            The time when the Order was created.
        state: :class:`~async_v20.OrderState`
            The current state of the Order.
        client_extensions: :class:`~async_v20.ClientExtensions`
            The client extensions of the Order. Do not set, modify,
            or delete clientExtensions if your account is associated with MT4.
        trade_id: :class:`~async_v20.TradeID`
        price: :class:`~async_v20.PriceValue`
        type: :class:`~async_v20.OrderType`
        client_trade_id: :class:`~async_v20.ClientID`
        time_in_force: :class:`~async_v20.TimeInForce`
        gtd_time: :class:`~async_v20.DateTime`
        trigger_condition: :class:`~async_v20.OrderTriggerCondition`
        filling_transaction_id: :class:`~async_v20.TransactionID`
        filled_time: :class:`~async_v20.DateTime`
        trade_opened_id: :class:`~async_v20.TradeID`
        trade_reduced_id: :class:`~async_v20.TradeID`
        trade_closed_ids: ( :class:`~async_v20.TradeID`, ...),
        cancelling_transaction_id: :class:`~async_v20.TransactionID`
        cancelled_time: :class:`~async_v20.DateTime`
        replaces_order_id: :class:`~async_v20.OrderID`
        replaced_by_order_id: :class:`~async_v20.OrderID`
        distance: :class:`~async_v20.PriceValue`
        trailing_stop_value: :class:`~async_v20.PriceValue`
        instrument: :class:`~async_v20.InstrumentName`
        units: :class:`~async_v20.DecimalNumber`
        partial_fill: :class:`str`
        position_fill: :class:`~async_v20.OrderPositionFill`
        take_profit_on_fill: :class:`~async_v20.TakeProfitDetails`
        stop_loss_on_fill: :class:`~async_v20.StopLossDetails`
        trailing_stop_loss_on_fill: :class:`~async_v20.TrailingStopLossDetails`
        trade_client_extensions: :class:`~async_v20.ClientExtensions`
        price_bound: :class:`~async_v20.PriceValue`
        initial_market_price: :class:`~async_v20.PriceValue`
        trade_close: :class:`~async_v20.MarketOrderTradeClose`
        long_position_closeout: :class:`~async_v20.MarketOrderPositionCloseout`
        short_position_closeout: :class:`~async_v20.MarketOrderPositionCloseout`
        margin_closeout: :class:`~async_v20.MarketOrderMarginCloseout`
        delayed_trade_close: :class:`~async_v20.MarketOrderDelayedTradeClose`
        trigger_distance: :class:`~async_v20.PriceValue`
        is_trigger_distance_exact: :class:`bool`
    """

    # TODO: Update the annotation for partial_fill when OANDA responds to email, & `guaranteed`

    def __init__(self, id: OrderID = sentinel, create_time: DateTime = sentinel, state: OrderState = sentinel,
                 client_extensions: ClientExtensions = sentinel, trade_id: TradeID = sentinel,
                 price: PriceValue = sentinel,
                 type: OrderType = sentinel, client_trade_id: ClientID = sentinel,
                 time_in_force: TimeInForce = sentinel,
                 gtd_time: DateTime = sentinel, trigger_condition: OrderTriggerCondition = sentinel,
                 filling_transaction_id: TransactionID = sentinel, filled_time: DateTime = sentinel,
                 trade_opened_id: TradeID = sentinel, trade_reduced_id: TradeID = sentinel,
                 trade_closed_ids: ArrayTradeID = sentinel, cancelling_transaction_id: TransactionID = sentinel,
                 cancelled_time: DateTime = sentinel, replaces_order_id: OrderID = sentinel,
                 replaced_by_order_id: OrderID = sentinel, distance: PriceValue = sentinel,
                 trailing_stop_value: PriceValue = sentinel, instrument: InstrumentName = sentinel,
                 units: DecimalNumber = sentinel,
                 partial_fill: str = sentinel, position_fill: OrderPositionFill = sentinel,
                 take_profit_on_fill: TakeProfitDetails = sentinel,
                 stop_loss_on_fill: StopLossDetails = sentinel,
                 trailing_stop_loss_on_fill: TrailingStopLossDetails = sentinel,
                 trade_client_extensions: ClientExtensions = sentinel, price_bound: PriceValue = sentinel,
                 initial_market_price: PriceValue = sentinel, trade_close: MarketOrderTradeClose = sentinel,
                 long_position_closeout: MarketOrderPositionCloseout = sentinel,
                 short_position_closeout: MarketOrderPositionCloseout = sentinel,
                 margin_closeout: MarketOrderMarginCloseout = sentinel,
                 delayed_trade_close: MarketOrderDelayedTradeClose = sentinel,
                 trigger_distance: PriceValue = sentinel, is_trigger_distance_exact: bool = sentinel,
                 guaranteed: bool = sentinel
                 ):
        Model.__init__(**locals()) class ArrayTransaction(Array, contains=Transaction):
    pass class ArrayTrade(Array, contains=Trade):
    pass class MarketOrderRejectTransaction(Transaction, type=TransactionType('MARKET_ORDER_REJECT')):
    """A MarketOrderRejectTransaction represents the rejection of the creation of
    a Market Order.

    Attributes:
        instrument: :class:`~async_v20.InstrumentName`
            The Market Order's Instrument.
        id: :class:`~async_v20.TransactionID`
            The Transaction's Identifier.
        time: :class:`~async_v20.DateTime`
            The date/time when the Transaction was created.
        user_id: :class:`int`
            The ID of the user that initiated the creation of the Transaction.
        account_id: :class:`~async_v20.AccountID`
            The ID of the Account the Transaction was created for.
        batch_id: :class:`~async_v20.TransactionID`
            The ID of the "batch" that the Transaction belongs to.
            Transactions in the same batch are applied to the Account simultaneously.
        request_id: :class:`~async_v20.RequestID`
            The Request ID of the request which generated the transaction.
        units: :class:`~async_v20.DecimalNumber`
            The quantity requested to be filled by the Market Order. A posititive number of units
            results in a long Order, and a negative number of units results in a short Order.
        time_in_force: :class:`~async_v20.TimeInForce`
            The time-in-force requested for the Market Order.
            Restricted to FOK or IOC for a MarketOrder.
        price_bound: :class:`~async_v20.PriceValue`
            The worst price that the client is willing to have the Market Order filled at.
        position_fill: :class:`~async_v20.OrderPositionFill`
            Specification of how Positions in the Account
            are modified when the Order is filled.
        trade_close: :class:`~async_v20.MarketOrderTradeClose`
            Details of the Trade requested to be closed, only provided when
            the Market Order is being used to explicitly close a Trade.
        long_position_closeout: :class:`~async_v20.MarketOrderPositionCloseout`
            Details of the long Position requested to be closed out, only provided
            when a Market Order is being used to explicitly closeout a long Position.
        short_position_closeout: :class:`~async_v20.MarketOrderPositionCloseout`
            Details of the short Position requested to be closed out, only provided
            when a Market Order is being used to explicitly closeout a short Position.
        margin_closeout: :class:`~async_v20.MarketOrderMarginCloseout`
            Details of the Margin Closeout that this Market Order was created for
        delayed_trade_close: :class:`~async_v20.MarketOrderDelayedTradeClose`
            Details of the delayed Trade close that this Market Order was created for
        reason: :class:`~async_v20.MarketOrderReason`
            The reason that the Market Order was created
        client_extensions: :class:`~async_v20.ClientExtensions`
            Client Extensions to add to the Order (only provided
            if the Order is being created with client extensions).
        take_profit_on_fill: :class:`~async_v20.TakeProfitDetails`
            The specification of the Take Profit Order that should be created for a
            Trade opened when the Order is filled (if such a Trade is created).
        stop_loss_on_fill: :class:`~async_v20.StopLossDetails`
            The specification of the Stop Loss Order that should be created for a
            Trade opened when the Order is filled (if such a Trade is created).
        trailing_stop_loss_on_fill: :class:`~async_v20.TrailingStopLossDetails`
            The specification of the Trailing Stop Loss Order that should be created for a
            Trade that is opened when the Order is filled (if such a Trade is created).
        trade_client_extensions: :class:`~async_v20.ClientExtensions`
            Client Extensions to add to the Trade created when the Order is filled (if such a
            Trade is created). Do not set, modify, delete tradeClientExtensions if your account is associated with MT4.
        reject_reason: :class:`~async_v20.TransactionRejectReason`
            The reason that the Reject Transaction was created

    """

    def __init__(self, instrument: InstrumentName = sentinel, units: DecimalNumber = sentinel,
                 id: TransactionID = sentinel,
                 time: DateTime = sentinel,
                 user_id: int = sentinel, account_id: AccountID = sentinel, batch_id: TransactionID = sentinel,
                 request_id: RequestID = sentinel,
                 time_in_force: TimeInForce = 'FOK', price_bound: PriceValue = sentinel,
                 position_fill: OrderPositionFill = 'DEFAULT', trade_close: MarketOrderTradeClose = sentinel,
                 long_position_closeout: MarketOrderPositionCloseout = sentinel,
                 short_position_closeout: MarketOrderPositionCloseout = sentinel,
                 margin_closeout: MarketOrderMarginCloseout = sentinel,
                 delayed_trade_close: MarketOrderDelayedTradeClose = sentinel, reason: MarketOrderReason = sentinel,
                 client_extensions: ClientExtensions = sentinel, take_profit_on_fill: TakeProfitDetails = sentinel,
                 stop_loss_on_fill: StopLossDetails = sentinel,
                 trailing_stop_loss_on_fill: TrailingStopLossDetails = sentinel,
                 trade_client_extensions: ClientExtensions = sentinel,
                 reject_reason: TransactionRejectReason = sentinel):
        Model.__init__(**locals()) class Transaction(Model):
    """The base Transaction specification. Contains all possible attributes a transaction
    may contain.

    Attributes:
        id: :class:`~async_v20.TransactionID`
            The Transaction's Identifier.
        time: :class:`~async_v20.DateTime`
            The date/time when the Transaction was created.
        user_id: :class:`int`
            The ID of the user that initiated the creation of the Transaction.
        account_id: :class:`~async_v20.AccountID`
            The ID of the Account the Transaction was created for.
        batch_id: :class:`~async_v20.TransactionID`
            The ID of the "batch" that the Transaction belongs to.
            Transactions in the same batch are applied to the Account simultaneously.
        request_id: :class:`~async_v20.RequestID`
            The Request ID of the request which generated the transaction.

    """

    def __init__(self, id: TransactionID = sentinel, time: DateTime = sentinel, user_id: int = sentinel,
                 account_id: AccountID = sentinel, batch_id: TransactionID = sentinel, request_id: RequestID = sentinel,
                 type: TransactionType = sentinel, extension_number: int = sentinel, division_id: int = sentinel,
                 site_id: int = sentinel, account_user_id: int = sentinel, account_number: int = sentinel,
                 home_currency: Currency = sentinel, alias: str = sentinel, margin_rate: DecimalNumber = sentinel,
                 reason: Reason = sentinel, trade_ids: TradeID = sentinel, order_id: OrderID = sentinel,
                 client_order_id: ClientID = sentinel, replaced_by_order_id: OrderID = sentinel,
                 closed_trade_id: OrderID = sentinel, trade_close_transaction_id: TransactionID = sentinel,
                 client_extensions_modify: ClientExtensions = sentinel,
                 trade_client_extensions_modify: ClientExtensions = sentinel, financing: AccountUnits = sentinel,
                 account_balance: AccountUnits = sentinel, account_financing_mode: AccountFinancingMode = sentinel,
                 position_financings: ArrayPositionFinancing = sentinel, trade_id: TradeID = sentinel,
                 client_trade_id: ClientID = sentinel, price: PriceValue = sentinel,
                 time_in_force: TimeInForce = sentinel,
                 gtd_time: DateTime = sentinel, trigger_condition: OrderTriggerCondition = sentinel,
                 client_extensions: ClientExtensions = sentinel, order_fill_transaction_id: TransactionID = sentinel,
                 replaces_order_id: OrderID = sentinel, cancelling_transaction_id: TransactionID = sentinel,
                 reject_reason: TransactionRejectReason = sentinel, amount: AccountUnits = sentinel,
                 funding_reason: FundingReason = sentinel, comment: str = sentinel,
                 instrument: InstrumentName = sentinel,
                 units: DecimalNumber = sentinel, price_bound: PriceValue = sentinel,
                 position_fill: OrderPositionFill = sentinel,
                 trade_close: MarketOrderTradeClose = sentinel,
                 long_position_closeout: MarketOrderPositionCloseout = sentinel,
                 short_position_closeout: MarketOrderPositionCloseout = sentinel,
                 margin_closeout: MarketOrderMarginCloseout = sentinel,
                 delayed_trade_close: MarketOrderDelayedTradeClose = sentinel,
                 take_profit_on_fill: TakeProfitDetails = sentinel, stop_loss_on_fill: StopLossDetails = sentinel,
                 trailing_stop_loss_on_fill: TrailingStopLossDetails = sentinel,
                 trade_client_extensions: ClientExtensions = sentinel, distance: PriceValue = sentinel,
                 full_price: ClientPrice = sentinel, pl: AccountUnits = sentinel, commission: AccountUnits = sentinel,
                 trade_opened: TradeOpen = sentinel, trades_closed: ArrayTradeReduce = sentinel,
                 trade_reduced: TradeReduce = sentinel, intended_replaces_order_id: OrderID = sentinel,
                 # TODO update when OANDA ADVISES correct type. This is currently a guess.
                 gain_quote_home_conversion_factor: DecimalNumber = sentinel,
                 loss_quote_home_conversion_factor: DecimalNumber = sentinel,
                 guaranteed_execution_fee: AccountUnits = sentinel,
                 half_spread_cost: AccountUnits = sentinel,
                 partial_fill: str = sentinel,
                 guaranteed: bool = sentinel,
                 requested_units: AccountUnits = sentinel,
                 full_vwap: DecimalNumber = sentinel):
        Model.__init__(**locals()) class TradeSpecifier(str, Primitive, Specifier):
    """The identification of a Trade as referred to by clients
    """

    # Correct syntax of value
    format_syntax = 'Either the Trade’s OANDA-assigned TradeID or the Trade’s client-provided ' \
                    'ClientID prefixed by the "@" symbol'
    # Example of correct format
    example = '@my_trade_id'

    def __new__(cls, value):
        return super().__new__(cls, value) class OrderSpecifier(str, Primitive, Specifier):
    """The specification of an Order as referred to by clients
    """

    # Correct syntax of value
    format_syntax = 'Either the Order’s OANDA-assigned OrderID or the Order’s client-provided ' \
                    'ClientID prefixed by the "@" symbol'
    # Example of correct format
    example = '1523'

    def __new__(cls, value):
        return super().__new__(cls, value) class PriceComponent(str, Primitive):
    # Valid values
    values = {'M': 'midpoint candles',
              'B': 'bid candles',
              'A': 'ask candles'}

    # Pre-constructed permutations to speed up domain checking
    value_permutations = {'AB', 'B', 'BAM', 'AM', 'M',
                          'BM', 'AMB', 'MBA', 'MA', 'A',
                          'MB', 'ABM', 'BMA', 'MAB', 'BA'}

    def __new__(cls, value):
        assert domain_check(value, possible_values=cls.value_permutations)
        return super().__new__(cls, value) class IncompatibleValue(AsyncV20Exception):
    """A supplied argument is different than the predefined value"""
    pass
from ..data.json_data import GETAccountID_response
from ..data.json_data import position_response
from ..data.json_data import order_cancel_transaction_json_dict
from ..data.json_data import example_order
from ..data.json_data import account_example
from ..data.json_data import example_transaction_array
from ..data.json_data import example_trade_array
from ..data.json_data import example_market_order_reject_transaction
from ..data.json_data import example_transaction
from async_v20.definitions.types import Position
from async_v20.definitions.types import Instrument
from async_v20.definitions.types import OrderCancelTransaction
from async_v20.definitions.types import ArrayOrder
from async_v20.definitions.types import Account
from async_v20.definitions.types import Order
from async_v20.definitions.types import ArrayTransaction
from async_v20.definitions.types import ArrayTrade
from async_v20.definitions.types import MarketOrderRejectTransaction
from async_v20.definitions.types import Transaction
from async_v20.definitions.primitives import TradeSpecifier
from async_v20.definitions.primitives import OrderSpecifier
from async_v20.definitions.primitives import PriceComponent
from async_v20.exceptions import IncompatibleValue
from itertools import permutations
import pandas as pd
import pytest


def test_account_builds_from_dict():
    account_instance = Account(**GETAccountID_response['account'])
    assert type(account_instance) == Account
    series = account_instance.series()
    assert type(series) == pd.Series


def test_position_builds_from_dict():
    position = Position(**position_response)
    assert type(position) == Position
    series = position.series()
    assert type(series) == pd.Series


def test_order_cancel_transaction_builds_from_dict():
    order_cancel_transaction = OrderCancelTransaction(**order_cancel_transaction_json_dict)
    assert type(order_cancel_transaction) == OrderCancelTransaction
    series = order_cancel_transaction.series()
    assert type(series) == pd.Series


def test_supplying_incorret_preset_argument_raises_error():
    order_cancel_transaction_json_dict.update(type='INCORRECT VALUE')
    with pytest.raises(IncompatibleValue):
        OrderCancelTransaction(**order_cancel_transaction_json_dict)

def test_passing_empty_list_tuple_to_array_returns_empty_array():
    array_order = ArrayOrder(*[])
    assert type(array_order) == ArrayOrder
    account = Account(orders=[])
    assert type(account.orders) == ArrayOrder
    account = Account(orders=())
    assert type(account.orders) == ArrayOrder

def test_specifiers_can_be_constructed_from_int():

    assert type(TradeSpecifier(1234)) == TradeSpecifier