From 47c75d68b157108df80fa4b39994e6b4881821a5 Mon Sep 17 00:00:00 2001 From: Sergey Date: Wed, 15 Jul 2026 10:26:55 +0300 Subject: [PATCH] build 044: establish canonical candles feed foundation --- .../acquisition/adapters/dzengi/mapper.py | 91 ++ .../acquisition/adapters/dzengi/models.py | 17 + .../acquisition/adapters/dzengi/parser.py | 154 ++ .../acquisition/adapters/dzengi/rest.py | 51 + app/src/market_data/acquisition/exceptions.py | 26 + .../acquisition/feeds/candles_feed.py | 53 + .../acquisition/handlers/candles_handler.py | 54 + .../market_data/acquisition/models/candle.py | 24 + app/src/market_data/acquisition/protocol.py | 55 + .../acquisition/validation/schema.py | 194 +++ .../acquisition/validation/values.py | 128 ++ .../adapters/dzengi/test_candle_mapper.py | 80 + .../adapters/dzengi/test_candle_parser.py | 135 ++ .../adapters/dzengi/test_candle_rest.py | 100 ++ .../acquisition/feeds/test_candles_feed.py | 164 +++ .../handlers/test_candles_handler.py | 31 + .../acquisition/models/test_candle.py | 52 + .../validation/test_candle_schema.py | 120 ++ .../validation/test_candle_values.py | 109 ++ docs/migrations/build_044.md | 1299 +++++++++++++++++ docs/migrations/greps.txt | 246 ---- .../Вывод grep по дополнительным полям.txt | 70 - 22 files changed, 2937 insertions(+), 316 deletions(-) create mode 100644 app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py create mode 100644 app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py create mode 100644 app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py create mode 100644 app/tests/unit/market_data/acquisition/feeds/test_candles_feed.py create mode 100644 app/tests/unit/market_data/acquisition/handlers/test_candles_handler.py create mode 100644 app/tests/unit/market_data/acquisition/models/test_candle.py create mode 100644 app/tests/unit/market_data/acquisition/validation/test_candle_schema.py create mode 100644 app/tests/unit/market_data/acquisition/validation/test_candle_values.py create mode 100644 docs/migrations/build_044.md delete mode 100644 docs/migrations/greps.txt delete mode 100644 docs/migrations/Вывод grep по дополнительным полям.txt diff --git a/app/src/market_data/acquisition/adapters/dzengi/mapper.py b/app/src/market_data/acquisition/adapters/dzengi/mapper.py index 90f7345..d4c9f3f 100644 --- a/app/src/market_data/acquisition/adapters/dzengi/mapper.py +++ b/app/src/market_data/acquisition/adapters/dzengi/mapper.py @@ -9,6 +9,7 @@ from src.market_data.acquisition.adapters.dzengi.models import ( DzengiExchangeInfoResponse, DzengiExchangeInfoSymbol, DzengiInstrumentFilter, + DzengiKlinesResponse, DzengiLotSizeFilter, DzengiMinNotionalFilter, DzengiRawNumeric, @@ -16,9 +17,11 @@ from src.market_data.acquisition.adapters.dzengi.models import ( DzengiWebSocketQuoteResponse, ) from src.market_data.acquisition.exceptions import ( + CandleMappingError, InstrumentReferenceMappingError, QuoteMappingError, ) +from src.market_data.acquisition.models.candle import Candle from src.market_data.acquisition.models.instrument import Instrument from src.market_data.acquisition.models.quote import Quote @@ -314,3 +317,91 @@ def map_dzengi_websocket_quote_to_quote( received_at=normalized_received_at, source=_DZENGI_SOURCE_NAME, ) + +def map_dzengi_klines_to_candles( + response: DzengiKlinesResponse, + *, + symbol: str, + interval: str, + source: str, +) -> tuple[Candle, ...]: + """ + Преобразовать проверенные raw-модели Dzengi klines + в канонический immutable-набор Candle. + + Функция предполагает, что до mapper уже были выполнены: + schema validation, parsing и value validation. + """ + + candles = tuple( + Candle( + symbol=symbol.strip(), + interval=interval.strip(), + open_time=_candle_timestamp_ms_to_utc_datetime( + item.open_time, + ), + open_price=_required_candle_decimal( + item.open_price, + field_name="open", + ), + high_price=_required_candle_decimal( + item.high_price, + field_name="high", + ), + low_price=_required_candle_decimal( + item.low_price, + field_name="low", + ), + close_price=_required_candle_decimal( + item.close_price, + field_name="close", + ), + volume=_required_candle_decimal( + item.volume, + field_name="volume", + ), + source=source.strip(), + ) + for item in response.items + ) + + return tuple( + sorted( + candles, + key=lambda candle: candle.open_time, + ) + ) + + +def _candle_timestamp_ms_to_utc_datetime(value: int) -> datetime: + try: + return datetime.fromtimestamp( + value / 1000, + tz=timezone.utc, + ) + except (OverflowError, OSError, ValueError) as exc: + raise CandleMappingError( + "Поле openTime свечи невозможно преобразовать " + "в UTC datetime." + ) from exc + + +def _required_candle_decimal( + value: DzengiRawNumeric, + *, + field_name: str, +) -> Decimal: + try: + result = Decimal(str(value)) + except (InvalidOperation, ValueError) as exc: + raise CandleMappingError( + f"Поле {field_name} свечи невозможно " + "преобразовать в Decimal." + ) from exc + + if not result.is_finite(): + raise CandleMappingError( + f"Поле {field_name} свечи должно быть конечным числом." + ) + + return result \ No newline at end of file diff --git a/app/src/market_data/acquisition/adapters/dzengi/models.py b/app/src/market_data/acquisition/adapters/dzengi/models.py index 0ff6631..3c2ec83 100644 --- a/app/src/market_data/acquisition/adapters/dzengi/models.py +++ b/app/src/market_data/acquisition/adapters/dzengi/models.py @@ -131,3 +131,20 @@ class DzengiWebSocketQuoteResponse: bid_price: DzengiRawNumeric ask_price: DzengiRawNumeric timestamp: int | None + + +# Транспортное представление одной свечи Dzengi GET /api/v1/klines. +@dataclass(frozen=True, slots=True) +class DzengiKline: + open_time: int + open_price: str | int | float + high_price: str | int | float + low_price: str | int | float + close_price: str | int | float + volume: str | int | float + + +# Транспортное представление ответа Dzengi GET /api/v1/klines. +@dataclass(frozen=True, slots=True) +class DzengiKlinesResponse: + items: tuple[DzengiKline, ...] \ No newline at end of file diff --git a/app/src/market_data/acquisition/adapters/dzengi/parser.py b/app/src/market_data/acquisition/adapters/dzengi/parser.py index d811d90..c2ef7fd 100644 --- a/app/src/market_data/acquisition/adapters/dzengi/parser.py +++ b/app/src/market_data/acquisition/adapters/dzengi/parser.py @@ -11,6 +11,8 @@ from src.market_data.acquisition.adapters.dzengi.models import ( DzengiInstrumentFilter, DzengiJsonNumber, DzengiJsonScalar, + DzengiKline, + DzengiKlinesResponse, DzengiLotSizeFilter, DzengiMinNotionalFilter, DzengiRateLimit, @@ -20,10 +22,12 @@ from src.market_data.acquisition.adapters.dzengi.models import ( DzengiWebSocketQuoteResponse, ) from src.market_data.acquisition.exceptions import ( + CandleParseError, InstrumentReferenceParseError, QuoteParseError, ) from src.market_data.acquisition.validation.schema import ( + ValidatedCandlesDocument, ValidatedExchangeInfoDocument, ValidatedQuoteDocument, ValidatedWebSocketQuoteDocument, @@ -714,3 +718,153 @@ def _websocket_optional_timestamp( return None return _quote_required_int(value, path=path) + +# Преобразовать структурно проверенный ответ klines в raw-модели Dzengi. +def parse_candles( + document: ValidatedCandlesDocument, +) -> DzengiKlinesResponse: + """ + Преобразовать элементы проверенного документа klines в transport-модели. + + Функция не выполняет предметную проверку числовых значений, + OHLC-инвариантов или mapping во внутреннюю модель Candle. + """ + + items = tuple( + _parse_candle_item( + item, + path=f"$.candles[{index}]", + ) + for index, item in enumerate(document.items) + ) + + return DzengiKlinesResponse(items=items) + + +def _parse_candle_item( + item: object, + *, + path: str, +) -> DzengiKline: + if isinstance(item, Mapping): + return _parse_candle_mapping(item, path=path) + + if isinstance(item, tuple): + return _parse_candle_sequence(item, path=path) + + raise CandleParseError( + f"{path} должен быть проверенным JSON-объектом или массивом." + ) + + +def _parse_candle_mapping( + item: Mapping[str, object], + *, + path: str, +) -> DzengiKline: + open_time_key = _first_present_key( + item, + keys=("openTime", "open_time", "time", "timestamp"), + ) + + if open_time_key is None: + raise CandleParseError( + f"{path} не содержит openTime, open_time, time или timestamp." + ) + + return DzengiKline( + open_time=_candle_required_int( + item.get(open_time_key), + path=f"{path}.{open_time_key}", + ), + open_price=_candle_required_raw_numeric( + _required_candle_field(item, key="open", path=path), + path=f"{path}.open", + ), + high_price=_candle_required_raw_numeric( + _required_candle_field(item, key="high", path=path), + path=f"{path}.high", + ), + low_price=_candle_required_raw_numeric( + _required_candle_field(item, key="low", path=path), + path=f"{path}.low", + ), + close_price=_candle_required_raw_numeric( + _required_candle_field(item, key="close", path=path), + path=f"{path}.close", + ), + volume=_candle_required_raw_numeric( + _required_candle_field(item, key="volume", path=path), + path=f"{path}.volume", + ), + ) + + +def _parse_candle_sequence( + item: tuple[object, ...], + *, + path: str, +) -> DzengiKline: + if len(item) < 6: + raise CandleParseError( + f"{path} должен содержать минимум 6 элементов." + ) + + return DzengiKline( + open_time=_candle_required_int(item[0], path=f"{path}[0]"), + open_price=_candle_required_raw_numeric(item[1], path=f"{path}[1]"), + high_price=_candle_required_raw_numeric(item[2], path=f"{path}[2]"), + low_price=_candle_required_raw_numeric(item[3], path=f"{path}[3]"), + close_price=_candle_required_raw_numeric(item[4], path=f"{path}[4]"), + volume=_candle_required_raw_numeric(item[5], path=f"{path}[5]"), + ) + + +def _first_present_key( + mapping: Mapping[str, object], + *, + keys: tuple[str, ...], +) -> str | None: + for key in keys: + if key in mapping: + return key + return None + + +def _required_candle_field( + mapping: Mapping[str, object], + *, + key: str, + path: str, +) -> object: + if key not in mapping: + raise CandleParseError( + f"{path}.{key} отсутствует в элементе klines." + ) + return mapping.get(key) + + +def _candle_required_int( + value: object, + *, + path: str, +) -> int: + if isinstance(value, bool) or not isinstance(value, int): + raise CandleParseError( + f"{path} должен быть целым числом, " + f"получен {type(value).__name__}." + ) + return value + + +def _candle_required_raw_numeric( + value: object, + *, + path: str, +) -> DzengiRawNumeric: + if isinstance(value, bool) or not isinstance(value, (str, int, float)): + raise CandleParseError( + f"{path} должен быть строкой или числом, " + f"получен {type(value).__name__}." + ) + return value diff --git a/app/src/market_data/acquisition/adapters/dzengi/rest.py b/app/src/market_data/acquisition/adapters/dzengi/rest.py index 36f9fac..7cac2e4 100644 --- a/app/src/market_data/acquisition/adapters/dzengi/rest.py +++ b/app/src/market_data/acquisition/adapters/dzengi/rest.py @@ -6,6 +6,7 @@ from typing import Protocol from src.integrations.exchange.rest_client import ExchangeRestClient from src.market_data.acquisition.exceptions import ( + CandleTransportError, InstrumentReferenceTransportError, QuoteTransportError, ) @@ -13,6 +14,7 @@ from src.market_data.acquisition.exceptions import ( _EXCHANGE_INFO_PATH = "/api/v1/exchangeInfo" _TICKER_24HR_PATH = "/api/v1/ticker/24hr" +_KLINES_PATH = "/api/v1/klines" # Минимальный транспортный контракт, необходимый Dzengi REST adapter. @@ -104,3 +106,52 @@ class DzengiQuoteDocumentSource: "Не удалось получить текущую котировку " f"от Dzengi для символа '{symbol}': {exc}" ) from exc + + +class DzengiCandlesDocumentSource: + """Источник сырого документа свечей через Dzengi REST API.""" + + def __init__( + self, + client: _PayloadRestClient | None = None, + ) -> None: + self._client = client + + def fetch_candles_document( + self, + symbol: str, + *, + interval: str, + limit: int, + price_type: str, + ) -> object: + """ + Получить декодированный ответ Dzengi klines без его обработки. + + Метод не выполняет нормализацию параметров запроса, schema validation, + parsing, value validation, mapping, retry, сортировку или кэширование. + """ + + try: + client: _PayloadRestClient = ( + self._client + if self._client is not None + else ExchangeRestClient() + ) + + return client.get_payload( + _KLINES_PATH, + params={ + "symbol": symbol, + "interval": interval, + "limit": str(limit), + "priceType": price_type, + }, + ) + + except Exception as exc: + raise CandleTransportError( + "Не удалось получить свечи " + f"от Dzengi для символа '{symbol}', " + f"интервала '{interval}' и типа цены '{price_type}': {exc}" + ) from exc \ No newline at end of file diff --git a/app/src/market_data/acquisition/exceptions.py b/app/src/market_data/acquisition/exceptions.py index 3ede317..89c4538 100644 --- a/app/src/market_data/acquisition/exceptions.py +++ b/app/src/market_data/acquisition/exceptions.py @@ -37,6 +37,7 @@ class InstrumentReferenceMappingError(MarketDataAcquisitionError): class InstrumentFeedRegistryError(MarketDataAcquisitionError): pass + # Ошибка получения Quotes Feed от внешнего источника. class QuoteTransportError(MarketDataAcquisitionError): pass @@ -65,3 +66,28 @@ class QuoteMappingError(MarketDataAcquisitionError): # Ошибка регистрации или получения Quotes Feed. class QuoteFeedRegistryError(MarketDataAcquisitionError): pass + + +# Ошибка получения Candles Feed от внешнего источника. +class CandleTransportError(MarketDataAcquisitionError): + pass + + +# Ошибка структуры документа Candles Feed. +class CandleSchemaError(MarketDataAcquisitionError): + pass + + +# Ошибка преобразования проверенного документа в raw-модели свечей. +class CandleParseError(MarketDataAcquisitionError): + pass + + +# Ошибка допустимости значений Candles Feed. +class CandleValueError(MarketDataAcquisitionError): + pass + + +# Ошибка преобразования raw-модели источника во внутреннюю модель Candle. +class CandleMappingError(MarketDataAcquisitionError): + pass \ No newline at end of file diff --git a/app/src/market_data/acquisition/feeds/candles_feed.py b/app/src/market_data/acquisition/feeds/candles_feed.py index e69de29..e1de496 100644 --- a/app/src/market_data/acquisition/feeds/candles_feed.py +++ b/app/src/market_data/acquisition/feeds/candles_feed.py @@ -0,0 +1,53 @@ +# app/src/market_data/acquisition/feeds/candles_feed.py + +from __future__ import annotations + +from src.market_data.acquisition.models.candle import Candle +from src.market_data.acquisition.protocol import ( + CandlesDocumentHandler, + CandlesDocumentSource, +) + + +class CandlesFeed: + """ + Read-only Feed канонических рыночных свечей. + + Feed координирует получение и обработку документа, но не выполняет + transport parsing, value validation, mapping или кэширование. + """ + + def __init__( + self, + *, + source: CandlesDocumentSource, + handler: CandlesDocumentHandler, + ) -> None: + self._source = source + self._handler = handler + + def load_candles( + self, + symbol: str, + *, + interval: str, + limit: int, + price_type: str, + ) -> tuple[Candle, ...]: + """ + Получить канонический immutable-набор свечей инструмента. + """ + + document = self._source.fetch_candles_document( + symbol, + interval=interval, + limit=limit, + price_type=price_type, + ) + + return self._handler.handle_candles_document( + document, + symbol=symbol, + interval=interval, + source=f"rest_klines:{price_type}", + ) \ No newline at end of file diff --git a/app/src/market_data/acquisition/handlers/candles_handler.py b/app/src/market_data/acquisition/handlers/candles_handler.py index e69de29..79dc6de 100644 --- a/app/src/market_data/acquisition/handlers/candles_handler.py +++ b/app/src/market_data/acquisition/handlers/candles_handler.py @@ -0,0 +1,54 @@ +# app/src/market_data/acquisition/handlers/candles_handler.py + +from __future__ import annotations + +from src.market_data.acquisition.adapters.dzengi.mapper import ( + map_dzengi_klines_to_candles, +) +from src.market_data.acquisition.adapters.dzengi.parser import ( + parse_candles, +) +from src.market_data.acquisition.models.candle import Candle +from src.market_data.acquisition.validation.schema import ( + validate_candles_schema, +) +from src.market_data.acquisition.validation.values import ( + validate_candles_values, +) + + +# Обработчик документа Candles Feed формата Dzengi /api/v1/klines. +class DzengiCandlesDocumentHandler: + def handle_candles_document( + self, + document: object, + *, + symbol: str, + interval: str, + source: str, + ) -> tuple[Candle, ...]: + """ + Преобразовать сырой документ Dzengi в канонические модели Candle. + + Порядок обработки: + + schema validation + → + parsing + → + value validation + → + mapping + """ + + validated_document = validate_candles_schema(document) + response = parse_candles(validated_document) + + validate_candles_values(response) + + return map_dzengi_klines_to_candles( + response, + symbol=symbol, + interval=interval, + source=source, + ) \ No newline at end of file diff --git a/app/src/market_data/acquisition/models/candle.py b/app/src/market_data/acquisition/models/candle.py index e69de29..aba86a3 100644 --- a/app/src/market_data/acquisition/models/candle.py +++ b/app/src/market_data/acquisition/models/candle.py @@ -0,0 +1,24 @@ +# app/src/market_data/acquisition/models/candle.py + +from __future__ import annotations + +from dataclasses import dataclass +from datetime import datetime +from decimal import Decimal + + +# Каноническая неизменяемая модель одной рыночной свечи OHLCV. +@dataclass(frozen=True, slots=True) +class Candle: + symbol: str + interval: str + + open_time: datetime + + open_price: Decimal + high_price: Decimal + low_price: Decimal + close_price: Decimal + volume: Decimal + + source: str \ No newline at end of file diff --git a/app/src/market_data/acquisition/protocol.py b/app/src/market_data/acquisition/protocol.py index 48d575d..3003530 100644 --- a/app/src/market_data/acquisition/protocol.py +++ b/app/src/market_data/acquisition/protocol.py @@ -4,6 +4,7 @@ from __future__ import annotations from typing import Protocol, runtime_checkable +from src.market_data.acquisition.models.candle import Candle from src.market_data.acquisition.models.instrument import Instrument from src.market_data.acquisition.models.quote import Quote @@ -83,4 +84,58 @@ class QuoteFeedProtocol(Protocol): """ Получить внутреннюю модель текущей котировки инструмента. """ + ... + + +# Источник сырого документа Candles Feed. +@runtime_checkable +class CandlesDocumentSource(Protocol): + def fetch_candles_document( + self, + symbol: str, + *, + interval: str, + limit: int, + price_type: str, + ) -> object: + """ + Получить декодированный транспортный документ рыночных свечей. + + Источник не выполняет schema validation, parsing, value validation + или mapping во внутреннюю модель Candle. + """ + ... + + +# Обработчик сырого документа Candles Feed. +@runtime_checkable +class CandlesDocumentHandler(Protocol): + def handle_candles_document( + self, + document: object, + *, + symbol: str, + interval: str, + source: str, + ) -> tuple[Candle, ...]: + """ + Преобразовать сырой документ в проверенный immutable-набор Candle. + """ + ... + + +# Источник готового набора свечей. +@runtime_checkable +class CandlesFeedProtocol(Protocol): + def load_candles( + self, + symbol: str, + *, + interval: str, + limit: int, + price_type: str, + ) -> tuple[Candle, ...]: + """ + Получить immutable-набор внутренних моделей Candle. + """ ... \ No newline at end of file diff --git a/app/src/market_data/acquisition/validation/schema.py b/app/src/market_data/acquisition/validation/schema.py index 38f2aa1..719ee0d 100644 --- a/app/src/market_data/acquisition/validation/schema.py +++ b/app/src/market_data/acquisition/validation/schema.py @@ -7,6 +7,7 @@ from types import MappingProxyType from typing import Mapping from src.market_data.acquisition.exceptions import ( + CandleSchemaError, InstrumentReferenceSchemaError, QuoteSchemaError, ) @@ -199,6 +200,7 @@ def _require_list( return value + # Структурно проверенное представление ответа ticker/24hr. @dataclass(frozen=True, slots=True) class ValidatedQuoteDocument: @@ -398,3 +400,195 @@ def _validate_websocket_quote_payload( raise QuoteSchemaError( "WebSocket quote не содержит bid/ask либо bids/asks." ) + + +# Структурно проверенное представление ответа Dzengi /api/v1/klines. +@dataclass(frozen=True, slots=True) +class ValidatedCandlesDocument: + items: tuple[object, ...] + + +def validate_candles_schema( + document: object, +) -> ValidatedCandlesDocument: + """ + Проверить структуру ответа Dzengi klines без проверки значений. + + Поддерживаются: + + 1. Корневой JSON-массив: + + [ + [...], + {...} + ] + + 2. Корневой JSON-объект с массивом в одном из полей: + + { + "klines": [...] + } + + { + "candles": [...] + } + + { + "data": [...] + } + + { + "result": [...] + } + + 3. Wrapped-формат: + + { + "payload": [...] + } + + { + "payload": { + "klines": [...] + } + } + + Внутри payload также поддерживаются поля candles и data. + """ + + raw_items = _extract_candle_items(document) + + validated_items: list[object] = [] + + for index, item in enumerate(raw_items): + path = f"$.candles[{index}]" + validated_items.append( + _validate_and_freeze_candle_item( + item, + path=path, + ) + ) + + return ValidatedCandlesDocument( + items=tuple(validated_items), + ) + + +def _extract_candle_items( + document: object, +) -> list[object]: + if isinstance(document, list): + return document + + root = _require_candle_mapping( + document, + path="$", + ) + + direct_items = _find_candle_list( + root, + keys=("klines", "candles", "data", "result"), + path="$", + ) + + if direct_items is not None: + return direct_items + + if "payload" not in root: + raise CandleSchemaError( + "$ не содержит поддерживаемый массив klines." + ) + + payload = root.get("payload") + + if isinstance(payload, list): + return payload + + payload_mapping = _require_candle_mapping( + payload, + path="$.payload", + ) + + wrapped_items = _find_candle_list( + payload_mapping, + keys=("klines", "candles", "data"), + path="$.payload", + ) + + if wrapped_items is not None: + return wrapped_items + + raise CandleSchemaError( + "$.payload не содержит поддерживаемый массив klines." + ) + + +def _find_candle_list( + mapping: Mapping[str, object], + *, + keys: tuple[str, ...], + path: str, +) -> list[object] | None: + for key in keys: + if key not in mapping: + continue + + value = mapping.get(key) + + if not isinstance(value, list): + raise CandleSchemaError( + f"{path}.{key} должен быть JSON-массивом, " + f"получен {type(value).__name__}." + ) + + return value + + return None + + +def _validate_and_freeze_candle_item( + item: object, + *, + path: str, +) -> object: + if isinstance(item, dict): + mapping = _require_candle_mapping( + item, + path=path, + ) + return MappingProxyType(dict(mapping)) + + if isinstance(item, list): + if len(item) < 6: + raise CandleSchemaError( + f"{path} должен содержать минимум 6 элементов, " + f"получено {len(item)}." + ) + + return tuple(item) + + raise CandleSchemaError( + f"{path} должен быть JSON-объектом или JSON-массивом, " + f"получен {type(item).__name__}." + ) + + +def _require_candle_mapping( + value: object, + *, + path: str, +) -> Mapping[str, object]: + if not isinstance(value, dict): + raise CandleSchemaError( + f"{path} должен быть JSON-объектом, " + f"получен {type(value).__name__}." + ) + + for key in value: + if not isinstance(key, str): + raise CandleSchemaError( + f"{path} содержит нестроковый ключ " + f"типа {type(key).__name__}." + ) + + return value \ No newline at end of file diff --git a/app/src/market_data/acquisition/validation/values.py b/app/src/market_data/acquisition/validation/values.py index 5793e1d..f1ddd00 100644 --- a/app/src/market_data/acquisition/validation/values.py +++ b/app/src/market_data/acquisition/validation/values.py @@ -13,10 +13,12 @@ from src.market_data.acquisition.adapters.dzengi.models import ( DzengiRateLimit, DzengiRawNumeric, DzengiUnknownFilter, + DzengiKlinesResponse, DzengiTicker24hrResponse, DzengiWebSocketQuoteResponse, ) from src.market_data.acquisition.exceptions import ( + CandleValueError, InstrumentReferenceValueError, QuoteValueError, ) @@ -454,6 +456,7 @@ def _to_finite_decimal( return decimal_value + def validate_quote_values( response: DzengiTicker24hrResponse, ) -> None: @@ -549,3 +552,128 @@ def validate_dzengi_websocket_quote_values( raise QuoteValueError( "$.payload.timestamp должно быть больше нуля." ) + +def validate_candles_values( + response: DzengiKlinesResponse, +) -> None: + """ + Проверить допустимость значений raw-моделей Dzengi klines. + + Функция не изменяет transport-модели, не выполняет mapping в Candle + и не проверяет последовательность временных меток между свечами. + """ + + for index, candle in enumerate(response.items): + path = f"$.candles[{index}]" + + if isinstance(candle.open_time, bool) or candle.open_time <= 0: + raise CandleValueError( + f"{path}.openTime должно быть целым числом больше нуля." + ) + + open_price = _candle_positive_decimal( + candle.open_price, + path=f"{path}.open", + ) + high_price = _candle_positive_decimal( + candle.high_price, + path=f"{path}.high", + ) + low_price = _candle_positive_decimal( + candle.low_price, + path=f"{path}.low", + ) + close_price = _candle_positive_decimal( + candle.close_price, + path=f"{path}.close", + ) + _candle_non_negative_decimal( + candle.volume, + path=f"{path}.volume", + ) + + if high_price < low_price: + raise CandleValueError( + f"{path}.high не должно быть меньше {path}.low." + ) + + if high_price < open_price: + raise CandleValueError( + f"{path}.high не должно быть меньше {path}.open." + ) + + if high_price < close_price: + raise CandleValueError( + f"{path}.high не должно быть меньше {path}.close." + ) + + if low_price > open_price: + raise CandleValueError( + f"{path}.low не должно превышать {path}.open." + ) + + if low_price > close_price: + raise CandleValueError( + f"{path}.low не должно превышать {path}.close." + ) + + +def _candle_positive_decimal( + value: object, + *, + path: str, +) -> Decimal: + decimal_value = _candle_decimal( + value, + path=path, + ) + + if decimal_value <= 0: + raise CandleValueError( + f"{path} должно быть больше нуля." + ) + + return decimal_value + + +def _candle_non_negative_decimal( + value: object, + *, + path: str, +) -> Decimal: + decimal_value = _candle_decimal( + value, + path=path, + ) + + if decimal_value < 0: + raise CandleValueError( + f"{path} должно быть больше или равно нулю." + ) + + return decimal_value + + +def _candle_decimal( + value: object, + *, + path: str, +) -> Decimal: + if isinstance(value, bool) or not isinstance(value, (str, int, float)): + raise CandleValueError( + f"{path} должно быть числом или числовой строкой." + ) + + try: + decimal_value = Decimal(str(value)) + except (InvalidOperation, ValueError) as exc: + raise CandleValueError( + f"{path} должно быть корректным числом." + ) from exc + + if not decimal_value.is_finite(): + raise CandleValueError( + f"{path} должно быть конечным числом." + ) + + return decimal_value \ No newline at end of file diff --git a/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py new file mode 100644 index 0000000..29d2bda --- /dev/null +++ b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py @@ -0,0 +1,80 @@ +# app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py + +from __future__ import annotations + +from datetime import timezone +from decimal import Decimal + +from src.market_data.acquisition.adapters.dzengi.mapper import ( + map_dzengi_klines_to_candles, +) +from src.market_data.acquisition.adapters.dzengi.models import ( + DzengiKline, + DzengiKlinesResponse, +) + + +def _item(open_time: int) -> DzengiKline: + return DzengiKline( + open_time=open_time, + open_price="100.10", + high_price="110.20", + low_price="90.30", + close_price="105.40", + volume="12.50", + ) + + +def test_map_dzengi_klines_to_candles_maps_canonical_values() -> None: + response = DzengiKlinesResponse(items=(_item(1000),)) + + result = map_dzengi_klines_to_candles( + response, + symbol="BTC/USD", + interval="1m", + source="rest_klines:bid", + ) + + assert len(result) == 1 + candle = result[0] + assert candle.symbol == "BTC/USD" + assert candle.interval == "1m" + assert candle.open_time.tzinfo is timezone.utc + assert candle.open_time.timestamp() == 1 + assert candle.open_price == Decimal("100.10") + assert candle.high_price == Decimal("110.20") + assert candle.low_price == Decimal("90.30") + assert candle.close_price == Decimal("105.40") + assert candle.volume == Decimal("12.50") + assert candle.source == "rest_klines:bid" + + +def test_map_dzengi_klines_to_candles_sorts_by_open_time() -> None: + response = DzengiKlinesResponse( + items=( + _item(3000), + _item(1000), + _item(2000), + ) + ) + + result = map_dzengi_klines_to_candles( + response, + symbol="BTC/USD", + interval="1m", + source="rest_klines:bid", + ) + + assert [item.open_time.timestamp() for item in result] == [1, 2, 3] + + +def test_map_dzengi_klines_to_candles_returns_tuple() -> None: + result = map_dzengi_klines_to_candles( + DzengiKlinesResponse(items=()), + symbol="BTC/USD", + interval="1m", + source="rest_klines:bid", + ) + + assert result == () + assert isinstance(result, tuple) diff --git a/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py new file mode 100644 index 0000000..8cbde2f --- /dev/null +++ b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py @@ -0,0 +1,135 @@ +# app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py + +from __future__ import annotations + +import pytest + +from src.market_data.acquisition.adapters.dzengi.parser import parse_candles +from src.market_data.acquisition.exceptions import CandleParseError +from src.market_data.acquisition.validation.schema import ( + validate_candles_schema, +) + + +def test_parse_candles_parses_object_item() -> None: + document = validate_candles_schema( + [ + { + "openTime": 1000, + "open": "100", + "high": "110", + "low": "90", + "close": "105", + "volume": "12.5", + } + ] + ) + + result = parse_candles(document) + + assert len(result.items) == 1 + item = result.items[0] + assert item.open_time == 1000 + assert item.open_price == "100" + assert item.high_price == "110" + assert item.low_price == "90" + assert item.close_price == "105" + assert item.volume == "12.5" + + +@pytest.mark.parametrize( + "time_key", + ["openTime", "open_time", "time", "timestamp"], +) +def test_parse_candles_supports_time_aliases(time_key: str) -> None: + document = validate_candles_schema( + [ + { + time_key: 1000, + "open": "100", + "high": "110", + "low": "90", + "close": "105", + "volume": "12.5", + } + ] + ) + + result = parse_candles(document) + + assert result.items[0].open_time == 1000 + + +def test_parse_candles_parses_array_item() -> None: + document = validate_candles_schema( + [[1000, "100", "110", "90", "105", "12.5", "ignored"]] + ) + + result = parse_candles(document) + + item = result.items[0] + assert item.open_time == 1000 + assert item.open_price == "100" + assert item.high_price == "110" + assert item.low_price == "90" + assert item.close_price == "105" + assert item.volume == "12.5" + + +def test_parse_candles_accepts_empty_document() -> None: + result = parse_candles(validate_candles_schema([])) + + assert result.items == () + + +def test_parse_candles_rejects_missing_required_field() -> None: + document = validate_candles_schema( + [ + { + "openTime": 1000, + "open": "100", + "high": "110", + "low": "90", + "volume": "12.5", + } + ] + ) + + with pytest.raises(CandleParseError, match="close"): + parse_candles(document) + + +@pytest.mark.parametrize( + "invalid_time", + [True, 1.5, "1000", None], +) +def test_parse_candles_rejects_invalid_open_time( + invalid_time: object, +) -> None: + document = validate_candles_schema( + [[invalid_time, "100", "110", "90", "105", "12.5"]] + ) + + with pytest.raises( + CandleParseError, + match=r"\$\.candles\[0\]\[0\]", + ): + parse_candles(document) + + +@pytest.mark.parametrize( + "invalid_value", + [True, None, {}, []], +) +def test_parse_candles_rejects_invalid_numeric_transport_value( + invalid_value: object, +) -> None: + document = validate_candles_schema( + [[1000, invalid_value, "110", "90", "105", "12.5"]] + ) + + with pytest.raises( + CandleParseError, + match=r"\$\.candles\[0\]\[1\]", + ): + parse_candles(document) diff --git a/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py new file mode 100644 index 0000000..a045046 --- /dev/null +++ b/app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py @@ -0,0 +1,100 @@ +# app/tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py + +from __future__ import annotations + +import pytest + +from src.market_data.acquisition.adapters.dzengi.rest import ( + DzengiCandlesDocumentSource, +) +from src.market_data.acquisition.exceptions import CandleTransportError + + +class StubPayloadRestClient: + def __init__( + self, + *, + result: object = None, + error: Exception | None = None, + ) -> None: + self.result = result + self.error = error + self.calls: list[ + tuple[str, dict[str, str] | None, dict[str, str] | None] + ] = [] + + def get_payload( + self, + path: str, + params: dict[str, str] | None = None, + headers: dict[str, str] | None = None, + ) -> object: + self.calls.append((path, params, headers)) + + if self.error is not None: + raise self.error + + return self.result + + +def test_fetch_candles_document_calls_klines_endpoint() -> None: + document = {"klines": []} + client = StubPayloadRestClient(result=document) + source = DzengiCandlesDocumentSource(client=client) + + result = source.fetch_candles_document( + "BTC/USD", + interval="5m", + limit=200, + price_type="ask", + ) + + assert result is document + assert client.calls == [ + ( + "/api/v1/klines", + { + "symbol": "BTC/USD", + "interval": "5m", + "limit": "200", + "priceType": "ask", + }, + None, + ) + ] + + +def test_fetch_candles_document_does_not_transform_document() -> None: + document = [ + [1000, "100", "110", "90", "105", "12.5"], + ] + client = StubPayloadRestClient(result=document) + source = DzengiCandlesDocumentSource(client=client) + + result = source.fetch_candles_document( + "BTC/USD", + interval="1m", + limit=1, + price_type="bid", + ) + + assert result is document + + +def test_fetch_candles_document_wraps_transport_error() -> None: + original_error = RuntimeError("transport unavailable") + client = StubPayloadRestClient(error=original_error) + source = DzengiCandlesDocumentSource(client=client) + + with pytest.raises( + CandleTransportError, + match="Не удалось получить свечи", + ) as error_info: + source.fetch_candles_document( + "BTC/USD", + interval="1m", + limit=100, + price_type="bid", + ) + + assert error_info.value.__cause__ is original_error diff --git a/app/tests/unit/market_data/acquisition/feeds/test_candles_feed.py b/app/tests/unit/market_data/acquisition/feeds/test_candles_feed.py new file mode 100644 index 0000000..688cdac --- /dev/null +++ b/app/tests/unit/market_data/acquisition/feeds/test_candles_feed.py @@ -0,0 +1,164 @@ +# app/tests/unit/market_data/acquisition/feeds/test_candles_feed.py + +from __future__ import annotations + +from datetime import datetime, timezone +from decimal import Decimal + +import pytest + +from src.market_data.acquisition.feeds.candles_feed import CandlesFeed +from src.market_data.acquisition.models.candle import Candle + + +def _candle() -> Candle: + return Candle( + symbol="BTC/USD", + interval="1m", + open_time=datetime(2026, 7, 15, 6, 0, tzinfo=timezone.utc), + open_price=Decimal("100"), + high_price=Decimal("110"), + low_price=Decimal("90"), + close_price=Decimal("105"), + volume=Decimal("12"), + source="rest_klines:bid", + ) + + +class StubCandlesDocumentSource: + def __init__( + self, + *, + document: object, + error: Exception | None = None, + ) -> None: + self.document = document + self.error = error + self.calls: list[tuple[str, str, int, str]] = [] + + def fetch_candles_document( + self, + symbol: str, + *, + interval: str, + limit: int, + price_type: str, + ) -> object: + self.calls.append((symbol, interval, limit, price_type)) + + if self.error is not None: + raise self.error + + return self.document + + +class StubCandlesDocumentHandler: + def __init__( + self, + *, + candles: tuple[Candle, ...], + error: Exception | None = None, + ) -> None: + self.candles = candles + self.error = error + self.calls: list[tuple[object, str, str, str]] = [] + + def handle_candles_document( + self, + document: object, + *, + symbol: str, + interval: str, + source: str, + ) -> tuple[Candle, ...]: + self.calls.append((document, symbol, interval, source)) + + if self.error is not None: + raise self.error + + return self.candles + + +def test_load_candles_coordinates_source_and_handler() -> None: + document = {"klines": []} + candles = (_candle(),) + source = StubCandlesDocumentSource(document=document) + handler = StubCandlesDocumentHandler(candles=candles) + feed = CandlesFeed(source=source, handler=handler) + + result = feed.load_candles( + "BTC/USD", + interval="1m", + limit=100, + price_type="bid", + ) + + assert result is candles + assert source.calls == [("BTC/USD", "1m", 100, "bid")] + assert handler.calls == [ + ( + document, + "BTC/USD", + "1m", + "rest_klines:bid", + ) + ] + + +def test_load_candles_does_not_trim_handler_result() -> None: + candles = (_candle(), _candle()) + source = StubCandlesDocumentSource(document=[]) + handler = StubCandlesDocumentHandler(candles=candles) + feed = CandlesFeed(source=source, handler=handler) + + result = feed.load_candles( + "BTC/USD", + interval="1m", + limit=1, + price_type="ask", + ) + + assert result is candles + assert len(result) == 2 + + +def test_load_candles_propagates_source_error() -> None: + original_error = RuntimeError("source failed") + source = StubCandlesDocumentSource( + document=None, + error=original_error, + ) + handler = StubCandlesDocumentHandler(candles=()) + feed = CandlesFeed(source=source, handler=handler) + + with pytest.raises(RuntimeError, match="source failed") as error_info: + feed.load_candles( + "BTC/USD", + interval="1m", + limit=100, + price_type="bid", + ) + + assert error_info.value is original_error + assert handler.calls == [] + + +def test_load_candles_propagates_handler_error() -> None: + original_error = ValueError("handler failed") + document = {"klines": []} + source = StubCandlesDocumentSource(document=document) + handler = StubCandlesDocumentHandler( + candles=(), + error=original_error, + ) + feed = CandlesFeed(source=source, handler=handler) + + with pytest.raises(ValueError, match="handler failed") as error_info: + feed.load_candles( + "BTC/USD", + interval="5m", + limit=50, + price_type="ask", + ) + + assert error_info.value is original_error diff --git a/app/tests/unit/market_data/acquisition/handlers/test_candles_handler.py b/app/tests/unit/market_data/acquisition/handlers/test_candles_handler.py new file mode 100644 index 0000000..16deaec --- /dev/null +++ b/app/tests/unit/market_data/acquisition/handlers/test_candles_handler.py @@ -0,0 +1,31 @@ +# app/tests/unit/market_data/acquisition/handlers/test_candles_handler.py + +from __future__ import annotations + +from src.market_data.acquisition.handlers.candles_handler import ( + DzengiCandlesDocumentHandler, +) + + +def test_handle_candles_document_runs_complete_pipeline() -> None: + handler = DzengiCandlesDocumentHandler() + + result = handler.handle_candles_document( + { + "payload": { + "klines": [ + [2000, "101", "111", "91", "106", "13"], + [1000, "100", "110", "90", "105", "12"], + ] + } + }, + symbol="BTC/USD", + interval="1m", + source="rest_klines:bid", + ) + + assert len(result) == 2 + assert [item.open_time.timestamp() for item in result] == [1, 2] + assert all(item.symbol == "BTC/USD" for item in result) + assert all(item.interval == "1m" for item in result) + assert all(item.source == "rest_klines:bid" for item in result) diff --git a/app/tests/unit/market_data/acquisition/models/test_candle.py b/app/tests/unit/market_data/acquisition/models/test_candle.py new file mode 100644 index 0000000..a03c862 --- /dev/null +++ b/app/tests/unit/market_data/acquisition/models/test_candle.py @@ -0,0 +1,52 @@ +# app/tests/unit/market_data/acquisition/models/test_candle.py + +from __future__ import annotations + +from dataclasses import FrozenInstanceError +from datetime import datetime, timezone +from decimal import Decimal + +import pytest + +from src.market_data.acquisition.models.candle import Candle + + +def _candle() -> Candle: + return Candle( + symbol="BTC/USD", + interval="1m", + open_time=datetime(2026, 7, 15, 6, 0, tzinfo=timezone.utc), + open_price=Decimal("100"), + high_price=Decimal("110"), + low_price=Decimal("90"), + close_price=Decimal("105"), + volume=Decimal("12.5"), + source="rest_klines:bid", + ) + + +def test_candle_stores_canonical_values() -> None: + candle = _candle() + + assert candle.symbol == "BTC/USD" + assert candle.interval == "1m" + assert candle.open_time.tzinfo is timezone.utc + assert candle.open_price == Decimal("100") + assert candle.high_price == Decimal("110") + assert candle.low_price == Decimal("90") + assert candle.close_price == Decimal("105") + assert candle.volume == Decimal("12.5") + assert candle.source == "rest_klines:bid" + + +def test_candle_is_frozen() -> None: + candle = _candle() + + with pytest.raises(FrozenInstanceError): + candle.close_price = Decimal("106") # type: ignore[misc] + + +def test_candle_uses_slots() -> None: + candle = _candle() + + assert not hasattr(candle, "__dict__") diff --git a/app/tests/unit/market_data/acquisition/validation/test_candle_schema.py b/app/tests/unit/market_data/acquisition/validation/test_candle_schema.py new file mode 100644 index 0000000..166b160 --- /dev/null +++ b/app/tests/unit/market_data/acquisition/validation/test_candle_schema.py @@ -0,0 +1,120 @@ +# app/tests/unit/market_data/acquisition/validation/test_candle_schema.py + +from __future__ import annotations + +from types import MappingProxyType + +import pytest + +from src.market_data.acquisition.exceptions import CandleSchemaError +from src.market_data.acquisition.validation.schema import ( + validate_candles_schema, +) + + +_VALID_ARRAY_ITEM = [1000, "100", "110", "90", "105", "12.5"] +_VALID_OBJECT_ITEM = { + "openTime": 1000, + "open": "100", + "high": "110", + "low": "90", + "close": "105", + "volume": "12.5", +} + + +@pytest.mark.parametrize( + "document", + [ + [_VALID_ARRAY_ITEM], + {"klines": [_VALID_ARRAY_ITEM]}, + {"candles": [_VALID_ARRAY_ITEM]}, + {"data": [_VALID_ARRAY_ITEM]}, + {"result": [_VALID_ARRAY_ITEM]}, + {"payload": [_VALID_ARRAY_ITEM]}, + {"payload": {"klines": [_VALID_ARRAY_ITEM]}}, + {"payload": {"candles": [_VALID_ARRAY_ITEM]}}, + {"payload": {"data": [_VALID_ARRAY_ITEM]}}, + ], +) +def test_validate_candles_schema_accepts_supported_envelopes( + document: object, +) -> None: + result = validate_candles_schema(document) + + assert len(result.items) == 1 + assert result.items[0] == tuple(_VALID_ARRAY_ITEM) + + +def test_validate_candles_schema_accepts_object_item() -> None: + result = validate_candles_schema([_VALID_OBJECT_ITEM]) + + assert len(result.items) == 1 + assert isinstance(result.items[0], MappingProxyType) + assert dict(result.items[0]) == _VALID_OBJECT_ITEM + + +def test_validate_candles_schema_accepts_empty_list() -> None: + result = validate_candles_schema([]) + + assert result.items == () + + +@pytest.mark.parametrize( + "document", + [ + None, + "invalid", + 123, + {"unknown": []}, + {"payload": {"unknown": []}}, + ], +) +def test_validate_candles_schema_rejects_unknown_document( + document: object, +) -> None: + with pytest.raises(CandleSchemaError): + validate_candles_schema(document) + + +@pytest.mark.parametrize( + "document", + [ + {"klines": {}}, + {"payload": {"klines": {}}}, + ], +) +def test_validate_candles_schema_rejects_non_list_container( + document: object, +) -> None: + with pytest.raises(CandleSchemaError, match="JSON-массивом"): + validate_candles_schema(document) + + +@pytest.mark.parametrize( + "item", + [ + "invalid", + 123, + None, + True, + ], +) +def test_validate_candles_schema_rejects_invalid_item( + item: object, +) -> None: + with pytest.raises( + CandleSchemaError, + match="JSON-объектом или JSON-массивом", + ): + validate_candles_schema([item]) + + +def test_validate_candles_schema_rejects_short_array() -> None: + with pytest.raises(CandleSchemaError, match="минимум 6"): + validate_candles_schema([[1000, "100", "110"]]) + + +def test_validate_candles_schema_rejects_non_string_object_key() -> None: + with pytest.raises(CandleSchemaError, match="нестроковый ключ"): + validate_candles_schema([{1: "invalid"}]) diff --git a/app/tests/unit/market_data/acquisition/validation/test_candle_values.py b/app/tests/unit/market_data/acquisition/validation/test_candle_values.py new file mode 100644 index 0000000..6e703ce --- /dev/null +++ b/app/tests/unit/market_data/acquisition/validation/test_candle_values.py @@ -0,0 +1,109 @@ +# app/tests/unit/market_data/acquisition/validation/test_candle_values.py + +from __future__ import annotations + +import pytest + +from src.market_data.acquisition.adapters.dzengi.models import ( + DzengiKline, + DzengiKlinesResponse, +) +from src.market_data.acquisition.exceptions import CandleValueError +from src.market_data.acquisition.validation.values import ( + validate_candles_values, +) + + +def _response( + *, + open_time: int = 1000, + open_price: str | int | float = "100", + high_price: str | int | float = "110", + low_price: str | int | float = "90", + close_price: str | int | float = "105", + volume: str | int | float = "12.5", +) -> DzengiKlinesResponse: + return DzengiKlinesResponse( + items=( + DzengiKline( + open_time=open_time, + open_price=open_price, + high_price=high_price, + low_price=low_price, + close_price=close_price, + volume=volume, + ), + ) + ) + + +def test_validate_candles_values_accepts_valid_response() -> None: + validate_candles_values(_response()) + + +def test_validate_candles_values_accepts_zero_volume() -> None: + validate_candles_values(_response(volume=0)) + + +@pytest.mark.parametrize( + ("field_name", "value"), + [ + ("open_price", 0), + ("high_price", 0), + ("low_price", 0), + ("close_price", 0), + ("volume", -1), + ], +) +def test_validate_candles_values_rejects_invalid_bounds( + field_name: str, + value: int, +) -> None: + kwargs = {field_name: value} + + with pytest.raises(CandleValueError): + validate_candles_values(_response(**kwargs)) + + +@pytest.mark.parametrize( + "value", + ["NaN", "Infinity", "-Infinity"], +) +def test_validate_candles_values_rejects_non_finite_values( + value: str, +) -> None: + with pytest.raises(CandleValueError): + validate_candles_values(_response(open_price=value)) + + +@pytest.mark.parametrize( + "open_time", + [0, -1], +) +def test_validate_candles_values_rejects_invalid_open_time( + open_time: int, +) -> None: + with pytest.raises( + CandleValueError, + match=r"\$\.candles\[0\]\.openTime", + ): + validate_candles_values(_response(open_time=open_time)) + + +@pytest.mark.parametrize( + "response", + [ + _response(high_price="99"), + _response(low_price="101"), + _response(high_price="80", low_price="90"), + ], +) +def test_validate_candles_values_rejects_invalid_ohlc( + response: DzengiKlinesResponse, +) -> None: + with pytest.raises(CandleValueError): + validate_candles_values(response) + + +def test_validate_candles_values_accepts_empty_response() -> None: + validate_candles_values(DzengiKlinesResponse(items=())) diff --git a/docs/migrations/build_044.md b/docs/migrations/build_044.md new file mode 100644 index 0000000..41f2103 --- /dev/null +++ b/docs/migrations/build_044.md @@ -0,0 +1,1299 @@ +# Build 044 — Canonical Candles Feed Foundation + +**Документ миграции** + +--- + +## Контроль документа + +| Свойство | Значение | +|---|---| +| Документ | Build 044 — Canonical Candles Feed Foundation | +| Тип документа | Migration Build Record | +| Проект | Dzentra | +| Подсистема | Market Data Acquisition | +| Направление | OHLCV Feed / Candles Feed | +| Статус | **Complete** | +| Язык | Русский | +| Дата | 2026-07-15 | + +--- + +## 1. Назначение Build + +Build 044 создаёт автономную каноническую основу **Candles Feed** в утверждённой подсистеме: + +```text +src/market_data/acquisition/ +``` + +Build реализует новую read-only цепочку получения и обработки свечей рядом с действующим legacy-потоком. + +Рабочий бот после Build 044 продолжает использовать существующий метод: + +```text +ExchangeService.get_klines() +``` + +Переключение рабочего runtime на новый Candles Feed в данный Build не входит. + +--- + +## 2. Причина выполнения Build + +После завершения миграции: + +```text +Instrument Reference Data +Quotes Feed +``` + +следующим активным legacy-потоком Market Data Acquisition остаётся получение OHLCV-свечей. + +До Build 044 рабочая цепочка свечей находилась в legacy exchange layer: + +```text +ExchangeService.get_klines() + ↓ +ExchangeRestClient + ↓ +GET /api/v1/klines + ↓ +ExchangeService._extract_klines_items() + ↓ +ExchangeService._parse_kline_item() + ↓ +Kline + ↓ +KlineBatch + ↓ +trading/market_analysis +``` + +В результате: + +- endpoint `/api/v1/klines` находился в `ExchangeService`; +- transport parsing выполнялся в `ExchangeService`; +- модель `Kline` находилась в `src/integrations/exchange/models.py`; +- Market Analysis зависел от legacy-моделей; +- новая структура `Candles Feed` существовала только как набор пустых файлов. + +Build 044 создаёт новую каноническую цепочку без изменения рабочего legacy-контракта. + +--- + +## 3. Границы Build + +### 3.1. В Build входит + +Реализована цепочка: + +```text +Dzengi REST /api/v1/klines + ↓ +schema validation + ↓ +parser + ↓ +value validation + ↓ +mapper + ↓ +Candle + ↓ +DzengiCandlesDocumentHandler + ↓ +CandlesFeed +``` + +Также добавлены: + +- candle-specific исключения; +- transport-модели Dzengi; +- контракты source, handler и feed; +- специализированные unit-тесты; +- архитектурные проверки. + +### 3.2. В Build не входит + +Build не изменяет: + +```text +src/integrations/exchange/service.py +src/integrations/exchange/models.py +src/trading/market_analysis/ +``` + +Build не выполняет: + +- переключение `ExchangeService.get_klines()`; +- замену `Kline`; +- замену `KlineBatch`; +- миграцию consumers; +- добавление CandleStore; +- добавление candle cache; +- регистрацию Candles Feed в registry; +- публикацию через MarketDataAcquisitionService; +- WebSocket-поток свечей; +- sequence gap detection; +- дедупликацию свечей; +- resampling; +- определение закрытости свечи; +- удаление legacy parsing. + +--- + +## 4. Реализованная архитектура + +### 4.1. Каноническая модель + +Создана модель: + +```text +src/market_data/acquisition/models/candle.py +``` + +Контракт: + +```python +@dataclass(frozen=True, slots=True) +class Candle: + symbol: str + interval: str + open_time: datetime + open_price: Decimal + high_price: Decimal + low_price: Decimal + close_price: Decimal + volume: Decimal + source: str +``` + +Свойства модели: + +- immutable; +- `slots=True`; +- цены и объём представлены `Decimal`; +- время открытия представлено timezone-aware UTC `datetime`; +- модель не зависит от Dzengi; +- модель не зависит от legacy exchange layer. + +В модель намеренно не добавлены: + +```text +close_time +is_closed +CandleBatch +``` + +Эти поля и сущности не требуются текущим подтверждённым контрактом. + +--- + +### 4.2. Transport-модели Dzengi + +В файл: + +```text +src/market_data/acquisition/adapters/dzengi/models.py +``` + +добавлены: + +```text +DzengiKline +DzengiKlinesResponse +``` + +Transport-модель хранит данные после parser, но до канонического mapping. + +Допустимые transport numeric-типы: + +```text +str | int | float +``` + +--- + +### 4.3. REST source + +В файл: + +```text +src/market_data/acquisition/adapters/dzengi/rest.py +``` + +добавлен endpoint: + +```text +/api/v1/klines +``` + +и источник: + +```text +DzengiCandlesDocumentSource +``` + +Источник выполняет только transport-вызов и не выполняет: + +- schema validation; +- parsing; +- value validation; +- mapping; +- сортировку; +- кэширование; +- нормализацию запроса. + +Transport-ошибки преобразуются в: + +```text +CandleTransportError +``` + +--- + +### 4.4. Schema validation + +В файл: + +```text +src/market_data/acquisition/validation/schema.py +``` + +добавлены: + +```text +ValidatedCandlesDocument +validate_candles_schema() +``` + +Поддерживаются legacy-compatible envelope-форматы: + +```text +root list +root.klines +root.candles +root.data +root.result +root.payload list +root.payload.klines +root.payload.candles +root.payload.data +``` + +Поддерживаются два формата одной свечи: + +```text +JSON object +JSON array +``` + +После schema validation: + +```text +dict → MappingProxyType +list → tuple +``` + +--- + +### 4.5. Parser + +В файл: + +```text +src/market_data/acquisition/adapters/dzengi/parser.py +``` + +добавлена функция: + +```text +parse_candles() +``` + +Поддерживаются object-поля: + +```text +openTime +open_time +time +timestamp +open +high +low +close +volume +``` + +Поддерживается array-формат: + +```text +[ + open_time, + open, + high, + low, + close, + volume, + ... +] +``` + +Дополнительные поля массива игнорируются. + +Parser: + +- проверяет transport-типы; +- не создаёт `Decimal`; +- не проверяет OHLC-инварианты; +- не создаёт canonical `Candle`. + +--- + +### 4.6. Value validation + +В файл: + +```text +src/market_data/acquisition/validation/values.py +``` + +добавлена функция: + +```text +validate_candles_values() +``` + +Проверяются: + +```text +open_time > 0 +open_price > 0 +high_price > 0 +low_price > 0 +close_price > 0 +volume >= 0 +``` + +Также проверяются: + +- конечность числовых значений; +- запрет `bool`; +- OHLC-инварианты; +- `high >= low`; +- `high >= open`; +- `high >= close`; +- `low <= open`; +- `low <= close`. + +В Build 044 не выполняются: + +- проверка последовательности timestamp; +- проверка gaps; +- проверка соответствия интервалу; +- дедупликация; +- проверка равномерности шага. + +--- + +### 4.7. Mapper + +В файл: + +```text +src/market_data/acquisition/adapters/dzengi/mapper.py +``` + +добавлена функция: + +```text +map_dzengi_klines_to_candles() +``` + +Mapper выполняет: + +```text +raw numeric → Decimal +milliseconds timestamp → UTC datetime +DzengiKline → Candle +sorting by open_time +list → tuple +``` + +Mapper не выполняет: + +- исправление некорректных значений; +- удаление свечей; +- обрезку по `limit`; +- дедупликацию; +- определение закрытости свечи. + +--- + +### 4.8. Handler + +Реализован: + +```text +src/market_data/acquisition/handlers/candles_handler.py +``` + +Основной класс: + +```text +DzengiCandlesDocumentHandler +``` + +Последовательность обработки: + +```text +validate_candles_schema() + ↓ +parse_candles() + ↓ +validate_candles_values() + ↓ +map_dzengi_klines_to_candles() +``` + +--- + +### 4.9. Feed + +Реализован: + +```text +src/market_data/acquisition/feeds/candles_feed.py +``` + +Основной класс: + +```text +CandlesFeed +``` + +Feed координирует: + +```text +CandlesDocumentSource + ↓ +CandlesDocumentHandler +``` + +Feed не выполняет: + +- transport parsing; +- value validation; +- mapping; +- кэширование; +- повторную обрезку результата по `limit`. + +--- + +### 4.10. Protocols + +В файл: + +```text +src/market_data/acquisition/protocol.py +``` + +добавлены: + +```text +CandlesDocumentSource +CandlesDocumentHandler +CandlesFeedProtocol +``` + +Runtime-проверка протоколов выполнена успешно: + +```text +candles protocols: OK +``` + +--- + +### 4.11. Exceptions + +В файл: + +```text +src/market_data/acquisition/exceptions.py +``` + +добавлены: + +```text +CandleTransportError +CandleSchemaError +CandleParseError +CandleValueError +CandleMappingError +``` + +Registry-specific исключение не добавлялось, поскольку регистрация Candles Feed не входит в Build 044. + +--- + +## 5. Изменённые production-файлы + +```text +src/market_data/acquisition/exceptions.py +src/market_data/acquisition/protocol.py +src/market_data/acquisition/models/candle.py +src/market_data/acquisition/adapters/dzengi/models.py +src/market_data/acquisition/adapters/dzengi/rest.py +src/market_data/acquisition/adapters/dzengi/parser.py +src/market_data/acquisition/adapters/dzengi/mapper.py +src/market_data/acquisition/validation/schema.py +src/market_data/acquisition/validation/values.py +src/market_data/acquisition/handlers/candles_handler.py +src/market_data/acquisition/feeds/candles_feed.py +``` + +--- + +## 6. Добавленные unit-тесты + +```text +tests/unit/market_data/acquisition/models/test_candle.py +tests/unit/market_data/acquisition/adapters/dzengi/test_candle_rest.py +tests/unit/market_data/acquisition/validation/test_candle_schema.py +tests/unit/market_data/acquisition/adapters/dzengi/test_candle_parser.py +tests/unit/market_data/acquisition/validation/test_candle_values.py +tests/unit/market_data/acquisition/adapters/dzengi/test_candle_mapper.py +tests/unit/market_data/acquisition/handlers/test_candles_handler.py +tests/unit/market_data/acquisition/feeds/test_candles_feed.py +``` + +Покрыты: + +- immutable-модель Candle; +- REST source; +- поддерживаемые envelope-форматы; +- object- и array-parsing; +- aliases времени; +- проверки transport-типов; +- проверки значений; +- OHLC-инварианты; +- Decimal mapping; +- UTC datetime mapping; +- сортировка; +- handler pipeline; +- feed orchestration; +- propagation исключений. + +--- + +## 7. Результаты тестирования + +### 7.1. Специализированные тесты Build 044 + +```text +70 passed +``` + +### 7.2. Полный unit-test suite проекта + +```text +683 passed in 3.29s +``` + +### 7.3. Проверка форматирования diff + +```text +git diff --check +``` + +Результат: + +```text +пустой вывод +``` + +--- + +## 8. Архитектурные проверки + +### 8.1. Endpoint `/api/v1/klines` + +Команда: + +```bash +grep -RIn \ + --exclude-dir="__pycache__" \ + --exclude="*.pyc" \ + '"/api/v1/klines"' \ + src +``` + +Результат: + +```text +src/market_data/acquisition/adapters/dzengi/rest.py +src/integrations/exchange/service.py +``` + +Две точки являются ожидаемым переходным состоянием: + +- новая canonical acquisition-цепочка; +- действующий legacy-путь. + +--- + +### 8.2. Импорты canonical Candle + +Команда: + +```bash +grep -RIn \ + --exclude-dir="__pycache__" \ + --exclude="*.pyc" \ + "models.candle import Candle" \ + src tests +``` + +Canonical `Candle` используется только в новой acquisition-цепочке и её тестах. + +--- + +### 8.3. Обратная зависимость Market Data → Trading + +Команда: + +```bash +grep -RIn \ + --exclude-dir="__pycache__" \ + --exclude="*.pyc" \ + "from src.trading\|import src.trading" \ + src/market_data +``` + +Результат: + +```text +пусто +``` + +--- + +### 8.4. Зависимость Candle Feed от ExchangeService + +Команда: + +```bash +grep -RIn \ + --exclude-dir="__pycache__" \ + --exclude="*.pyc" \ + "ExchangeService" \ + src/market_data/acquisition/models/candle.py \ + src/market_data/acquisition/feeds/candles_feed.py \ + src/market_data/acquisition/handlers/candles_handler.py +``` + +Результат: + +```text +пусто +``` + +--- + +## 9. Сопутствующая очистка документации + +Вместе с Build 044 намеренно удалены устаревшие временные grep-файлы: + +```text +docs/migrations/greps.txt +docs/migrations/Вывод grep по дополнительным полям.txt +``` + +Эти файлы не являлись нормативной миграционной документацией и больше не использовались. + +--- + +## 10. Совместимость + +После Build 044: + +- рабочий бот продолжает использовать legacy `ExchangeService.get_klines()`; +- `Kline` и `KlineBatch` сохранены; +- Market Analysis не изменён; +- runtime не переключён; +- существующее поведение торгового бота сохранено; +- новая Candles Feed foundation работает параллельно legacy-потоку. + +--- + +## 11. Критерии завершения + +Build 044 считается завершённым, поскольку: + +- создана canonical модель `Candle`; +- реализован REST source `/api/v1/klines`; +- реализована schema validation; +- реализован parser object/list форматов; +- реализована value validation; +- реализован canonical mapper; +- реализован handler; +- реализован standalone Candles Feed; +- добавлены runtime-checkable protocols; +- добавлены специализированные исключения; +- добавлено полное unit-покрытие foundation-цепочки; +- targeted-тесты проходят; +- полный suite проходит; +- архитектурные grep соответствуют ожидаемому переходному состоянию; +- legacy runtime не изменён. + +--- + +# 12. Ориентировочный дальнейший план миграции + +Ниже приведён ориентировочный план. Номера и границы Build могут уточняться после обязательного аудита фактического кода перед каждым следующим Build. + +Главный принцип остаётся неизменным: + +```text +foundation + ↓ +service/registry integration + ↓ +compatibility facade + ↓ +consumer migration + ↓ +legacy removal + ↓ +architecture verification +``` + +--- + +## 12.1. Завершение OHLCV Feed + +### Build 045 — register canonical Candles Feed + +Цель: + +- добавить Candles Feed в `registry.py`; +- добавить candle-specific registry contract; +- добавить registry tests; +- не менять `ExchangeService`; +- не менять Market Analysis. + +Ожидаемый результат: + +```text +CandlesFeed + ↓ +Candles registry +``` + +--- + +### Build 046 — expose Candles Feed through Acquisition Service + +Цель: + +- добавить read-only метод загрузки свечей в `service.py`; +- сохранить точные параметры: + - symbol; + - interval; + - limit; + - price_type; +- добавить service tests; +- не переключать legacy runtime. + +Ожидаемый результат: + +```text +MarketDataAcquisitionService.load_candles() + ↓ +CandlesFeed +``` + +--- + +### Build 047 — switch ExchangeService klines facade + +Цель: + +- сохранить публичный контракт `ExchangeService.get_klines()`; +- внутри переключить получение данных на canonical Acquisition Service; +- временно преобразовывать `Candle` в legacy `Kline`; +- сохранить `KlineBatch`; +- добавить compatibility tests; +- удалить прямой REST-вызов `/api/v1/klines` из `ExchangeService`; +- удалить legacy parsing из `ExchangeService`. + +Ожидаемый результат: + +```text +ExchangeService.get_klines() + ↓ +MarketDataAcquisitionService.load_candles() + ↓ +Candle + ↓ +temporary compatibility mapping + ↓ +KlineBatch +``` + +--- + +### Build 048 — migrate Market Analysis to Candle + +Цель: + +- перевести `trading/market_analysis` с `Kline` на canonical `Candle`; +- сохранить расчётную семантику; +- локально адаптировать timestamp и numeric-типы; +- не изменять сами торговые алгоритмы; +- добавить/обновить тесты consumers. + +Ожидаемый результат: + +```text +Market Analysis + ↓ +Candle +``` + +--- + +### Build 049 — remove legacy Kline compatibility + +Цель: + +- удалить `Kline`; +- удалить `KlineBatch`, если он больше не нужен; +- удалить compatibility mapping; +- удалить legacy candle parsing; +- очистить импорты `src.integrations.exchange.models.Kline`. + +--- + +### Build 050 — finalize OHLCV Feed architecture verification + +Цель: + +- полный архитектурный аудит Candles Feed; +- контроль endpoint; +- контроль raw transport keys; +- контроль legacy imports; +- контроль consumer contracts; +- документация итогового состояния; +- полный suite. + +--- + +## 12.2. Trades Feed — Time & Sales + +После завершения OHLCV Feed выполнить отдельный аудит: + +```text +REST trades endpoints +WebSocket trade messages +journal trade events +execution trade records +market trade data +``` + +Важно не смешивать: + +```text +Market Trades Feed +``` + +с: + +```text +сделками самого торгового бота +execution events +journal events +``` + +Ориентировочная последовательность: + +### Build 051 — audit Trades Feed sources and consumers + +- определить фактические Dzengi endpoints/messages; +- отделить рыночные сделки от execution-событий; +- определить текущие consumers; +- зафиксировать минимальный scope. + +### Build 052 — establish canonical Trades Feed foundation + +- `Trade`; +- transport model; +- REST/WebSocket source; +- schema; +- parser; +- values; +- mapper; +- handler; +- feed; +- tests. + +### Build 053 — register and expose Trades Feed + +- registry; +- acquisition service; +- tests. + +### Build 054 — integrate first read-only consumer + +- подключить один фактический consumer; +- не менять торговую семантику. + +### Build 055 — remove legacy trade market-data path + +- удалить legacy parsing; +- удалить старые transport-модели; +- очистить imports. + +### Build 056 — finalize Trades Feed verification + +- полный suite; +- grep; +- документация. + +--- + +## 12.3. Order Book Feed + +Текущий `/api/v1/depth` используется для получения best bid / best ask и построения Quote. + +Поэтому перед миграцией Order Book Feed обязательно разделить: + +```text +Quote use case +``` + +и: + +```text +canonical Order Book use case +``` + +Нельзя удалять WebSocket depth-путь, пока Quotes Feed использует его как источник котировки. + +Ориентировочная последовательность: + +### Build 057 — audit Order Book and depth contracts + +- определить фактический формат Dzengi depth; +- определить уровни доступной глубины; +- определить sequence identifiers; +- определить snapshot/delta семантику; +- определить consumers; +- зафиксировать зависимость Quotes Feed. + +### Build 058 — establish Order Book model foundation + +- `OrderBook`; +- `OrderBookLevel`; +- snapshot model; +- transport model; +- schema; +- parser; +- values; +- mapper; +- tests. + +### Build 059 — establish Order Book snapshot feed + +- REST snapshot source; +- handler; +- feed; +- registry; +- service. + +### Build 060 — establish Order Book WebSocket updates + +- delta/update parsing; +- sequence validation; +- snapshot reconciliation; +- tests. + +### Build 061 — add Order Book runtime storage + +Только если подтверждено фактическими consumers: + +- OrderBookStore; +- atomic update; +- source/runtime keys; +- freshness policy. + +### Build 062 — integrate execution-quality consumers + +- spread/depth/slippage consumers; +- сохранить fallback на Quote; +- не менять торговые решения одним Build. + +### Build 063 — separate Quotes Feed from legacy depth runtime + +- оставить Quotes Feed на canonical WebSocket adapter; +- удалить старый depth parsing из legacy runtime. + +### Build 064 — finalize Order Book verification + +--- + +## 12.4. Derivatives Market Feed + +Перед foundation Build требуется аудит фактических данных: + +```text +funding rate +overnight fee +mark price +open interest +contract metadata +leverage limits +liquidation-related fields +``` + +Нужно отделить: + +```text +Instrument Reference Data +Trading Conditions +Derivatives Market Data +Account-specific data +``` + +Ориентировочная последовательность: + +### Build 065 — audit derivatives data contracts + +### Build 066 — establish canonical Derivatives Feed foundation + +### Build 067 — register and expose Derivatives Feed + +### Build 068 — migrate funding / overnight consumers + +### Build 069 — migrate mark-price / open-interest consumers + +### Build 070 — remove legacy derivatives parsing + +### Build 071 — finalize Derivatives Feed verification + +--- + +## 12.5. Market Index Feed + +Перед началом требуется подтвердить, какие индексы реально предоставляет Dzengi: + +```text +index price +reference price +composite index +underlying index +``` + +Ориентировочная последовательность: + +### Build 072 — audit index data sources + +### Build 073 — establish Market Index Feed foundation + +### Build 074 — register and expose Index Feed + +### Build 075 — integrate confirmed consumers + +### Build 076 — remove legacy index path + +### Build 077 — finalize Index Feed verification + +--- + +## 12.6. Exchange Time Feed + +Текущий endpoint: + +```text +/api/v1/time +``` + +находится в: + +```text +ExchangeService.get_exchange_server_time_ms() +``` + +и используется логикой time synchronization. + +Ориентировочная последовательность: + +### Build 078 — establish Exchange Time Feed foundation + +- canonical time model; +- REST source; +- schema; +- parser; +- values; +- mapper; +- handler; +- feed; +- tests. + +### Build 079 — register and expose Time Feed + +### Build 080 — switch ExchangeService time facade + +- сохранить текущий публичный контракт; +- переключить внутренний источник; +- сохранить time-sync поведение. + +### Build 081 — remove legacy time REST path + +### Build 082 — finalize Exchange Time Feed verification + +--- + +## 12.7. Exchange Status Feed + +Перед началом требуется разделить: + +```text +exchange availability +market availability +instrument status +runtime freshness +authentication status +account availability +``` + +Не все перечисленные состояния относятся к Market Data Acquisition. + +Ориентировочная последовательность: + +### Build 083 — audit status semantics + +### Build 084 — establish Exchange Status Feed foundation + +### Build 085 — register and expose Status Feed + +### Build 086 — migrate public exchange-status consumers + +### Build 087 — remove legacy public-status acquisition + +### Build 088 — finalize Exchange Status Feed verification + +--- + +## 12.8. Runtime подсистемы Acquisition + +Файлы: + +```text +runtime/heartbeat.py +runtime/reconnect.py +runtime/scheduler.py +runtime/supervisor.py +``` + +не должны наполняться заранее. + +Они должны мигрироваться только после появления реальных потоков, которым необходим общий lifecycle. + +Ориентировочная последовательность после стабилизации Quotes, Trades и Order Book: + +### Build 089 — audit acquisition runtime ownership + +- определить существующие runner/stream responsibilities; +- определить lifecycle ownership; +- определить реальные retry/reconnect policies. + +### Build 090 — establish common reconnect policy + +### Build 091 — establish heartbeat contract + +### Build 092 — establish acquisition scheduler + +### Build 093 — establish acquisition supervisor + +### Build 094 — migrate MarketDataRunner responsibilities + +### Build 095 — remove legacy market runtime orchestration + +### Build 096 — finalize Acquisition runtime verification + +--- + +## 12.9. Финальная консолидация Market Data Acquisition + +После миграции всех фактически используемых Feed: + +### Build 097 — remove unused acquisition placeholders + +Только после отдельного подтверждения: + +- удалить неиспользуемые placeholders; +- не удалять утверждённые модули, если их реализация отложена; +- зафиксировать статус каждого Feed. + +### Build 098 — finalize Acquisition service surface + +- единый публичный read-only API; +- отсутствие transport details; +- отсутствие consumer-specific логики; +- стабильные protocols. + +### Build 099 — finalize Dzengi adapter isolation + +- endpoint strings только в adapter; +- raw keys только в adapter/validation; +- отсутствие Dzengi transport-моделей вне adapter. + +### Build 100 — complete Market Data Acquisition migration + +- итоговый полный suite; +- итоговый архитектурный grep; +- удаление подтверждённого legacy Market Data кода; +- итоговая документация; +- release checkpoint. + +--- + +## 13. Правила применения дальнейшего плана + +Этот план является ориентировочным и не разрешает автоматическое выполнение всех перечисленных Build. + +Перед каждым Build обязательно: + +1. выполнить аудит фактического текущего кода; +2. определить реальные sources и consumers; +3. проверить, используется ли placeholder; +4. выбрать минимальный безопасный scope; +5. подготовить пошаговый план; +6. согласовать план; +7. только после согласования изменять код; +8. выполнить targeted tests; +9. выполнить полный unit-test suite; +10. выполнить архитектурные grep; +11. оформить `docs/migrations/build_XXX.md`; +12. создать отдельный git commit. + +Запрещено: + +- объединять несколько Feed в один Build; +- создавать store без подтверждённой runtime-потребности; +- добавлять поля моделей «на будущее»; +- удалять legacy до переключения consumers; +- менять торговую семантику внутри Market Data migration; +- пересматривать утверждённую структуру каталогов без отдельного обсуждения. + +--- + +## 14. Git commit + +Рекомендуемое сообщение: + +```bash +git commit -m "build 044: establish canonical candles feed foundation" +``` diff --git a/docs/migrations/greps.txt b/docs/migrations/greps.txt deleted file mode 100644 index 0735675..0000000 --- a/docs/migrations/greps.txt +++ /dev/null @@ -1,246 +0,0 @@ -((.venv) ) segeba@mbpbsg dzentra_bot % >.... - elif isinstance(data.get("payload"), dict): - payload = data["payload"] - if isinstance(payload.get("symbols"), list): - symbols = payload["symbols"] - -print("Количество symbols:", len(symbols) if symbols is not None else None) - -if symbols: - dict_items = [item for item in symbols if isinstance(item, dict)] - - all_keys = sorted( - { - key - for item in dict_items - for key in item - } - ) - - print("Все ключи symbol items:") - for key in all_keys: - print(f" {key}") - - print("\nПервый symbol item:") - print(json.dumps(dict_items[0], ensure_ascii=False, indent=2)) -PY -Корневой тип: dict -Корневые ключи: ['exchangeFilters', 'rateLimits', 'serverTime', 'symbols', 'timezone'] -Количество symbols: 51 -Все ключи symbol items: - assetType - baseAsset - baseAssetPrecision - country - filters - industry - longRate - marketModes - marketType - maxSLGap - maxTPGap - minSLGap - minTPGap - name - orderTypes - quoteAsset - quoteAssetId - quotePrecision - sector - shortRate - status - swapChargeInterval - symbol - tickSize - tickValue - tradingFee - tradingHours - -Первый symbol item: -{ - "assetType": "CRYPTOCURRENCY", - "baseAsset": "ETH", - "baseAssetPrecision": 3, - "country": "", - "filters": [ - { - "filterType": "LOT_SIZE", - "maxQty": "1000", - "minQty": "0.001", - "stepSize": "0.001" - }, - { - "filterType": "MIN_NOTIONAL", - "minNotional": "2" - } - ], - "industry": "", - "longRate": -0.01, - "marketModes": [ - "REGULAR" - ], - "marketType": "LEVERAGE", - "maxSLGap": 50.0, - "maxTPGap": 50.0, - "minSLGap": 0, - "minTPGap": 0, - "name": "ETH/EUR", - "orderTypes": [ - "LIMIT", - "MARKET", - "STOP" - ], - "quoteAsset": "EUR", - "quoteAssetId": "EUR_LEVERAGE", - "quotePrecision": 3, - "sector": "", - "shortRate": 0.01, - "status": "TRADING", - "swapChargeInterval": 480, - "symbol": "ETH/EUR_LEVERAGE", - "tickSize": 0.01, - "tickValue": 18.3415, - "tradingFee": 0.06, - "tradingHours": "UTC; Mon - 21:00, 21:05 -; Tue - 21:00, 21:05 -; Wed - 21:00, 21:05 -; Thu - 21:00, 21:05 -; Fri - 21:00, 22:01 -; Sat - 05:00, 07:00 - 21:00, 21:05 -; Sun - 21:00, 21:05 -" -} - - -((.venv) ) segeba@mbpbsg dzentra_bot % >.... -filter_keys: dict[str, set[str]] = {} - -for item in symbols: - if not isinstance(item, dict): - continue - - filters = item.get("filters") - if not isinstance(filters, list): - continue - - for entry in filters: - if not isinstance(entry, dict): - continue - - filter_type = str(entry.get("filterType") or "") - filter_types[filter_type] += 1 - filter_keys.setdefault(filter_type, set()).update( - str(key) for key in entry - ) - -print("Типы filters:") -for filter_type, count in sorted(filter_types.items()): - print(f"{filter_type}: {count}") - print(" keys:", sorted(filter_keys[filter_type])) -PY -Типы filters: -LOT_SIZE: 51 - keys: ['filterType', 'maxQty', 'minQty', 'stepSize'] -MIN_NOTIONAL: 39 - keys: ['filterType', 'minNotional'] - - -python - <<'PY' -import json -from collections import Counter -from pathlib import Path - -path = Path( - "app/tools/dzengi_probe/runtime_samples/rest/exchangeInfo/all.json" -) - -data = json.loads(path.read_text(encoding="utf-8")) - -if isinstance(data, dict) and isinstance(data.get("symbols"), list): - symbols = data["symbols"] -elif ( - isinstance(data, dict) - and isinstance(data.get("payload"), dict) - and isinstance(data["payload"].get("symbols"), list) -): - symbols = data["payload"]["symbols"] -else: - raise SystemExit("symbols не найдены") - -fields = [ - "symbol", - "name", - "status", - "baseAsset", - "quoteAsset", - "marketModes", - "marketType", - "tickSize", - "stepSize", - "minQty", - "minNotional", - "filters", -] - -for field in fields: - present = 0 - non_empty = 0 - types = Counter() - - for item in symbols: - if not isinstance(item, dict): - continue - - if field in item: - present += 1 - value = item[field] - types[type(value).__name__] += 1 - - if value not in (None, "", [], {}): - non_empty += 1 - - print( - f"{field}: present={present}, " - f"non_empty={non_empty}, " - f"types={dict(types)}" - ) -PY -symbol: present=51, non_empty=51, types={'str': 51} -name: present=51, non_empty=51, types={'str': 51} -status: present=51, non_empty=51, types={'str': 51} -baseAsset: present=51, non_empty=51, types={'str': 51} -quoteAsset: present=51, non_empty=51, types={'str': 51} -marketModes: present=51, non_empty=51, types={'list': 51} -marketType: present=51, non_empty=51, types={'str': 51} -tickSize: present=51, non_empty=51, types={'float': 48, 'int': 3} -stepSize: present=0, non_empty=0, types={} -minQty: present=0, non_empty=0, types={} -minNotional: present=0, non_empty=0, types={} -filters: present=51, non_empty=51, types={'list': 51} -((.venv) ) segeba@mbpbsg dzentra_bot % ;2B - - -((.venv) ) segeba@mbpbsg dzentra_bot % ;2Bgrep -RIn \ - --exclude-dir="__pycache__" \ - --exclude="*.pyc" \ - -E "from src\.telegram\.handlers\.market import|import src\.telegram\.handlers\.market|include_router\(.*market|market\.router|handlers\.market" \ - app/src app/tests tests 2>/dev/null - -((.venv) ) segeba@mbpbsg dzentra_bot % grep -RIn \ - --exclude-dir="__pycache__" \ - --exclude="*.pyc" \ - -E "include_router|include_routers" \ - app/src \ - | grep -Ei "market|router" -app/src/telegram/routers.py:16: dispatcher.include_router(start_router) -app/src/telegram/routers.py:17: dispatcher.include_router(home_router) -app/src/telegram/routers.py:18: dispatcher.include_router(portfolio_router) -app/src/telegram/routers.py:19: dispatcher.include_router(auto_router) -app/src/telegram/routers.py:20: dispatcher.include_router(journal_router) -app/src/telegram/routers.py:21: dispatcher.include_router(debug_auto_router) -app/src/telegram/routers.py:22: dispatcher.include_router(debug_router) -app/src/telegram/routers.py:23: dispatcher.include_router(system_router) -app/src/telegram/handlers/auto/__init__.py:8:router.include_router(main_router) -app/src/telegram/handlers/auto/__init__.py:9:router.include_router(risk_router) -((.venv) ) segeba@mbpbsg dzentra_bot % - -((.venv) ) segeba@mbpbsg dzentra_bot % grep -RIn \ - --exclude-dir="__pycache__" \ - --exclude="*.pyc" \ - -E "from src\.telegram\.ui\.currency_ui import|import src\.telegram\.ui\.currency_ui" \ - app/src app/tests tests 2>/dev/null -app/src/telegram/handlers/market.py:28:from src.telegram.ui.currency_ui import format_usd_amount -app/src/telegram/handlers/portfolio.py:26:from src.telegram.ui.currency_ui import ( \ No newline at end of file diff --git a/docs/migrations/Вывод grep по дополнительным полям.txt b/docs/migrations/Вывод grep по дополнительным полям.txt deleted file mode 100644 index cc9d6b8..0000000 --- a/docs/migrations/Вывод grep по дополнительным полям.txt +++ /dev/null @@ -1,70 +0,0 @@ -((.venv) ) segeba@mbpbsg dzentra_bot % grep -RIn \ - --exclude-dir="__pycache__" \ - --exclude="*.pyc" \ - -E "pricePrecision|quantityPrecision|baseAssetPrecision|quoteAssetPrecision|maxQty|maxNotional|maxPrice|minPrice|contractSize|lotSize|tradingMode|tradeMode|availableForTrading|isTradingAllowed|tradingAllowed|isTradable|tradable|marketOpen|isOpen|enabled" \ - app/src app/tests tests docs 2>/dev/null -app/src/core/config.py:34: exchange_enabled: bool -app/src/core/config.py:52: debug_enabled: bool -app/src/core/config.py:53: journal_debug_enabled: bool -app/src/core/config.py:94: debug_enabled=_parse_bool(os.getenv("DEBUG_ENABLED", "false")), -app/src/core/config.py:95: journal_debug_enabled=_parse_bool( -app/src/core/config.py:100: exchange_enabled=_parse_bool(os.getenv("EXCHANGE_ENABLED", "false")), -app/src/integrations/exchange/service.py:79: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:145: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:473: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:651: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:687: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:788: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:820: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:879: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:954: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:1017: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:1061: if not self.settings.exchange_enabled: -app/src/integrations/exchange/service.py:1185: "isTradingAllowed", -app/src/integrations/exchange/service.py:1186: "tradingAllowed", -app/src/integrations/exchange/service.py:1187: "availableForTrading", -app/src/integrations/exchange/service.py:1188: "isTradable", -app/src/integrations/exchange/service.py:1189: "tradable", -app/src/integrations/exchange/service.py:1191: "marketOpen", -app/src/integrations/exchange/service.py:1192: "isOpen", -app/src/integrations/exchange/service.py:1193: "enabled", -app/src/integrations/exchange/service.py:1208: for key in ("tradingMode", "tradeMode", "mode", "state"): -app/src/integrations/exchange/service.py:1279: if not self.settings.exchange_enabled: -app/src/integrations/exchange/market_stream.py:134: if not settings.exchange_enabled: -app/src/integrations/exchange/status.py:170: reason="market_not_tradable", -app/src/telegram/handlers/system.py:758:def _journal_debug_enabled() -> bool: -app/src/telegram/handlers/system.py:759: return bool(load_settings().journal_debug_enabled) -app/src/telegram/handlers/system.py:786: if _journal_debug_enabled(): -app/src/telegram/handlers/system.py:818: if _journal_debug_enabled() -app/src/telegram/handlers/system.py:839: enabled = _journal_debug_enabled() -app/src/telegram/handlers/system.py:840: new_value = "false" if enabled else "true" -app/src/telegram/handlers/system.py:849: if enabled -app/src/telegram/handlers/system.py:855: "journal_debug_enabled": not enabled, -app/src/telegram/handlers/system.py:864: "Debug логирование выключено" if enabled else "Debug логирование включено" -app/src/telegram/handlers/auto/ui.py:1104: enabled: list[tuple[str, float]] = [] -app/src/telegram/handlers/auto/ui.py:1107: enabled.append(("SL", sl_value)) -app/src/telegram/handlers/auto/ui.py:1110: enabled.append(("TP", tp_value)) -app/src/telegram/handlers/auto/ui.py:1113: enabled.append(("ML", ml_value)) -app/src/telegram/handlers/auto/ui.py:1115: if len(enabled) == 1: -app/src/telegram/handlers/auto/ui.py:1116: key, value = enabled[0] -app/src/telegram/handlers/debug.py:23:def _debug_enabled() -> bool: -app/src/telegram/handlers/debug.py:24: return bool(load_settings().debug_enabled) -app/src/telegram/handlers/debug.py:62: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:71: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:222: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:318: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:338: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:376: if not _debug_enabled(): -app/src/telegram/handlers/debug.py:397: if not _debug_enabled(): -app/src/trading/journal/service.py:128: if not load_settings().journal_debug_enabled: -app/src/trading/journal/service.py:148: if not load_settings().journal_debug_enabled: -app/src/trading/market_intelligence/common/models.py:47: enabled_by_default: bool = True -docs/stages/stage-03_1-integration_mock.md:25:- exchange_enabled -docs/stages/stage-04_1-storage.md:78:- exchange_enabled -docs/market_intelligence/information/dzengi_market_data_inventory.md:731:| `baseAssetPrecision` | integer | Точность базового актива. | -docs/market_intelligence/information/dzengi_market_data_inventory.md:753:| `maxQty` | string | Максимальное количество. | -docs/market_intelligence/information/dzengi_openapi.json:1:{"swagger":"2.0","info":{"title":"Api Documentation","termsOfService":"https://dzengi.com/agreement"},"host":"https://api-adapter.dzengi.com/ ]\n[ Base demo URL: https://demo-api-adapter.dzengi.com","basePath":"/","tags":[{"name":"rest-api","description":"Rest API"},{"name":"websocket-api","description":"WebSocket API"}],"paths":{"/api/v1/account":{"get":{"tags":["rest-api"],"summary":"accountInfo","description":"Get current account information","operationId":"accountUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"showZeroBalance","in":"query","description":"showZeroBalance","required":false,"type":"boolean"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"makerCommission\":0.20,\n \"takerCommission\":0.20,\n \"buyerCommission\":0.20,\n \"sellerCommission\":0.20,\n \"canTrade\":true,\n \"canWithdraw\":true,\n \"canDeposit\":true,\n \"updateTime\":1586935521,\n \"balances\":[\n {\n \"accountId\":\"2376104765040206\",\n \"collateralCurrency\":true,\n \"asset\":\"BYN\",\n \"free\":0.0,\n \"locked\":0.0,\n \"default\":false\n },\n {\n \"accountId\":\"2376109060084932\",\n \"collateralCurrency\":true,\n \"asset\":\"USD\",\n \"free\":515.59092523,\n \"locked\":0.0,\n \"default\":true\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/AccountResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/aggTrades":{"get":{"tags":["rest-api"],"summary":"tradesAggregated","description":"Get compressed, aggregate trades. Trades that fill at the same time, from the same order, with the same price will have the quantity aggregated.","operationId":"aggTradesUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"//a\":\"Aggregate tradeId\",\n \"a\":1582595833,\n \"//p\":\"Price\",\n \"p\":\"8980.4\",\n \"//q\":\"Quantity (should be ignored)\",\n \"q\":\"0.0\",\n \"//T\":\"Timestamp\",\n \"T\":1580204505793,\n \"//m\":\"Was the buyer the maker\",\n \"m\":false\n }\n ]\n\n}","schema":{"type":"array","items":{"$ref":"#/definitions/AggTrades"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/closeTradingPosition":{"post":{"tags":["rest-api"],"summary":"tradingPositionClose","description":"Close an active leverage trade.","operationId":"closeTradingPositionUsingPOST_1","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"positionId","in":"query","description":"positionId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"request\":[\n {\n \"id\":242057,\n \"accountId\":2376109060084932,\n \"instrumentId\":\"45076691096786116\",\n \"rqType\":\"ORDER_NEW\",\n \"state\":\"PROCESSED\",\n \"createdTimestamp\":1587031306969\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionCloseAllResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/currencies":{"get":{"tags":["rest-api"],"summary":"ListOfCurrencies","description":"Get all system currencies","operationId":"getCurrenciesUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"name\": \"US Dollar\",\n \"displaySymbol\": \"USD.cx\",\n \"precision\": 2,\n \"type\": \"FIAT\",\n \"minWithdrawal\": 100,\n \"maxWithdrawal\": 100000000,\n \"commissionMin\": 0.02,\n \"commissionPercent\": 1.5,\n \"minDeposit\": 100\n }\n ]\n\n}","schema":{"$ref":"#/definitions/CurrencyResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/depositAddress":{"get":{"tags":["rest-api"],"summary":"stringOfAddress","description":"Get deposit address by coin","operationId":"getDepositAddressUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"coin","in":"query","description":"coin","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":{\n \"address\": \"0xa12b8b8157da0e44d3e56cda7ade1d587141c27f\"\n }\n\n}","schema":{"$ref":"#/definitions/BlockchainAddressGetResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/deposits":{"get":{"tags":["rest-api"],"summary":"ListOfDeposits","description":"Get deposits for user","operationId":"getDepositsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n\t\t \"id\": 77170270,\n \"balance\": 100000.0,\n \t\"amount\": 100000.0,\n \"currency\": \"BYN\",\n \"type\": \"deposit\",\n \t\"timestamp\": 1647000860502,\n \t\"commission\": 3500.0,\n \t\"paymentMethod\": \"VISA\",\n \t\"status\": \"PROCESSED\"\n \t }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/depth":{"get":{"tags":["rest-api"],"summary":"orderBook","description":"Order book","operationId":"depthUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"lastUpdateId\":1027024,\n \"asks\":[\n [\n \"//Price\",\n \"4.00000200\",\n \"//Qty\",\n \"12.00000000\"\n ]\n ],\n \"bids\":[\n [\n \"// Price\",\n \"4.00000000\",\n \"// Quantity\",\n \"431.00000000\"\n ]\n ]\n }\n\n}","schema":{"$ref":"#/definitions/DepthResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/exchangeInfo":{"get":{"tags":["rest-api"],"summary":"exchangeInfo","description":"Current exchange trading rules and symbol information. When using signature parameter returns the market pairs which are traded under the account's jurisdiction. Also note that when sending an authorized request and using the X-MBX-API-KEY header timestamp and signature parameters are mandatory.","operationId":"exchangeInfoUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":false,"type":"string"},{"name":"signature","in":"query","description":"signature","required":false,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"timezone\":\"UTC\",\n \"serverTime\":1628193845310,\n \"rateLimits\":[\n ],\n \"exchangeFilters\":[\n ],\n \"symbols\":[\n {\n \"symbol\":\"EVK\",\n \"name\":\"Evonik\",\n \"status\":\"BREAK\",\n \"baseAsset\":\"EVK\",\n \"baseAssetPrecision\":3,\n \"quoteAsset\":\"EUR\",\n \"quoteAssetId\":\"EUR\",\n \"quotePrecision\":3,\n \"orderTypes\":[\n \"LIMIT\",\n \"MARKET\"\n ],\n \"filters\":[\n {\n \"filterType\":\"LOT_SIZE\",\n \"minQty\":\"1\",\n \"maxQty\":\"27000\",\n \"stepSize\":\"1\"\n },\n {\n \"filterType\":\"MIN_NOTIONAL\",\n \"minNotional\":\"29\"\n }\n ],\n \"marketModes\":[\n \"REGULAR\"\n ],\n \"marketType\":\"SPOT\",\n \"country\":\"DE\",\n \"sector\":\"Basic Materials\",\n \"industry\":\"Diversified Chemicals\",\n \"tradingHours\":\"UTC; Mon 07:02 - 15:30; Tue 07:02 - 15:30; Wed 07:02 - 15:30; Thu 07:02 - 15:30; Fri 07:02 - 15:30\",\n \"tickSize\":0.005,\n \"tickValue\":0.14475,\n \"exchangeFee\":0.05\n }\n ]\n }\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/fetchOrder":{"get":{"tags":["rest-api"],"summary":"Order","description":"Fetch order by symbol and order id","operationId":"getOrderUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"accountId\":19042209961170116,\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\",\n \"quantity\":1.0,\n \"price\":95.0,\n \"timestamp\":1651072423560,\n \"status\":\"CREATED\",\n \"type\":\"LIMIT\",\n \"expireTime\":2208988800000,\n \"timeInForceType\":\"GTC\",\n \"side\":\"BUY\",\n \"guaranteedStopLoss\":true,\n \"margin\":0.05,\n \"takeProfit\":25.0,\n \"takeProfitType\":\"OFFSET\",\n \"stopLoss\":-15.0,\n \"stopLossType\":\"OFFSET\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/GetOrderDtoResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/fundingLimits":{"get":{"tags":["rest-api"],"summary":"ListOfFundingLimits","description":"Get all system Funding limits","operationId":"getFundingLimitsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"TOKENISED ASSETS\",\n \t\"minWithdrawal\": \"100 USD equivalent\"\n },\n {\n \t\"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"BAT\",\n \t\"minWithdrawal\": \"52\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/FundingLimitsDtoResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/klines":{"get":{"tags":["rest-api"],"summary":"klines","description":"Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.","operationId":"klinesUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"interval","in":"query","description":"interval","required":true,"type":"string"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"priceType","in":"query","description":"priceType","required":false,"type":"string","default":"bid"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"},{"name":"type","in":"query","description":"type","required":false,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n [\n \"// Open time\",\n 1499040000000,\n \" // Open\",\n \"0.01634790\",\n \" // High\",\n \"0.80000000\",\n \" // Low\",\n \"0.01575800\",\n \" // Close\",\n \"0.01577100\",\n \" // Volume.\",\n \"148976.11427815\"\n ]\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/ledger":{"get":{"tags":["rest-api"],"summary":"ListOfLedgers","description":"Get ledger by limit","operationId":"getLedgerUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 77753629,\n\t \"balance\": 20423.49571214,\n\t \"amount\": -0.002601,\n\t \"currency\": \"USD\",\n\t \"type\": \"exchange_commission\",\n\t \"timestamp\": 1647609091989,\n\t \"commission\": 0.002601,\n \"status\": \"PROCESSED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/leverageSettings":{"get":{"tags":["rest-api"],"summary":"leverageSettings","description":"General leverage settings can be seen.","operationId":"leverageSettingsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"values\":[\n 2,\n 5,\n 10,\n 20,\n 50,\n 100,\n \" // the possible leverage sizes;\"\n ],\n \"//value\":\"depicts a default leverage size which will be set in case you don’t mention the ‘leverage’ parameter in the corresponding requests.\",\n \"value\":20\n }\n\n}","schema":{"$ref":"#/definitions/LeverageSettingsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/myTrades":{"get":{"tags":["rest-api"],"summary":"listOfTrades","description":"Get trades for a specific account and symbol.","operationId":"myTradesUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0004-0000-00000006f0a2\",\n \"price\":\"9593.2\",\n \"qty\":\"0.1\",\n \"commission\":\"0.20\",\n \"commissionAsset\":\"USD\",\n \"time\":1582192427437,\n \"maker\":false,\n \"buyer\":true,\n \"isBuyer\":true,\n \"isMaker\":false\n }\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/openOrders":{"get":{"tags":["rest-api"],"summary":"listOfOpenOrders","description":"Get all open orders within exchange and leverage trading modes on a symbol. Careful when accessing this with no symbol.","operationId":"openOrdersUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"NEW\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\",\n \"time\":1586958863147,\n \"updateTime\":1586958863147,\n \"leverage\":false,\n \"working\":true\n }\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/order":{"post":{"tags":["rest-api"],"summary":"createOrder","description":"To create a market or limit order in the exchange trading mode, and market, limit or stop order in the leverage trading mode.\nPlease note that to open an order within the ‘leverage’ trading mode symbolLeverage should be used and additional accountId parameter should be mentioned in the request.","operationId":"orderUsingPOST_1","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"newOrderRespType","in":"query","description":"newOrderRespType in the exchange trading mode for MARKET order RESULT or FULL can be mentioned. MARKET order type default to FULL. LIMIT order type can be only RESULT. For the leverage trading mode only RESULT is available.","required":false,"type":"string","allowEmptyValue":false},{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"type","in":"query","description":"Type MARKET or LIMIT should be mentioned to open an order in the exchange trading mode. Type MARKET, LIMIT or STOP should be mentioned to open an order in the leverage trading mode.","required":true,"type":"string","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"accountId","in":"query","description":"accountId","required":false,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean"},{"name":"leverage","in":"query","description":"leverage","required":false,"type":"integer","format":"int32"},{"name":"price","in":"query","description":"price","required":false,"type":"number"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"quantity","in":"query","description":"quantity","required":true,"type":"number"},{"name":"side","in":"query","description":"side","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0000-0000-0000000c028d\",\n \"transactTime\":1589879478020,\n \"price\":\"9797.05500000\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.01\",\n \"status\":\"FILLED\",\n \"timeInForce\":\"FOK\",\n \"type\":\"MARKET\",\n \"side\":\"BUY\"\n }\n\n}","schema":{"$ref":"#/definitions/NewOrderResponseRESULT"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}},"put":{"tags":["rest-api"],"summary":"Edit exchange order","description":"Edit exchange order expirationTime or price","operationId":"putEditOrderUsingPUT_1","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"price","in":"query","description":"price","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/EditExchangeOrderResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}},"delete":{"tags":["rest-api"],"summary":"cancelOrder","description":"Cancel an active order within exchange and leverage trading modes.","operationId":"cancelOrderUsingDELETE_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"CANCELED\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\"\n }\n\n}","schema":{"$ref":"#/definitions/CancelOrderResponse"}},"204":{"description":"No Content"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/api/v1/ticker/24hr":{"get":{"tags":["rest-api"],"summary":"priceChange","description":"24 hour rolling window price change statistics. Careful when accessing this with no symbol.","operationId":"ticker_24hrUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"LTC/USD\",\n \"priceChange\":\"0.88\",\n \"priceChangePercent\":\"1.49\",\n \"weightedAvgPrice\":\"59.29\",\n \"prevClosePrice\":\"58.37\",\n \"lastPrice\":\"59.25\",\n \"lastQty\":\"220.0\",\n \"bidPrice\":\"59.25\",\n \"askPrice\":\"59.32\",\n \"openPrice\":\"58.37\",\n \"highPrice\":\"61.39\",\n \"lowPrice\":\"58.37\",\n \"volume\":\"22632\",\n \"quoteVolume\":\"440.0\",\n \"openTime\":1580169600000,\n \"closeTime\":1580205307222\n }\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/time":{"get":{"tags":["rest-api"],"summary":"serverTime","description":"Test connectivity to the API and get the current server time.","operationId":"timeUsingGET_1","produces":["*/*"],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"3\",\n \"payload\":{\n \"serverTime\":1628195607917\n }\n\n}","schema":{"$ref":"#/definitions/ServerTime"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/tradingFees":{"get":{"tags":["rest-api"],"summary":"ListOfFees","description":"Get all system fees","operationId":"getTradingFeesUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"UNI/USD\",\n \"name\": \"UNI/USD\",\n \"fee\": 0.1\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TradingFeesResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/tradingLimits":{"get":{"tags":["rest-api"],"summary":"ListOfLimits","description":"Get all system limits","operationId":"getTradingLimitsUsingGET_1","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"EVK\",\n \t\"name\": \"Evonik\",\n \t\"minVolume\": 1.0,\n \t\"maxVolume\": 27000.0,\n \t\t\"minStep\": 1.0,\n \t\"tickSize\": 0.005\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TradingLimitsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/tradingPositions":{"get":{"tags":["rest-api"],"summary":"listOfLeverageTrades","description":"Get all open trades within the account.","operationId":"tradingPositionsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"positions\":[\n {\n \"accountId\":2376109060084932,\n \"id\":\"00a02503-0079-54c4-0000-00004067006b\",\n \"instrumentId\":\"45076691096786116\",\n \"orderId\":\"00a02503-0079-54c4-0000-00004067006a\",\n \"openQuantity\":0.01,\n \"openPrice\":6734.4,\n \"closeQuantity\":0.0,\n \"closePrice\":0,\n \"takeProfit\":7999.15,\n \"stopLoss\":5999.15,\n \"guaranteedStopLoss\":false,\n \"rpl\":0,\n \"rplConverted\":0,\n \"swap\":-0.00335894,\n \"swapConverted\":-0.00335894,\n \"fee\":-0.050508,\n \"dividend\":0,\n \"margin\":0.5,\n \"state\":\"ACTIVE\",\n \"currency\":\"USD\",\n \"createdTimestamp\":1586953061455,\n \"openTimestamp\":1586953061243,\n \"cost\":33.73775,\n \"symbol\":\"BTC/USD_LEVERAGE\"\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionListResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/tradingPositionsHistory":{"get":{"tags":["rest-api"],"summary":"listOfHistoricalPositions","description":"Get all closes postions within the account.","operationId":"tradingPositionsHistoryUsingGET_1","produces":["*/*"],"parameters":[{"name":"from","in":"query","description":"Timestamp in milliseconds, Filtration based on execTimestamp parameter","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"to","in":"query","description":"Timestamp in milliseconds, Filtration based on execTimestamp parameter","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"history\":[\n {\n \"accountId\":19039018800469188,\n \"accountCurrency\":\"USD\",\n \"positionId\":\"00a18509-0079-54c4-0000-00004062007b\",\n \"currency\":\"USD\",\n \"executionType\":\"IOC\",\n \"quantity\":-0.1,\n \"price\":44.95,\n \"source\":\"USER\",\n \"status\":\"CLOSED\",\n \"rpl\":-0.002,\n \"rplConverted\":-0.002,\n \"fee\":0,\n \"createdTimestamp\":1606999328398,\n \"execTimestamp\":1606999315265,\n \"symbol\":\"Oil - Crude.\"\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionHistoryResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/transactions":{"get":{"tags":["rest-api"],"summary":"ListOfTransactions","description":"Get transactions by limit and sinceTime","operationId":"getTransactionsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/updateTradingOrder":{"post":{"tags":["rest-api"],"summary":"leverageOrdersEdit","description":"Edit current leverage orders by changing take profit and stop loss levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"updateTradingOrderUsingPOST_1","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean","default":false},{"name":"newPrice","in":"query","description":"newPrice","required":false,"type":"number"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean","default":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":241986,\n \"state\":\"PROCESSED\"\n }\n\n}","schema":{"$ref":"#/definitions/TradingOrderUpdateResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/updateTradingPosition":{"post":{"tags":["rest-api"],"summary":"leverageTradeEdit","description":"Edit current leverage trade by changing stop loss and take profit levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"updateTradingPositionUsingPOST_1","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean","default":false},{"name":"positionId","in":"query","description":"positionId","required":true,"type":"string","format":"uuid"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean","default":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":242040,\n \"state\":\"PROCESSED\"\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionUpdateResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v1/withdrawals":{"get":{"tags":["rest-api"],"summary":"ListOfWithdrawals","description":"Get withdrawals for user","operationId":"getWithdrawalsUsingGET_1","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/account":{"get":{"tags":["rest-api"],"summary":"accountInfo","description":"Get current account information","operationId":"accountUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"showZeroBalance","in":"query","description":"showZeroBalance","required":false,"type":"boolean"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"makerCommission\":0.20,\n \"takerCommission\":0.20,\n \"buyerCommission\":0.20,\n \"sellerCommission\":0.20,\n \"canTrade\":true,\n \"canWithdraw\":true,\n \"canDeposit\":true,\n \"updateTime\":1586935521,\n \"balances\":[\n {\n \"accountId\":\"2376104765040206\",\n \"collateralCurrency\":true,\n \"asset\":\"BYN\",\n \"free\":0.0,\n \"locked\":0.0,\n \"default\":false\n },\n {\n \"accountId\":\"2376109060084932\",\n \"collateralCurrency\":true,\n \"asset\":\"USD\",\n \"free\":515.59092523,\n \"locked\":0.0,\n \"default\":true\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/AccountResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/aggTrades":{"get":{"tags":["rest-api"],"summary":"tradesAggregated","description":"Get compressed, aggregate trades. Trades that fill at the same time, from the same order, with the same price will have the quantity aggregated.","operationId":"aggTradesUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"//a\":\"Aggregate tradeId\",\n \"a\":1582595833,\n \"//p\":\"Price\",\n \"p\":\"8980.4\",\n \"//q\":\"Quantity (should be ignored)\",\n \"q\":\"0.0\",\n \"//T\":\"Timestamp\",\n \"T\":1580204505793,\n \"//m\":\"Was the buyer the maker\",\n \"m\":false\n }\n ]\n\n}","schema":{"type":"array","items":{"$ref":"#/definitions/AggTrades"}}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/closeTradingPosition":{"post":{"tags":["rest-api"],"summary":"tradingPositionClose","description":"Close an active leverage trade.","operationId":"closeTradingPositionUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"positionId","in":"query","description":"positionId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"request\":[\n {\n \"id\":242057,\n \"accountId\":2376109060084932,\n \"instrumentId\":\"45076691096786116\",\n \"rqType\":\"ORDER_NEW\",\n \"state\":\"PROCESSED\",\n \"createdTimestamp\":1587031306969\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionCloseAllResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/currencies":{"get":{"tags":["rest-api"],"summary":"ListOfCurrencies","description":"Get all system currencies","operationId":"getCurrenciesUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"name\": \"US Dollar\",\n \"displaySymbol\": \"USD.cx\",\n \"precision\": 2,\n \"type\": \"FIAT\",\n \"minWithdrawal\": 100,\n \"maxWithdrawal\": 100000000,\n \"commissionMin\": 0.02,\n \"commissionPercent\": 1.5,\n \"minDeposit\": 100\n }\n ]\n\n}","schema":{"$ref":"#/definitions/CurrencyResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/depositAddress":{"get":{"tags":["rest-api"],"summary":"stringOfAddress","description":"Get deposit address by coin","operationId":"getDepositAddressUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"coin","in":"query","description":"coin","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":{\n \"address\": \"0xa12b8b8157da0e44d3e56cda7ade1d587141c27f\"\n }\n\n}","schema":{"$ref":"#/definitions/BlockchainAddressGetResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/deposits":{"get":{"tags":["rest-api"],"summary":"ListOfDeposits","description":"Get deposits for user","operationId":"getDepositsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n\t\t \"id\": 77170270,\n \"balance\": 100000.0,\n \t\"amount\": 100000.0,\n \"currency\": \"BYN\",\n \"type\": \"deposit\",\n \t\"timestamp\": 1647000860502,\n \t\"commission\": 3500.0,\n \t\"paymentMethod\": \"VISA\",\n \t\"status\": \"PROCESSED\"\n \t }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/depth":{"get":{"tags":["rest-api"],"summary":"orderBook","description":"Order book","operationId":"depthUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"lastUpdateId\":1027024,\n \"asks\":[\n [\n \"//Price\",\n \"4.00000200\",\n \"//Qty\",\n \"12.00000000\"\n ]\n ],\n \"bids\":[\n [\n \"// Price\",\n \"4.00000000\",\n \"// Quantity\",\n \"431.00000000\"\n ]\n ]\n }\n\n}","schema":{"$ref":"#/definitions/DepthResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/exchangeInfo":{"get":{"tags":["rest-api"],"summary":"exchangeInfo","description":"Current exchange trading rules and symbol information. When using signature parameter returns the market pairs which are traded under the account's jurisdiction. Also note that when sending an authorized request and using the X-MBX-API-KEY header timestamp and signature parameters are mandatory.","operationId":"exchangeInfoUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":false,"type":"string"},{"name":"signature","in":"query","description":"signature","required":false,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"timezone\":\"UTC\",\n \"serverTime\":1628193845310,\n \"rateLimits\":[\n ],\n \"exchangeFilters\":[\n ],\n \"symbols\":[\n {\n \"symbol\":\"EVK\",\n \"name\":\"Evonik\",\n \"status\":\"BREAK\",\n \"baseAsset\":\"EVK\",\n \"baseAssetPrecision\":3,\n \"quoteAsset\":\"EUR\",\n \"quoteAssetId\":\"EUR\",\n \"quotePrecision\":3,\n \"orderTypes\":[\n \"LIMIT\",\n \"MARKET\"\n ],\n \"filters\":[\n {\n \"filterType\":\"LOT_SIZE\",\n \"minQty\":\"1\",\n \"maxQty\":\"27000\",\n \"stepSize\":\"1\"\n },\n {\n \"filterType\":\"MIN_NOTIONAL\",\n \"minNotional\":\"29\"\n }\n ],\n \"marketModes\":[\n \"REGULAR\"\n ],\n \"marketType\":\"SPOT\",\n \"country\":\"DE\",\n \"sector\":\"Basic Materials\",\n \"industry\":\"Diversified Chemicals\",\n \"tradingHours\":\"UTC; Mon 07:02 - 15:30; Tue 07:02 - 15:30; Wed 07:02 - 15:30; Thu 07:02 - 15:30; Fri 07:02 - 15:30\",\n \"tickSize\":0.005,\n \"tickValue\":0.14475,\n \"exchangeFee\":0.05\n }\n ]\n }\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/fetchOrder":{"get":{"tags":["rest-api"],"summary":"Order","description":"Fetch order by symbol and order id","operationId":"getOrderUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"accountId\":19042209961170116,\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\",\n \"quantity\":1.0,\n \"price\":95.0,\n \"timestamp\":1651072423560,\n \"status\":\"CREATED\",\n \"type\":\"LIMIT\",\n \"expireTime\":2208988800000,\n \"timeInForceType\":\"GTC\",\n \"side\":\"BUY\",\n \"guaranteedStopLoss\":true,\n \"margin\":0.05,\n \"takeProfit\":25.0,\n \"takeProfitType\":\"OFFSET\",\n \"stopLoss\":-15.0,\n \"stopLossType\":\"OFFSET\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/GetOrderDtoResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/fundingLimits":{"get":{"tags":["rest-api"],"summary":"ListOfFundingLimits","description":"Get all system Funding limits","operationId":"getFundingLimitsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"TOKENISED ASSETS\",\n \t\"minWithdrawal\": \"100 USD equivalent\"\n },\n {\n \t\"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"BAT\",\n \t\"minWithdrawal\": \"52\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/FundingLimitsDtoResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/klines":{"get":{"tags":["rest-api"],"summary":"klines","description":"Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.","operationId":"klinesUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"interval","in":"query","description":"interval","required":true,"type":"string"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"priceType","in":"query","description":"priceType","required":false,"type":"string","default":"bid"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"},{"name":"type","in":"query","description":"type","required":false,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n [\n \"// Open time\",\n 1499040000000,\n \" // Open\",\n \"0.01634790\",\n \" // High\",\n \"0.80000000\",\n \" // Low\",\n \"0.01575800\",\n \" // Close\",\n \"0.01577100\",\n \" // Volume.\",\n \"148976.11427815\"\n ]\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/ledger":{"get":{"tags":["rest-api"],"summary":"ListOfLedgers","description":"Get ledger by limit","operationId":"getLedgerUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 77753629,\n\t \"balance\": 20423.49571214,\n\t \"amount\": -0.002601,\n\t \"currency\": \"USD\",\n\t \"type\": \"exchange_commission\",\n\t \"timestamp\": 1647609091989,\n\t \"commission\": 0.002601,\n \"status\": \"PROCESSED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/leverageSettings":{"get":{"tags":["rest-api"],"summary":"leverageSettings","description":"General leverage settings can be seen.","operationId":"leverageSettingsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"values\":[\n 2,\n 5,\n 10,\n 20,\n 50,\n 100,\n \" // the possible leverage sizes;\"\n ],\n \"//value\":\"depicts a default leverage size which will be set in case you don’t mention the ‘leverage’ parameter in the corresponding requests.\",\n \"value\":20\n }\n\n}","schema":{"$ref":"#/definitions/LeverageSettingsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/myTrades":{"get":{"tags":["rest-api"],"summary":"listOfTrades","description":"Get trades for a specific account and symbol.","operationId":"myTradesUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0004-0000-00000006f0a2\",\n \"price\":\"9593.2\",\n \"qty\":\"0.1\",\n \"commission\":\"0.20\",\n \"commissionAsset\":\"USD\",\n \"time\":1582192427437,\n \"maker\":false,\n \"buyer\":true,\n \"isBuyer\":true,\n \"isMaker\":false\n }\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/openOrders":{"get":{"tags":["rest-api"],"summary":"listOfOpenOrders","description":"Get all open orders within exchange and leverage trading modes on a symbol. Careful when accessing this with no symbol.","operationId":"openOrdersUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"NEW\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\",\n \"time\":1586958863147,\n \"updateTime\":1586958863147,\n \"leverage\":false,\n \"working\":true\n }\n ]\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/order":{"post":{"tags":["rest-api"],"summary":"createOrder","description":"To create a market or limit order in the exchange trading mode, and market, limit or stop order in the leverage trading mode.\nPlease note that to open an order within the ‘leverage’ trading mode symbolLeverage should be used and additional accountId parameter should be mentioned in the request.","operationId":"orderUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"newOrderRespType","in":"query","description":"newOrderRespType in the exchange trading mode for MARKET order RESULT or FULL can be mentioned. MARKET order type default to FULL. LIMIT order type can be only RESULT. For the leverage trading mode only RESULT is available.","required":false,"type":"string","allowEmptyValue":false},{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"type","in":"query","description":"Type MARKET or LIMIT should be mentioned to open an order in the exchange trading mode. Type MARKET, LIMIT or STOP should be mentioned to open an order in the leverage trading mode.","required":true,"type":"string","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"accountId","in":"query","description":"accountId","required":false,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean"},{"name":"leverage","in":"query","description":"leverage","required":false,"type":"integer","format":"int32"},{"name":"price","in":"query","description":"price","required":false,"type":"number"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"quantity","in":"query","description":"quantity","required":true,"type":"number"},{"name":"side","in":"query","description":"side","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0000-0000-0000000c028d\",\n \"transactTime\":1589879478020,\n \"price\":\"9797.05500000\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.01\",\n \"status\":\"FILLED\",\n \"timeInForce\":\"FOK\",\n \"type\":\"MARKET\",\n \"side\":\"BUY\"\n }\n\n}","schema":{"$ref":"#/definitions/NewOrderResponseRESULT"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}},"put":{"tags":["rest-api"],"summary":"Edit exchange order","description":"Edit exchange order expirationTime or price","operationId":"putEditOrderUsingPUT","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"price","in":"query","description":"price","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/EditExchangeOrderResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}},"delete":{"tags":["rest-api"],"summary":"cancelOrder","description":"Cancel an active order within exchange and leverage trading modes.","operationId":"cancelOrderUsingDELETE","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":true,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"CANCELED\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\"\n }\n\n}","schema":{"$ref":"#/definitions/CancelOrderResponse"}},"204":{"description":"No Content"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"}}}},"/api/v2/ticker/24hr":{"get":{"tags":["rest-api"],"summary":"priceChange","description":"24 hour rolling window price change statistics. Careful when accessing this with no symbol.","operationId":"ticker_24hrUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"LTC/USD\",\n \"priceChange\":\"0.88\",\n \"priceChangePercent\":\"1.49\",\n \"weightedAvgPrice\":\"59.29\",\n \"prevClosePrice\":\"58.37\",\n \"lastPrice\":\"59.25\",\n \"lastQty\":\"220.0\",\n \"bidPrice\":\"59.25\",\n \"askPrice\":\"59.32\",\n \"openPrice\":\"58.37\",\n \"highPrice\":\"61.39\",\n \"lowPrice\":\"58.37\",\n \"volume\":\"22632\",\n \"quoteVolume\":\"440.0\",\n \"openTime\":1580169600000,\n \"closeTime\":1580205307222\n }\n\n}","schema":{"type":"object"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/time":{"get":{"tags":["rest-api"],"summary":"serverTime","description":"Test connectivity to the API and get the current server time.","operationId":"timeUsingGET","produces":["*/*"],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"3\",\n \"payload\":{\n \"serverTime\":1628195607917\n }\n\n}","schema":{"$ref":"#/definitions/ServerTime"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/tradingFees":{"get":{"tags":["rest-api"],"summary":"ListOfFees","description":"Get all system fees","operationId":"getTradingFeesUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"UNI/USD\",\n \"name\": \"UNI/USD\",\n \"fee\": 0.1\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TradingFeesResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/tradingLimits":{"get":{"tags":["rest-api"],"summary":"ListOfLimits","description":"Get all system limits","operationId":"getTradingLimitsUsingGET","produces":["*/*"],"parameters":[{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"EVK\",\n \t\"name\": \"Evonik\",\n \t\"minVolume\": 1.0,\n \t\"maxVolume\": 27000.0,\n \t\t\"minStep\": 1.0,\n \t\"tickSize\": 0.005\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TradingLimitsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/tradingPositions":{"get":{"tags":["rest-api"],"summary":"listOfLeverageTrades","description":"Get all open trades within the account.","operationId":"tradingPositionsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"positions\":[\n {\n \"accountId\":2376109060084932,\n \"id\":\"00a02503-0079-54c4-0000-00004067006b\",\n \"instrumentId\":\"45076691096786116\",\n \"orderId\":\"00a02503-0079-54c4-0000-00004067006a\",\n \"openQuantity\":0.01,\n \"openPrice\":6734.4,\n \"closeQuantity\":0.0,\n \"closePrice\":0,\n \"takeProfit\":7999.15,\n \"stopLoss\":5999.15,\n \"guaranteedStopLoss\":false,\n \"rpl\":0,\n \"rplConverted\":0,\n \"swap\":-0.00335894,\n \"swapConverted\":-0.00335894,\n \"fee\":-0.050508,\n \"dividend\":0,\n \"margin\":0.5,\n \"state\":\"ACTIVE\",\n \"currency\":\"USD\",\n \"createdTimestamp\":1586953061455,\n \"openTimestamp\":1586953061243,\n \"cost\":33.73775,\n \"symbol\":\"BTC/USD_LEVERAGE\"\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionListResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/tradingPositionsHistory":{"get":{"tags":["rest-api"],"summary":"listOfHistoricalPositions","description":"Get all closes postions within the account.","operationId":"tradingPositionsHistoryUsingGET","produces":["*/*"],"parameters":[{"name":"from","in":"query","description":"Timestamp in milliseconds, Filtration based on execTimestamp parameter","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"symbol","in":"query","description":"Symbol - In order to receive orders within an ‘exchange’ trading mode ‘symbol’ parameter value from the exchangeInfo endpoint: ‘BTC%2FUSD’.\nIn order to mention the right symbolLeverage it should be checked with the ‘symbol’ parameter value from the exchangeInfo endpoint. In case ‘symbol’ has currencies in its name then the following format should be used: ‘BTC%2FUSD_LEVERAGE’. In case ‘symbol’ has only an asset name then for the leverage trading mode the following format is correct: ‘Oil%20-%20Brent.’","required":false,"type":"string","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"to","in":"query","description":"Timestamp in milliseconds, Filtration based on execTimestamp parameter","required":false,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"history\":[\n {\n \"accountId\":19039018800469188,\n \"accountCurrency\":\"USD\",\n \"positionId\":\"00a18509-0079-54c4-0000-00004062007b\",\n \"currency\":\"USD\",\n \"executionType\":\"IOC\",\n \"quantity\":-0.1,\n \"price\":44.95,\n \"source\":\"USER\",\n \"status\":\"CLOSED\",\n \"rpl\":-0.002,\n \"rplConverted\":-0.002,\n \"fee\":0,\n \"createdTimestamp\":1606999328398,\n \"execTimestamp\":1606999315265,\n \"symbol\":\"Oil - Crude.\"\n }\n ]\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionHistoryResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/transactions":{"get":{"tags":["rest-api"],"summary":"ListOfTransactions","description":"Get transactions by limit and sinceTime","operationId":"getTransactionsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/updateTradingOrder":{"post":{"tags":["rest-api"],"summary":"leverageOrdersEdit","description":"Edit current leverage orders by changing take profit and stop loss levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"updateTradingOrderUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"expireTimestamp","in":"query","description":"expireTimestamp","required":false,"type":"integer","format":"int64"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean","default":false},{"name":"newPrice","in":"query","description":"newPrice","required":false,"type":"number"},{"name":"orderId","in":"query","description":"orderId","required":true,"type":"string"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean","default":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":241986,\n \"state\":\"PROCESSED\"\n }\n\n}","schema":{"$ref":"#/definitions/TradingOrderUpdateResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/updateTradingPosition":{"post":{"tags":["rest-api"],"summary":"leverageTradeEdit","description":"Edit current leverage trade by changing stop loss and take profit levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"updateTradingPositionUsingPOST","consumes":["application/json"],"produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"guaranteedStopLoss","in":"query","description":"guaranteedStopLoss","required":false,"type":"boolean","default":false},{"name":"positionId","in":"query","description":"positionId","required":true,"type":"string","format":"uuid"},{"name":"profitDistance","in":"query","description":"profitDistance","required":false,"type":"number"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"stopDistance","in":"query","description":"stopDistance","required":false,"type":"number"},{"name":"stopLoss","in":"query","description":"stopLoss","required":false,"type":"number"},{"name":"takeProfit","in":"query","description":"takeProfit","required":false,"type":"number"},{"name":"trailingStopLoss","in":"query","description":"trailingStopLoss","required":false,"type":"boolean","default":false}],"responses":{"200":{"description":"Example:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":242040,\n \"state\":\"PROCESSED\"\n }\n\n}","schema":{"$ref":"#/definitions/TradingPositionUpdateResponse"}},"201":{"description":"Created"},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"/api/v2/withdrawals":{"get":{"tags":["rest-api"],"summary":"ListOfWithdrawals","description":"Get withdrawals for user","operationId":"getWithdrawalsUsingGET","produces":["*/*"],"parameters":[{"name":"recvWindow","in":"query","description":"recvWindow cannot be greater than 60000","required":false,"type":"integer","default":5000,"format":"int64","allowEmptyValue":false},{"name":"timestamp","in":"query","description":"Timestamp in milliseconds","required":true,"type":"integer","format":"int64","allowEmptyValue":false},{"name":"X-MBX-APIKEY","in":"header","description":"X-MBX-APIKEY","required":true,"type":"string"},{"name":"endTime","in":"query","description":"endTime","required":false,"type":"integer","format":"int64"},{"name":"limit","in":"query","description":"limit","required":false,"type":"integer","default":10,"format":"int32"},{"name":"signature","in":"query","description":"signature","required":true,"type":"string"},{"name":"startTime","in":"query","description":"startTime","required":false,"type":"integer","format":"int64"}],"responses":{"200":{"description":"Example:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}","schema":{"$ref":"#/definitions/TransactionsResponse"}},"401":{"description":"Unauthorized"},"403":{"description":"Forbidden"},"404":{"description":"Not Found"}}}},"wss:/api/v1/account":{"get":{"tags":["websocket-api"],"summary":"accountInfo","description":"Get current account information","operationId":"websocketmethods_53","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AccountRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"makerCommission\":0.20,\n \"takerCommission\":0.20,\n \"buyerCommission\":0.20,\n \"sellerCommission\":0.20,\n \"canTrade\":true,\n \"canWithdraw\":true,\n \"canDeposit\":true,\n \"updateTime\":1586935521,\n \"balances\":[\n {\n \"accountId\":\"2376104765040206\",\n \"collateralCurrency\":true,\n \"asset\":\"BYN\",\n \"free\":0.0,\n \"locked\":0.0,\n \"default\":false\n },\n {\n \"accountId\":\"2376109060084932\",\n \"collateralCurrency\":true,\n \"asset\":\"USD\",\n \"free\":515.59092523,\n \"locked\":0.0,\n \"default\":true\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/AccountResponse"}}}}},"wss:/api/v1/aggTrades":{"get":{"tags":["websocket-api"],"summary":"tradesAggregated","description":"Get compressed, aggregate trades. Trades that fill at the same time, from the same order, with the same price will have the quantity aggregated.","operationId":"websocketmethods_7","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AggTradesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"//a\":\"Aggregate tradeId\",\n \"a\":1582595833,\n \"//p\":\"Price\",\n \"p\":\"8980.4\",\n \"//q\":\"Quantity (should be ignored)\",\n \"q\":\"0.0\",\n \"//T\":\"Timestamp\",\n \"T\":1580204505793,\n \"//m\":\"Was the buyer the maker\",\n \"m\":false\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/AggTradesResponse"}}}}},"wss:/api/v1/closeTradingPosition":{"get":{"tags":["websocket-api"],"summary":"tradingPositionClose","description":"Close an active leverage trade.","operationId":"websocketmethods_13","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CloseTradingPositionRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"request\":[\n {\n \"id\":242057,\n \"accountId\":2376109060084932,\n \"instrumentId\":\"45076691096786116\",\n \"rqType\":\"ORDER_NEW\",\n \"state\":\"PROCESSED\",\n \"createdTimestamp\":1587031306969\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionCloseAllResponse"}}}}},"wss:/api/v1/currencies":{"get":{"tags":["websocket-api"],"summary":"ListOfCurrencies","description":"Get all system currencies","operationId":"websocketmethods_20","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"name\": \"US Dollar\",\n \"displaySymbol\": \"USD.cx\",\n \"precision\": 2,\n \"type\": \"FIAT\",\n \"minWithdrawal\": 100,\n \"maxWithdrawal\": 100000000,\n \"commissionMin\": 0.02,\n \"commissionPercent\": 1.5,\n \"minDeposit\": 100\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/CurrencyResponse"}}}}},"wss:/api/v1/depositAddress":{"get":{"tags":["websocket-api"],"summary":"stringOfAddress","description":"Get deposit address by coin","operationId":"websocketmethods_3","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/BlockchainAddressRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":{\n \"address\": \"0xa12b8b8157da0e44d3e56cda7ade1d587141c27f\"\n }\n\n}\n","schema":{"$ref":"#/definitions/BlockchainAddressGetResponse"}}}}},"wss:/api/v1/deposits":{"get":{"tags":["websocket-api"],"summary":"ListOfDeposits","description":"Get deposits for user","operationId":"websocketmethods_4","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n\t\t \"id\": 77170270,\n \"balance\": 100000.0,\n \t\"amount\": 100000.0,\n \"currency\": \"BYN\",\n \"type\": \"deposit\",\n \t\"timestamp\": 1647000860502,\n \t\"commission\": 3500.0,\n \t\"paymentMethod\": \"VISA\",\n \t\"status\": \"PROCESSED\"\n \t }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v1/depth":{"get":{"tags":["websocket-api"],"summary":"orderBook","description":"Order book","operationId":"websocketmethods_12","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/DepthRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"lastUpdateId\":1027024,\n \"asks\":[\n [\n \"//Price\",\n \"4.00000200\",\n \"//Qty\",\n \"12.00000000\"\n ]\n ],\n \"bids\":[\n [\n \"// Price\",\n \"4.00000000\",\n \"// Quantity\",\n \"431.00000000\"\n ]\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/DepthResponse"}}}}},"wss:/api/v1/exchangeInfo":{"get":{"tags":["websocket-api"],"summary":"exchangeInfo","description":"Current exchange trading rules and symbol information. When using signature parameter returns the market pairs which are traded under the account's jurisdiction. Also note that when sending an authorized request and using the X-MBX-API-KEY header timestamp and signature parameters are mandatory.","operationId":"websocketmethods_22","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/OptionalAuthRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"timezone\":\"UTC\",\n \"serverTime\":1628193845310,\n \"rateLimits\":[\n ],\n \"exchangeFilters\":[\n ],\n \"symbols\":[\n {\n \"symbol\":\"EVK\",\n \"name\":\"Evonik\",\n \"status\":\"BREAK\",\n \"baseAsset\":\"EVK\",\n \"baseAssetPrecision\":3,\n \"quoteAsset\":\"EUR\",\n \"quoteAssetId\":\"EUR\",\n \"quotePrecision\":3,\n \"orderTypes\":[\n \"LIMIT\",\n \"MARKET\"\n ],\n \"filters\":[\n {\n \"filterType\":\"LOT_SIZE\",\n \"minQty\":\"1\",\n \"maxQty\":\"27000\",\n \"stepSize\":\"1\"\n },\n {\n \"filterType\":\"MIN_NOTIONAL\",\n \"minNotional\":\"29\"\n }\n ],\n \"marketModes\":[\n \"REGULAR\"\n ],\n \"marketType\":\"SPOT\",\n \"country\":\"DE\",\n \"sector\":\"Basic Materials\",\n \"industry\":\"Diversified Chemicals\",\n \"tradingHours\":\"UTC; Mon 07:02 - 15:30; Tue 07:02 - 15:30; Wed 07:02 - 15:30; Thu 07:02 - 15:30; Fri 07:02 - 15:30\",\n \"tickSize\":0.005,\n \"tickValue\":0.14475,\n \"exchangeFee\":0.05\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/ExchangeInfo"}}}}},"wss:/api/v1/fetchOrder":{"get":{"tags":["websocket-api"],"summary":"Order","description":"Fetch order by symbol and order id","operationId":"websocketmethods","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/GetOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"accountId\":19042209961170116,\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\",\n \"quantity\":1.0,\n \"price\":95.0,\n \"timestamp\":1651072423560,\n \"status\":\"CREATED\",\n \"type\":\"LIMIT\",\n \"expireTime\":2208988800000,\n \"timeInForceType\":\"GTC\",\n \"side\":\"BUY\",\n \"guaranteedStopLoss\":true,\n \"margin\":0.05,\n \"takeProfit\":25.0,\n \"takeProfitType\":\"OFFSET\",\n \"stopLoss\":-15.0,\n \"stopLossType\":\"OFFSET\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/GetOrderDtoResponse"}}}}},"wss:/api/v1/fundingLimits":{"get":{"tags":["websocket-api"],"summary":"ListOfFundingLimits","description":"Get all system Funding limits","operationId":"websocketmethods_54","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"TOKENISED ASSETS\",\n \t\"minWithdrawal\": \"100 USD equivalent\"\n },\n {\n \t\"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"BAT\",\n \t\"minWithdrawal\": \"52\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/FundingLimitsDtoResponseWS"}}}}},"wss:/api/v1/klines":{"get":{"tags":["websocket-api"],"summary":"klines","description":"Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.","operationId":"websocketmethods_15","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/KLinesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n [\n \"// Open time\",\n 1499040000000,\n \" // Open\",\n \"0.01634790\",\n \" // High\",\n \"0.80000000\",\n \" // Low\",\n \"0.01575800\",\n \" // Close\",\n \"0.01577100\",\n \" // Volume.\",\n \"148976.11427815\"\n ]\n ]\n\n}\n","schema":{"$ref":"#/definitions/KLinesResponse"}}}}},"wss:/api/v1/ledger":{"get":{"tags":["websocket-api"],"summary":"ListOfLedgers","description":"Get ledger by limit","operationId":"websocketmethods_2","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 77753629,\n\t \"balance\": 20423.49571214,\n\t \"amount\": -0.002601,\n\t \"currency\": \"USD\",\n\t \"type\": \"exchange_commission\",\n\t \"timestamp\": 1647609091989,\n\t \"commission\": 0.002601,\n \"status\": \"PROCESSED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v1/leverageSettings":{"get":{"tags":["websocket-api"],"summary":"leverageSettings","description":"General leverage settings can be seen.","operationId":"websocketmethods_19","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/LeverageSettingsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"values\":[\n 2,\n 5,\n 10,\n 20,\n 50,\n 100,\n \" // the possible leverage sizes;\"\n ],\n \"//value\":\"depicts a default leverage size which will be set in case you don’t mention the ‘leverage’ parameter in the corresponding requests.\",\n \"value\":20\n }\n\n}\n","schema":{"$ref":"#/definitions/LeverageSettingsResponse"}}}}},"wss:/api/v1/myTrades":{"get":{"tags":["websocket-api"],"summary":"listOfTrades","description":"Get trades for a specific account and symbol.","operationId":"websocketmethods_14","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AllMyTradesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0004-0000-00000006f0a2\",\n \"price\":\"9593.2\",\n \"qty\":\"0.1\",\n \"commission\":\"0.20\",\n \"commissionAsset\":\"USD\",\n \"time\":1582192427437,\n \"maker\":false,\n \"buyer\":true,\n \"isBuyer\":true,\n \"isMaker\":false\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/AllMyTradesResponse"}}}}},"wss:/api/v1/openOrders":{"get":{"tags":["websocket-api"],"summary":"listOfOpenOrders","description":"Get all open orders within exchange and leverage trading modes on a symbol. Careful when accessing this with no symbol.","operationId":"websocketmethods_9","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedBySymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"NEW\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\",\n \"time\":1586958863147,\n \"updateTime\":1586958863147,\n \"leverage\":false,\n \"working\":true\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/OpenOrdersReponse"}}}}},"wss:/api/v1/order/cancel":{"get":{"tags":["websocket-api"],"summary":"cancelOrder","description":"Cancel an active order within exchange and leverage trading modes.","operationId":"websocketmethods_52","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CancelOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"CANCELED\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\"\n }\n\n}\n","schema":{"$ref":"#/definitions/CancelOrderResponse"}}}}},"wss:/api/v1/order/create":{"get":{"tags":["websocket-api"],"summary":"createOrder","description":"To create a market or limit order in the exchange trading mode, and market, limit or stop order in the leverage trading mode.\nPlease note that to open an order within the ‘leverage’ trading mode symbolLeverage should be used and additional accountId parameter should be mentioned in the request.","operationId":"websocketmethods_21","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CreateOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0000-0000-0000000c028d\",\n \"transactTime\":1589879478020,\n \"price\":\"9797.05500000\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.01\",\n \"status\":\"FILLED\",\n \"timeInForce\":\"FOK\",\n \"type\":\"MARKET\",\n \"side\":\"BUY\"\n }\n\n}\n","schema":{"$ref":"#/definitions/NewOrderResponseRESULT"}}}}},"wss:/api/v1/order/edit":{"get":{"tags":["websocket-api"],"summary":"Edit exchange order","description":"Edit exchange order expirationTime or price","operationId":"websocketmethods_51","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/EditExchangeOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/EditExchangeOrderResponse"}}}}},"wss:/api/v1/ticker/24hr":{"get":{"tags":["websocket-api"],"summary":"priceChange","description":"24 hour rolling window price change statistics. Careful when accessing this with no symbol.","operationId":"websocketmethods_8","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/BySymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"LTC/USD\",\n \"priceChange\":\"0.88\",\n \"priceChangePercent\":\"1.49\",\n \"weightedAvgPrice\":\"59.29\",\n \"prevClosePrice\":\"58.37\",\n \"lastPrice\":\"59.25\",\n \"lastQty\":\"220.0\",\n \"bidPrice\":\"59.25\",\n \"askPrice\":\"59.32\",\n \"openPrice\":\"58.37\",\n \"highPrice\":\"61.39\",\n \"lowPrice\":\"58.37\",\n \"volume\":\"22632\",\n \"quoteVolume\":\"440.0\",\n \"openTime\":1580169600000,\n \"closeTime\":1580205307222\n }\n\n}\n","schema":{"$ref":"#/definitions/Ticker24HResponse"}}}}},"wss:/api/v1/time":{"get":{"tags":["websocket-api"],"summary":"serverTime","description":"Test connectivity to the API and get the current server time.","operationId":"websocketmethods_17","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/EmptyRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"3\",\n \"payload\":{\n \"serverTime\":1628195607917\n }\n\n}\n","schema":{"$ref":"#/definitions/ServerTime"}}}}},"wss:/api/v1/tradingFees":{"get":{"tags":["websocket-api"],"summary":"ListOfFees","description":"Get all system fees","operationId":"websocketmethods_10","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"UNI/USD\",\n \"name\": \"UNI/USD\",\n \"fee\": 0.1\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TradingFeesResponseWS"}}}}},"wss:/api/v1/tradingLimits":{"get":{"tags":["websocket-api"],"summary":"ListOfLimits","description":"Get all system limits","operationId":"websocketmethods_55","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"EVK\",\n \t\"name\": \"Evonik\",\n \t\"minVolume\": 1.0,\n \t\"maxVolume\": 27000.0,\n \t\t\"minStep\": 1.0,\n \t\"tickSize\": 0.005\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TradingLimitsResponseWS"}}}}},"wss:/api/v1/tradingPositions":{"get":{"tags":["websocket-api"],"summary":"listOfLeverageTrades","description":"Get all open trades within the account.","operationId":"websocketmethods_6","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"positions\":[\n {\n \"accountId\":2376109060084932,\n \"id\":\"00a02503-0079-54c4-0000-00004067006b\",\n \"instrumentId\":\"45076691096786116\",\n \"orderId\":\"00a02503-0079-54c4-0000-00004067006a\",\n \"openQuantity\":0.01,\n \"openPrice\":6734.4,\n \"closeQuantity\":0.0,\n \"closePrice\":0,\n \"takeProfit\":7999.15,\n \"stopLoss\":5999.15,\n \"guaranteedStopLoss\":false,\n \"rpl\":0,\n \"rplConverted\":0,\n \"swap\":-0.00335894,\n \"swapConverted\":-0.00335894,\n \"fee\":-0.050508,\n \"dividend\":0,\n \"margin\":0.5,\n \"state\":\"ACTIVE\",\n \"currency\":\"USD\",\n \"createdTimestamp\":1586953061455,\n \"openTimestamp\":1586953061243,\n \"cost\":33.73775,\n \"symbol\":\"BTC/USD_LEVERAGE\"\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionListResponse"}}}}},"wss:/api/v1/tradingPositionsHistory":{"get":{"tags":["websocket-api"],"summary":"listOfHistoricalPositions","description":"Get all closes postions within the account.","operationId":"websocketmethods_11","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/PositionHistoryRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"history\":[\n {\n \"accountId\":19039018800469188,\n \"accountCurrency\":\"USD\",\n \"positionId\":\"00a18509-0079-54c4-0000-00004062007b\",\n \"currency\":\"USD\",\n \"executionType\":\"IOC\",\n \"quantity\":-0.1,\n \"price\":44.95,\n \"source\":\"USER\",\n \"status\":\"CLOSED\",\n \"rpl\":-0.002,\n \"rplConverted\":-0.002,\n \"fee\":0,\n \"createdTimestamp\":1606999328398,\n \"execTimestamp\":1606999315265,\n \"symbol\":\"Oil - Crude.\"\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionHistoryResponse"}}}}},"wss:/api/v1/transactions":{"get":{"tags":["websocket-api"],"summary":"ListOfTransactions","description":"Get transactions by limit and sinceTime","operationId":"websocketmethods_5","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v1/updateTradingOrder":{"get":{"tags":["websocket-api"],"summary":"leverageOrdersEdit","description":"Edit current leverage orders by changing take profit and stop loss levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"websocketmethods_18","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/UpdateTradingOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":241986,\n \"state\":\"PROCESSED\"\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingOrderUpdateResponse"}}}}},"wss:/api/v1/updateTradingPosition":{"get":{"tags":["websocket-api"],"summary":"leverageTradeEdit","description":"Edit current leverage trade by changing stop loss and take profit levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"websocketmethods_1","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/UpdateTradingPositionRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":242040,\n \"state\":\"PROCESSED\"\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionUpdateResponse"}}}}},"wss:/api/v1/withdrawals":{"get":{"tags":["websocket-api"],"summary":"ListOfWithdrawals","description":"Get withdrawals for user","operationId":"websocketmethods_16","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v2/account":{"get":{"tags":["websocket-api"],"summary":"accountInfo","description":"Get current account information","operationId":"websocketmethods_33","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AccountRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"makerCommission\":0.20,\n \"takerCommission\":0.20,\n \"buyerCommission\":0.20,\n \"sellerCommission\":0.20,\n \"canTrade\":true,\n \"canWithdraw\":true,\n \"canDeposit\":true,\n \"updateTime\":1586935521,\n \"balances\":[\n {\n \"accountId\":\"2376104765040206\",\n \"collateralCurrency\":true,\n \"asset\":\"BYN\",\n \"free\":0.0,\n \"locked\":0.0,\n \"default\":false\n },\n {\n \"accountId\":\"2376109060084932\",\n \"collateralCurrency\":true,\n \"asset\":\"USD\",\n \"free\":515.59092523,\n \"locked\":0.0,\n \"default\":true\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/AccountResponse"}}}}},"wss:/api/v2/aggTrades":{"get":{"tags":["websocket-api"],"summary":"tradesAggregated","description":"Get compressed, aggregate trades. Trades that fill at the same time, from the same order, with the same price will have the quantity aggregated.","operationId":"websocketmethods_46","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AggTradesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"//a\":\"Aggregate tradeId\",\n \"a\":1582595833,\n \"//p\":\"Price\",\n \"p\":\"8980.4\",\n \"//q\":\"Quantity (should be ignored)\",\n \"q\":\"0.0\",\n \"//T\":\"Timestamp\",\n \"T\":1580204505793,\n \"//m\":\"Was the buyer the maker\",\n \"m\":false\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/AggTradesResponse"}}}}},"wss:/api/v2/closeTradingPosition":{"get":{"tags":["websocket-api"],"summary":"tradingPositionClose","description":"Close an active leverage trade.","operationId":"websocketmethods_30","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CloseTradingPositionRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"request\":[\n {\n \"id\":242057,\n \"accountId\":2376109060084932,\n \"instrumentId\":\"45076691096786116\",\n \"rqType\":\"ORDER_NEW\",\n \"state\":\"PROCESSED\",\n \"createdTimestamp\":1587031306969\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionCloseAllResponse"}}}}},"wss:/api/v2/currencies":{"get":{"tags":["websocket-api"],"summary":"ListOfCurrencies","description":"Get all system currencies","operationId":"websocketmethods_37","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"name\": \"US Dollar\",\n \"displaySymbol\": \"USD.cx\",\n \"precision\": 2,\n \"type\": \"FIAT\",\n \"minWithdrawal\": 100,\n \"maxWithdrawal\": 100000000,\n \"commissionMin\": 0.02,\n \"commissionPercent\": 1.5,\n \"minDeposit\": 100\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/CurrencyResponse"}}}}},"wss:/api/v2/depositAddress":{"get":{"tags":["websocket-api"],"summary":"stringOfAddress","description":"Get deposit address by coin","operationId":"websocketmethods_32","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/BlockchainAddressRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":{\n \"address\": \"0xa12b8b8157da0e44d3e56cda7ade1d587141c27f\"\n }\n\n}\n","schema":{"$ref":"#/definitions/BlockchainAddressGetResponse"}}}}},"wss:/api/v2/deposits":{"get":{"tags":["websocket-api"],"summary":"ListOfDeposits","description":"Get deposits for user","operationId":"websocketmethods_24","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n\t\t \"id\": 77170270,\n \"balance\": 100000.0,\n \t\"amount\": 100000.0,\n \"currency\": \"BYN\",\n \"type\": \"deposit\",\n \t\"timestamp\": 1647000860502,\n \t\"commission\": 3500.0,\n \t\"paymentMethod\": \"VISA\",\n \t\"status\": \"PROCESSED\"\n \t }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v2/depth":{"get":{"tags":["websocket-api"],"summary":"orderBook","description":"Order book","operationId":"websocketmethods_49","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/DepthRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"lastUpdateId\":1027024,\n \"asks\":[\n [\n \"//Price\",\n \"4.00000200\",\n \"//Qty\",\n \"12.00000000\"\n ]\n ],\n \"bids\":[\n [\n \"// Price\",\n \"4.00000000\",\n \"// Quantity\",\n \"431.00000000\"\n ]\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/DepthResponse"}}}}},"wss:/api/v2/exchangeInfo":{"get":{"tags":["websocket-api"],"summary":"exchangeInfo","description":"Current exchange trading rules and symbol information. When using signature parameter returns the market pairs which are traded under the account's jurisdiction. Also note that when sending an authorized request and using the X-MBX-API-KEY header timestamp and signature parameters are mandatory.","operationId":"websocketmethods_40","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/OptionalAuthRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"timezone\":\"UTC\",\n \"serverTime\":1628193845310,\n \"rateLimits\":[\n ],\n \"exchangeFilters\":[\n ],\n \"symbols\":[\n {\n \"symbol\":\"EVK\",\n \"name\":\"Evonik\",\n \"status\":\"BREAK\",\n \"baseAsset\":\"EVK\",\n \"baseAssetPrecision\":3,\n \"quoteAsset\":\"EUR\",\n \"quoteAssetId\":\"EUR\",\n \"quotePrecision\":3,\n \"orderTypes\":[\n \"LIMIT\",\n \"MARKET\"\n ],\n \"filters\":[\n {\n \"filterType\":\"LOT_SIZE\",\n \"minQty\":\"1\",\n \"maxQty\":\"27000\",\n \"stepSize\":\"1\"\n },\n {\n \"filterType\":\"MIN_NOTIONAL\",\n \"minNotional\":\"29\"\n }\n ],\n \"marketModes\":[\n \"REGULAR\"\n ],\n \"marketType\":\"SPOT\",\n \"country\":\"DE\",\n \"sector\":\"Basic Materials\",\n \"industry\":\"Diversified Chemicals\",\n \"tradingHours\":\"UTC; Mon 07:02 - 15:30; Tue 07:02 - 15:30; Wed 07:02 - 15:30; Thu 07:02 - 15:30; Fri 07:02 - 15:30\",\n \"tickSize\":0.005,\n \"tickValue\":0.14475,\n \"exchangeFee\":0.05\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/ExchangeInfo"}}}}},"wss:/api/v2/fetchOrder":{"get":{"tags":["websocket-api"],"summary":"Order","description":"Fetch order by symbol and order id","operationId":"websocketmethods_42","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/GetOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"accountId\":19042209961170116,\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\",\n \"quantity\":1.0,\n \"price\":95.0,\n \"timestamp\":1651072423560,\n \"status\":\"CREATED\",\n \"type\":\"LIMIT\",\n \"expireTime\":2208988800000,\n \"timeInForceType\":\"GTC\",\n \"side\":\"BUY\",\n \"guaranteedStopLoss\":true,\n \"margin\":0.05,\n \"takeProfit\":25.0,\n \"takeProfitType\":\"OFFSET\",\n \"stopLoss\":-15.0,\n \"stopLossType\":\"OFFSET\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/GetOrderDtoResponse"}}}}},"wss:/api/v2/fundingLimits":{"get":{"tags":["websocket-api"],"summary":"ListOfFundingLimits","description":"Get all system Funding limits","operationId":"websocketmethods_43","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"TOKENISED ASSETS\",\n \t\"minWithdrawal\": \"100 USD equivalent\"\n },\n {\n \t\"paymentOption\": \"CRYPTO\",\n \t\"accountCurrency\": \"BAT\",\n \t\"minWithdrawal\": \"52\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/FundingLimitsDtoResponseWS"}}}}},"wss:/api/v2/klines":{"get":{"tags":["websocket-api"],"summary":"klines","description":"Kline/candlestick bars for a symbol. Klines are uniquely identified by their open time.","operationId":"websocketmethods_27","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/KLinesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n [\n \"// Open time\",\n 1499040000000,\n \" // Open\",\n \"0.01634790\",\n \" // High\",\n \"0.80000000\",\n \" // Low\",\n \"0.01575800\",\n \" // Close\",\n \"0.01577100\",\n \" // Volume.\",\n \"148976.11427815\"\n ]\n ]\n\n}\n","schema":{"$ref":"#/definitions/KLinesResponse"}}}}},"wss:/api/v2/ledger":{"get":{"tags":["websocket-api"],"summary":"ListOfLedgers","description":"Get ledger by limit","operationId":"websocketmethods_47","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 77753629,\n\t \"balance\": 20423.49571214,\n\t \"amount\": -0.002601,\n\t \"currency\": \"USD\",\n\t \"type\": \"exchange_commission\",\n\t \"timestamp\": 1647609091989,\n\t \"commission\": 0.002601,\n \"status\": \"PROCESSED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v2/leverageSettings":{"get":{"tags":["websocket-api"],"summary":"leverageSettings","description":"General leverage settings can be seen.","operationId":"websocketmethods_31","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/LeverageSettingsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"values\":[\n 2,\n 5,\n 10,\n 20,\n 50,\n 100,\n \" // the possible leverage sizes;\"\n ],\n \"//value\":\"depicts a default leverage size which will be set in case you don’t mention the ‘leverage’ parameter in the corresponding requests.\",\n \"value\":20\n }\n\n}\n","schema":{"$ref":"#/definitions/LeverageSettingsResponse"}}}}},"wss:/api/v2/myTrades":{"get":{"tags":["websocket-api"],"summary":"listOfTrades","description":"Get trades for a specific account and symbol.","operationId":"websocketmethods_48","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/AllMyTradesRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0004-0000-00000006f0a2\",\n \"price\":\"9593.2\",\n \"qty\":\"0.1\",\n \"commission\":\"0.20\",\n \"commissionAsset\":\"USD\",\n \"time\":1582192427437,\n \"maker\":false,\n \"buyer\":true,\n \"isBuyer\":true,\n \"isMaker\":false\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/AllMyTradesResponse"}}}}},"wss:/api/v2/openOrders":{"get":{"tags":["websocket-api"],"summary":"listOfOpenOrders","description":"Get all open orders within exchange and leverage trading modes on a symbol. Careful when accessing this with no symbol.","operationId":"websocketmethods_26","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedBySymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"NEW\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\",\n \"time\":1586958863147,\n \"updateTime\":1586958863147,\n \"leverage\":false,\n \"working\":true\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/OpenOrdersReponse"}}}}},"wss:/api/v2/order/cancel":{"get":{"tags":["websocket-api"],"summary":"cancelOrder","description":"Cancel an active order within exchange and leverage trading modes.","operationId":"websocketmethods_41","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CancelOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0002-0000-0000000b3302\",\n \"price\":\"6600\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.0\",\n \"status\":\"CANCELED\",\n \"timeInForce\":\"GTC\",\n \"type\":\"LIMIT\",\n \"side\":\"BUY\"\n }\n\n}\n","schema":{"$ref":"#/definitions/CancelOrderResponse"}}}}},"wss:/api/v2/order/create":{"get":{"tags":["websocket-api"],"summary":"createOrder","description":"To create a market or limit order in the exchange trading mode, and market, limit or stop order in the leverage trading mode.\nPlease note that to open an order within the ‘leverage’ trading mode symbolLeverage should be used and additional accountId parameter should be mentioned in the request.","operationId":"websocketmethods_44","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/CreateOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00000000-0000-0000-0000-0000000c028d\",\n \"transactTime\":1589879478020,\n \"price\":\"9797.05500000\",\n \"origQty\":\"0.01\",\n \"executedQty\":\"0.01\",\n \"status\":\"FILLED\",\n \"timeInForce\":\"FOK\",\n \"type\":\"MARKET\",\n \"side\":\"BUY\"\n }\n\n}\n","schema":{"$ref":"#/definitions/NewOrderResponseRESULT"}}}}},"wss:/api/v2/order/edit":{"get":{"tags":["websocket-api"],"summary":"Edit exchange order","description":"Edit exchange order expirationTime or price","operationId":"websocketmethods_50","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/EditExchangeOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":[\n {\n \"orderId\":\"00a0c503-0079-54c4-0000-0000803400c0\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/EditExchangeOrderResponse"}}}}},"wss:/api/v2/ticker/24hr":{"get":{"tags":["websocket-api"],"summary":"priceChange","description":"24 hour rolling window price change statistics. Careful when accessing this with no symbol.","operationId":"websocketmethods_25","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/BySymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"symbol\":\"LTC/USD\",\n \"priceChange\":\"0.88\",\n \"priceChangePercent\":\"1.49\",\n \"weightedAvgPrice\":\"59.29\",\n \"prevClosePrice\":\"58.37\",\n \"lastPrice\":\"59.25\",\n \"lastQty\":\"220.0\",\n \"bidPrice\":\"59.25\",\n \"askPrice\":\"59.32\",\n \"openPrice\":\"58.37\",\n \"highPrice\":\"61.39\",\n \"lowPrice\":\"58.37\",\n \"volume\":\"22632\",\n \"quoteVolume\":\"440.0\",\n \"openTime\":1580169600000,\n \"closeTime\":1580205307222\n }\n\n}\n","schema":{"$ref":"#/definitions/Ticker24HResponse"}}}}},"wss:/api/v2/time":{"get":{"tags":["websocket-api"],"summary":"serverTime","description":"Test connectivity to the API and get the current server time.","operationId":"websocketmethods_28","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/EmptyRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"3\",\n \"payload\":{\n \"serverTime\":1628195607917\n }\n\n}\n","schema":{"$ref":"#/definitions/ServerTime"}}}}},"wss:/api/v2/tradingFees":{"get":{"tags":["websocket-api"],"summary":"ListOfFees","description":"Get all system fees","operationId":"websocketmethods_38","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"UNI/USD\",\n \"name\": \"UNI/USD\",\n \"fee\": 0.1\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TradingFeesResponseWS"}}}}},"wss:/api/v2/tradingLimits":{"get":{"tags":["websocket-api"],"summary":"ListOfLimits","description":"Get all system limits","operationId":"websocketmethods_35","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SymbolRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"symbol\": \"EVK\",\n \t\"name\": \"Evonik\",\n \t\"minVolume\": 1.0,\n \t\"maxVolume\": 27000.0,\n \t\t\"minStep\": 1.0,\n \t\"tickSize\": 0.005\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TradingLimitsResponseWS"}}}}},"wss:/api/v2/tradingPositions":{"get":{"tags":["websocket-api"],"summary":"listOfLeverageTrades","description":"Get all open trades within the account.","operationId":"websocketmethods_39","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SignedRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"positions\":[\n {\n \"accountId\":2376109060084932,\n \"id\":\"00a02503-0079-54c4-0000-00004067006b\",\n \"instrumentId\":\"45076691096786116\",\n \"orderId\":\"00a02503-0079-54c4-0000-00004067006a\",\n \"openQuantity\":0.01,\n \"openPrice\":6734.4,\n \"closeQuantity\":0.0,\n \"closePrice\":0,\n \"takeProfit\":7999.15,\n \"stopLoss\":5999.15,\n \"guaranteedStopLoss\":false,\n \"rpl\":0,\n \"rplConverted\":0,\n \"swap\":-0.00335894,\n \"swapConverted\":-0.00335894,\n \"fee\":-0.050508,\n \"dividend\":0,\n \"margin\":0.5,\n \"state\":\"ACTIVE\",\n \"currency\":\"USD\",\n \"createdTimestamp\":1586953061455,\n \"openTimestamp\":1586953061243,\n \"cost\":33.73775,\n \"symbol\":\"BTC/USD_LEVERAGE\"\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionListResponse"}}}}},"wss:/api/v2/tradingPositionsHistory":{"get":{"tags":["websocket-api"],"summary":"listOfHistoricalPositions","description":"Get all closes postions within the account.","operationId":"websocketmethods_36","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/PositionHistoryRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"history\":[\n {\n \"accountId\":19039018800469188,\n \"accountCurrency\":\"USD\",\n \"positionId\":\"00a18509-0079-54c4-0000-00004062007b\",\n \"currency\":\"USD\",\n \"executionType\":\"IOC\",\n \"quantity\":-0.1,\n \"price\":44.95,\n \"source\":\"USER\",\n \"status\":\"CLOSED\",\n \"rpl\":-0.002,\n \"rplConverted\":-0.002,\n \"fee\":0,\n \"createdTimestamp\":1606999328398,\n \"execTimestamp\":1606999315265,\n \"symbol\":\"Oil - Crude.\"\n }\n ]\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionHistoryResponse"}}}}},"wss:/api/v2/transactions":{"get":{"tags":["websocket-api"],"summary":"ListOfTransactions","description":"Get transactions by limit and sinceTime","operationId":"websocketmethods_23","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:/api/v2/updateTradingOrder":{"get":{"tags":["websocket-api"],"summary":"leverageOrdersEdit","description":"Edit current leverage orders by changing take profit and stop loss levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"websocketmethods_29","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/UpdateTradingOrderRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":241986,\n \"state\":\"PROCESSED\"\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingOrderUpdateResponse"}}}}},"wss:/api/v2/updateTradingPosition":{"get":{"tags":["websocket-api"],"summary":"leverageTradeEdit","description":"Edit current leverage trade by changing stop loss and take profit levels. Please note that in case guaranteedStopLoss or trailingStopLoss values are not mentioned in the request then they are set to false automatically.","operationId":"websocketmethods_45","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/UpdateTradingPositionRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"requestId\":242040,\n \"state\":\"PROCESSED\"\n }\n\n}\n","schema":{"$ref":"#/definitions/TradingPositionUpdateResponse"}}}}},"wss:/api/v2/withdrawals":{"get":{"tags":["websocket-api"],"summary":"ListOfWithdrawals","description":"Get withdrawals for user","operationId":"websocketmethods_34","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/TransactionsRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n{\n\n \"status\": \"OK\",\n \"correlationId\": \"2\",\n \"payload\":[\n {\n \"id\": 12225003,\n \"balance\": 19759.5292569,\n \"amount\": -100,\n \"currency\": \"dEUR\",\n \"timestamp\": 1562831860753,\n \"commission\": 4.6,\n \"paymentMethod\": \"MASTERCARD\",\n \"status\": \"DECLINED\"\n }\n ]\n\n}\n","schema":{"$ref":"#/definitions/TransactionsResponse"}}}}},"wss:OHLCMarketData.subscribe":{"get":{"tags":["websocket-api"],"summary":"OHLCMarketData","description":"OHLC market data stream","operationId":"websocketmethods_58","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/OHLCSubscribeRequest"}}],"responses":{"200":{"description":"This subscription produces the following events:\n{\n\n \"status\":\"OK\",\n \"correlationId\":\"2\",\n \"payload\":{\n \"status\":\"OK\",\n \"Destination\":\"ohlc.event\",\n \"Payload\":{\n \"interval\":\"1m\",\n \"symbol\":\"TS\",\n \"T\":1597850100000,\n \"H\":11.89,\n \"L\":11.88,\n \"O\":11.89,\n \"C\":11.89\n }\n }\n\n}","schema":{"$ref":"#/definitions/SubscribeResponse"}}}}},"wss:depthMarketData.subscribe":{"get":{"tags":["websocket-api"],"summary":"DepthMarketData","description":"Depth market data stream","operationId":"websocketmethods_56","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SubscribeRequest"}}],"responses":{"200":{"description":"This subscription produces the following events:\n{\n\n \"status\":\"OK\",\n \"Destination\":\"marketdepth.event\",\n \"Payload\":{\n \"Data\":{\n \"ts\":1597849462575,\n \"Bid\":{\n \"2\":25,\n \"1.94\":25.9\n },\n \"Ofr\":{\n \"3.3\":1,\n \"2.627\":6.1\n }\n },\n \"symbol\":\"Natural Gas\"\n }\n\n}","schema":{"$ref":"#/definitions/SubscribeResponse"}}}}},"wss:marketData.subscribe":{"get":{"tags":["websocket-api"],"summary":"MarketData","description":"Market data stream","operationId":"websocketmethods_57","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SubscribeRequest"}}],"responses":{"200":{"description":"This subscription produces the following events:\n{\n\n \"status\":\"OK\",\n \"Destination\":\"internal.quote\",\n \"Payload\":{\n \"symbolName\":\"TXN\",\n \"bid\":139.85,\n \"bidQty\":2500,\n \"ofr\":139.92000000000002,\n \"ofrQty\":2500,\n \"timestamp\":1597850971558\n }\n\n}","schema":{"$ref":"#/definitions/SubscribeResponse"}}}}},"wss:ping":{"get":{"tags":["websocket-api"],"summary":"ping","description":"Ping pong","operationId":"websocketmethods_60","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/PingRequest"}}],"responses":{"200":{"description":"This stream results in the following response:\n {} \n","schema":{"$ref":"#/definitions/PingResponse"}}}}},"wss:trades.subscribe":{"get":{"tags":["websocket-api"],"summary":"Trades","description":"Trades stream","operationId":"websocketmethods_59","parameters":[{"in":"body","name":"request","description":"query parameter","required":true,"schema":{"$ref":"#/definitions/SubscribeRequest"}}],"responses":{"200":{"description":"This subscription produces the following events:\n{\n\n \"status\":\"OK\",\n \"destination\":\"internal.trade\",\n \"payload\":{\n \"price\":11400.95,\n \"size\":0.058,\n \"id\":1616651347,\n \"ts\":1596625079952,\n \"symbol\":\"BTC/USD\",\n \"orderId\":\"00a02503-0079-54c4-0000-00004020316a\",\n \"clientOrderId\":\"00a02503-0079-54c4-0000-482f00003a06\",\n \"buyer\":true\n }\n\n}","schema":{"$ref":"#/definitions/SubscribeResponse"}}}}}},"definitions":{"AccountBalance":{"type":"object","properties":{"accountId":{"type":"string"},"asset":{"type":"string"},"collateralCurrency":{"type":"boolean"},"default":{"type":"boolean"},"free":{"type":"number"},"locked":{"type":"number"}},"title":"AccountBalance"},"AccountRequest":{"type":"object","required":["apiKey","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"showZeroBalance":{"type":"boolean"},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"AccountRequest"},"AccountResponse":{"type":"object","properties":{"affiliateId":{"type":"string"},"balances":{"type":"array","items":{"$ref":"#/definitions/AccountBalance"}},"buyerCommission":{"type":"number"},"canDeposit":{"type":"boolean"},"canTrade":{"type":"boolean"},"canWithdraw":{"type":"boolean"},"makerCommission":{"type":"number"},"sellerCommission":{"type":"number"},"takerCommission":{"type":"number"},"updateTime":{"type":"integer","format":"int64"},"userId":{"type":"integer","format":"int64"}},"title":"AccountResponse"},"AggTrades":{"type":"object","properties":{"T":{"type":"integer","format":"int64"},"a":{"type":"integer","format":"int64"},"m":{"type":"boolean"},"p":{"type":"string"},"q":{"type":"string"}},"title":"AggTrades"},"AggTradesRequest":{"type":"object","required":["symbol"],"properties":{"endTime":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int32"},"startTime":{"type":"integer","format":"int64"},"symbol":{"type":"string"}},"title":"AggTradesRequest"},"AggTradesResponse":{"type":"object","properties":{"aggTrades":{"type":"array","items":{"$ref":"#/definitions/AggTrades"}}},"title":"AggTradesResponse"},"AllMyTradesRequest":{"type":"object","required":["apiKey","signature","symbol","timestamp"],"properties":{"apiKey":{"type":"string"},"endTime":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int32"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"startTime":{"type":"integer","format":"int64"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"AllMyTradesRequest"},"AllMyTradesResponse":{"type":"object","properties":{"myTrades":{"type":"array","items":{"$ref":"#/definitions/MyTradesResponse"}}},"title":"AllMyTradesResponse"},"BlockchainAddressGetResponse":{"type":"object","properties":{"address":{"type":"string"},"addressLegacy":{"type":"string"},"destinationTag":{"type":"string"}},"title":"BlockchainAddressGetResponse"},"BlockchainAddressRequest":{"type":"object","required":["apiKey","coin","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"coin":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"BlockchainAddressRequest"},"BySymbolRequest":{"type":"object","properties":{"symbol":{"type":"string"}},"title":"BySymbolRequest"},"CancelOrderRequest":{"type":"object","required":["apiKey","orderId","signature","symbol","timestamp"],"properties":{"apiKey":{"type":"string"},"orderId":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"CancelOrderRequest"},"CancelOrderResponse":{"type":"object","properties":{"executedQty":{"type":"string"},"orderId":{"type":"string"},"origQty":{"type":"string"},"price":{"type":"string"},"side":{"type":"string","enum":["BUY","SELL"]},"status":{"type":"string","enum":["CANCELED","EXPIRED","FILLED","NEW","PARTIALLY_FILLED","PENDING_CANCEL","REJECTED"]},"symbol":{"type":"string"},"timeInForce":{"type":"string","enum":["FOK","GTC","IOC"]},"type":{"type":"string","enum":["LIMIT","MARKET","STOP","TRAILING_STOP"]}},"title":"CancelOrderResponse"},"CloseTradingPositionRequest":{"type":"object","required":["apiKey","positionId","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"positionId":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"CloseTradingPositionRequest"},"CreateOrderRequest":{"type":"object","required":["apiKey","quantity","side","signature","symbol","timestamp","type"],"properties":{"accountId":{"type":"integer","format":"int64"},"apiKey":{"type":"string"},"expireTimestamp":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"leverage":{"type":"integer","format":"int32"},"newOrderRespType":{"type":"string"},"price":{"type":"number"},"profitDistance":{"type":"number"},"quantity":{"type":"number"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"side":{"type":"string"},"signature":{"type":"string"},"stopDistance":{"type":"number"},"stopLoss":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"timestamp":{"type":"integer","format":"int64"},"trailingStopLoss":{"type":"boolean"},"type":{"type":"string"}},"title":"CreateOrderRequest"},"CurrencyDtoResponse":{"type":"object","properties":{"commissionFixed":{"type":"number"},"commissionMin":{"type":"number"},"commissionPercent":{"type":"number"},"displaySymbol":{"type":"string"},"maxWithdrawal":{"type":"number"},"minDeposit":{"type":"number"},"minWithdrawal":{"type":"number"},"name":{"type":"string"},"precision":{"type":"integer","format":"int32"},"type":{"type":"string","enum":["CRYPTO","EXCHANGE_TOKEN","FIAT","ICO","TOKEN","TOKENISED_SECURITY","UTILITY_TOKENS"]}},"title":"CurrencyDtoResponse"},"CurrencyResponse":{"type":"object","properties":{"currencies":{"type":"array","items":{"$ref":"#/definitions/CurrencyDtoResponse"}}},"title":"CurrencyResponse"},"DepthRequest":{"type":"object","required":["symbol"],"properties":{"limit":{"type":"integer","format":"int32"},"symbol":{"type":"string"}},"title":"DepthRequest"},"DepthResponse":{"type":"object","properties":{"asks":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"bids":{"type":"array","items":{"type":"array","items":{"type":"number"}}},"lastUpdateId":{"type":"integer","format":"int64"}},"title":"DepthResponse"},"EditExchangeOrderRequest":{"type":"object","required":["apiKey","orderId","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"expireTimestamp":{"type":"integer","format":"int64"},"orderId":{"type":"string"},"price":{"type":"number"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"EditExchangeOrderRequest"},"EditExchangeOrderResponse":{"type":"object","properties":{"orderId":{"type":"string","format":"uuid"}},"title":"EditExchangeOrderResponse"},"EmptyRequest":{"type":"object","title":"EmptyRequest"},"ExchangeFilter":{"type":"object","title":"ExchangeFilter"},"ExchangeInfo":{"type":"object","properties":{"exchangeFilters":{"type":"array","items":{"$ref":"#/definitions/ExchangeFilter"}},"rateLimits":{"type":"array","items":{"$ref":"#/definitions/RateLimits"}},"serverTime":{"type":"integer","format":"int64"},"symbols":{"type":"array","items":{"$ref":"#/definitions/ExchangeSymbolInfo"}},"timezone":{"type":"string"}},"title":"ExchangeInfo"},"ExchangeSymbolInfo":{"type":"object","properties":{"assetType":{"type":"string","enum":["BOND","COMMODITY","CREDIT","CRYPTOCURRENCY","CURRENCY","EQUITY","ICO","INDEX","INTEREST_RATE","OPT_TOKENS","OTHER_ASSET","REAL_ESTATE","UTILITY_TOKENS"]},"baseAsset":{"type":"string"},"baseAssetPrecision":{"type":"integer","format":"int32"},"country":{"type":"string"},"exchangeFee":{"type":"number"},"filters":{"type":"array","items":{"$ref":"#/definitions/SymbolFilter"}},"industry":{"type":"string"},"longRate":{"type":"number","format":"double"},"makerFee":{"type":"number"},"marketModes":{"type":"array","items":{"type":"string","enum":["CLOSED_FOR_CORPORATE_ACTION","CLOSE_ONLY","DELISTING","HOLIDAY","LONG_ONLY","REGULAR","UNKNOWN","VIEW_AND_REQUEST","VIEW_ONLY"]}},"marketType":{"type":"string","enum":["LEVERAGE","SPOT"]},"maxSLGap":{"type":"number"},"maxTPGap":{"type":"number"},"minSLGap":{"type":"number"},"minTPGap":{"type":"number"},"name":{"type":"string"},"orderTypes":{"type":"array","items":{"type":"string","enum":["LIMIT","MARKET","STOP","TRAILING_STOP"]}},"quoteAsset":{"type":"string"},"quoteAssetId":{"type":"string"},"quotePrecision":{"type":"integer","format":"int32"},"sector":{"type":"string"},"shortRate":{"type":"number","format":"double"},"status":{"type":"string","enum":["AUCTION_MATCH","BREAK","END_OF_DAY","HALT","POST_TRADING","PRE_TRADING","TRADING"]},"swapChargeInterval":{"type":"integer","format":"int64"},"symbol":{"type":"string"},"takerFee":{"type":"number"},"tickSize":{"type":"number"},"tickValue":{"type":"number"},"tradingFee":{"type":"number"},"tradingHours":{"type":"string"}},"title":"ExchangeSymbolInfo"},"FundingLimitsDtoResponse":{"type":"object","properties":{"accountCurrency":{"type":"string"},"minWithdrawal":{"type":"string"},"paymentOption":{"type":"string"}},"title":"FundingLimitsDtoResponse"},"FundingLimitsDtoResponseWS":{"type":"object","properties":{"fundingLimits":{"type":"array","items":{"$ref":"#/definitions/FundingLimitsDtoResponse"}}},"title":"FundingLimitsDtoResponseWS"},"GetOrderDtoResponseReq":{"type":"object","properties":{"accountId":{"type":"integer","format":"int64"},"execPrice":{"type":"number"},"execQuantity":{"type":"number"},"expireTime":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"margin":{"type":"number","format":"double"},"orderId":{"type":"string"},"price":{"type":"number"},"quantity":{"type":"number"},"rejectReason":{"type":"string"},"side":{"type":"string"},"status":{"type":"string"},"stopLoss":{"type":"number"},"symbol":{"type":"string"},"symbolAndReturn":{"type":"string"},"takeProfit":{"type":"number"},"timeInForceType":{"type":"string"},"timestamp":{"type":"integer","format":"int64"},"trailingStopLoss":{"type":"boolean"},"type":{"type":"string"}},"title":"GetOrderDtoResponseReq"},"GetOrderDtoResponseRes":{"type":"object","properties":{"accountId":{"type":"integer","format":"int64"},"execPrice":{"type":"number"},"execQuantity":{"type":"number"},"expireTime":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"margin":{"type":"number","format":"double"},"orderId":{"type":"string"},"price":{"type":"number"},"quantity":{"type":"number"},"rejectReason":{"type":"string"},"side":{"type":"string"},"status":{"type":"string"},"stopLoss":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"timeInForceType":{"type":"string"},"timestamp":{"type":"integer","format":"int64"},"trailingStopLoss":{"type":"boolean"},"type":{"type":"string"}},"title":"GetOrderDtoResponseRes"},"GetOrderRequest":{"type":"object","required":["apiKey","orderId","signature","symbol","timestamp"],"properties":{"apiKey":{"type":"string"},"orderId":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"GetOrderRequest"},"InternalQuote":{"type":"object","properties":{"bid":{"type":"number","format":"double"},"bidQty":{"type":"number","format":"double"},"ofr":{"type":"number","format":"double"},"ofrQty":{"type":"number","format":"double"},"symbolName":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"InternalQuote"},"KLinesRequest":{"type":"object","required":["interval","symbol"],"properties":{"endTime":{"type":"integer","format":"int64"},"interval":{"type":"string"},"limit":{"type":"integer","format":"int32"},"priceType":{"type":"string"},"startTime":{"type":"integer","format":"int64"},"symbol":{"type":"string"},"type":{"type":"string"}},"title":"KLinesRequest"},"KLinesResponse":{"type":"object","properties":{"lines":{"type":"array","items":{"type":"array","items":{"type":"object"}}}},"title":"KLinesResponse"},"LeverageSettingsRequest":{"type":"object","required":["apiKey","signature","symbol","timestamp"],"properties":{"apiKey":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"LeverageSettingsRequest"},"LeverageSettingsResponse":{"type":"object","properties":{"value":{"type":"integer","format":"int32"},"values":{"type":"array","items":{"type":"integer","format":"int32"}}},"title":"LeverageSettingsResponse"},"MarketDepthData":{"type":"object","properties":{"bid":{"type":"object","additionalProperties":{"type":"number"}},"ofr":{"type":"object","additionalProperties":{"type":"number"}},"ts":{"type":"integer","format":"int64"}},"title":"MarketDepthData"},"MarketDepthEvent":{"type":"object","properties":{"data":{"$ref":"#/definitions/MarketDepthData"},"symbol":{"type":"string"}},"title":"MarketDepthEvent"},"MyTradesResponse":{"type":"object","properties":{"buyer":{"type":"boolean"},"commission":{"type":"string"},"commissionAsset":{"type":"string"},"id":{"type":"string"},"isBuyer":{"type":"boolean"},"isMaker":{"type":"boolean"},"maker":{"type":"boolean"},"orderId":{"type":"string"},"price":{"type":"string"},"qty":{"type":"string"},"quoteQty":{"type":"string"},"symbol":{"type":"string"},"time":{"type":"integer","format":"int64"}},"title":"MyTradesResponse"},"NewOrderResponseRESULT":{"type":"object","properties":{"executedQty":{"type":"string"},"expireTimestamp":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"margin":{"type":"number"},"orderId":{"type":"string"},"origQty":{"type":"string"},"price":{"type":"string"},"profitDistance":{"type":"number"},"rejectMessage":{"type":"string"},"side":{"type":"string","enum":["BUY","SELL"]},"status":{"type":"string","enum":["CANCELED","EXPIRED","FILLED","NEW","PARTIALLY_FILLED","PENDING_CANCEL","REJECTED"]},"stopDistance":{"type":"number"},"stopLoss":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"timeInForce":{"type":"string","enum":["FOK","GTC","IOC"]},"trailingStopLoss":{"type":"boolean"},"transactTime":{"type":"integer","format":"int64"},"type":{"type":"string","enum":["LIMIT","MARKET","STOP","TRAILING_STOP"]}},"title":"NewOrderResponseRESULT"},"OHLCBar":{"type":"object","properties":{"c":{"type":"number","format":"double"},"h":{"type":"number","format":"double"},"interval":{"type":"string"},"l":{"type":"number","format":"double"},"o":{"type":"number","format":"double"},"symbol":{"type":"string"},"t":{"type":"integer","format":"int64"},"type":{"type":"string"}},"title":"OHLCBar"},"OHLCSubscribeRequest":{"type":"object","properties":{"intervals":{"type":"array","description":"Identifies intervals for subscription. Available: 1m, 5m, 15m, 30m, 1h, 4h, 1d, 1w. Default: 1m.","items":{"type":"string"}},"symbols":{"type":"array","description":"Identifies symbols for subscription.","items":{"type":"string"}},"type":{"type":"string","description":"Type of candlestick. Available: classic, heikin-ashi."}},"title":"OHLCSubscribeRequest","description":"Class representing an OHLC market data subscription."},"OpenOrdersReponse":{"type":"object","properties":{"openOrders":{"type":"array","items":{"$ref":"#/definitions/QueryOrderResponse"}}},"title":"OpenOrdersReponse"},"OptionalAuthRequest":{"type":"object","properties":{"apiKey":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"OptionalAuthRequest"},"OvernightRate":{"type":"object","properties":{"longRate":{"type":"number","format":"double"},"shortRate":{"type":"number","format":"double"}},"title":"OvernightRate"},"PingRequest":{"type":"object","title":"PingRequest"},"PingResponse":{"type":"object","title":"PingResponse"},"PositionDto":{"type":"object","required":["accountId","closePrice","closeQuantity","createdTimestamp","currency","id","instrumentId","margin","openPrice","openQuantity","openTimestamp","orderId","state"],"properties":{"accountId":{"type":"string"},"closePrice":{"type":"number"},"closeQuantity":{"type":"number"},"closeTimestamp":{"type":"integer","format":"int64"},"cost":{"type":"number"},"createdTimestamp":{"type":"integer","format":"int64"},"currency":{"type":"string"},"currentTrailingPrice":{"type":"number"},"currentTrailingPriceUpdatedTimestamp":{"type":"integer","format":"int64"},"dividend":{"type":"number"},"fee":{"type":"number"},"guaranteedStopLoss":{"type":"boolean"},"id":{"type":"string","format":"uuid"},"instrumentId":{"type":"integer","format":"int64"},"margin":{"type":"number"},"openPrice":{"type":"number"},"openQuantity":{"type":"number"},"openTimestamp":{"type":"integer","format":"int64"},"orderId":{"type":"string","format":"uuid"},"rpl":{"type":"number"},"rplConverted":{"type":"number"},"state":{"type":"string","enum":["ACTIVE","INACTIVE","INVALID"]},"stopLoss":{"type":"number"},"swap":{"type":"number"},"swapConverted":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"trailingQuotedPrice":{"type":"number"},"trailingStopLoss":{"type":"boolean"},"type":{"type":"string","enum":["HEDGE","NET"]},"upl":{"type":"number"},"uplConverted":{"type":"number"}},"title":"PositionDto"},"PositionExecutionReportDto":{"type":"object","required":["accountCurrency","accountId","createdTimestamp","currency","execId","execTimestamp","instrumentId","positionId","source","status"],"properties":{"accountCurrency":{"type":"string"},"accountId":{"type":"integer","format":"int64"},"createdTimestamp":{"type":"integer","format":"int64"},"currency":{"type":"string"},"execId":{"type":"string"},"execTimestamp":{"type":"integer","format":"int64"},"executionType":{"type":"string","enum":["GTC","IOC"]},"fee":{"type":"number"},"feeDetails":{"type":"object","additionalProperties":{"type":"number"}},"fxRate":{"type":"number"},"gSL":{"type":"boolean"},"instrumentId":{"type":"integer","format":"int64"},"positionId":{"type":"string"},"price":{"type":"number"},"quantity":{"type":"number"},"rejectReason":{"type":"string","enum":["ACCOUNT_NOT_FOUND","CLOSED_MARKET","CLOSE_ONLY","ENGINE_BUSY","HEDGING_MODE_GSL","INSTRUMENT_NOT_AVAILABLE","INSTRUMENT_NOT_FOUND","INVALID_ORDER","INVALID_ORDER_QTY","INVALID_PRICE","LONG_ONLY","OFF_MARKET","ORDER_NOT_FOUND","ORIGINAL_GSL_UPDATE","POSITION_NOT_FOUND","RC_INSTRUMENT_CLIENT_MOP","RC_INSTRUMENT_GLOBAL_MOP","RC_NOT_ENOUGH_MARGIN","RC_NOT_FOUND","RC_NO_RATES","RC_SETTLEMENT","RC_UNKNOWN","REQUIRED_GSL","RISK_CHECK","THROTTLING","UNKNOWN"]},"rpl":{"type":"number"},"rplConverted":{"type":"number"},"source":{"type":"string","enum":["CLOSE_OUT","DEALER","SL","SYSTEM","TP","USER"]},"status":{"type":"string","enum":["CLOSED","DIVIDEND","MODIFIED","MODIFY_REJECT","OPENED","SWAP"]},"stopLoss":{"type":"number"},"swap":{"type":"number"},"swapConverted":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"trailingStopLoss":{"type":"boolean"}},"title":"PositionExecutionReportDto"},"PositionHistoryRequest":{"type":"object","required":["apiKey","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"from":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int32"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"},"to":{"type":"integer","format":"int64"}},"title":"PositionHistoryRequest"},"QueryOrderResponse":{"type":"object","properties":{"accountId":{"type":"string"},"executedQty":{"type":"string"},"expireTimestamp":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"icebergQty":{"type":"string"},"leverage":{"type":"boolean"},"margin":{"type":"number"},"orderId":{"type":"string"},"origQty":{"type":"string"},"price":{"type":"string"},"side":{"type":"string","enum":["BUY","SELL"]},"status":{"type":"string","enum":["CANCELED","EXPIRED","FILLED","NEW","PARTIALLY_FILLED","PENDING_CANCEL","REJECTED"]},"stopLoss":{"type":"number"},"symbol":{"type":"string"},"takeProfit":{"type":"number"},"time":{"type":"integer","format":"int64"},"timeInForce":{"type":"string","enum":["FOK","GTC","IOC"]},"trailingStopLoss":{"type":"boolean"},"type":{"type":"string","enum":["LIMIT","MARKET","STOP","TRAILING_STOP"]},"updateTime":{"type":"integer","format":"int64"},"working":{"type":"boolean"}},"title":"QueryOrderResponse"},"RateLimits":{"type":"object","properties":{"interval":{"type":"string"},"intervalNum":{"type":"integer","format":"int32"},"limit":{"type":"integer","format":"int32"},"rateLimitType":{"type":"string"}},"title":"RateLimits"},"RequestDto":{"type":"object","required":["accountId","createdTimestamp","id","rqType","state"],"properties":{"accountId":{"type":"string"},"createdTimestamp":{"type":"integer","format":"int64"},"id":{"type":"integer","format":"int64"},"orderId":{"type":"string"},"positionId":{"type":"string"},"rejectReason":{"type":"string","enum":["ACCOUNT_NOT_FOUND","CLOSED_MARKET","CLOSE_ONLY","ENGINE_BUSY","HEDGING_MODE_GSL","INSTRUMENT_NOT_AVAILABLE","INSTRUMENT_NOT_FOUND","INVALID_ORDER","INVALID_ORDER_QTY","INVALID_PRICE","LONG_ONLY","OFF_MARKET","ORDER_NOT_FOUND","ORIGINAL_GSL_UPDATE","POSITION_NOT_FOUND","RC_INSTRUMENT_CLIENT_MOP","RC_INSTRUMENT_GLOBAL_MOP","RC_NOT_ENOUGH_MARGIN","RC_NOT_FOUND","RC_NO_RATES","RC_SETTLEMENT","RC_UNKNOWN","REQUIRED_GSL","RISK_CHECK","THROTTLING","UNKNOWN"]},"rqType":{"type":"string","enum":["ORDER_CANCEL","ORDER_MODIFY","ORDER_NEW","POSITION_MODIFY"]},"state":{"type":"string","enum":["CANCELLED","PENDING","PROCESSED"]}},"title":"RequestDto"},"ServerTime":{"type":"object","properties":{"serverTime":{"type":"integer","format":"int64"}},"title":"ServerTime"},"SignedBySymbolRequest":{"type":"object","required":["apiKey","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"symbol":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"SignedBySymbolRequest"},"SignedRequest":{"type":"object","required":["apiKey","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"timestamp":{"type":"integer","format":"int64"}},"title":"SignedRequest"},"SubscribeRequest":{"type":"object","properties":{"symbols":{"type":"array","description":"Identifies symbols for subscription.","items":{"type":"string"}}},"title":"SubscribeRequest","description":"Class representing an subscription."},"SubscribeResponse":{"type":"object","properties":{"errorCode":{"type":"string"},"subscriptions":{"type":"object","additionalProperties":{"type":"string"}}},"title":"SubscribeResponse"},"SymbolFilter":{"type":"object","properties":{"filterType":{"type":"string"}},"title":"SymbolFilter"},"SymbolRequest":{"type":"object","properties":{"symbol":{"type":"string"}},"title":"SymbolRequest"},"Ticker24HResponse":{"type":"object","properties":{"tickers":{"type":"array","items":{"$ref":"#/definitions/Ticker24hr"}}},"title":"Ticker24HResponse"},"Ticker24hr":{"type":"object","properties":{"askPrice":{"type":"string"},"bidPrice":{"type":"string"},"closeTime":{"type":"integer","format":"int64"},"highPrice":{"type":"string"},"lastPrice":{"type":"string"},"lastQty":{"type":"string"},"lowPrice":{"type":"string"},"openPrice":{"type":"string"},"openTime":{"type":"integer","format":"int64"},"prevClosePrice":{"type":"string"},"priceChange":{"type":"string"},"priceChangePercent":{"type":"string"},"quoteVolume":{"type":"string"},"symbol":{"type":"string"},"volume":{"type":"string"},"weightedAvgPrice":{"type":"string"}},"title":"Ticker24hr"},"TradeEventReq":{"type":"object","properties":{"id":{"type":"integer","format":"int32"},"orderId":{"type":"string"},"price":{"type":"number","format":"double"},"size":{"type":"number","format":"double"},"symbol":{"type":"string"},"ts":{"type":"integer","format":"int64"}},"title":"TradeEventReq"},"TradeEventRes":{"type":"object","properties":{"buyer":{"type":"boolean"},"id":{"type":"integer","format":"int32"},"orderId":{"type":"string"},"price":{"type":"number","format":"double"},"size":{"type":"number","format":"double"},"symbol":{"type":"string"},"ts":{"type":"integer","format":"int64"}},"title":"TradeEventRes"},"TradingFeesResponse":{"type":"object","properties":{"fee":{"type":"number","format":"double"},"name":{"type":"string"},"overnightFeeTimestamp":{"type":"integer","format":"int64"},"overnightRates":{"$ref":"#/definitions/OvernightRate"},"symbol":{"type":"string"}},"title":"TradingFeesResponse"},"TradingFeesResponseWS":{"type":"object","properties":{"fees":{"type":"array","items":{"$ref":"#/definitions/TradingFeesResponse"}}},"title":"TradingFeesResponseWS"},"TradingLimitsResponse":{"type":"object","properties":{"lastPrice":{"type":"number"},"maxVolume":{"type":"number","format":"double"},"minStep":{"type":"number","format":"double"},"minVolume":{"type":"number","format":"double"},"name":{"type":"string"},"symbol":{"type":"string"},"tickSize":{"type":"number","format":"double"}},"title":"TradingLimitsResponse"},"TradingLimitsResponseWS":{"type":"object","properties":{"limits":{"type":"array","items":{"$ref":"#/definitions/TradingLimitsResponse"}}},"title":"TradingLimitsResponseWS"},"TradingOrderUpdateResponse":{"type":"object","required":["requestId","state"],"properties":{"requestId":{"type":"integer","format":"int64"},"state":{"type":"string","enum":["CANCELLED","PENDING","PROCESSED"]}},"title":"TradingOrderUpdateResponse"},"TradingPositionCloseAllResponse":{"type":"object","properties":{"request":{"type":"array","items":{"$ref":"#/definitions/RequestDto"}}},"title":"TradingPositionCloseAllResponse"},"TradingPositionHistoryResponse":{"type":"object","properties":{"history":{"type":"array","items":{"$ref":"#/definitions/PositionExecutionReportDto"}}},"title":"TradingPositionHistoryResponse"},"TradingPositionListResponse":{"type":"object","properties":{"positions":{"type":"array","items":{"$ref":"#/definitions/PositionDto"}}},"title":"TradingPositionListResponse"},"TradingPositionUpdateResponse":{"type":"object","required":["requestId","state"],"properties":{"requestId":{"type":"integer","format":"int64"},"state":{"type":"string","enum":["CANCELLED","PENDING","PROCESSED"]}},"title":"TradingPositionUpdateResponse"},"TransactionDTOResponse":{"type":"object","properties":{"amount":{"type":"number"},"balance":{"type":"number"},"blockchainTransactionHash":{"type":"string"},"commission":{"type":"number"},"currency":{"type":"string"},"id":{"type":"integer","format":"int64"},"paymentMethod":{"type":"string"},"status":{"type":"string"},"timestamp":{"type":"integer","format":"int64"},"type":{"type":"string"}},"title":"TransactionDTOResponse"},"TransactionsRequest":{"type":"object","required":["apiKey","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"endTime":{"type":"integer","format":"int64"},"limit":{"type":"integer","format":"int32"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"startTime":{"type":"integer","format":"int64"},"timestamp":{"type":"integer","format":"int64"}},"title":"TransactionsRequest"},"TransactionsResponse":{"type":"object","properties":{"transactions":{"type":"array","items":{"$ref":"#/definitions/TransactionDTOResponse"}}},"title":"TransactionsResponse"},"UpdateTradingOrderRequest":{"type":"object","required":["apiKey","orderId","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"expireTimestamp":{"type":"integer","format":"int64"},"guaranteedStopLoss":{"type":"boolean"},"newPrice":{"type":"number"},"orderId":{"type":"string"},"profitDistance":{"type":"number"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"stopDistance":{"type":"number"},"stopLoss":{"type":"number"},"takeProfit":{"type":"number"},"timestamp":{"type":"integer","format":"int64"},"trailingStopLoss":{"type":"boolean"}},"title":"UpdateTradingOrderRequest"},"UpdateTradingPositionRequest":{"type":"object","required":["apiKey","positionId","signature","timestamp"],"properties":{"apiKey":{"type":"string"},"guaranteedStopLoss":{"type":"boolean"},"positionId":{"type":"string"},"profitDistance":{"type":"number"},"recvWindow":{"type":"integer","format":"int64","maximum":60000,"exclusiveMaximum":false},"signature":{"type":"string"},"stopDistance":{"type":"number"},"stopLoss":{"type":"number"},"takeProfit":{"type":"number"},"timestamp":{"type":"integer","format":"int64"},"trailingStopLoss":{"type":"boolean"}},"title":"UpdateTradingPositionRequest"}}} -docs/market_intelligence/builds/build-015-3-common-models-engine-registration.md:116:enabled_by_default -docs/market_intelligence/builds/build-006-1-common-models-engine-metadata.md:119: enabled_by_default: bool = True -docs/market_intelligence/builds/build-006-1-common-models-engine-metadata.md:174:### enabled_by_default -((.venv) ) segeba@mbpbsg dzentra_bot % \ No newline at end of file