"""
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 CancelAlgoOrderSpotAlgoResponse
from ..models import QueryCurrentAlgoOpenOrdersSpotAlgoResponse
from ..models import QueryHistoricalAlgoOrdersSpotAlgoResponse
from ..models import QuerySubOrdersSpotAlgoResponse
from ..models import TimeWeightedAveragePriceSpotAlgoResponse


class SpotAlgoApi:
    """API Client for SpotAlgoApi 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_spot_algo(
        self,
        algo_id: Union[int, None],
        recv_window: Optional[int] = None,
    ) -> ApiResponse[CancelAlgoOrderSpotAlgoResponse]:
        """
                Cancel Algo Order(TRADE)
                DELETE /sapi/v1/algo/spot/order
                https://developers.binance.com/docs/algo/spot-algo/Cancel-Algo-Order

                Cancel an open TWAP order

        Weight: 1

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

                Returns:
                    ApiResponse[CancelAlgoOrderSpotAlgoResponse]

                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/spot/order",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=CancelAlgoOrderSpotAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

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

                Get all open SPOT TWAP orders

        Weight: 1

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

                Returns:
                    ApiResponse[QueryCurrentAlgoOpenOrdersSpotAlgoResponse]

                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/spot/openOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QueryCurrentAlgoOpenOrdersSpotAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

    def query_historical_algo_orders_spot_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[QueryHistoricalAlgoOrdersSpotAlgoResponse]:
        """
                Query Historical Algo Orders(USER_DATA)
                GET /sapi/v1/algo/spot/historicalOrders
                https://developers.binance.com/docs/algo/spot-algo/Query-Historical-Algo-Orders

                Get all historical SPOT TWAP orders

        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[QueryHistoricalAlgoOrdersSpotAlgoResponse]

                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/spot/historicalOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QueryHistoricalAlgoOrdersSpotAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

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

                Get respective sub orders for a specified algoId

        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[QuerySubOrdersSpotAlgoResponse]

                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/spot/subOrders",
            payload=payload,
            body=body,
            time_unit=self._configuration.time_unit,
            response_model=QuerySubOrdersSpotAlgoResponse,
            is_signed=True,
            signer=self._signer,
        )

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

                Place a new spot TWAP order with Algo service.

        * Total Algo open orders max allowed: `20` orders.

        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]
                    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
                    limit_price (Optional[float] = None): Limit price of the order; If it is not sent, will place order by market price by default

                Returns:
                    ApiResponse[TimeWeightedAveragePriceSpotAlgoResponse]

                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,
            "client_algo_id": client_algo_id,
            "limit_price": limit_price,
        }

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