<?php
/**
 * OhlcvApi
 * PHP version 8.1
 *
 * @category Class
 * @package  OpenAPI\Client
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */

/**
 * FinFeedAPI Stock REST API
 *
 * No description provided (generated by Openapi Generator https://github.com/openapitools/openapi-generator)
 *
 * The version of the OpenAPI document: v1
 * Contact: support@apibricks.io
 * Generated by: https://openapi-generator.tech
 * Generator version: 7.14.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 OpenAPI\Client\Api;

use GuzzleHttp\Client;
use GuzzleHttp\ClientInterface;
use GuzzleHttp\Exception\ConnectException;
use GuzzleHttp\Exception\RequestException;
use GuzzleHttp\Psr7\MultipartStream;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\RequestOptions;
use Psr\Http\Message\RequestInterface;
use Psr\Http\Message\ResponseInterface;
use OpenAPI\Client\ApiException;
use OpenAPI\Client\Configuration;
use OpenAPI\Client\FormDataProcessor;
use OpenAPI\Client\HeaderSelector;
use OpenAPI\Client\ObjectSerializer;

/**
 * OhlcvApi Class Doc Comment
 *
 * @category Class
 * @package  OpenAPI\Client
 * @author   OpenAPI Generator team
 * @link     https://openapi-generator.tech
 */
class OhlcvApi
{
    /**
     * @var ClientInterface
     */
    protected $client;

    /**
     * @var Configuration
     */
    protected $config;

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

    /**
     * @var int Host index
     */
    protected $hostIndex;

    /** @var string[] $contentTypes **/
    public const contentTypes = [
        'v1OhlcvExchangeExchangeIdHistoryGet' => [
            'application/json',
        ],
        'v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet' => [
            'application/json',
        ],
        'v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet' => [
            'application/json',
        ],
        'v1OhlcvPeriodsGet' => [
            'application/json',
        ],
    ];

    /**
     * @param ClientInterface $client
     * @param Configuration   $config
     * @param HeaderSelector  $selector
     * @param int             $hostIndex (Optional) host index to select the list of hosts if defined in the OpenAPI spec
     */
    public function __construct(
        ?ClientInterface $client = null,
        ?Configuration $config = null,
        ?HeaderSelector $selector = null,
        int $hostIndex = 0
    ) {
        $this->client = $client ?: new Client();
        $this->config = $config ?: Configuration::getDefaultConfiguration();
        $this->headerSelector = $selector ?: new HeaderSelector();
        $this->hostIndex = $hostIndex;
    }

    /**
     * Set the host index
     *
     * @param int $hostIndex Host index (required)
     */
    public function setHostIndex($hostIndex): void
    {
        $this->hostIndex = $hostIndex;
    }

    /**
     * Get the host index
     *
     * @return int Host index
     */
    public function getHostIndex()
    {
        return $this->hostIndex;
    }

    /**
     * @return Configuration
     */
    public function getConfig()
    {
        return $this->config;
    }

    /**
     * Operation v1OhlcvExchangeExchangeIdHistoryGet
     *
     * Historical data by exchange
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;1DAY&#x60;) (required)
     * @param  string $time_start Timeseries starting time in ISO 8601 (required)
     * @param  string $time_end Timeseries ending time in ISO 8601 (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[]
     */
    public function v1OhlcvExchangeExchangeIdHistoryGet($exchange_id, $period_id, $time_start, $time_end, string $contentType = self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'][0])
    {
        list($response) = $this->v1OhlcvExchangeExchangeIdHistoryGetWithHttpInfo($exchange_id, $period_id, $time_start, $time_end, $contentType);
        return $response;
    }

    /**
     * Operation v1OhlcvExchangeExchangeIdHistoryGetWithHttpInfo
     *
     * Historical data by exchange
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;1DAY&#x60;) (required)
     * @param  string $time_start Timeseries starting time in ISO 8601 (required)
     * @param  string $time_end Timeseries ending time in ISO 8601 (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[], HTTP status code, HTTP response headers (array of strings)
     */
    public function v1OhlcvExchangeExchangeIdHistoryGetWithHttpInfo($exchange_id, $period_id, $time_start, $time_end, string $contentType = self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'][0])
    {
        $request = $this->v1OhlcvExchangeExchangeIdHistoryGetRequest($exchange_id, $period_id, $time_start, $time_end, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } 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(
                        '\OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[]',
                        $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(
                '\OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation v1OhlcvExchangeExchangeIdHistoryGetAsync
     *
     * Historical data by exchange
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;1DAY&#x60;) (required)
     * @param  string $time_start Timeseries starting time in ISO 8601 (required)
     * @param  string $time_end Timeseries ending time in ISO 8601 (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeExchangeIdHistoryGetAsync($exchange_id, $period_id, $time_start, $time_end, string $contentType = self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'][0])
    {
        return $this->v1OhlcvExchangeExchangeIdHistoryGetAsyncWithHttpInfo($exchange_id, $period_id, $time_start, $time_end, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation v1OhlcvExchangeExchangeIdHistoryGetAsyncWithHttpInfo
     *
     * Historical data by exchange
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;1DAY&#x60;) (required)
     * @param  string $time_start Timeseries starting time in ISO 8601 (required)
     * @param  string $time_end Timeseries ending time in ISO 8601 (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeExchangeIdHistoryGetAsyncWithHttpInfo($exchange_id, $period_id, $time_start, $time_end, string $contentType = self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'][0])
    {
        $returnType = '\OpenAPI\Client\Model\OHLCVExchangeTimeseriesItem[]';
        $request = $this->v1OhlcvExchangeExchangeIdHistoryGetRequest($exchange_id, $period_id, $time_start, $time_end, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'v1OhlcvExchangeExchangeIdHistoryGet'
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;1DAY&#x60;) (required)
     * @param  string $time_start Timeseries starting time in ISO 8601 (required)
     * @param  string $time_end Timeseries ending time in ISO 8601 (required)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function v1OhlcvExchangeExchangeIdHistoryGetRequest($exchange_id, $period_id, $time_start, $time_end, string $contentType = self::contentTypes['v1OhlcvExchangeExchangeIdHistoryGet'][0])
    {

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

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

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

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


        $resourcePath = '/v1/ohlcv/exchange/{exchange_id}/history';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($exchange_id !== null) {
            $resourcePath = str_replace(
                '{' . 'exchange_id' . '}',
                ObjectSerializer::toPathValue($exchange_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['text/plain', 'application/json', 'text/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 (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }
        // this endpoint requires Bearer (JWT) authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

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

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet
     *
     * Historical data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  string|null $time_start Timeseries starting time in ISO 8601 (optional)
     * @param  string|null $time_end Timeseries ending time in ISO 8601 (optional)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \OpenAPI\Client\Model\OHLCVTimeseriesItem[]
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet($exchange_id, $symbol_id, $period_id, $time_start = null, $time_end = null, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'][0])
    {
        list($response) = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetWithHttpInfo($exchange_id, $symbol_id, $period_id, $time_start, $time_end, $limit, $contentType);
        return $response;
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetWithHttpInfo
     *
     * Historical data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  string|null $time_start Timeseries starting time in ISO 8601 (optional)
     * @param  string|null $time_end Timeseries ending time in ISO 8601 (optional)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \OpenAPI\Client\Model\OHLCVTimeseriesItem[], HTTP status code, HTTP response headers (array of strings)
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetWithHttpInfo($exchange_id, $symbol_id, $period_id, $time_start = null, $time_end = null, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'][0])
    {
        $request = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetRequest($exchange_id, $symbol_id, $period_id, $time_start, $time_end, $limit, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } 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(
                        '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                        $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(
                '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetAsync
     *
     * Historical data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  string|null $time_start Timeseries starting time in ISO 8601 (optional)
     * @param  string|null $time_end Timeseries ending time in ISO 8601 (optional)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetAsync($exchange_id, $symbol_id, $period_id, $time_start = null, $time_end = null, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'][0])
    {
        return $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetAsyncWithHttpInfo($exchange_id, $symbol_id, $period_id, $time_start, $time_end, $limit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetAsyncWithHttpInfo
     *
     * Historical data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  string|null $time_start Timeseries starting time in ISO 8601 (optional)
     * @param  string|null $time_end Timeseries ending time in ISO 8601 (optional)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetAsyncWithHttpInfo($exchange_id, $symbol_id, $period_id, $time_start = null, $time_end = null, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'][0])
    {
        $returnType = '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]';
        $request = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetRequest($exchange_id, $symbol_id, $period_id, $time_start, $time_end, $limit, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  string|null $time_start Timeseries starting time in ISO 8601 (optional)
     * @param  string|null $time_end Timeseries ending time in ISO 8601 (optional)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGetRequest($exchange_id, $symbol_id, $period_id, $time_start = null, $time_end = null, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdHistoryGet'][0])
    {

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

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

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





        $resourcePath = '/v1/ohlcv/exchange-symbol/{exchange_id}/{symbol_id}/history';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($exchange_id !== null) {
            $resourcePath = str_replace(
                '{' . 'exchange_id' . '}',
                ObjectSerializer::toPathValue($exchange_id),
                $resourcePath
            );
        }
        // path params
        if ($symbol_id !== null) {
            $resourcePath = str_replace(
                '{' . 'symbol_id' . '}',
                ObjectSerializer::toPathValue($symbol_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['text/plain', 'application/json', 'text/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 (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }
        // this endpoint requires Bearer (JWT) authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

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

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet
     *
     * Latest data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \OpenAPI\Client\Model\OHLCVTimeseriesItem[]
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet($exchange_id, $symbol_id, $period_id, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'][0])
    {
        list($response) = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetWithHttpInfo($exchange_id, $symbol_id, $period_id, $limit, $contentType);
        return $response;
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetWithHttpInfo
     *
     * Latest data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \OpenAPI\Client\Model\OHLCVTimeseriesItem[], HTTP status code, HTTP response headers (array of strings)
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetWithHttpInfo($exchange_id, $symbol_id, $period_id, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'][0])
    {
        $request = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetRequest($exchange_id, $symbol_id, $period_id, $limit, $contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } 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(
                        '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                        $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(
                '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetAsync
     *
     * Latest data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetAsync($exchange_id, $symbol_id, $period_id, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'][0])
    {
        return $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetAsyncWithHttpInfo($exchange_id, $symbol_id, $period_id, $limit, $contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetAsyncWithHttpInfo
     *
     * Latest data
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetAsyncWithHttpInfo($exchange_id, $symbol_id, $period_id, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'][0])
    {
        $returnType = '\OpenAPI\Client\Model\OHLCVTimeseriesItem[]';
        $request = $this->v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetRequest($exchange_id, $symbol_id, $period_id, $limit, $contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'
     *
     * @param  string $exchange_id Exchange identifier of requested timeseries (from the Metadata -&gt; Exchanges) (required)
     * @param  string $symbol_id Symbol identifier of requested timeseries (from the Metadata -&gt; Symbols) (required)
     * @param  string $period_id Identifier of requested timeseries period (e.g. &#x60;5SEC&#x60; or &#x60;2MTH&#x60;) (required)
     * @param  int|null $limit Amount of items to return (mininum is 1, maximum is 100000, default value is 100, if the parameter is used then every 100 output items are counted as one request) (optional, default to 100)
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGetRequest($exchange_id, $symbol_id, $period_id, $limit = 100, string $contentType = self::contentTypes['v1OhlcvExchangeSymbolExchangeIdSymbolIdLatestGet'][0])
    {

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

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

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



        $resourcePath = '/v1/ohlcv/exchange-symbol/{exchange_id}/{symbol_id}/latest';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;

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


        // path params
        if ($exchange_id !== null) {
            $resourcePath = str_replace(
                '{' . 'exchange_id' . '}',
                ObjectSerializer::toPathValue($exchange_id),
                $resourcePath
            );
        }
        // path params
        if ($symbol_id !== null) {
            $resourcePath = str_replace(
                '{' . 'symbol_id' . '}',
                ObjectSerializer::toPathValue($symbol_id),
                $resourcePath
            );
        }


        $headers = $this->headerSelector->selectHeaders(
            ['text/plain', 'application/json', 'text/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 (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }
        // this endpoint requires Bearer (JWT) authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

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

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Operation v1OhlcvPeriodsGet
     *
     * List all periods
     *
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvPeriodsGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return \OpenAPI\Client\Model\OHLCVTimeseriesPeriod[]
     */
    public function v1OhlcvPeriodsGet(string $contentType = self::contentTypes['v1OhlcvPeriodsGet'][0])
    {
        list($response) = $this->v1OhlcvPeriodsGetWithHttpInfo($contentType);
        return $response;
    }

    /**
     * Operation v1OhlcvPeriodsGetWithHttpInfo
     *
     * List all periods
     *
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvPeriodsGet'] to see the possible values for this operation
     *
     * @throws \OpenAPI\Client\ApiException on non-2xx response or if the response body is not in the expected format
     * @throws \InvalidArgumentException
     * @return array of \OpenAPI\Client\Model\OHLCVTimeseriesPeriod[], HTTP status code, HTTP response headers (array of strings)
     */
    public function v1OhlcvPeriodsGetWithHttpInfo(string $contentType = self::contentTypes['v1OhlcvPeriodsGet'][0])
    {
        $request = $this->v1OhlcvPeriodsGetRequest($contentType);

        try {
            $options = $this->createHttpClientOption();
            try {
                $response = $this->client->send($request, $options);
            } 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(
                        '\OpenAPI\Client\Model\OHLCVTimeseriesPeriod[]',
                        $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(
                '\OpenAPI\Client\Model\OHLCVTimeseriesPeriod[]',
                $request,
                $response,
            );
        } catch (ApiException $e) {
            switch ($e->getCode()) {
                case 200:
                    $data = ObjectSerializer::deserialize(
                        $e->getResponseBody(),
                        '\OpenAPI\Client\Model\OHLCVTimeseriesPeriod[]',
                        $e->getResponseHeaders()
                    );
                    $e->setResponseObject($data);
                    throw $e;
            }
        

            throw $e;
        }
    }

    /**
     * Operation v1OhlcvPeriodsGetAsync
     *
     * List all periods
     *
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvPeriodsGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvPeriodsGetAsync(string $contentType = self::contentTypes['v1OhlcvPeriodsGet'][0])
    {
        return $this->v1OhlcvPeriodsGetAsyncWithHttpInfo($contentType)
            ->then(
                function ($response) {
                    return $response[0];
                }
            );
    }

    /**
     * Operation v1OhlcvPeriodsGetAsyncWithHttpInfo
     *
     * List all periods
     *
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvPeriodsGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Promise\PromiseInterface
     */
    public function v1OhlcvPeriodsGetAsyncWithHttpInfo(string $contentType = self::contentTypes['v1OhlcvPeriodsGet'][0])
    {
        $returnType = '\OpenAPI\Client\Model\OHLCVTimeseriesPeriod[]';
        $request = $this->v1OhlcvPeriodsGetRequest($contentType);

        return $this->client
            ->sendAsync($request, $this->createHttpClientOption())
            ->then(
                function ($response) use ($returnType) {
                    if ($returnType === '\SplFileObject') {
                        $content = $response->getBody(); //stream goes to serializer
                    } else {
                        $content = (string) $response->getBody();
                        if ($returnType !== 'string') {
                            $content = json_decode($content);
                        }
                    }

                    return [
                        ObjectSerializer::deserialize($content, $returnType, []),
                        $response->getStatusCode(),
                        $response->getHeaders()
                    ];
                },
                function ($exception) {
                    $response = $exception->getResponse();
                    $statusCode = $response->getStatusCode();
                    throw new ApiException(
                        sprintf(
                            '[%d] Error connecting to the API (%s)',
                            $statusCode,
                            $exception->getRequest()->getUri()
                        ),
                        $statusCode,
                        $response->getHeaders(),
                        (string) $response->getBody()
                    );
                }
            );
    }

    /**
     * Create request for operation 'v1OhlcvPeriodsGet'
     *
     * @param  string $contentType The value for the Content-Type header. Check self::contentTypes['v1OhlcvPeriodsGet'] to see the possible values for this operation
     *
     * @throws \InvalidArgumentException
     * @return \GuzzleHttp\Psr7\Request
     */
    public function v1OhlcvPeriodsGetRequest(string $contentType = self::contentTypes['v1OhlcvPeriodsGet'][0])
    {


        $resourcePath = '/v1/ohlcv/periods';
        $formParams = [];
        $queryParams = [];
        $headerParams = [];
        $httpBody = '';
        $multipart = false;





        $headers = $this->headerSelector->selectHeaders(
            ['text/plain', 'application/json', 'text/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 (stripos($headers['Content-Type'], 'application/json') !== false) {
                # if Content-Type contains "application/json", json_encode the form parameters
                $httpBody = \GuzzleHttp\Utils::jsonEncode($formParams);
            } else {
                // for HTTP post (form)
                $httpBody = ObjectSerializer::buildQuery($formParams);
            }
        }

        // this endpoint requires API key authentication
        $apiKey = $this->config->getApiKeyWithPrefix('Authorization');
        if ($apiKey !== null) {
            $headers['Authorization'] = $apiKey;
        }
        // this endpoint requires Bearer (JWT) authentication (access token)
        if (!empty($this->config->getAccessToken())) {
            $headers['Authorization'] = 'Bearer ' . $this->config->getAccessToken();
        }

        $defaultHeaders = [];
        if ($this->config->getUserAgent()) {
            $defaultHeaders['User-Agent'] = $this->config->getUserAgent();
        }

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

        $operationHost = $this->config->getHost();
        $query = ObjectSerializer::buildQuery($queryParams);
        return new Request(
            'GET',
            $operationHost . $resourcePath . ($query ? "?{$query}" : ''),
            $headers,
            $httpBody
        );
    }

    /**
     * Create http client option
     *
     * @throws \RuntimeException on file opening failure
     * @return array of http client options
     */
    protected function createHttpClientOption()
    {
        $options = [];
        if ($this->config->getDebug()) {
            $options[RequestOptions::DEBUG] = fopen($this->config->getDebugFile(), 'a');
            if (!$options[RequestOptions::DEBUG]) {
                throw new \RuntimeException('Failed to open the debug file: ' . $this->config->getDebugFile());
            }
        }

        return $options;
    }

    private function handleResponseWithDataType(
        string $dataType,
        RequestInterface $request,
        ResponseInterface $response
    ): array {
        if ($dataType === '\SplFileObject') {
            $content = $response->getBody(); //stream goes to serializer
        } else {
            $content = (string) $response->getBody();
            if ($dataType !== 'string') {
                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
                    );
                }
            }
        }

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

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

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