"""
Binance Algo REST API

OpenAPI Specification for the Binance Algo REST API
The version of the OpenAPI document: 1.0.0
Generated by OpenAPI Generator (https://openapi-generator.tech)

Do not edit the class manually.
"""

from typing import Optional, Union
from requests import Session
from binance_common.configuration import ConfigurationRestAPI
from binance_common.errors import RequiredError
from binance_common.models import ApiResponse
from binance_common.signature import Signers
from binance_common.utils import send_request

from ..models import CancelAlgoOrderFutureAlgoResponse
from ..models import QueryCurrentAlgoOpenOrdersFutureAlgoResponse
from ..models import QueryHistoricalAlgoOrdersFutureAlgoResponse
from ..models import QuerySubOrdersFutureAlgoResponse
from ..models import TimeWeightedAveragePriceFutureAlgoResponse
from ..models import VolumeParticipationFutureAlgoResponse


class FutureAlgoApi:
    """API Client for FutureAlgoApi endpoints."""

    def __init__(
        self,
        configuration: ConfigurationRestAPI = None,
        session: Session = None,
        signer: Signers = None,
    ) -> None:
        self._configuration = configuration
        self._session = session
        self._signer = signer

    def cancel_algo_order_future_algo(
        self,
        algo_id: Union[int, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CancelAlgoOrderFutureAlgoResponse]:
        """
                Cancel Algo Order(TRADE)
                DELETE /sapi/v1/algo/futures/order
                https://developers.binance.com/docs/algo/future-algo/Cancel-Algo-Order

                Cancel an active order.

        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 1

                Args:
                    algo_id (Union[int, None]): eg. 14511
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[CancelAlgoOrderFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if algo_id is None:
            raise RequiredError(
                field="algo_id", error_message="Missing required parameter 'algo_id'"
            )

        body = {}
        payload = {"algo_id": algo_id, "recv_window": recv_window}

        return send_request(
            self._session,
            self._configuration,
            method="DELETE",
            path="/sapi/v1/algo/futures/order",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=CancelAlgoOrderFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def query_current_algo_open_orders_future_algo(
        self,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryCurrentAlgoOpenOrdersFutureAlgoResponse]:
        """
                Query Current Algo Open Orders(USER_DATA)
                GET /sapi/v1/algo/futures/openOrders
                https://developers.binance.com/docs/algo/future-algo/Query-Current-Algo-Open-Orders

                Query Current Algo Open Orders

        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 1

                Args:
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[QueryCurrentAlgoOpenOrdersFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        body = {}
        payload = {"recv_window": recv_window}

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/algo/futures/openOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QueryCurrentAlgoOpenOrdersFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def query_historical_algo_orders_future_algo(
        self,
        symbol: Optional[str] = None,
        side: Optional[str] = None,
        start_time: Optional[int] = None,
        end_time: Optional[int] = None,
        page: Optional[int] = None,
        page_size: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QueryHistoricalAlgoOrdersFutureAlgoResponse]:
        """
                Query Historical Algo Orders(USER_DATA)
                GET /sapi/v1/algo/futures/historicalOrders
                https://developers.binance.com/docs/algo/future-algo/Query-Historical-Algo-Orders

                Query Historical Algo Order

        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 1

                Args:
                    symbol (Optional[str] = None): Trading symbol eg. BTCUSDT
                    side (Optional[str] = None): BUY or SELL
                    start_time (Optional[int] = None): in milliseconds  eg.1641522717552
                    end_time (Optional[int] = None): in milliseconds  eg.1641522526562
                    page (Optional[int] = None): Default is 1
                    page_size (Optional[int] = None): MIN 1, MAX 100; Default 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[QueryHistoricalAlgoOrdersFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        body = {}
        payload = {
            "symbol": symbol,
            "side": side,
            "start_time": start_time,
            "end_time": end_time,
            "page": page,
            "page_size": page_size,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/algo/futures/historicalOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QueryHistoricalAlgoOrdersFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def query_sub_orders_future_algo(
        self,
        algo_id: Union[int, None],
        page: Optional[int] = None,
        page_size: Optional[int] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[QuerySubOrdersFutureAlgoResponse]:
        """
                Query Sub Orders(USER_DATA)
                GET /sapi/v1/algo/futures/subOrders
                https://developers.binance.com/docs/algo/future-algo/Query-Sub-Orders

                Get respective sub orders for a specified algoId

        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 1

                Args:
                    algo_id (Union[int, None]): eg. 14511
                    page (Optional[int] = None): Default is 1
                    page_size (Optional[int] = None): MIN 1, MAX 100; Default 100
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[QuerySubOrdersFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if algo_id is None:
            raise RequiredError(
                field="algo_id", error_message="Missing required parameter 'algo_id'"
            )

        body = {}
        payload = {
            "algo_id": algo_id,
            "page": page,
            "page_size": page_size,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="GET",
            path="/sapi/v1/algo/futures/subOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QuerySubOrdersFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def time_weighted_average_price_future_algo(
        self,
        symbol: Union[str, None],
        side: Union[str, None],
        quantity: Union[float, None],
        duration: Union[int, None],
        position_side: Optional[str] = None,
        client_algo_id: Optional[str] = None,
        reduce_only: Optional[bool] = None,
        limit_price: Optional[float] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[TimeWeightedAveragePriceFutureAlgoResponse]:
        """
                Time-Weighted Average Price(Twap) New Order(TRADE)
                POST /sapi/v1/algo/futures/newOrderTwap
                https://developers.binance.com/docs/algo/future-algo/Time-Weighted-Average-Price-New-Order

                Send in a Twap new order.
        Only support on USDⓈ-M Contracts.

        * Total Algo open orders max allowed: `30` orders.
        * Leverage of symbols and position mode will be the same as your futures account settings. You can set up through the trading page or fapi.
        * Receiving `"success": true` does not mean that your order will be executed. Please use the query order endpoints（`GET sapi/v1/algo/futures/openOrders` or `GET sapi/v1/algo/futures/historicalOrders`） to check the order status.
        For example: Your futures balance is insufficient, or open position with reduce only or position side is inconsistent with your own setting. In these cases you will receive `"success": true`, but the order status will be `expired` after we check it.
        * `quantity` * 60 / `duration` should be larger than minQty
        * `duration` cannot be less than 5 mins or more than 24 hours.
        * For delivery contracts, TWAP end time should be one hour earlier than the delivery time of the symbol.
        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 3000

                Args:
                    symbol (Union[str, None]): Trading symbol eg. BTCUSDT
                    side (Union[str, None]): Trading side ( BUY or SELL )
                    quantity (Union[float, None]): Quantity of base asset; Maximum notional per order is 200k, 2mm or 10mm, depending on symbol. Please reduce your size if you order is above the maximum notional per order.
                    duration (Union[int, None]): Duration for TWAP orders in seconds. [300, 86400]
                    position_side (Optional[str] = None): Default `BOTH` for One-way Mode ; `LONG` or `SHORT` for Hedge Mode. It must be sent in Hedge Mode.
                    client_algo_id (Optional[str] = None): A unique id among Algo orders (length should be 32 characters)， If it is not sent, we will give default value
                    reduce_only (Optional[bool] = None): "true" or "false". Default "false"; Cannot be sent in Hedge Mode; Cannot be sent when you open a position
                    limit_price (Optional[float] = None): Limit price of the order; If it is not sent, will place order by market price by default
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[TimeWeightedAveragePriceFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if side is None:
            raise RequiredError(
                field="side", error_message="Missing required parameter 'side'"
            )
        if quantity is None:
            raise RequiredError(
                field="quantity", error_message="Missing required parameter 'quantity'"
            )
        if duration is None:
            raise RequiredError(
                field="duration", error_message="Missing required parameter 'duration'"
            )

        body = {}
        payload = {
            "symbol": symbol,
            "side": side,
            "quantity": quantity,
            "duration": duration,
            "position_side": position_side,
            "client_algo_id": client_algo_id,
            "reduce_only": reduce_only,
            "limit_price": limit_price,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/algo/futures/newOrderTwap",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=TimeWeightedAveragePriceFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def volume_participation_future_algo(
        self,
        symbol: Union[str, None],
        side: Union[str, None],
        quantity: Union[float, None],
        urgency: Union[str, None],
        position_side: Optional[str] = None,
        client_algo_id: Optional[str] = None,
        reduce_only: Optional[bool] = None,
        limit_price: Optional[float] = None,
        recv_window: Optional[int] = None,
    ) -> ApiResponse[VolumeParticipationFutureAlgoResponse]:
        """
                Volume Participation(VP) New Order (TRADE)
                POST /sapi/v1/algo/futures/newOrderVp
                https://developers.binance.com/docs/algo/future-algo/Volume-Participation-New-Order

                Send in a VP new order.
        Only support on USDⓈ-M Contracts.

        * Total Algo open orders max allowed: `10` orders.
        * Leverage of symbols and position mode will be the same as your futures account settings. You can set up through the trading page or fapi.
        * Receiving `"success": true` does not mean that your order will be executed. Please use the query order endpoints（`GET sapi/v1/algo/futures/openOrders` or `GET sapi/v1/algo/futures/historicalOrders`） to check the order status.
        For example: Your futures balance is insufficient, or open position with reduce only or position side is inconsistent with your own setting. In these cases you will receive `"success": true`, but the order status will be `expired` after we check it.
        * You need to enable `Futures Trading Permission` for the api key which requests this endpoint.
        * Base URL: https://api.binance.com

        Weight: 300

                Args:
                    symbol (Union[str, None]): Trading symbol eg. BTCUSDT
                    side (Union[str, None]): Trading side ( BUY or SELL )
                    quantity (Union[float, None]): Quantity of base asset; Maximum notional per order is 200k, 2mm or 10mm, depending on symbol. Please reduce your size if you order is above the maximum notional per order.
                    urgency (Union[str, None]): Represent the relative speed of the current execution; ENUM: LOW, MEDIUM, HIGH
                    position_side (Optional[str] = None): Default `BOTH` for One-way Mode ; `LONG` or `SHORT` for Hedge Mode. It must be sent in Hedge Mode.
                    client_algo_id (Optional[str] = None): A unique id among Algo orders (length should be 32 characters)， If it is not sent, we will give default value
                    reduce_only (Optional[bool] = None): "true" or "false". Default "false"; Cannot be sent in Hedge Mode; Cannot be sent when you open a position
                    limit_price (Optional[float] = None): Limit price of the order; If it is not sent, will place order by market price by default
                    recv_window (Optional[int] = None):

                Returns:
                    ApiResponse[VolumeParticipationFutureAlgoResponse]

                Raises:
                    RequiredError: If a required parameter is missing.

        """

        if symbol is None:
            raise RequiredError(
                field="symbol", error_message="Missing required parameter 'symbol'"
            )
        if side is None:
            raise RequiredError(
                field="side", error_message="Missing required parameter 'side'"
            )
        if quantity is None:
            raise RequiredError(
                field="quantity", error_message="Missing required parameter 'quantity'"
            )
        if urgency is None:
            raise RequiredError(
                field="urgency", error_message="Missing required parameter 'urgency'"
            )

        body = {}
        payload = {
            "symbol": symbol,
            "side": side,
            "quantity": quantity,
            "urgency": urgency,
            "position_side": position_side,
            "client_algo_id": client_algo_id,
            "reduce_only": reduce_only,
            "limit_price": limit_price,
            "recv_window": recv_window,
        }

        return send_request(
            self._session,
            self._configuration,
            method="POST",
            path="/sapi/v1/algo/futures/newOrderVp",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=VolumeParticipationFutureAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )
