<?php

/**
 * AccountApi
 * PHP version 8.1.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */

/**
 * Binance Derivatives Trading Portfolio Margin Pro REST API.
 *
 * OpenAPI Specification for the Binance Derivatives Trading Portfolio Margin Pro REST API
 *
 * The version of the OpenAPI document: 1.0.0
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.12.0
 */

/**
 * NOTE: This class is auto generated by OpenAPI Generator (https://openapi-generator.tech).
 * https://openapi-generator.tech
 * Do not edit the class manually.
 */

namespace Binance\Client\DerivativesTradingPortfolioMarginPro\Api;

use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\BnbTransferRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\BnbTransferResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\ChangeAutoRepayFuturesStatusRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\ChangeAutoRepayFuturesStatusResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundAutoCollectionRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundAutoCollectionResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundCollectionByAssetRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundCollectionByAssetResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetAutoRepayFuturesStatusResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountBalanceResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountInfoResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProSpanAccountInfoResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetTransferableEarnAssetBalanceForPortfolioMarginResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\MintBfusdForPortfolioMarginRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\MintBfusdForPortfolioMarginResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\PortfolioMarginProBankruptcyLoanRepayRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\PortfolioMarginProBankruptcyLoanRepayResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanAmountResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RedeemBfusdForPortfolioMarginRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RedeemBfusdForPortfolioMarginResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RepayFuturesNegativeBalanceRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RepayFuturesNegativeBalanceResponse;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\TransferLdusdtForPortfolioMarginRequest;
use Binance\Client\DerivativesTradingPortfolioMarginPro\Model\TransferLdusdtForPortfolioMarginResponse;
use Binance\Common\ApiException;
use Binance\Common\Auth\SignerFactory;
use Binance\Common\Auth\SignerInterface;
use Binance\Common\CommonUtils;
use Binance\Common\Configuration\ClientConfiguration;
use Binance\Common\Dtos\ApiResponse;
use Binance\Common\HeaderSelector;
use Binance\Common\HttpClient;
use Binance\Common\ObjectSerializer;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Utils;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;

/**
 * AccountApi Class Doc Comment.
 *
 * @category Class
 *
 * @author   OpenAPI Generator team
 *
 * @see     https://openapi-generator.tech
 */
class AccountApi
{
    /** @var string[] */
    public const contentTypes = [
        'bnbTransfer' => ['application/x-www-form-urlencoded'],
        'changeAutoRepayFuturesStatus' => ['application/x-www-form-urlencoded'],
        'fundAutoCollection' => ['application/x-www-form-urlencoded'],
        'fundCollectionByAsset' => ['application/x-www-form-urlencoded'],
        'getAutoRepayFuturesStatus' => ['application/x-www-form-urlencoded'],
        'getPortfolioMarginProAccountBalance' => ['application/x-www-form-urlencoded'],
        'getPortfolioMarginProAccountInfo' => ['application/x-www-form-urlencoded'],
        'getPortfolioMarginProSpanAccountInfo' => ['application/x-www-form-urlencoded'],
        'getTransferableEarnAssetBalanceForPortfolioMargin' => ['application/x-www-form-urlencoded'],
        'mintBfusdForPortfolioMargin' => ['application/x-www-form-urlencoded'],
        'portfolioMarginProBankruptcyLoanRepay' => ['application/x-www-form-urlencoded'],
        'queryPortfolioMarginProBankruptcyLoanAmount' => ['application/x-www-form-urlencoded'],
        'queryPortfolioMarginProBankruptcyLoanRepayHistory' => ['application/x-www-form-urlencoded'],
        'queryPortfolioMarginProNegativeBalanceInterestHistory' => ['application/x-www-form-urlencoded'],
        'redeemBfusdForPortfolioMargin' => ['application/x-www-form-urlencoded'],
        'repayFuturesNegativeBalance' => ['application/x-www-form-urlencoded'],
        'transferLdusdtForPortfolioMargin' => ['application/x-www-form-urlencoded'],
    ];
    private const HAS_TIME_UNIT = false;

    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var HeaderSelector
     */
    protected $headerSelector;

    /**
     * Summary of clientConfig.
     *
     * @var ClientConfiguration
     */
    protected $clientConfig;

    /**
     * Summary of signer.
     *
     * @var SignerInterface
     */
    protected $signer;

    /**
     * userAgent for HTTP requests.
     *
     * @var string
     */
    private $userAgent;

    public function __construct(
        ?ClientConfiguration $clientConfig = new ClientConfiguration(),
        ?ClientInterface $client = null,
        ?HeaderSelector $selector = null,
    ) {
        $this->clientConfig = $clientConfig;
        $this->client = $client ?: new HttpClient($clientConfig);
        $this->headerSelector = $selector ?: new HeaderSelector();
        if (!empty($clientConfig->getSignatureConfiguration())) {
            $this->signer = SignerFactory::getSigner($clientConfig->getSignatureConfiguration());
        }
        $this->userAgent = CommonUtils::getUserAgent('derivatives-trading-portfolio-margin-pro');
    }

    /**
     * Operation bnbTransfer.
     *
     * BNB transfer(USER_DATA)
     *
     * @param BnbTransferRequest $bnbTransferRequest bnbTransferRequest (required)
     *
     * @return ApiResponse<BnbTransferResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function bnbTransfer($bnbTransferRequest): ApiResponse
    {
        return $this->bnbTransferWithHttpInfo($bnbTransferRequest);
    }

    /**
     * Operation bnbTransferWithHttpInfo.
     *
     * BNB transfer(USER_DATA)
     *
     * @param BnbTransferRequest $bnbTransferRequest (required)
     *
     * @return ApiResponse<BnbTransferResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function bnbTransferWithHttpInfo($bnbTransferRequest): ApiResponse
    {
        $request = $this->bnbTransferRequest($bnbTransferRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\BnbTransferResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\BnbTransferResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\BnbTransferResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'bnbTransfer'.
     *
     * @param BnbTransferRequest $bnbTransferRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function bnbTransferRequest($bnbTransferRequest)
    {
        $contentType = self::contentTypes['bnbTransfer'][0];

        // verify the required parameter 'bnbTransferRequest' is set
        if (null === $bnbTransferRequest || (is_array($bnbTransferRequest) && 0 === count($bnbTransferRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $bnbTransferRequest when calling bnbTransfer'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/bnb-transfer';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $bnbTransferRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $bnbTransferRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $bnbTransferRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($bnbTransferRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($bnbTransferRequest));
            } else {
                $httpBody = $bnbTransferRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation changeAutoRepayFuturesStatus.
     *
     * Change Auto-repay-futures Status(TRADE)
     *
     * @param ChangeAutoRepayFuturesStatusRequest $changeAutoRepayFuturesStatusRequest changeAutoRepayFuturesStatusRequest (required)
     *
     * @return ApiResponse<ChangeAutoRepayFuturesStatusResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function changeAutoRepayFuturesStatus($changeAutoRepayFuturesStatusRequest): ApiResponse
    {
        return $this->changeAutoRepayFuturesStatusWithHttpInfo($changeAutoRepayFuturesStatusRequest);
    }

    /**
     * Operation changeAutoRepayFuturesStatusWithHttpInfo.
     *
     * Change Auto-repay-futures Status(TRADE)
     *
     * @param ChangeAutoRepayFuturesStatusRequest $changeAutoRepayFuturesStatusRequest (required)
     *
     * @return ApiResponse<ChangeAutoRepayFuturesStatusResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function changeAutoRepayFuturesStatusWithHttpInfo($changeAutoRepayFuturesStatusRequest): ApiResponse
    {
        $request = $this->changeAutoRepayFuturesStatusRequest($changeAutoRepayFuturesStatusRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\ChangeAutoRepayFuturesStatusResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\ChangeAutoRepayFuturesStatusResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\ChangeAutoRepayFuturesStatusResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'changeAutoRepayFuturesStatus'.
     *
     * @param ChangeAutoRepayFuturesStatusRequest $changeAutoRepayFuturesStatusRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function changeAutoRepayFuturesStatusRequest($changeAutoRepayFuturesStatusRequest)
    {
        $contentType = self::contentTypes['changeAutoRepayFuturesStatus'][0];

        // verify the required parameter 'changeAutoRepayFuturesStatusRequest' is set
        if (null === $changeAutoRepayFuturesStatusRequest || (is_array($changeAutoRepayFuturesStatusRequest) && 0 === count($changeAutoRepayFuturesStatusRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $changeAutoRepayFuturesStatusRequest when calling changeAutoRepayFuturesStatus'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/repay-futures-switch';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $changeAutoRepayFuturesStatusRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $changeAutoRepayFuturesStatusRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $changeAutoRepayFuturesStatusRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($changeAutoRepayFuturesStatusRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($changeAutoRepayFuturesStatusRequest));
            } else {
                $httpBody = $changeAutoRepayFuturesStatusRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation fundAutoCollection.
     *
     * Fund Auto-collection(USER_DATA)
     *
     * @param FundAutoCollectionRequest $fundAutoCollectionRequest fundAutoCollectionRequest (required)
     *
     * @return ApiResponse<FundAutoCollectionResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function fundAutoCollection($fundAutoCollectionRequest): ApiResponse
    {
        return $this->fundAutoCollectionWithHttpInfo($fundAutoCollectionRequest);
    }

    /**
     * Operation fundAutoCollectionWithHttpInfo.
     *
     * Fund Auto-collection(USER_DATA)
     *
     * @param FundAutoCollectionRequest $fundAutoCollectionRequest (required)
     *
     * @return ApiResponse<FundAutoCollectionResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function fundAutoCollectionWithHttpInfo($fundAutoCollectionRequest): ApiResponse
    {
        $request = $this->fundAutoCollectionRequest($fundAutoCollectionRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundAutoCollectionResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundAutoCollectionResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundAutoCollectionResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'fundAutoCollection'.
     *
     * @param FundAutoCollectionRequest $fundAutoCollectionRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function fundAutoCollectionRequest($fundAutoCollectionRequest)
    {
        $contentType = self::contentTypes['fundAutoCollection'][0];

        // verify the required parameter 'fundAutoCollectionRequest' is set
        if (null === $fundAutoCollectionRequest || (is_array($fundAutoCollectionRequest) && 0 === count($fundAutoCollectionRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $fundAutoCollectionRequest when calling fundAutoCollection'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/auto-collection';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $fundAutoCollectionRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $fundAutoCollectionRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $fundAutoCollectionRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($fundAutoCollectionRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fundAutoCollectionRequest));
            } else {
                $httpBody = $fundAutoCollectionRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation fundCollectionByAsset.
     *
     * Fund Collection by Asset(USER_DATA)
     *
     * @param FundCollectionByAssetRequest $fundCollectionByAssetRequest fundCollectionByAssetRequest (required)
     *
     * @return ApiResponse<FundCollectionByAssetResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function fundCollectionByAsset($fundCollectionByAssetRequest): ApiResponse
    {
        return $this->fundCollectionByAssetWithHttpInfo($fundCollectionByAssetRequest);
    }

    /**
     * Operation fundCollectionByAssetWithHttpInfo.
     *
     * Fund Collection by Asset(USER_DATA)
     *
     * @param FundCollectionByAssetRequest $fundCollectionByAssetRequest (required)
     *
     * @return ApiResponse<FundCollectionByAssetResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function fundCollectionByAssetWithHttpInfo($fundCollectionByAssetRequest): ApiResponse
    {
        $request = $this->fundCollectionByAssetRequest($fundCollectionByAssetRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundCollectionByAssetResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundCollectionByAssetResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\FundCollectionByAssetResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'fundCollectionByAsset'.
     *
     * @param FundCollectionByAssetRequest $fundCollectionByAssetRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function fundCollectionByAssetRequest($fundCollectionByAssetRequest)
    {
        $contentType = self::contentTypes['fundCollectionByAsset'][0];

        // verify the required parameter 'fundCollectionByAssetRequest' is set
        if (null === $fundCollectionByAssetRequest || (is_array($fundCollectionByAssetRequest) && 0 === count($fundCollectionByAssetRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $fundCollectionByAssetRequest when calling fundCollectionByAsset'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/asset-collection';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $fundCollectionByAssetRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $fundCollectionByAssetRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $fundCollectionByAssetRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($fundCollectionByAssetRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($fundCollectionByAssetRequest));
            } else {
                $httpBody = $fundCollectionByAssetRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getAutoRepayFuturesStatus.
     *
     * Get Auto-repay-futures Status(USER_DATA)
     *
     * @param null|int $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<GetAutoRepayFuturesStatusResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getAutoRepayFuturesStatus($recvWindow = null): ApiResponse
    {
        return $this->getAutoRepayFuturesStatusWithHttpInfo($recvWindow);
    }

    /**
     * Operation getAutoRepayFuturesStatusWithHttpInfo.
     *
     * Get Auto-repay-futures Status(USER_DATA)
     *
     * @param null|int $recvWindow (optional)
     *
     * @return ApiResponse<GetAutoRepayFuturesStatusResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getAutoRepayFuturesStatusWithHttpInfo($recvWindow = null): ApiResponse
    {
        $request = $this->getAutoRepayFuturesStatusRequest($recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetAutoRepayFuturesStatusResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetAutoRepayFuturesStatusResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetAutoRepayFuturesStatusResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'getAutoRepayFuturesStatus'.
     *
     * @param null|int $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function getAutoRepayFuturesStatusRequest($recvWindow = null)
    {
        $contentType = self::contentTypes['getAutoRepayFuturesStatus'][0];

        $resourcePath = '/sapi/v1/portfolio/repay-futures-switch';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPortfolioMarginProAccountBalance.
     *
     * Get Portfolio Margin Pro Account Balance(USER_DATA)
     *
     * @param null|string $asset      asset (optional)
     * @param null|int    $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProAccountBalanceResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountBalance($asset = null, $recvWindow = null): ApiResponse
    {
        return $this->getPortfolioMarginProAccountBalanceWithHttpInfo($asset, $recvWindow);
    }

    /**
     * Operation getPortfolioMarginProAccountBalanceWithHttpInfo.
     *
     * Get Portfolio Margin Pro Account Balance(USER_DATA)
     *
     * @param null|string $asset      (optional)
     * @param null|int    $recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProAccountBalanceResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountBalanceWithHttpInfo($asset = null, $recvWindow = null): ApiResponse
    {
        $request = $this->getPortfolioMarginProAccountBalanceRequest($asset, $recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountBalanceResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountBalanceResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountBalanceResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'getPortfolioMarginProAccountBalance'.
     *
     * @param null|string $asset      (optional)
     * @param null|int    $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountBalanceRequest($asset = null, $recvWindow = null)
    {
        $contentType = self::contentTypes['getPortfolioMarginProAccountBalance'][0];

        $resourcePath = '/sapi/v1/portfolio/balance';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $asset,
            'asset', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPortfolioMarginProAccountInfo.
     *
     * Get Portfolio Margin Pro Account Info(USER_DATA)
     *
     * @param null|int $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProAccountInfoResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountInfo($recvWindow = null): ApiResponse
    {
        return $this->getPortfolioMarginProAccountInfoWithHttpInfo($recvWindow);
    }

    /**
     * Operation getPortfolioMarginProAccountInfoWithHttpInfo.
     *
     * Get Portfolio Margin Pro Account Info(USER_DATA)
     *
     * @param null|int $recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProAccountInfoResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountInfoWithHttpInfo($recvWindow = null): ApiResponse
    {
        $request = $this->getPortfolioMarginProAccountInfoRequest($recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountInfoResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountInfoResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProAccountInfoResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'getPortfolioMarginProAccountInfo'.
     *
     * @param null|int $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProAccountInfoRequest($recvWindow = null)
    {
        $contentType = self::contentTypes['getPortfolioMarginProAccountInfo'][0];

        $resourcePath = '/sapi/v1/portfolio/account';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getPortfolioMarginProSpanAccountInfo.
     *
     * Get Portfolio Margin Pro SPAN Account Info(USER_DATA)
     *
     * @param null|int $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProSpanAccountInfoResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProSpanAccountInfo($recvWindow = null): ApiResponse
    {
        return $this->getPortfolioMarginProSpanAccountInfoWithHttpInfo($recvWindow);
    }

    /**
     * Operation getPortfolioMarginProSpanAccountInfoWithHttpInfo.
     *
     * Get Portfolio Margin Pro SPAN Account Info(USER_DATA)
     *
     * @param null|int $recvWindow (optional)
     *
     * @return ApiResponse<GetPortfolioMarginProSpanAccountInfoResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProSpanAccountInfoWithHttpInfo($recvWindow = null): ApiResponse
    {
        $request = $this->getPortfolioMarginProSpanAccountInfoRequest($recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProSpanAccountInfoResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProSpanAccountInfoResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetPortfolioMarginProSpanAccountInfoResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'getPortfolioMarginProSpanAccountInfo'.
     *
     * @param null|int $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function getPortfolioMarginProSpanAccountInfoRequest($recvWindow = null)
    {
        $contentType = self::contentTypes['getPortfolioMarginProSpanAccountInfo'][0];

        $resourcePath = '/sapi/v2/portfolio/account';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation getTransferableEarnAssetBalanceForPortfolioMargin.
     *
     * Get Transferable Earn Asset Balance for Portfolio Margin (USER_DATA)
     *
     * @param string   $asset        &#x60;LDUSDT&#x60; only (required)
     * @param string   $transferType &#x60;EARN_TO_FUTURE&#x60; /&#x60;FUTURE_TO_EARN&#x60; (required)
     * @param null|int $recvWindow   recvWindow (optional)
     *
     * @return ApiResponse<GetTransferableEarnAssetBalanceForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getTransferableEarnAssetBalanceForPortfolioMargin($asset, $transferType, $recvWindow = null): ApiResponse
    {
        return $this->getTransferableEarnAssetBalanceForPortfolioMarginWithHttpInfo($asset, $transferType, $recvWindow);
    }

    /**
     * Operation getTransferableEarnAssetBalanceForPortfolioMarginWithHttpInfo.
     *
     * Get Transferable Earn Asset Balance for Portfolio Margin (USER_DATA)
     *
     * @param string   $asset        &#x60;LDUSDT&#x60; only (required)
     * @param string   $transferType &#x60;EARN_TO_FUTURE&#x60; /&#x60;FUTURE_TO_EARN&#x60; (required)
     * @param null|int $recvWindow   (optional)
     *
     * @return ApiResponse<GetTransferableEarnAssetBalanceForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function getTransferableEarnAssetBalanceForPortfolioMarginWithHttpInfo($asset, $transferType, $recvWindow = null): ApiResponse
    {
        $request = $this->getTransferableEarnAssetBalanceForPortfolioMarginRequest($asset, $transferType, $recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetTransferableEarnAssetBalanceForPortfolioMarginResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetTransferableEarnAssetBalanceForPortfolioMarginResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\GetTransferableEarnAssetBalanceForPortfolioMarginResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'getTransferableEarnAssetBalanceForPortfolioMargin'.
     *
     * @param string   $asset        &#x60;LDUSDT&#x60; only (required)
     * @param string   $transferType &#x60;EARN_TO_FUTURE&#x60; /&#x60;FUTURE_TO_EARN&#x60; (required)
     * @param null|int $recvWindow   (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function getTransferableEarnAssetBalanceForPortfolioMarginRequest($asset, $transferType, $recvWindow = null)
    {
        $contentType = self::contentTypes['getTransferableEarnAssetBalanceForPortfolioMargin'][0];

        // verify the required parameter 'asset' is set
        if (null === $asset || (is_array($asset) && 0 === count($asset))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $asset when calling getTransferableEarnAssetBalanceForPortfolioMargin'
            );
        }

        // verify the required parameter 'transferType' is set
        if (null === $transferType || (is_array($transferType) && 0 === count($transferType))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $transferType when calling getTransferableEarnAssetBalanceForPortfolioMargin'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/earn-asset-balance';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $asset,
            'asset', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $transferType,
            'transferType', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            true // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation mintBfusdForPortfolioMargin.
     *
     * Mint BFUSD for Portfolio Margin(TRADE)
     *
     * @param MintBfusdForPortfolioMarginRequest $mintBfusdForPortfolioMarginRequest mintBfusdForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<MintBfusdForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function mintBfusdForPortfolioMargin($mintBfusdForPortfolioMarginRequest): ApiResponse
    {
        return $this->mintBfusdForPortfolioMarginWithHttpInfo($mintBfusdForPortfolioMarginRequest);
    }

    /**
     * Operation mintBfusdForPortfolioMarginWithHttpInfo.
     *
     * Mint BFUSD for Portfolio Margin(TRADE)
     *
     * @param MintBfusdForPortfolioMarginRequest $mintBfusdForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<MintBfusdForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function mintBfusdForPortfolioMarginWithHttpInfo($mintBfusdForPortfolioMarginRequest): ApiResponse
    {
        $request = $this->mintBfusdForPortfolioMarginRequest($mintBfusdForPortfolioMarginRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\MintBfusdForPortfolioMarginResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\MintBfusdForPortfolioMarginResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\MintBfusdForPortfolioMarginResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'mintBfusdForPortfolioMargin'.
     *
     * @param MintBfusdForPortfolioMarginRequest $mintBfusdForPortfolioMarginRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function mintBfusdForPortfolioMarginRequest($mintBfusdForPortfolioMarginRequest)
    {
        $contentType = self::contentTypes['mintBfusdForPortfolioMargin'][0];

        // verify the required parameter 'mintBfusdForPortfolioMarginRequest' is set
        if (null === $mintBfusdForPortfolioMarginRequest || (is_array($mintBfusdForPortfolioMarginRequest) && 0 === count($mintBfusdForPortfolioMarginRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $mintBfusdForPortfolioMarginRequest when calling mintBfusdForPortfolioMargin'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/mint';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $mintBfusdForPortfolioMarginRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $mintBfusdForPortfolioMarginRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $mintBfusdForPortfolioMarginRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($mintBfusdForPortfolioMarginRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($mintBfusdForPortfolioMarginRequest));
            } else {
                $httpBody = $mintBfusdForPortfolioMarginRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation portfolioMarginProBankruptcyLoanRepay.
     *
     * Portfolio Margin Pro Bankruptcy Loan Repay
     *
     * @param PortfolioMarginProBankruptcyLoanRepayRequest $portfolioMarginProBankruptcyLoanRepayRequest portfolioMarginProBankruptcyLoanRepayRequest (required)
     *
     * @return ApiResponse<PortfolioMarginProBankruptcyLoanRepayResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function portfolioMarginProBankruptcyLoanRepay($portfolioMarginProBankruptcyLoanRepayRequest): ApiResponse
    {
        return $this->portfolioMarginProBankruptcyLoanRepayWithHttpInfo($portfolioMarginProBankruptcyLoanRepayRequest);
    }

    /**
     * Operation portfolioMarginProBankruptcyLoanRepayWithHttpInfo.
     *
     * Portfolio Margin Pro Bankruptcy Loan Repay
     *
     * @param PortfolioMarginProBankruptcyLoanRepayRequest $portfolioMarginProBankruptcyLoanRepayRequest (required)
     *
     * @return ApiResponse<PortfolioMarginProBankruptcyLoanRepayResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function portfolioMarginProBankruptcyLoanRepayWithHttpInfo($portfolioMarginProBankruptcyLoanRepayRequest): ApiResponse
    {
        $request = $this->portfolioMarginProBankruptcyLoanRepayRequest($portfolioMarginProBankruptcyLoanRepayRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\PortfolioMarginProBankruptcyLoanRepayResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\PortfolioMarginProBankruptcyLoanRepayResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\PortfolioMarginProBankruptcyLoanRepayResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'portfolioMarginProBankruptcyLoanRepay'.
     *
     * @param PortfolioMarginProBankruptcyLoanRepayRequest $portfolioMarginProBankruptcyLoanRepayRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function portfolioMarginProBankruptcyLoanRepayRequest($portfolioMarginProBankruptcyLoanRepayRequest)
    {
        $contentType = self::contentTypes['portfolioMarginProBankruptcyLoanRepay'][0];

        // verify the required parameter 'portfolioMarginProBankruptcyLoanRepayRequest' is set
        if (null === $portfolioMarginProBankruptcyLoanRepayRequest || (is_array($portfolioMarginProBankruptcyLoanRepayRequest) && 0 === count($portfolioMarginProBankruptcyLoanRepayRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $portfolioMarginProBankruptcyLoanRepayRequest when calling portfolioMarginProBankruptcyLoanRepay'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/repay';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $portfolioMarginProBankruptcyLoanRepayRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $portfolioMarginProBankruptcyLoanRepayRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $portfolioMarginProBankruptcyLoanRepayRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($portfolioMarginProBankruptcyLoanRepayRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($portfolioMarginProBankruptcyLoanRepayRequest));
            } else {
                $httpBody = $portfolioMarginProBankruptcyLoanRepayRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation queryPortfolioMarginProBankruptcyLoanAmount.
     *
     * Query Portfolio Margin Pro Bankruptcy Loan Amount(USER_DATA)
     *
     * @param null|int $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProBankruptcyLoanAmountResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanAmount($recvWindow = null): ApiResponse
    {
        return $this->queryPortfolioMarginProBankruptcyLoanAmountWithHttpInfo($recvWindow);
    }

    /**
     * Operation queryPortfolioMarginProBankruptcyLoanAmountWithHttpInfo.
     *
     * Query Portfolio Margin Pro Bankruptcy Loan Amount(USER_DATA)
     *
     * @param null|int $recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProBankruptcyLoanAmountResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanAmountWithHttpInfo($recvWindow = null): ApiResponse
    {
        $request = $this->queryPortfolioMarginProBankruptcyLoanAmountRequest($recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanAmountResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanAmountResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanAmountResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'queryPortfolioMarginProBankruptcyLoanAmount'.
     *
     * @param null|int $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanAmountRequest($recvWindow = null)
    {
        $contentType = self::contentTypes['queryPortfolioMarginProBankruptcyLoanAmount'][0];

        $resourcePath = '/sapi/v1/portfolio/pmLoan';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation queryPortfolioMarginProBankruptcyLoanRepayHistory.
     *
     * Query Portfolio Margin Pro Bankruptcy Loan Repay History(USER_DATA)
     *
     * @param null|int $startTime  startTime (optional)
     * @param null|int $endTime    endTime (optional)
     * @param null|int $current    Currently querying page. Start from 1. Default:1 (optional)
     * @param null|int $size       Default:10 Max:100 (optional)
     * @param null|int $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanRepayHistory($startTime = null, $endTime = null, $current = null, $size = null, $recvWindow = null): ApiResponse
    {
        return $this->queryPortfolioMarginProBankruptcyLoanRepayHistoryWithHttpInfo($startTime, $endTime, $current, $size, $recvWindow);
    }

    /**
     * Operation queryPortfolioMarginProBankruptcyLoanRepayHistoryWithHttpInfo.
     *
     * Query Portfolio Margin Pro Bankruptcy Loan Repay History(USER_DATA)
     *
     * @param null|int $startTime  (optional)
     * @param null|int $endTime    (optional)
     * @param null|int $current    Currently querying page. Start from 1. Default:1 (optional)
     * @param null|int $size       Default:10 Max:100 (optional)
     * @param null|int $recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanRepayHistoryWithHttpInfo($startTime = null, $endTime = null, $current = null, $size = null, $recvWindow = null): ApiResponse
    {
        $request = $this->queryPortfolioMarginProBankruptcyLoanRepayHistoryRequest($startTime, $endTime, $current, $size, $recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProBankruptcyLoanRepayHistoryResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'queryPortfolioMarginProBankruptcyLoanRepayHistory'.
     *
     * @param null|int $startTime  (optional)
     * @param null|int $endTime    (optional)
     * @param null|int $current    Currently querying page. Start from 1. Default:1 (optional)
     * @param null|int $size       Default:10 Max:100 (optional)
     * @param null|int $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProBankruptcyLoanRepayHistoryRequest($startTime = null, $endTime = null, $current = null, $size = null, $recvWindow = null)
    {
        $contentType = self::contentTypes['queryPortfolioMarginProBankruptcyLoanRepayHistory'][0];

        $resourcePath = '/sapi/v1/portfolio/pmloan-history';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $startTime,
            'startTime', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $endTime,
            'endTime', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $current,
            'current', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $size,
            'size', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation queryPortfolioMarginProNegativeBalanceInterestHistory.
     *
     * Query Portfolio Margin Pro Negative Balance Interest History(USER_DATA)
     *
     * @param null|string $asset      asset (optional)
     * @param null|int    $startTime  startTime (optional)
     * @param null|int    $endTime    endTime (optional)
     * @param null|int    $size       Default:10 Max:100 (optional)
     * @param null|int    $recvWindow recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProNegativeBalanceInterestHistory($asset = null, $startTime = null, $endTime = null, $size = null, $recvWindow = null): ApiResponse
    {
        return $this->queryPortfolioMarginProNegativeBalanceInterestHistoryWithHttpInfo($asset, $startTime, $endTime, $size, $recvWindow);
    }

    /**
     * Operation queryPortfolioMarginProNegativeBalanceInterestHistoryWithHttpInfo.
     *
     * Query Portfolio Margin Pro Negative Balance Interest History(USER_DATA)
     *
     * @param null|string $asset      (optional)
     * @param null|int    $startTime  (optional)
     * @param null|int    $endTime    (optional)
     * @param null|int    $size       Default:10 Max:100 (optional)
     * @param null|int    $recvWindow (optional)
     *
     * @return ApiResponse<QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProNegativeBalanceInterestHistoryWithHttpInfo($asset = null, $startTime = null, $endTime = null, $size = null, $recvWindow = null): ApiResponse
    {
        $request = $this->queryPortfolioMarginProNegativeBalanceInterestHistoryRequest($asset, $startTime, $endTime, $size, $recvWindow);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\QueryPortfolioMarginProNegativeBalanceInterestHistoryResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'queryPortfolioMarginProNegativeBalanceInterestHistory'.
     *
     * @param null|string $asset      (optional)
     * @param null|int    $startTime  (optional)
     * @param null|int    $endTime    (optional)
     * @param null|int    $size       Default:10 Max:100 (optional)
     * @param null|int    $recvWindow (optional)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function queryPortfolioMarginProNegativeBalanceInterestHistoryRequest($asset = null, $startTime = null, $endTime = null, $size = null, $recvWindow = null)
    {
        $contentType = self::contentTypes['queryPortfolioMarginProNegativeBalanceInterestHistory'][0];

        $resourcePath = '/sapi/v1/portfolio/interest-history';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $asset,
            'asset', // param base name
            'string', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $startTime,
            'startTime', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $endTime,
            'endTime', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $size,
            'size', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);
        // query params
        $queryParams = array_merge($queryParams, ObjectSerializer::toQueryValue(
            $recvWindow,
            'recvWindow', // param base name
            'integer', // openApiType
            'form', // style
            true, // explode
            false // required
        ) ?? []);

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'GET',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation redeemBfusdForPortfolioMargin.
     *
     * Redeem BFUSD for Portfolio Margin(TRADE)
     *
     * @param RedeemBfusdForPortfolioMarginRequest $redeemBfusdForPortfolioMarginRequest redeemBfusdForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<RedeemBfusdForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function redeemBfusdForPortfolioMargin($redeemBfusdForPortfolioMarginRequest): ApiResponse
    {
        return $this->redeemBfusdForPortfolioMarginWithHttpInfo($redeemBfusdForPortfolioMarginRequest);
    }

    /**
     * Operation redeemBfusdForPortfolioMarginWithHttpInfo.
     *
     * Redeem BFUSD for Portfolio Margin(TRADE)
     *
     * @param RedeemBfusdForPortfolioMarginRequest $redeemBfusdForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<RedeemBfusdForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function redeemBfusdForPortfolioMarginWithHttpInfo($redeemBfusdForPortfolioMarginRequest): ApiResponse
    {
        $request = $this->redeemBfusdForPortfolioMarginRequest($redeemBfusdForPortfolioMarginRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RedeemBfusdForPortfolioMarginResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RedeemBfusdForPortfolioMarginResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RedeemBfusdForPortfolioMarginResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'redeemBfusdForPortfolioMargin'.
     *
     * @param RedeemBfusdForPortfolioMarginRequest $redeemBfusdForPortfolioMarginRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function redeemBfusdForPortfolioMarginRequest($redeemBfusdForPortfolioMarginRequest)
    {
        $contentType = self::contentTypes['redeemBfusdForPortfolioMargin'][0];

        // verify the required parameter 'redeemBfusdForPortfolioMarginRequest' is set
        if (null === $redeemBfusdForPortfolioMarginRequest || (is_array($redeemBfusdForPortfolioMarginRequest) && 0 === count($redeemBfusdForPortfolioMarginRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $redeemBfusdForPortfolioMarginRequest when calling redeemBfusdForPortfolioMargin'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/redeem';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $redeemBfusdForPortfolioMarginRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $redeemBfusdForPortfolioMarginRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $redeemBfusdForPortfolioMarginRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($redeemBfusdForPortfolioMarginRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($redeemBfusdForPortfolioMarginRequest));
            } else {
                $httpBody = $redeemBfusdForPortfolioMarginRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation repayFuturesNegativeBalance.
     *
     * Repay futures Negative Balance(USER_DATA)
     *
     * @param RepayFuturesNegativeBalanceRequest $repayFuturesNegativeBalanceRequest repayFuturesNegativeBalanceRequest (required)
     *
     * @return ApiResponse<RepayFuturesNegativeBalanceResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function repayFuturesNegativeBalance($repayFuturesNegativeBalanceRequest): ApiResponse
    {
        return $this->repayFuturesNegativeBalanceWithHttpInfo($repayFuturesNegativeBalanceRequest);
    }

    /**
     * Operation repayFuturesNegativeBalanceWithHttpInfo.
     *
     * Repay futures Negative Balance(USER_DATA)
     *
     * @param RepayFuturesNegativeBalanceRequest $repayFuturesNegativeBalanceRequest (required)
     *
     * @return ApiResponse<RepayFuturesNegativeBalanceResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function repayFuturesNegativeBalanceWithHttpInfo($repayFuturesNegativeBalanceRequest): ApiResponse
    {
        $request = $this->repayFuturesNegativeBalanceRequest($repayFuturesNegativeBalanceRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RepayFuturesNegativeBalanceResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RepayFuturesNegativeBalanceResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\RepayFuturesNegativeBalanceResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'repayFuturesNegativeBalance'.
     *
     * @param RepayFuturesNegativeBalanceRequest $repayFuturesNegativeBalanceRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function repayFuturesNegativeBalanceRequest($repayFuturesNegativeBalanceRequest)
    {
        $contentType = self::contentTypes['repayFuturesNegativeBalance'][0];

        // verify the required parameter 'repayFuturesNegativeBalanceRequest' is set
        if (null === $repayFuturesNegativeBalanceRequest || (is_array($repayFuturesNegativeBalanceRequest) && 0 === count($repayFuturesNegativeBalanceRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $repayFuturesNegativeBalanceRequest when calling repayFuturesNegativeBalance'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/repay-futures-negative-balance';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $repayFuturesNegativeBalanceRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $repayFuturesNegativeBalanceRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $repayFuturesNegativeBalanceRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($repayFuturesNegativeBalanceRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($repayFuturesNegativeBalanceRequest));
            } else {
                $httpBody = $repayFuturesNegativeBalanceRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation transferLdusdtForPortfolioMargin.
     *
     * Transfer LDUSDT for Portfolio Margin(TRADE)
     *
     * @param TransferLdusdtForPortfolioMarginRequest $transferLdusdtForPortfolioMarginRequest transferLdusdtForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<TransferLdusdtForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function transferLdusdtForPortfolioMargin($transferLdusdtForPortfolioMarginRequest): ApiResponse
    {
        return $this->transferLdusdtForPortfolioMarginWithHttpInfo($transferLdusdtForPortfolioMarginRequest);
    }

    /**
     * Operation transferLdusdtForPortfolioMarginWithHttpInfo.
     *
     * Transfer LDUSDT for Portfolio Margin(TRADE)
     *
     * @param TransferLdusdtForPortfolioMarginRequest $transferLdusdtForPortfolioMarginRequest (required)
     *
     * @return ApiResponse<TransferLdusdtForPortfolioMarginResponse>
     *
     * @throws ApiException              on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     */
    public function transferLdusdtForPortfolioMarginWithHttpInfo($transferLdusdtForPortfolioMarginRequest): ApiResponse
    {
        $request = $this->transferLdusdtForPortfolioMarginRequest($transferLdusdtForPortfolioMarginRequest);

        try {
            try {
                $response = $this->client->send($request, []);
            } catch (RequestException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    $e->getResponse() ? $e->getResponse()->getHeaders() : null,
                    $e->getResponse() ? (string) $e->getResponse()->getBody() : null
                );
            } catch (ConnectException $e) {
                throw new ApiException(
                    "[{$e->getCode()}] {$e->getMessage()}",
                    (int) $e->getCode(),
                    null,
                    null
                );
            }

            $statusCode = $response->getStatusCode();

            switch ($statusCode) {
                case 200:
                    return $this->handleResponseWithDataType(
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\TransferLdusdtForPortfolioMarginResponse',
                        $request,
                        $response,
                    );
            }

            if ($statusCode < 200 || $statusCode > 299) {
                throw new ApiException(
                    sprintf(
                        '[%d] Error connecting to the API (%s)',
                        $statusCode,
                        (string) $request->getUri()
                    ),
                    $statusCode,
                    $response->getHeaders(),
                    (string) $response->getBody()
                );
            }

            return $this->handleResponseWithDataType(
                '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\TransferLdusdtForPortfolioMarginResponse',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\Binance\Client\DerivativesTradingPortfolioMarginPro\Model\TransferLdusdtForPortfolioMarginResponse',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);

                    throw $e;
            }

            throw $e;
        }
    }

    /**
     * Create request for operation 'transferLdusdtForPortfolioMargin'.
     *
     * @param TransferLdusdtForPortfolioMarginRequest $transferLdusdtForPortfolioMarginRequest (required)
     *
     * @return Request
     *
     * @throws \InvalidArgumentException
     */
    public function transferLdusdtForPortfolioMarginRequest($transferLdusdtForPortfolioMarginRequest)
    {
        $contentType = self::contentTypes['transferLdusdtForPortfolioMargin'][0];

        // verify the required parameter 'transferLdusdtForPortfolioMarginRequest' is set
        if (null === $transferLdusdtForPortfolioMarginRequest || (is_array($transferLdusdtForPortfolioMarginRequest) && 0 === count($transferLdusdtForPortfolioMarginRequest))) {
            throw new \InvalidArgumentException(
                'Missing the required parameter $transferLdusdtForPortfolioMarginRequest when calling transferLdusdtForPortfolioMargin'
            );
        }

        $resourcePath = '/sapi/v1/portfolio/earn-asset-transfer';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

        $getters = $transferLdusdtForPortfolioMarginRequest::getters();
        $formParams = [];
        foreach ($getters as $property => $getter) {
            $value = $transferLdusdtForPortfolioMarginRequest->{$getter}();
            if (!empty($value)) {
                $formParams[$property] = $transferLdusdtForPortfolioMarginRequest->{$getter}();
            }
        }

        $headers = $this->headerSelector->selectHeaders(
            ['application/json'],
            $contentType,
            $multipart
        );

        // for model (json/xml)
        if (count($formParams) > 0) {
            if ($multipart) {
                $multipartContents = [];
                foreach ($formParams as $formParamName => $formParamValue) {
                    $formParamValueItems = is_array($formParamValue) ? $formParamValue : [$formParamValue];
                    foreach ($formParamValueItems as $formParamValueItem) {
                        $multipartContents[] = [
                            'name' => $formParamName,
                            'contents' => $formParamValueItem,
                        ];
                    }
                }
                // for HTTP post (form)
                $httpBody = new MultipartStream($multipartContents);
            } elseif (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        } elseif (isset($transferLdusdtForPortfolioMarginRequest)) {
            if (false !== stripos($headers['Content-Type'], 'application/json')) {
                // if Content-Type contains "application/json", json_encode the body
                $httpBody = Utils::jsonEncode(ObjectSerializer::sanitizeForSerialization($transferLdusdtForPortfolioMarginRequest));
            } else {
                $httpBody = $transferLdusdtForPortfolioMarginRequest;
            }
        }

        $defaultHeaders = [];
        $defaultHeaders['User-Agent'] = $this->userAgent;

        if (self::HAS_TIME_UNIT && !empty($this->clientConfig->getTimeUnit())) {
            $defaultHeaders['X-MBX-TIME-UNIT'] = $this->clientConfig->getTimeUnit();
        }

        $headers = array_merge(
            $defaultHeaders,
            $headerParams,
            $headers
        );

        $operationHost = $this->clientConfig->getUrl();

        $queryParams['timestamp'] = $this->getTimestamp();
        $query = ObjectSerializer::buildQuery($queryParams);
        $queryParams['signature'] = $this->signer->sign($query.$httpBody);
        $headers['X-MBX-APIKEY'] = $this->clientConfig->getSignatureConfiguration()->getApiKey();
        $query = ObjectSerializer::buildQuery($queryParams);

        return new Request(
            'POST',
            $operationHost.$resourcePath.($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Summary of getTimestamp.
     */
    public function getTimestamp(): string
    {
        return date_create()->format('Uv');
    }

    private function handleResponseWithDataType(
        string $dataType,
        RequestInterface $request,
        ResponseInterface $response
    ): ApiResponse {
        if ('\SplFileObject' === $dataType) {
            $content = $response->getBody(); // stream goes to serializer
        } else {
            $content = (string) $response->getBody();
            if ('string' !== $dataType) {
                try {
                    $content = json_decode($content, false, 512, JSON_THROW_ON_ERROR);
                } catch (\JsonException $exception) {
                    throw new ApiException(
                        sprintf(
                            'Error JSON decoding server response (%s)',
                            $request->getUri()
                        ),
                        $response->getStatusCode(),
                        $response->getHeaders(),
                        $content
                    );
                }
            }
        }

        $rateLimits = CommonUtils::getRateLimits($response->getStatusCode(), $response->getHeaders());

        return new ApiResponse(
            $response->getStatusCode(),
            $response->getHeaders(),
            ObjectSerializer::deserialize($content, $dataType, []),
            $rateLimits
        );
    }

    private function responseWithinRangeCode(
        string $rangeCode,
        int $statusCode
    ): bool {
        $left = (int) ($rangeCode[0].'00');
        $right = (int) ($rangeCode[0].'99');

        return $statusCode >= $left && $statusCode <= $right;
    }
}
