commit 2a820866832312dfc22ac36e8a1e44ef83762541 Author: nicolas Date: Sun May 24 16:12:04 2026 -0300 Add initial triangular arbitrage bot Two-process architecture: a C17 fused engine (WebSocket order book mirror, triangle enumeration, real-time profitability evaluation) communicating via Unix domain socket to a Python 3 executor (order placement with paper/live trading modes, REST control API). Targets KuCoin spot market. diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..365db96 --- /dev/null +++ b/.gitignore @@ -0,0 +1,14 @@ +.venv/ +config.yaml +__pycache__/ +*.pyc +*.pyo +.pytest_cache/ +.mypy_cache/ +.ruff_cache/ +*.so +.DS_Store +deploy.sh +deploy_amzn.sh +build/ +triangular_arb.egg-info/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..a77e0df --- /dev/null +++ b/README.md @@ -0,0 +1,109 @@ +# Triangular Arbitrage Bot + +Real-time triangular arbitrage detection and execution for centralized crypto exchanges. Currently supports **KuCoin**. + +## Architecture + +Two-process design communicating via Unix domain sockets: + +| Process | Role | +|---|---| +| `fused_engine` | C binary combining Feed Handler, Order Book, and Opportunity Engine. KuCoin WebSocket subscriber, order book mirror, triangle enumeration, live opportunity evaluation. Emits signals to executor. | +| `executor` | Consumes signals from `fused_engine`, places 3-leg KuCoin REST orders. Fire-and-forget: no re-evaluation, no queue, drop if busy. | + +``` +[KuCoin WS] ──▶ [fused_engine] ──────────────────── Unix socket ──▶ [executor] + │ + Triangle Evaluator +``` + +`fused_engine` evaluates triangles on live book updates and emits signals to the executor. The executor does **not** re-evaluate books — it trusts the signal as valid at emission time and places orders directly via KuCoin REST API. + +## Status + +| Component | Status | +|---|---| +| `fused_engine` | Complete — WebSocket subscription, order book mirror, triangle enumeration, top-level profitability evaluation with chained `max_volume`, signal dispatch via Unix socket | +| `executor` | Complete — Signal consumption via Unix socket, paper-mode order validation via `/api/v1/hf/orders/test`, deterministic fill simulation, REST control API | + +## Prerequisites + +- C compiler (gcc/clang), CMake 3.22+, OpenSSL, libyaml, pthread +- Python 3.11+ (for executor only) + +## Building fused_engine + +```bash +mkdir -p build && cd build +cmake ../src -DCMAKE_BUILD_TYPE=Release +make -j$(nproc) +``` + +Binary at `build/fused_engine`. + +## Configuration + +Edit `config.yaml`: + +- `hold_currencies` — currencies held as capital. Only triangles starting and ending in one of these are evaluated (default: `["USDT", "USDC", "USD1"]`) +- `excluded_currencies` — currencies to exclude from triangle enumeration +- `signal_threshold_bps` — minimum net profit in basis points to fire a signal (default: `0.2`) +- `cooldown_ms` — minimum milliseconds between opportunity notifications for the same triangle (default: `1000`) +- `api.key` / `api.secret` / `api.passphrase` — KuCoin API credentials + +## Running + +**Startup order:** `executor` → `fused_engine` + +### 1. Start the executor + +```bash +source .venv/bin/activate +python3 -m executor +``` + +Creates the Unix socket at `/tmp/executor.sock` and listens for signals. + +### 2. Start fused_engine + +```bash +./build/fused_engine +``` + +Fetches all KuCoin pairs, enumerates triangles, subscribes to WebSocket order books, evaluates triangles on every book update, and dispatches signals to the executor via Unix socket. + +## Project Structure + +``` +tri_arb/ +├── src/ # C source for fused_engine +│ ├── main.c # Entry point +│ ├── ws_client.c/h # KuCoin WebSocket client (TLS, masked frames) +│ ├── book.c/h # Order book store +│ ├── symbols_api.c/h # Symbol discovery, triangle enumeration +│ ├── triangle.c/h # Triangle set management +│ ├── evaluate.c/h # Triangle evaluation & signal construction +│ ├── events.c/h # Event loop, Unix socket client to executor +│ ├── queue.c/h # SPSC lock-free queue (hot → cold thread) +│ ├── config.c/h # YAML config parser +│ ├── http_client.c/h # KuCoin REST API client (HMAC signing) +│ ├── hash.c/h # Hash table +│ ├── cJSON.c/h # JSON parser +│ ├── jsmn.h # Minimal JSON tokenizer (header-only, unused) +│ └── CMakeLists.txt +├── executor/ # Triangular Arbitrage Executor (Python) +│ ├── __main__.py +│ ├── executor.py +│ ├── kucoin_api.py +│ ├── rest_api.py +│ ├── socket_server.py +│ └── config.py +├── common/ # Shared Python utilities +│ ├── config.py +│ └── log.py +├── build/ # Build output (not committed) +├── scripts/ +│ └── install.sh +├── config.yaml +└── config.yaml.example +``` diff --git a/common/__init__.py b/common/__init__.py new file mode 100644 index 0000000..64c70fe --- /dev/null +++ b/common/__init__.py @@ -0,0 +1,6 @@ +"""Common utilities for triangular arbitrage bot.""" + +from common.config import Settings +from common.log import configure_logging + +__all__ = ["Settings", "configure_logging"] \ No newline at end of file diff --git a/common/config.py b/common/config.py new file mode 100644 index 0000000..7b36eb1 --- /dev/null +++ b/common/config.py @@ -0,0 +1,65 @@ +import asyncio +from pathlib import Path +from typing import Optional + +import yaml +from pydantic import BaseModel, Field +from pydantic_settings import BaseSettings + + +class FHobSettings(BaseModel): + symbols: list[str] = Field( + default_factory=list, + description="Trading pairs to subscribe to. Empty = no subscriptions. oe_em adds pairs via REST.", + ) + log_level: str = Field(default="INFO", description="Logging level") + log_file: Path = Field( + default=Path("/tmp/fh_ob.log"), + description="Path to log file. Logs are written here in addition to stdout.", + ) + socket_path: Path = Field( + default=Path("/tmp/fh_ob.sock"), + description="Unix domain socket path for OE+EM", + ) + rest_host: str = Field(default="0.0.0.0", description="FastAPI debug host") + rest_port: int = Field(default=8000, description="FastAPI debug port") + ws_url: str = Field( + default="wss://ws-api-spot.kucoin.com", + description="KuCoin WebSocket endpoint", + ) + token_url: str = Field( + default="https://api.kucoin.com/api/v1/bullet-public", + description="KuCoin public token endpoint", + ) + reconnect_base_delay: float = Field( + default=1.0, + description="Base delay for reconnect exponential backoff (seconds)", + ) + reconnect_max_delay: float = Field( + default=60.0, + description="Max delay for reconnect exponential backoff (seconds)", + ) + heartbeat_interval: float = Field( + default=18.0, + description="WS ping interval (seconds) - KuCoin uses 18s", + ) + + +class Settings(BaseSettings): + fh_ob: FHobSettings = Field(default_factory=FHobSettings) + + @classmethod + async def from_yaml(cls, path: Path) -> "Settings": + loop = asyncio.get_running_loop() + + def _read() -> dict: + with open(path) as f: + return yaml.safe_load(f) or {} + + data = await loop.run_in_executor(None, _read) + fh_ob_data = data.get("fh_ob", {}) + if fh_ob_data.get("symbols") is None: + fh_ob_data["symbols"] = [] + return cls(**data) + + model_config = {"env_prefix": "TRIARB_", "extra": "ignore"} \ No newline at end of file diff --git a/common/log.py b/common/log.py new file mode 100644 index 0000000..d853f04 --- /dev/null +++ b/common/log.py @@ -0,0 +1,133 @@ +""" +Shared logging configuration for all components. + +Provides configure_logging() which sets up structlog with JSON output to stdout +and an optional plain-text file handler. All components (fh_ob, oe_em, executor) +call this at startup before any other logging. +""" +import asyncio +import logging +import sys +from pathlib import Path +from typing import Optional + +import structlog + + +class _AsyncFileHandler(logging.Handler): + """Non-blocking file handler that queues log records for async writing.""" + + def __init__(self, filepath: Path) -> None: + super().__init__() + self._filepath = filepath + self._queue: Optional[asyncio.Queue] = None + self._task: Optional[asyncio.Task] = None + + def _ensure_loop(self) -> None: + if self._queue is None: + self._queue = asyncio.Queue(maxsize=4096) + loop = asyncio.get_running_loop() + self._task = loop.create_task(self._writer_loop()) + + async def _writer_loop(self) -> None: + loop = asyncio.get_running_loop() + log_file = self._filepath + + def _write(msg: str) -> None: + with open(log_file, "a") as f: + f.write(msg + "\n") + + while True: + record = await self._queue.get() + try: + msg = self.format(record) + await loop.run_in_executor(None, _write, msg) + except Exception: + pass + self._queue.task_done() + + def emit(self, record: logging.LogRecord) -> None: + self._ensure_loop() + try: + self._queue.put_nowait(record) + except asyncio.QueueFull: + pass + + def close(self) -> None: + """Override stdlib Handler.close() — no-op, use async _flush() instead.""" + pass + + def flush(self) -> None: + """Override stdlib Handler.flush() — no-op, queue is non-blocking.""" + pass + + async def _flush(self) -> None: + """Wait for all queued records to be written.""" + if self._queue: + await self._queue.join() + + +_async_file_handler: Optional[_AsyncFileHandler] = None + + +def configure_logging(level: str = "INFO", log_file: Path | None = None) -> None: + """ + Configure structlog with JSON output to stdout and optional file handler. + + Uses stdlib logging as the backend so that standard-library integrations + (e.g. uvicorn, aiohttp) produce structured JSON too. + + Parameters + ---------- + level : str + Log level string (DEBUG, INFO, WARNING, ERROR). + log_file : Path or None + If set, a FileHandler is added to the root logger writing the + same JSON lines to disk. + """ + global _async_file_handler + + logging.basicConfig( + level=getattr(logging, level.upper()), + format="%(message)s", + handlers=[], + ) + + root_logger = logging.getLogger() + root_logger.setLevel(getattr(logging, level.upper())) + root_logger.handlers.clear() + + console_handler = logging.StreamHandler(sys.stdout) + console_handler.setFormatter(logging.Formatter("%(message)s")) + console_handler.setLevel(getattr(logging, level.upper())) + root_logger.addHandler(console_handler) + + structlog.configure( + wrapper_class=structlog.make_filtering_bound_logger( + getattr(logging, level.upper()) + ), + context_class=dict, + logger_factory=structlog.stdlib.LoggerFactory(), + cache_logger_on_first_use=True, + processors=[ + structlog.stdlib.add_log_level, + structlog.processors.TimeStamper(fmt="iso"), + structlog.processors.JSONRenderer(), + ], + ) + + if log_file: + _async_file_handler = _AsyncFileHandler(log_file) + _async_file_handler.setFormatter(logging.Formatter("%(message)s")) + _async_file_handler.setLevel(getattr(logging, level.upper())) + root_logger.addHandler(_async_file_handler) + + root_logger.propagate = False + + +async def close_logging() -> None: + """Flush and close the async file handler.""" + global _async_file_handler + if _async_file_handler: + await _async_file_handler._flush() + _async_file_handler = None diff --git a/compare_enum.py b/compare_enum.py new file mode 100644 index 0000000..ab62133 --- /dev/null +++ b/compare_enum.py @@ -0,0 +1,85 @@ +"""Compare Python triangle enumeration with C output.""" +import json, sys + +pairs = [] +with open("/tmp/pairs.jsonl") as f: + for line in f: + d = json.loads(line) + if d.get("enableTrading") is not True: + continue + base = d.get("base", "") + quote = d.get("quote", "") + sym = d.get("symbol", "") + if not all([sym, base, quote]): + continue + pairs.append({"symbol": sym, "base": base, "quote": quote}) + +# Filter excluded +excluded = {"EUR", "BRL"} +pairs = [p for p in pairs if p["base"] not in excluded and p["quote"] not in excluded] +print(f"Total pairs after filter: {len(pairs)}", file=sys.stderr) + +# Check duplicates +from collections import Counter +dup_counts = Counter() +for p in pairs: + key = frozenset([p["base"], p["quote"]]) + dup_counts[key] += 1 +dup_multi = {k: v for k, v in dup_counts.items() if v > 1} +print(f"Duplicate currency pairs: {len(dup_multi)}", file=sys.stderr) +for k, v in dup_multi.items(): + bases = list(k) + my_pairs = [p for p in pairs if frozenset([p["base"], p["quote"]]) == k] + print(f" {v}x: {bases} -> {[(p['symbol'], p['base'], p['quote'], p.get('feeCurrency','')) for p in my_pairs]}", file=sys.stderr) + +# Build edge_map and pair_map (Python style) +edge_map = {} +for p in pairs: + for c in [p["base"], p["quote"]]: + if c not in edge_map: + edge_map[c] = [] + edge_map[c].append(frozenset([p["base"], p["quote"]])) + +pair_map = {} +for p in pairs: + pair_map[frozenset([p["base"], p["quote"]])] = p + +hold_set = {"USDT", "USDC", "USD1"} +all_currencies = sorted(edge_map.keys()) +seen = set() +tri_count = 0 +unique_sets = [] + +for c1 in all_currencies: + for c2_edge in edge_map.get(c1, []): + c2 = next(x for x in c2_edge if x != c1) + for c3_edge in edge_map.get(c2, []): + c3 = next(x for x in c3_edge if x != c2) + if c3 == c1: + continue + if c3_edge == c2_edge: + continue + if frozenset([c1, c3]) not in pair_map: + continue + currencies = frozenset([c1, c2, c3]) + if currencies in seen: + continue + seen.add(currencies) + + in_triangle = hold_set & currencies + if not in_triangle: + continue + + unique_sets.append(tuple(sorted(currencies))) + + for hold_curr in in_triangle: + others = [c for c in [c1, c2, c3] if c != hold_curr] + for x, y in [(others[0], others[1]), (others[1], others[0])]: + tri_count += 1 + +unique_sets.sort() +for s in unique_sets: + print(",".join(s)) + +print(f"\nTOTAL_C_SETS: {len(unique_sets)}") +print(f"TOTAL_TRIANGLES: {tri_count}") diff --git a/config.yaml.example b/config.yaml.example new file mode 100644 index 0000000..3e9ae5e --- /dev/null +++ b/config.yaml.example @@ -0,0 +1,31 @@ +live_mode: false + +fused_engine: + log_level: INFO + signal_threshold_bps: 2 + excluded_currencies: [EUR, BRL] + hold_currencies: [USDT, USDC, USD1] + send_signals: true + ws_url: wss://ws-api-spot.kucoin.com + token_url: https://api.kucoin.com/api/v1/bullet-public + reconnect_base_delay: 1.0 + reconnect_max_delay: 60.0 + heartbeat_interval: 18.0 + +executor: + fill_timeout_ms: 1000 + log_level: INFO + log_file: /tmp/executor.log + socket_path: /tmp/executor.sock + concurrent_slots: 1 + enforce_same_base_isolation: true + enforce_pair_isolation: true + rest_port: 8002 + initial_capital: + USDT: 5 + USDC: 5 + USD1: 5 + +kucoin_api_key: "" +kucoin_api_secret: "" +kucoin_api_passphrase: "" diff --git a/docs/fused-engine-plan.md b/docs/fused-engine-plan.md new file mode 100644 index 0000000..68fe648 --- /dev/null +++ b/docs/fused-engine-plan.md @@ -0,0 +1,766 @@ +# Fused Engine — Development Plan + +## 1. Objective + +Fuse the `fh_ob` (Feed Handler + Order Book) and `oe_em` (Opportunity Engine + Emission) +Python components into a single C binary (`fused_engine`) that eliminates: + +- Two-process IPC overhead (Unix socket serialization/deserialization between fh_ob → oe_em) +- Three-way JSON serialization (WS parse → socket serialize → socket deserialize → signal serialize) +- Python interpreter overhead on the hot path (object allocation, GIL, asyncio dispatch) +- GC pressure from transient `OrderBookTop5`, `BookLevel`, and `dict` allocations + +The **design maxima**: from the moment an order book update arrives, triangle +re-evaluation and signal dispatch must be **immediate**. No blocking I/O on the hot path. + +## 2. Current Architecture (for reference) + +### 2.1 Process Layout + +``` +[KuCoin WS] → [fh_ob] --Unix socket (JSON book snapshots)--> [oe_em] --Unix socket (JSON signals)--> [executor] +``` + +Three processes, two IPC hops. The critical path is: + +``` +WS frame arrives at fh_ob + → json.loads() (fh_ob/ws_client.py:239-240) + → BookStore.update() (fh_ob/book_store.py:42-82) [allocates OrderBookTop5, BookLevel objects] + → json.dumps(book) (fh_ob/book_store.py:86-91) [serializes to JSON] + → write to Unix socket (fh_ob/socket_server.py:107-114) + → oe_em reads from socket (oe_em/book_consumer.py:77-93) + → json.loads() (oe_em/book_consumer.py:84-91) [second parse] + → evaluate_triangles_for_pair() (oe_em/opportunity.py:152-230) [Python loop, dict lookups] + → json.dumps(signal) (oe_em/opportunity.py:290-310) [third serialization] + → write to executor socket (oe_em/socket_client.py:33-53) +``` + +### 2.2 Key Python Files and Line References + +| File | Lines | Purpose | +|---|---|---| +| `fh_ob/ws_client.py` | 1-148 | KuCoin WS connection, multi-worker model, token fetch, subscribe/unsubscribe | +| `fh_ob/ws_client.py` | 149-168 | Dynamic subscription loop (REST-triggered add/remove symbols) | +| `fh_ob/ws_client.py` | 199-206 | Public token fetch via `/api/v1/bullet-public` | +| `fh_ob/ws_client.py` | 208-227 | Batch subscribe (100 symbols per message, topic `/spotMarket/level2Depth5:...`) | +| `fh_ob/ws_client.py` | 238-270 | Message handler: welcome/pong/ack/disconnect/message routing | +| `fh_ob/book_store.py` | 18-25 | `BookLevel` dataclass (price, size as `Decimal`) | +| `fh_ob/book_store.py` | 27-40 | `OrderBookTop5` dataclass (symbol, ts, sequence, bids/asks as lists) | +| `fh_ob/book_store.py` | 42-82 | `BookStore.update()` — parse WS message, allocate objects, store in dict | +| `fh_ob/book_store.py` | 84-91 | `to_json()` — serialize book snapshot for IPC | +| `fh_ob/socket_server.py` | 1-114 | Unix socket server, broadcast to all connected oe_em clients | +| `fh_ob/rest_server.py` | 1-189 | FastAPI REST: `/health`, `/book/{symbol}`, `/symbols` CRUD | +| `fh_ob/__main__.py` | 1-196 | Startup: config load, WS client init, dynamic subscription setup, REST server | +| `oe_em/book_consumer.py` | 1-93 | Unix socket client, connect to fh_ob, JSON parse, callback dispatch | +| `oe_em/opportunity.py` | 47-109 | `FeeTable` — fetch from KuCoin `/api/v1/base-fee`, apply KCS discount | +| `oe_em/opportunity.py` | 111-149 | `TriangleEnumerator` — enumerate triangles from pairs, filter by hold currencies | +| `oe_em/opportunity.py` | 152-230 | `evaluate_triangles_for_pair()` — hot path: cumulative rate, fee factor, max_volume | +| `oe_em/opportunity.py` | 232-288 | `create_signal()` — build signal dict with legs, books, metadata | +| `oe_em/opportunity.py` | 290-310 | `format_signal_json()` — serialize signal for executor | +| `oe_em/opportunity.py` | 312-330 | `check_cooldown()` — per-triangle cooldown enforcement | +| `oe_em/triangle_enum.py` | 1-203 | Standalone triangle enumeration utility (not used at runtime) | +| `oe_em/kucoin_api.py` | 1-107 | REST client for fee table, trading pairs fetch | +| `oe_em/socket_client.py` | 1-53 | Unix socket client to executor, reconnect loop | +| `oe_em/__main__.py` | 1-281 | Startup: config, fee table, triangle enum, book consumer, signal sender | +| `executor/executor.py` | 204-227 | `handle_signal()` — entry point, exception safety | +| `executor/executor.py` | 229-305 | `_handle_signal_impl()` — pause check, validation, stale rejection, slot check | +| `executor/executor.py` | 307-398 | `_precheck_volume()` — backward-propagation minimum calculation | +| `executor/executor.py` | 464-852 | `_execute_triangle()` — sequential 3-leg execution, paper/live mode | +| `executor/executor.py` | 474-483 | Timing markers: `t-2_book_snapshot`, `t-1_signal_created`, `signal_received` | +| `executor/executor.py` | 854-890 | `_emit_report()` — execution report with timing log | +| `executor/config.py` | 1-81 | Executor settings: paper mode, concurrency, isolation, initial capital | +| `executor/socket_server.py` | 1-90 | Unix socket server receiving signals from oe_em | +| `common/config.py` | 1-59 | fh_ob settings (YAML schema): symbols, WS URL, heartbeat, reconnect | +| `oe_em/config.py` | 1-84 | oe_em settings (YAML schema): threshold, cooldown, hold currencies, KCS discount | + +### 2.3 KuCoin API References + +| Endpoint / Feature | Doc URL | Notes | +|---|---|---| +| Public Token (Classic Spot) | https://www.kucoin.com/docs-new/websocket-api/base-info/get-public-token-spot-margin.md | POST `/api/v1/bullet-public`, returns token + `instanceServers` with `pingInterval`/`pingTimeout` | +| WS Connection | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | `wss://ws-api-spot.kucoin.com?token=...&connectId=...`, welcome message on connect | +| WS Heartbeat | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | Ping every `pingInterval` (18s), timeout after `pingTimeout` (10s). Any outgoing message resets timeout. | +| WS Subscribe | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | `{"type":"subscribe","topic":"/spotMarket/level2Depth5:BTC-USDT,...","response":true}` | +| WS Unsubscribe | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | `{"type":"unsubscribe","topic":"/spotMarket/level2Depth5:BTC-USDT","response":true}` | +| WS Message Format | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | `{"type":"message","subject":"matchLevel2","topic":"/spotMarket/level2Depth5:SYMBOL","data":{"time":...,"sequence":...,"bids":[...],"asks":[...]}}` | +| WS Topic Limit | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | **400 topics per connection**. Multiple connections needed for >400 symbols. | +| WS Token TTL | https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md | Token valid 24 hours, connection disconnected after 24h. | +| Get Symbols | https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-all-symbols.md | GET `/api/v1/symbols`, returns pair metadata (base, quote, min sizes, increments) | +| Get Fee Table | https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-basic-fee-spot-margin.md | GET `/api/v1/base-fee`, returns taker/maker fees per currency | +| Order Test | https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-order-test.md | POST `/api/v1/orders/test`, validates order without placing | +| Place Order | https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-order.md | POST `/api/v1/orders`, places market/limit order | + +### 2.4 WS Message Format (Classic API) + +```json +{ + "type": "message", + "subject": "matchLevel2", + "topic": "/spotMarket/level2Depth5:BTC-USDT", + "data": { + "time": 1746789012345, + "sequence": 123456789, + "sequenceNum": 123456789, + "bids": [ + ["90701.1", "0.13918404"], + ["90700.0", "1.00000000"], + ["90699.5", "2.50000000"], + ["90698.0", "0.75000000"], + ["90697.5", "3.20000000"] + ], + "asks": [ + ["90701.2", "0.57715830"], + ["90702.0", "0.25000000"], + ["90703.5", "1.10000000"], + ["90704.0", "0.80000000"], + ["90705.0", "2.00000000"] + ] + } +} +``` + +### 2.5 Signal Format (oe_em → executor) + +From `oe_em/opportunity.py:232-310`: + +```json +{ + "type": "signal", + "correlation_id": "abc123", + "triangle_key": ["USDT", "BTC", "ETH"], + "primary_quote": "USDT", + "legs": [ + { + "pair": "BTC-USDT", + "input_currency": "USDT", + "output_currency": "BTC", + "fee_currency": "USDT", + "fee_rate": 0.001, + "exchange_rate": 0.00001102, + "side": "buy" + }, + { + "pair": "ETH-BTC", + "input_currency": "BTC", + "output_currency": "ETH", + "fee_currency": "BTC", + "fee_rate": 0.001, + "exchange_rate": 16.5, + "side": "buy" + }, + { + "pair": "ETH-USDT", + "input_currency": "ETH", + "output_currency": "USDT", + "fee_currency": "USDT", + "fee_rate": 0.001, + "exchange_rate": 90701.2, + "side": "sell" + } + ], + "predicted_bps": 1.50, + "max_volume": "100.00", + "ts_ms": 1746789012349, + "book_ts_ms": 1746789012345, + "books": [ + { + "symbol": "BTC-USDT", + "bids": [{"price": "90701.1", "size": "0.139"}, ...], + "asks": [{"price": "90701.2", "size": "0.577"}, ...], + "ts_ms": 1746789012345 + }, + ... + ] +} +``` + +The executor uses `books[i].asks[0].price` or `books[i].bids[0].price` for price lookup +in `_precheck_volume()` (executor/executor.py:344-348) and `_execute_triangle()` (executor/executor.py:539-545). + +## 3. Target Architecture + +### 3.1 High-Level Diagram + +``` +[KuCoin WS] ──▶ [ fused_engine (C binary) ] ──Unix socket──▶ [executor (Python)] + │ │ + │ N WS connections │ triangle_index (precomputed) + │ each ≤400 topics │ book[] (fixed array) + │ single epoll loop │ + └── REST API (port 8000) ──┘ +``` + +Single binary replaces fh_ob + oe_em. Executor is **unchanged** except for reading +two new timing fields from the signal. + +### 3.2 Threading Model + +Two threads, separated by hot/cold concern: + +``` +Thread 1 (HOT — evaluation only) Thread 2 (COLD — I/O) +───────────────────────────────── ───────────────────── +epoll: epoll: + [WS fd #1, WS fd #2, ..., WS fd #N] [unix_socket_server_fd, + [timerfd for WS pings] rest_server_fd, + eventfd_wakeup] + +Incoming WS frame: Drains SPSC ring buffer: + 1. Decode WS frame (stack-only) → JSON write signal to executor socket + 2. jsmn parse (0 alloc) → Handle REST API requests + 3. Update book[sym_idx] in-place → HTTP token refresh, pair fetch + 4. clock_gettime(CLOCK_MONOTONIC) → t_arrive → WS reconnect I/O + 5. clock_gettime(CLOCK_MONOTONIC) → t_eval → Dynamic subscribe/unsubscribe + 6. for tri in tri_index[sym_idx]: + compute net return (6 muls, 2 subs) + if profitable && cooldown_ok: + clock_gettime() → t_signal + format signal JSON into fixed buffer + push to SPSC ring buffer + log latency line to stderr + 7. Return immediately (never blocks) +``` + +**Guarantees:** +- WS read + triangle evaluation is **never blocked** by signal dispatch or REST traffic +- Signal enters SPSC queue within microseconds of detection +- Thread 2 stalls → Thread 1 keeps processing WS messages +- SPSC push is lock-free: single atomic increment, < 100ns + +### 3.3 SPSC Ring Buffer + +``` +Thread 1 pushes: atomic increment head → copy signal blob → atomic publish +Thread 2 drains: atomic read tail → copy signal blob → atomic increment tail +``` + +Bounded ring buffer of fixed-size entries (~4KB each, max 1024 entries). +`eventfd` used to wake Thread 2 from epoll when buffer transitions from empty to non-empty. + +### 3.4 File Structure + +``` +src/ + CMakeLists.txt — build configuration + main.c — startup, config parse, thread spawn, signal handling + config.c/h — YAML config parser (libyaml), reads fh_ob + oe_em sections + hash.c/h — FNV-1a string hash, symbol table (sorted array + bsearch) + http_client.c/h — raw HTTP GET/POST over TCP (token, pairs, symbols, fees) + http_server.c/h — minimal HTTP/1.1 server (REST API endpoints) + hmac.c/h — HMAC-SHA256 via OpenSSL EVP (for private endpoints if needed) + queue.c/h — lock-free SPSC ring buffer + eventfd wakeup + triangle.c/h — triangle enumeration, index builder, fee table + ws_client.c/h — WebSocket frame parser, OpenSSL BIO TLS, subscribe/unsubscribe + book.c/h — order book array (fixed-size, 0 alloc updates) + evaluate.c/h — triangle evaluation loop (HOT PATH, all inline) + signal.c/h — JSON signal formatter, pushes to SPSC queue + events.c/h — epoll loop, timerfd, eventfd, signal handling + jsmn.h — jsmn library (header-only, dropped in) +config.json.example — example config (same schema as config.yaml) +``` + +### 3.5 Dependencies + +| Library | Purpose | Notes | +|---|---|---| +| **OpenSSL** | TLS (WS connections), HMAC-SHA256 | System-installed, `find_package(OpenSSL REQUIRED)` | +| **libyaml** | Parse `config.yaml` at startup | Startup-only, not on hot path | +| **jsmn** | JSON parsing (WS messages, token response, REST requests) | Header-only, 0 allocation, drop `jsmn.h` into `src/` | +| **libc** | epoll, timerfd, eventfd, Unix sockets, pthreads, clock_gettime | Linux 6.12+ only | + +### 3.6 Config + +`config.yaml` is **unchanged** — read by both the C binary and the executor. +The C binary uses libyaml to parse the `fh_ob` and `oe_em` sections at startup. + +Relevant settings from `common/config.py:9-45` (fh_ob section): +- `symbols` — initial symbol list (can be empty, dynamic add via REST) +- `log_level` — logging verbosity +- `socket_path` — Unix socket path for executor (still `/tmp/fh_ob.sock` for fh_ob→oe_em internal, but the C binary writes directly to executor socket at `/tmp/executor.sock`) +- `rest_host`, `rest_port` — REST API bind address/port +- `ws_url` — KuCoin WS endpoint (from token response, not hardcoded) +- `token_url` — KuCoin public token endpoint +- `reconnect_base_delay`, `reconnect_max_delay` — exponential backoff +- `heartbeat_interval` — WS ping interval (from token response, default 18s) + +Relevant settings from `oe_em/config.py:16-68` (oe_em section): +- `signal_threshold_bps` — minimum net return in bps to fire signal +- `hold_currencies` — base currencies for triangle enumeration (default `["USDT"]`) +- `excluded_currencies` — currencies to exclude from enumeration +- `kcs_discount_active` — multiply taker fees by 0.8 +- `executor_socket_path` — Unix socket path for executor signals (`/tmp/executor.sock`) +- `send_signals` — whether to emit signals to executor + +## 4. Data Structures + +### 4.1 Symbol Table + +```c +// Sorted array of symbol entries, indexed by FNV-1a hash → bsearch +typedef struct { + char name[16]; // e.g. "BTC-USDT\0" + uint16_t index; // index into book[] array +} symbol_entry_t; + +typedef struct { + symbol_entry_t *entries; + uint32_t count; +} symbol_table_t; + +// O(log N) lookup: hash string → bsearch in sorted array → return book index +uint16_t symbol_table_lookup(symbol_table_t *table, const char *name); +``` + +### 4.2 Order Book + +```c +typedef struct { + uint16_t symbol_idx; + int64_t ts_ms; // KuCoin's "time" field from WS message + int64_t sequence; // sequence number for ordering + double bids[5][2]; // [level][0] = price, [level][1] = size + double asks[5][2]; + uint8_t bid_count; // actual number of bid levels (0-5) + uint8_t ask_count; // actual number of ask levels (0-5) +} order_book_t; + +// Fixed-size array, indexed by symbol index +// book[symbol_idx] gives O(1) access, cache-friendly +#define MAX_SYMBOLS 2048 +order_book_t books[MAX_SYMBOLS]; +``` + +### 4.3 Triangle + +```c +typedef struct { + uint16_t symbol_idx[3]; // book[] indices for each leg + uint8_t use_bid[3]; // 1 = read bid (sell), 0 = read ask (buy) + double fee_factor[3]; // precomputed: (1.0 - taker_fee * kcs_discount) + uint16_t id; // unique triangle ID (for cooldown tracking) + uint8_t currency_ids[3]; // compact currency identifiers + uint8_t primary_quote_id; // index into hold_currencies[] + char symbol_names[3][16];// symbol strings for signal JSON + char base[16]; // base currency (e.g., "USDT") + char mid[16]; // mid currency (e.g., "BTC") + char quote[16]; // quote currency (e.g., "ETH") +} triangle_t; +``` + +### 4.4 Triangle Index + +```c +// For each symbol, offset/count into the flat triangle[] array +// Triangles are sorted by their first symbol index, then second, then third +// so all triangles containing a given symbol are contiguous +typedef struct { + uint32_t offset; + uint32_t count; +} tri_index_entry_t; + +tri_index_entry_t tri_index[MAX_SYMBOLS]; +``` + +### 4.5 Signal (SPSC Queue Entry) + +```c +#define SIGNAL_MAX_SIZE 4096 + +typedef struct { + char data[SIGNAL_MAX_SIZE]; // pre-formatted JSON + uint32_t len; + int64_t ts_ms; // signal creation timestamp +} signal_entry_t; + +#define SPSC_CAPACITY 1024 +signal_entry_t ring[SPSC_CAPACITY]; +atomic_uint head; // writer (Thread 1) +atomic_uint tail; // reader (Thread 2) +``` + +### 4.6 Cooldown State + +```c +typedef struct { + int64_t last_signal_ms; // timestamp of last fired signal (ms) +} cooldown_t; + +cooldown_t cooldowns[MAX_TRIANGLES]; +``` + +## 5. Hot Path (evaluate.c) + +The hot path runs inline in the WS message handler on Thread 1. Zero heap +allocation. All data accessed by index into fixed arrays. + +```c +// Called from ws_client.c message handler, immediately after book update +// sym_idx is the index of the symbol that just updated +void evaluate_and_signal(uint16_t sym_idx) { + // Timestamp: arrival (after WS decode + book update) + struct timespec ts_arrive; + clock_gettime(CLOCK_MONOTONIC, &ts_arrive); + int64_t t_arrive_ms = ts_arrive.tv_sec * 1000 + ts_arrive.tv_nsec / 1e6; + + tri_index_entry_t *idx = &tri_index[sym_idx]; + int64_t book_ts_ms = books[sym_idx].ts_ms; + + for (uint32_t i = 0; i < idx->count; i++) { + triangle_t *tri = &triangles[idx->offset + i]; + + // Timestamp: evaluation start + struct timespec ts_eval; + clock_gettime(CLOCK_MONOTONIC, &ts_eval); + int64_t t_eval_ms = ts_eval.tv_sec * 1000 + ts_eval.tv_nsec / 1e6; + + // Compute cumulative rate through all 3 legs + double cum = 1.0; + for (int leg = 0; leg < 3; leg++) { + order_book_t *b = &books[tri->symbol_idx[leg]]; + double rate = tri->use_bid[leg] + ? b->bids[0][0] // sell leg: use best bid + : 1.0 / b->asks[0][0]; // buy leg: use best ask (invert) + cum *= rate * tri->fee_factor[leg]; + } + + double net_bps = (cum - 1.0) * 10000.0; + + if (net_bps > signal_threshold_bps + && cooldown_ok(tri->id) + && max_volume_ok(tri)) { + + // Compute max_volume (chained minimum across 3 legs) + double max_vol = compute_max_volume(tri); + + // Timestamp: signal creation + struct timespec ts_signal; + clock_gettime(CLOCK_MONOTONIC, &ts_signal); + int64_t t_signal_ms = ts_signal.tv_sec * 1000 + ts_signal.tv_nsec / 1e6; + + // Format signal JSON into fixed buffer + char buf[SIGNAL_MAX_SIZE]; + int len = format_signal(buf, sizeof(buf), tri, net_bps, max_vol, + t_arrive_ms, t_eval_ms, t_signal_ms, book_ts_ms); + + // Push to SPSC queue (lock-free, never blocks) + spsc_push(buf, len, t_signal_ms); + + // Log latency line (to stderr, not disk) + fprintf(stderr, + "SIGNAL corr=%s sym=%s tri=%s/%s/%s bps=%.2f " + "t_exchange=%ld t_arrive=%ld t_eval=%ld t_signal=%ld\n", + correlation_id, tri->symbol_names[0], + tri->base, tri->mid, tri->quote, + net_bps, + (long)book_ts_ms, (long)t_arrive_ms, + (long)t_eval_ms, (long)t_signal_ms); + + set_cooldown(tri->id, t_signal_ms); + } + } +} +``` + +**Performance characteristics:** +- Per triangle: 6 double multiplications, 2 subtractions, 3 array lookups +- No heap allocation, no function call overhead (all `static inline`) +- `clock_gettime(CLOCK_MONOTONIC)` is ~10ns on modern Linux +- Worst case for a symbol in 50 triangles: ~50 × 1µs = 50µs total eval time + +## 6. Signal JSON Format + +Same as current oe_em → executor format, with two new timing fields. +The executor reads `t_arrive_ms` and `t_eval_ms` (new) alongside existing +`ts_ms` and `book_ts_ms`. + +```json +{ + "type": "signal", + "correlation_id": "abc123", + "triangle_key": ["USDT", "BTC", "ETH"], + "primary_quote": "USDT", + "legs": [ + { + "pair": "BTC-USDT", + "input_currency": "USDT", + "output_currency": "BTC", + "fee_currency": "USDT", + "fee_rate": 0.001, + "exchange_rate": 0.00001102, + "side": "buy" + }, + { + "pair": "ETH-BTC", + "input_currency": "BTC", + "output_currency": "ETH", + "fee_currency": "BTC", + "fee_rate": 0.001, + "exchange_rate": 16.5, + "side": "buy" + }, + { + "pair": "ETH-USDT", + "input_currency": "ETH", + "output_currency": "USDT", + "fee_currency": "USDT", + "fee_rate": 0.001, + "exchange_rate": 90701.2, + "side": "sell" + } + ], + "predicted_bps": 1.50, + "max_volume": "100.00", + "book_ts_ms": 1746789012345, + "t_arrive_ms": 1746789012347, + "t_eval_ms": 1746789012347, + "ts_ms": 1746789012349, + "books": [ + { + "symbol": "BTC-USDT", + "bids": [{"price": "90701.1", "size": "0.13918404"}, ...], + "asks": [{"price": "90701.2", "size": "0.57715830"}, ...], + "ts_ms": 1746789012345 + }, + ... + ] +} +``` + +### 6.1 Executor Timing Derivation + +The executor (executor/executor.py:474-483) currently derives: +```python +timings.append({"step": "t-2_book_snapshot", "elapsed_ms": -(executor_receive_ts_ms - book_ts_ms)}) +timings.append({"step": "t-1_signal_created", "elapsed_ms": -(executor_receive_ts_ms - signal_ts_ms)}) +``` + +With the two new fields, the executor derives: + +| Metric | Formula | Meaning | +|---|---|---| +| Network latency | `t_arrive_ms - book_ts_ms` | KuCoin server → our doorstep | +| Dispatch overhead | `t_eval_ms - t_arrive_ms` | Book update → eval start | +| Eval time | `ts_ms - t_eval_ms` | Triangle evaluation loop | +| Socket + queue latency | `executor_receive_ts_ms - ts_ms` | SPSC push → executor receive | +| Total end-to-end | `executor_receive_ts_ms - book_ts_ms` | Full pipeline | + +**Executor change required:** In `executor/executor.py:474-483`, read the two new +fields and add derived timing entries. Approximately 5 lines of code. + +## 7. WS Connection Model + +### 7.1 Multi-Connection Architecture + +KuCoin limits each WS connection to **400 topics** (KuCoin API docs: +https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md). +With ~100 symbols, a single connection suffices. But the design supports +dynamic symbol addition that could exceed 400. + +```c +typedef struct { + int socket_fd; // epoll'd file descriptor + BIO *bio; // OpenSSL BIO for TLS + SSL *ssl; // OpenSSL SSL context + char buffer[65536]; // WS frame receive buffer + int buffer_len; + uint32_t topic_count; // current subscription count + uint32_t max_topics; // typically 400 + int64_t last_ping_ms; // last ping timestamp + int64_t ping_interval_ms; // from token response + int64_t ping_timeout_ms; // from token response + char token[512]; // public WS token + char connect_id[64]; // unique connection ID + uint16_t symbol_indices[400]; // subscribed symbol indices + uint32_t symbol_count; +} ws_connection_t; + +#define MAX_WS_CONNECTIONS 8 +ws_connection_t ws_connections[MAX_WS_CONNECTIONS]; +uint32_t ws_connection_count; +``` + +### 7.2 WS Frame Protocol + +Classic KuCoin WS uses standard WebSocket framing over TLS. The C implementation +handles framing manually (no libwebsockets dependency): + +**Outgoing:** +1. Construct WS frame: FIN=1, opcode=1 (text), masked, payload = JSON string +2. Send via `BIO_write(bio, frame, frame_len)` + +**Incoming:** +1. Read from `BIO_read(bio, buf, sizeof(buf))` +2. Parse frame header (2-14 bytes): FIN, RSV, opcode, mask, payload length +3. Unmask payload (XOR with 4-byte masking key) +4. Pass to jsmn parser + +Frame parsing is ~50 lines of C. See `rfc6455` Section 5.2 for frame format. + +### 7.3 Subscribe/Unsubscribe + +From `fh_ob/ws_client.py:208-227`: subscribe in batches of 100 symbols. +Topic format: `/spotMarket/level2Depth5:SYMBOL1,SYMBOL2,...` + +```c +// Subscribe symbols to a WS connection +int ws_subscribe(ws_connection_t *conn, uint16_t *symbol_indices, uint32_t count); + +// Unsubscribe symbols from a WS connection +int ws_unsubscribe(ws_connection_t *conn, uint16_t *symbol_indices, uint32_t count); +``` + +Dynamic subscribe/unsubscribe is triggered by REST API calls +(`POST /symbols` and `DELETE /symbols/{symbol}`). + +## 8. REST API + +Kept from fh_ob for operational use. Same endpoints as `fh_ob/rest_server.py:1-189`. + +| Endpoint | Method | Purpose | Ref | +|---|---|---|---| +| `/health` | GET | Status: WS connected, book count, symbol count, uptime | `fh_ob/rest_server.py:35-48` | +| `/book/{symbol}` | GET | Current top-of-book for symbol (all 5 levels) | `fh_ob/rest_server.py:50-68` | +| `/books` | GET | All books | `fh_ob/rest_server.py:70-80` | +| `/symbols` | GET | List subscribed symbols | `fh_ob/rest_server.py:82-92` | +| `/symbols` | POST | Add symbol (subscribe to WS, add to triangle eval) | `fh_ob/rest_server.py:94-120` | +| `/symbols/{symbol}` | DELETE | Remove symbol (unsubscribe from WS) | `fh_ob/rest_server.py:122-145` | + +HTTP/1.1 server is raw socket + simple parser. No libhttp dependency. +Handles GET/POST/DELETE with Content-Type: application/json. +Binds to `0.0.0.0:8000` (configurable via `fh_ob.rest_port`). + +## 9. Triangle Enumeration + +From `oe_em/opportunity.py:111-149` and `oe_em/triangle_enum.py:1-203`. + +Algorithm: +1. Fetch KuCoin symbols via `GET /api/v1/symbols` (oe_em/kucoin_api.py:39-56) +2. Filter: `base != quote`, symbol is active +3. For each pair of symbols (A, B) where A.quote == B.base or A.base == B.quote: + - Find third pair (C) that completes the triangle (C.base == A.base, C.quote == B.quote, etc.) + - Filter: triangle starts and ends in a hold currency (`oe_em/config.py:55-57`, default `["USDT"]`) + - Exclude triangles containing excluded currencies (`oe_em/config.py:50-53`) +4. Build `triangle_t` array with precomputed fee factors +5. Sort triangles, build `tri_index` for O(1) lookup by symbol + +Fee table from `GET /api/v1/base-fee` (oe_em/kucoin_api.py:60-78). +KCS discount: if `kcs_discount_active`, multiply taker fee by 0.8 (oe_em/opportunity.py:50-64). + +## 10. Startup Sequence + +``` +1. Parse config.yaml (libyaml) — read fh_ob + oe_em sections +2. Fetch KuCoin symbols: HTTP GET /api/v1/symbols +3. Fetch KuCoin fee table: HTTP GET /api/v1/base-fee +4. Enumerate triangles → build sorted triangle[] + tri_index[] +5. Fetch public WS token: HTTP POST /api/v1/bullet-public +6. Create WS connections (N connections, each ≤400 topics) +7. Subscribe to initial symbols (from config.yaml fh_ob.symbols) +8. Bind Unix socket at executor_socket_path (oe_em config) +9. Start HTTP server on rest_port (fh_ob config) +10. Spawn Thread 1 (hot epoll loop: WS fds + timerfd) +11. Spawn Thread 2 (cold epoll loop: Unix socket, REST, eventfd) +12. Enter event loops +``` + +## 11. Executor Compatibility + +### 11.1 Unix Socket Protocol + +The executor's `SignalSocketServer` (executor/socket_server.py:1-90) expects: +- Unix domain socket at `/tmp/executor.sock` +- JSON messages, one per connection message +- Message format: `{"type":"signal", ...}` followed by newline + +The C binary writes to the same socket path. No changes needed to the +executor's socket server. + +### 11.2 Signal Payload + +The signal JSON is identical to the current format, with two additional fields: +- `t_arrive_ms` — monotonic timestamp when WS frame decode completed +- `t_eval_ms` — monotonic timestamp when triangle evaluation started + +The executor reads these in `executor/executor.py:474-483`. Required change: + +```python +# In executor/executor.py, around line 474: +t_arrive_ms = signal.get("t_arrive_ms", 0) +t_eval_ms = signal.get("t_eval_ms", 0) +if t_arrive_ms > 0: + timings.append({"step": "t-3_ws_arrive", "elapsed_ms": -(executor_receive_ts_ms - t_arrive_ms)}) +if t_eval_ms > 0: + timings.append({"step": "t-4_eval_start", "elapsed_ms": -(executor_receive_ts_ms - t_eval_ms)}) +``` + +### 11.3 Executor Disconnect Handling + +The C binary keeps the executor Unix socket open and waits for reconnection. +If the executor disconnects, Thread 2 logs a warning and keeps the server +socket listening. New executor connections are accepted normally. +(Signal queue entries for disconnected executor are dropped.) + +## 12. Implementation Order + +### Phase 1: Foundation (Week 1) +1. `CMakeLists.txt` — build config, OpenSSL + libyaml dependencies +2. `config.c/h` — YAML parser, reads fh_ob + oe_em sections +3. `hash.c/h` — FNV-1a hash, symbol table +4. `http_client.c/h` — raw HTTP GET/POST (token, pairs, fees) +5. `triangle.c/h` — triangle enumeration, index builder +6. `book.c/h` — order book array, update function +7. Unit tests: config parse, symbol table, triangle enum + +### Phase 2: WS + Hot Path (Week 2) +8. `jsmn.h` — drop in library +9. `ws_client.c/h` — WS frame parser, OpenSSL BIO TLS, subscribe/unsubscribe +10. `evaluate.c/h` — triangle evaluation loop (inline, zero alloc) +11. `signal.c/h` — JSON signal formatter +12. Integration test: connect to KuCoin WS, verify book updates + +### Phase 3: IPC + REST (Week 3) +13. `queue.c/h` — SPSC ring buffer, eventfd +14. `http_server.c/h` — REST API server +15. `events.c/h` — epoll loops, timerfd, signal handling +16. `main.c` — startup, thread spawn, signal handling +17. Integration test: full pipeline, signal to executor + +### Phase 4: Polish (Week 4) +18. Dynamic subscribe/unsubscribe via REST +19. Reconnection logic (exponential backoff) +20. Timing field integration in executor +21. Performance benchmarking +22. Edge case handling, error paths +23. Deployment script update + +## 13. Performance Targets + +| Metric | Current (Python) | Target (C) | +|---|---|---| +| WS arrive → eval start | ~500µs (asyncio dispatch + IPC) | <1µs (inline) | +| Eval 50 triangles | ~5ms (Python loop) | <50µs (C loop) | +| Signal dispatch | ~1ms (JSON + socket write) | <10µs (SPSC push) | +| Total end-to-end (exchange → executor) | ~15-30ms | ~5-10ms (network-bound) | + +The dominant latency component will be network RTT to KuCoin (~5-20ms). +The C binary aims to add <100µs of processing latency on top. + +## 14. Files Affected + +### New Files +- `src/` directory with all C source files (listed in §3.4) + +### Modified Files +- `executor/executor.py` — add `t_arrive_ms` and `t_eval_ms` to timing derivation (~5 lines) + +### Unchanged Files +- `config.yaml` — read by both C binary and executor +- `executor/` (except `executor.py` timing change) — fully compatible +- `common/log.py` — still used by executor +- `deploy.sh` — updated to deploy compiled binary instead of Python files + +### Deleted Files +- `fh_ob/` — entire directory (replaced by C binary) +- `oe_em/` — entire directory (replaced by C binary) +- `common/config.py` — fh_ob settings moved to C config parser; oe_em settings merged into C config diff --git a/docs/kucoin_api_reference.txt b/docs/kucoin_api_reference.txt new file mode 100644 index 0000000..24a5528 --- /dev/null +++ b/docs/kucoin_api_reference.txt @@ -0,0 +1,463 @@ +# KUCOIN API + +## Docs +- [Introduction](https://www.kucoin.com/docs-new/introduction.md): +- [Authentication](https://www.kucoin.com/docs-new/authentication.md): +- [Enums Definitions](https://www.kucoin.com/docs-new/enums-definitions.md): +- [Terms Definitions](https://www.kucoin.com/docs-new/terms-definitions.md): +- [SDK](https://www.kucoin.com/docs-new/sdk.md): +- [OpenClaw](https://www.kucoin.com/docs-new/kucoin_skills_hub.md): +- [Rate Limit](https://www.kucoin.com/docs-new/rate-limit.md): +- [Change Log](https://www.kucoin.com/docs-new/change-log.md): +- User Service [Market Making Incentive Scheme](https://www.kucoin.com/docs-new/user-service/market-making-incentive-scheme.md): +- User Service [VIP Fast Track](https://www.kucoin.com/docs-new/user-service/vip-fast-track.md): +- User Service [Broker Program](https://www.kucoin.com/docs-new/user-service/broker-program.md): +- Pro REST [Introduction](https://www.kucoin.com/docs-new/rest/ua/introduction.md): +- Pro REST > VIP Lending [Introduction](https://www.kucoin.com/docs-new/rest/ua/vip-lending/introduction.md): +- Pro WebSocket > Base Info [Introduction](https://www.kucoin.com/docs-new/websocket-api/base-info/introduction-uta.md): +- Classic REST > Futures Trading [Introduction](https://www.kucoin.com/docs-new/rest/futures-trading/introduction.md): +- Classic REST > VIP Lending [Introduction](https://www.kucoin.com/docs-new/rest/vip-lending/introduction.md): +- Classic REST > Affiliate [Introduction](https://www.kucoin.com/docs-new/rest/affiliate/introduction.md): +- Classic REST > Broker [Introduction](https://www.kucoin.com/docs-new/rest/broker/introduction/main.md): +- Classic REST > Broker [Broker Application](https://www.kucoin.com/docs-new/rest/broker/broker-application.md): +- Classic REST > Broker [Instructions](https://www.kucoin.com/docs-new/rest/broker/instructions.md): +- Classic REST > Broker > Broker Pro [Introduction](https://www.kucoin.com/docs-new/rest/broker/api-broker/introduction.md): +- Classic REST > Broker > Broker Pro [Broker Fast API Service](https://www.kucoin.com/docs-new/rest/broker/api-broker/fast-api.md): +- Classic REST > Broker > Exchange Broker [Introduction](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/introduction.md): +- Classic REST > Copy Trading [Introduction](https://www.kucoin.com/docs-new/rest/copy-trading/introduction.md): +- Classic REST > Convert [Introduction](https://www.kucoin.com/docs-new/rest/convert/introduction.md): +- Classic WebSocket > Base Info [Introduction](https://www.kucoin.com/docs-new/websocket-api/base-info/introduction.md): +- Web3 Wallet [Browser Extension Wallet](https://www.kucoin.com/docs-new/web3/browser-extension-wallet.md): +- Error Code [HTTP](https://www.kucoin.com/docs-new/error-code/http.md): +- Error Code [Spot](https://www.kucoin.com/docs-new/error-code/spot.md): +- Error Code [Margin](https://www.kucoin.com/docs-new/error-code/margin.md): +- Error Code [Futures](https://www.kucoin.com/docs-new/error-code/futures.md): +- Error Code [Earn](https://www.kucoin.com/docs-new/error-code/earn.md): +- Error Code [Broker](https://www.kucoin.com/docs-new/error-code/broker.md): +- Error Code [CopyTrading](https://www.kucoin.com/docs-new/error-code/copytrading.md): +- Error Code [Websocket](https://www.kucoin.com/docs-new/error-code/websocket.md): +- Error Code [Pro API](https://www.kucoin.com/docs-new/error-code/pro-api.md): +- Abandoned Endpoints [Introduction](https://www.kucoin.com/docs-new/abandoned-endpoints/introduction.md): +- Developing [Introduction](https://www.kucoin.com/docs-new/338210m0.md): + +## API Docs +- Pro REST > Market Data [Get Announcements](https://www.kucoin.com/docs-new/rest/ua/get-announcements.md): :::info[Description] +- Pro REST > Market Data [Get Currency](https://www.kucoin.com/docs-new/rest/ua/get-currency.md): :::info[Description] +- Pro REST > Market Data [Get Currencies](https://www.kucoin.com/docs-new/rest/ua/get-currencies.md): :::info[Description] +- Pro REST > Market Data [Get Symbol](https://www.kucoin.com/docs-new/rest/ua/get-symbol.md): :::info[Description] +- Pro REST > Market Data [Get Ticker](https://www.kucoin.com/docs-new/rest/ua/get-ticker.md): :::info[Description] +- Pro REST > Market Data [Get OrderBook](https://www.kucoin.com/docs-new/rest/ua/get-orderbook.md): :::info[Description] +- Pro REST > Market Data [Get Klines](https://www.kucoin.com/docs-new/rest/ua/get-klines.md): :::info[Description] +- Pro REST > Market Data [Get Trades](https://www.kucoin.com/docs-new/rest/ua/get-trades.md): :::info[Description] +- Pro REST > Market Data [Get Collateral Ratio](https://www.kucoin.com/docs-new/rest/ua/get-collateral-ratio.md): :::info[Description] +- Pro REST > Market Data [Get Cross Margin Config](https://www.kucoin.com/docs-new/rest/ua/get-cross-margin-config.md): :::info[Description] +- Pro REST > Market Data [Get Index Price](https://www.kucoin.com/docs-new/rest/ua/get-index-price.md): :::info[Description] +- Pro REST > Market Data [Get Current Funding Rate](https://www.kucoin.com/docs-new/rest/ua/get-current-funding-rate.md): :::info[Description] +- Pro REST > Market Data [Get History Funding Rate](https://www.kucoin.com/docs-new/rest/ua/get-history-funding-rate.md): :::info[Description] +- Pro REST > Market Data [Get Position Tiers](https://www.kucoin.com/docs-new/rest/ua/get-position-tiers.md): :::info[Description] +- Pro REST > Market Data [Get Futures Open Interest](https://www.kucoin.com/docs-new/rest/ua/get-futures-open-interset.md): :::info[Description] +- Pro REST > Market Data [Get Service Status](https://www.kucoin.com/docs-new/rest/ua/get-service-status.md): :::info[Description] +- Pro REST > Market Data [Get Third-Party Custody Currencies](https://www.kucoin.com/docs-new/rest/ua/get-oes-settlement-currency.md): :::info[Description] +- Pro REST > Market Data [Get Borrowable Currencies](https://www.kucoin.com/docs-new/rest/ua/get-borrowable-currencies.md): :::info[Description] +- Pro REST > Market Data [Get KYC Regions](https://www.kucoin.com/docs-new/rest/ua/get-kyc-region.md): :::info[Description] +- Pro REST > Account [Get Account Overview (UTA)](https://www.kucoin.com/docs-new/rest/ua/account/get-account-overview-uta.md): :::info[Description] +- Pro REST > Account [Get Account Currency Assets (UTA)](https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-uta.md): :::info[Description] +- Pro REST > Account [Get Account Currency Assets (Classic)](https://www.kucoin.com/docs-new/rest/ua/get-account-currency-assets-classic.md): :::info[Description] +- Pro REST > Account [Get Sub Account Currency Assets](https://www.kucoin.com/docs-new/rest/ua/get-sub-account-currency-assets.md): :::info[Description] +- Pro REST > Account [Get Transfer Quotas](https://www.kucoin.com/docs-new/rest/ua/get-transfer-quotas.md): :::info[Description] +- Pro REST > Account [Flex Transfer](https://www.kucoin.com/docs-new/rest/ua/flex-transfer.md): :::info[Description] +- Pro REST > Account [Set Sub Account Transfer Permission](https://www.kucoin.com/docs-new/rest/ua/set-sub-account-transfer-permission.md): :::info[Description] +- Pro REST > Account [Get Account Mode](https://www.kucoin.com/docs-new/rest/ua/get-account-mode.md): :::info[Description] +- Pro REST > Account [Set Account Mode](https://www.kucoin.com/docs-new/rest/ua/set-account-mode.md): :::info[Description] +- Pro REST > Account [Get Fee Rate](https://www.kucoin.com/docs-new/rest/ua/get-actual-fee.md): :::info[Description] +- Pro REST > Account [Get Account Ledger](https://www.kucoin.com/docs-new/rest/ua/get-account-ledger.md): :::info[Description] +- Pro REST > Account [Get Interest History (UTA)](https://www.kucoin.com/docs-new/rest/ua/get-interest-history-uta.md): :::info[Description] +- Pro REST > Account [Modify Futures Leverage (UTA)](https://www.kucoin.com/docs-new/rest/ua/modify-leverage-uta.md): :::info[Description] +- Pro REST > Account [Get Deposit Address](https://www.kucoin.com/docs-new/rest/ua/get-deposit-address.md): :::info[Description] +- Pro REST > Account [Get Third-Party Custody Account Currency Limits](https://www.kucoin.com/docs-new/rest/ua/get-oes-custody-quota.md): :::info[Description] +- Pro REST > Account [Modify Leverage Margin Cross (UTA)](https://www.kucoin.com/docs-new/rest/ua/modify-cross-margin-leverage-uta.md): :::info[Description] +- Pro REST > Account [Get Leverage (UTA)](https://www.kucoin.com/docs-new/rest/ua/get-leverage.md): :::info[Description] +- Pro REST > Account [Get Borrowing Rates and Limits](https://www.kucoin.com/docs-new/rest/ua/get-borrowing-rates-and-limits.md): :::info[Description] +- Pro REST > Account [Get Apikey Info](https://www.kucoin.com/docs-new/rest/ua/get-apikey-info.md): :::info[Description] +- Pro REST > Account [Add sub-account](https://www.kucoin.com/docs-new/rest/ua/add-sub-account.md): :::info[Description] +- Pro REST > Account [Get sub-account API List](https://www.kucoin.com/docs-new/rest/ua/get-sub-account-api-list.md): :::info[Description] +- Pro REST > Account [Add sub-account API](https://www.kucoin.com/docs-new/rest/ua/add-sub-account-api.md): :::info[Description] +- Pro REST > Account [Delete sub-account API](https://www.kucoin.com/docs-new/rest/ua/delete-sub-account-api.md): :::info[Description] +- Pro REST > Account [Get Withdrawal Quotas](https://www.kucoin.com/docs-new/rest/ua/get-withdrawal-quotas.md): :::info[Description] +- Pro REST > Account [Withdraw](https://www.kucoin.com/docs-new/rest/ua/withdrawal.md): :::info[Description] +- Pro REST > Account [Cancel Withdrawal](https://www.kucoin.com/docs-new/rest/ua/cancel-withdrawal.md): :::info[Description] +- Pro REST > Account [Get Client IP Address](https://www.kucoin.com/docs-new/rest/ua/get-client-ip-address.md): :::info[Description] +- Pro REST > Orders [Place Order](https://www.kucoin.com/docs-new/rest/ua/place-order.md): :::info[Description] +- Pro REST > Orders [Batch Place Order (Classic)](https://www.kucoin.com/docs-new/rest/ua/batch-place-order-classic.md): :::info[Description] +- Pro REST > Orders [Cancel Order](https://www.kucoin.com/docs-new/rest/ua/cancel-order.md): :::info[Description] +- Pro REST > Orders [Batch Cancel Orders By ID](https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-id.md): :::info[Description] +- Pro REST > Orders [Batch Cancel Orders By Symbol](https://www.kucoin.com/docs-new/rest/ua/batch-cancel-order-by-symbol.md): :::info[Description] +- Pro REST > Orders [Get Order Details ](https://www.kucoin.com/docs-new/rest/ua/get-order-details.md): :::info[Description] +- Pro REST > Orders [Get Open Order List](https://www.kucoin.com/docs-new/rest/ua/get-open-order-list.md): :::info[Description] +- Pro REST > Orders [Get Order History](https://www.kucoin.com/docs-new/rest/ua/get-order-history.md): :::info[Description] +- Pro REST > Orders [Get Trade History](https://www.kucoin.com/docs-new/rest/ua/get-trade-history.md): :::info[Description] +- Pro REST > Orders [Set DCP (Classic)](https://www.kucoin.com/docs-new/rest/ua/set-dcp-classic.md): :::info[Description] +- Pro REST > Orders [Get DCP (Classic)](https://www.kucoin.com/docs-new/rest/ua/get-dcp-classic.md): :::info[Description] +- Pro REST > Positions [Get Position List (UTA)](https://www.kucoin.com/docs-new/rest/ua/get-position-list-uta.md): :::info[Description] +- Pro REST > Positions [Get Positions History (UTA)](https://www.kucoin.com/docs-new/rest/ua/get-position-history-uta.md): :::info[Description] +- Pro REST > Positions [Get Account Position Tiers](https://www.kucoin.com/docs-new/rest/ua/get-account-position-tiers.md): :::info[Description] +- Pro REST > Positions [Get Private Funding Fee History](https://www.kucoin.com/docs-new/rest/ua/get-private-funding-fee-history.md): :::info[Description] +- Pro REST > VIP Lending [Get Collateral Ratio](https://www.kucoin.com/docs-new/rest/ua/vip-lending/get-collateral-ratio.md): :::info[Description] +- Pro REST > VIP Lending [Get Loan Info](https://www.kucoin.com/docs-new/rest/ua/vip-lending/get-loan-info.md): :::info[Description] +- Pro REST > VIP Lending [Get Accounts](https://www.kucoin.com/docs-new/rest/ua/vip-lending/get-accounts.md): :::info[Description] +- Pro WebSocket > Base Info [Get Private Token - Pro API Private Channels](https://www.kucoin.com/docs-new/websocket-api/base-info/get-private-token-uta.md): :::info[Description] +- Pro WebSocket > Public Channels [Kline](https://www.kucoin.com/docs-new/3470223w0.md): :::info[Description] +- Pro WebSocket > Public Channels [Ticker](https://www.kucoin.com/docs-new/3470222w0.md): :::info[Description] +- Pro WebSocket > Public Channels [Orderbook](https://www.kucoin.com/docs-new/3470221w0.md): :::info[Description] +- Pro WebSocket > Public Channels [Trade](https://www.kucoin.com/docs-new/3470224w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Order](https://www.kucoin.com/docs-new/3470228w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Balance](https://www.kucoin.com/docs-new/3470231w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Execution](https://www.kucoin.com/docs-new/3470232w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Execution Lite](https://www.kucoin.com/docs-new/3470264w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Position](https://www.kucoin.com/docs-new/3470233w0.md): :::info[Description] +- Pro WebSocket > Private Channels [Leverage](https://www.kucoin.com/docs-new/3470237w0.md): :::info[Description] +- Pro WebSocket > Private Channels [LiquidationWarning](https://www.kucoin.com/docs-new/3470236w0.md): ## Topic:/liquidationWarning +- Pro WebSocket > Add/Cancel Order [Add Order](https://www.kucoin.com/docs-new/3470133w0.md): :::info[Description] +- Pro WebSocket > Add/Cancel Order [Cancel Order](https://www.kucoin.com/docs-new/3470134w0.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Summary Info](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-summary-info.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Apikey Info](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-apikey-info.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Type - Spot ](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-type-spot.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account List - Spot](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-list-spot.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Detail - Spot](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-detail-spot.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account - Cross Margin](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-cross-margin.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account - Isolated Margin](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-isolated-margin.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account - Futures](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-futures.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Ledgers - Spot/Margin](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-spot-margin.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Ledgers - Trade_hf](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-tradehf.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Ledgers - Margin_hf](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-marginhf.md): :::info[Description] +- Classic REST > Account Info > Account & Funding [Get Account Ledgers - Futures](https://www.kucoin.com/docs-new/rest/account-info/account-funding/get-account-ledgers-futures.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Add sub-account](https://www.kucoin.com/docs-new/rest/account-info/sub-account/add-subaccount.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Add sub-account Margin Permission](https://www.kucoin.com/docs-new/rest/account-info/sub-account/add-subaccount-margin-permission.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Add sub-account Futures Permission](https://www.kucoin.com/docs-new/rest/account-info/sub-account/add-subaccount-futures-permission.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Get sub-account List - Summary Info](https://www.kucoin.com/docs-new/rest/account-info/sub-account/get-subaccount-list-summary-info.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Get sub-account Detail - Balance](https://www.kucoin.com/docs-new/rest/account-info/sub-account/get-subaccount-detail-balance.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Get sub-account List - Spot Balance (V2)](https://www.kucoin.com/docs-new/rest/account-info/sub-account/get-subaccount-list-spot-balance-v2.md): :::info[Description] +- Classic REST > Account Info > Sub Account [Get sub-account List - Futures Balance (V2)](https://www.kucoin.com/docs-new/rest/account-info/sub-account/get-subaccount-list-futures-balance-v2.md): :::info[Description] +- Classic REST > Account Info > Sub Account API [Get sub-account API List](https://www.kucoin.com/docs-new/rest/account-info/sub-account-api/get-subaccount-api-list.md): :::info[Description] +- Classic REST > Account Info > Sub Account API [Add sub-account API](https://www.kucoin.com/docs-new/rest/account-info/sub-account-api/add-subaccount-api.md): :::info[Description] +- Classic REST > Account Info > Sub Account API [Modify sub-account API](https://www.kucoin.com/docs-new/rest/account-info/sub-account-api/modify-subaccount-api.md): :::info[Description] +- Classic REST > Account Info > Sub Account API [Delete sub-account API](https://www.kucoin.com/docs-new/rest/account-info/sub-account-api/delete-subaccount-api.md): :::info[Description] +- Classic REST > Account Info > Deposit [Add Deposit Address (V3)](https://www.kucoin.com/docs-new/rest/account-info/deposit/add-deposit-address-v3.md): :::info[Description] +- Classic REST > Account Info > Deposit [Get Deposit Address (V3)](https://www.kucoin.com/docs-new/rest/account-info/deposit/get-deposit-address-v3/en.md): :::info[Description] +- Classic REST > Account Info > Deposit [Get Deposit History](https://www.kucoin.com/docs-new/rest/account-info/deposit/get-deposit-history.md): :::info[Description] +- Classic REST > Account Info > Withdrawals [Get Withdrawal Quotas](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/get-withdrawal-quotas.md): :::info[Description] +- Classic REST > Account Info > Withdrawals [Withdraw (V3)](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/withdraw-v3.md): :::info[Description] +- Classic REST > Account Info > Withdrawals [Cancel Withdrawal](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/cancel-withdrawal.md): :::info[Description] +- Classic REST > Account Info > Withdrawals [Get Withdrawal History](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/get-withdrawal-history.md): :::info[Description] +- Classic REST > Account Info > Withdrawals [Get Withdrawal History By ID](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/get-withdrawal-by-id.md): :::info[Description] +- Classic REST > Account Info > Transfer [Get Transfer Quotas](https://www.kucoin.com/docs-new/rest/account-info/transfer/get-transfer-quotas.md): :::info[Description] +- Classic REST > Account Info > Transfer [Flex Transfer](https://www.kucoin.com/docs-new/rest/account-info/transfer/flex-transfer.md): :::info[Description] +- Classic REST > Account Info > Trade Fee [Get Basic Fee - Spot/Margin](https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-basic-fee-spot-margin.md): :::info[Description] +- Classic REST > Account Info > Trade Fee [Get Actual Fee - Spot/Margin](https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-actual-fee-spot-margin.md): :::info[Description] +- Classic REST > Account Info > Trade Fee [Get Actual Fee - Futures](https://www.kucoin.com/docs-new/rest/account-info/trade-fee/get-actual-fee-futures.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Announcements](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-announcements.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Currency](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-currency.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get All Currencies](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-all-currencies.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Symbol ](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-symbol.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get All Symbols](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-all-symbols.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Ticker](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-ticker.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get All Tickers](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-all-tickers.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Trade History](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-trade-history.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Klines](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-klines.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Part OrderBook](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-part-orderbook.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Full OrderBook](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-full-orderbook.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Call Auction Part OrderBook](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-call-auction-part-orderbook.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Call Auction Info](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-call-auction-info.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Fiat Price](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-fiat-price.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get 24hr Stats](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-24hr-stats.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Market List](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-market-list.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Client IP Address](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-client-ip-address.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Server Time](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-server-time.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get Service Status](https://www.kucoin.com/docs-new/rest/spot-trading/market-data/get-service-status.md): :::info[Description] +- Classic REST > Spot Trading > Market Data [Get KYC Regions](https://www.kucoin.com/docs-new/rest/account-info/withdrawals/get-kyc-regions.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Add Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Add Order Sync](https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-order-sync.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Add Order Test](https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-order-test.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Batch Add Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/batch-add-orders.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Batch Add Orders Sync](https://www.kucoin.com/docs-new/rest/spot-trading/orders/batch-add-orders-sync.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Order By OrderId Sync](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-order-by-orderld-sync.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Order By ClientOid Sync](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-order-by-clientoid-sync.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Partial Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-partial-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel All Orders By Symbol](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-all-orders-by-symbol.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel All Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-all-orders.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Modify Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/modify-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Symbols With Open Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-symbols-with-open-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Open Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Open Orders By Page](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-open-orders-by-page.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Closed Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-closed-orders.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Trade History](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-trade-history.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get DCP](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-dcp.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Set DCP](https://www.kucoin.com/docs-new/rest/spot-trading/orders/set-dcp.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Add Stop Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-stop-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Stop Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-stop-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel Stop Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-stop-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Batch Cancel Stop Orders](https://www.kucoin.com/docs-new/rest/spot-trading/orders/batch-cancel-stop-orders.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Stop Orders List](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-stop-orders-list.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Stop Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-stop-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get Stop Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/get-stop-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Add OCO Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/add-oco-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel OCO Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-oco-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Cancel OCO Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/cancel-oco-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Batch Cancel OCO Order](https://www.kucoin.com/docs-new/rest/spot-trading/orders/batch-cancel-oco-order.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get OCO Order By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-oco-order-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get OCO Order By ClientOid](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-oco-order-by-clientoid.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get OCO Order Detail By OrderId](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-oco-order-detail-by-orderld.md): :::info[Description] +- Classic REST > Spot Trading > Orders [Get OCO Order List](https://www.kucoin.com/docs-new/rest/spot-trading/orders/get-oco-order-list.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Symbols - Cross Margin](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-symbols-cross-margin.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Symbols - Isolated Margin](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-symbols-isolated-margin.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Mark Price Detail](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-mark-price-detail.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Margin Config](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-margin-config.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Mark Price List](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-mark-price-list.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Margin Collateral Ratio](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-margin-collateral-ratio.md): :::info[Description] +- Classic REST > Margin Trading > Market Data [Get Market Available Inventory ](https://www.kucoin.com/docs-new/rest/margin-trading/market-data/get-margin.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Add Order](https://www.kucoin.com/docs-new/rest/margin-trading/orders/add-order.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Add Order Test](https://www.kucoin.com/docs-new/rest/margin-trading/orders/add-order-test.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel All Orders By Symbol](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-all-orders-by-symbol.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Symbols With Open Order](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-symbols-with-open-order.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Open Orders](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-open-orders.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Closed Orders](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-closed-orders.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Trade History](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-trade-history.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Add Stop Order](https://www.kucoin.com/docs-new/rest/margin-trading/orders/add-stop-order.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel Stop Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-stop-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel Stop Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-stop-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Batch Cancel Stop Orders](https://www.kucoin.com/docs-new/rest/margin-trading/orders/batch-cancel-stop-orders.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Stop Orders List](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-list.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Stop Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get Stop Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-stop-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Add OCO Order](https://www.kucoin.com/docs-new/rest/margin-trading/orders/add-oco-order.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel OCO Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-oco-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Cancel OCO Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/cancel-oco-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Batch Cancel OCO Order](https://www.kucoin.com/docs-new/rest/margin-trading/orders/batch-cancel-oco-orders.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get OCO Order By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-oco-order-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get OCO Order By ClientOid](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-oco-order-by-clientoid.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get OCO Order Detail By OrderId](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-oco-order-detail-by-orderld.md): :::info[Description] +- Classic REST > Margin Trading > Orders [Get OCO Order List](https://www.kucoin.com/docs-new/rest/margin-trading/orders/get-oco-order-list.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Get Borrow Interest Rate](https://www.kucoin.com/docs-new/rest/margin-trading/debit/get-borrow-interest-rate.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Borrow](https://www.kucoin.com/docs-new/rest/margin-trading/debit/borrow.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Get Borrow History](https://www.kucoin.com/docs-new/rest/margin-trading/debit/get-borrow-history.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Repay](https://www.kucoin.com/docs-new/rest/margin-trading/debit/repay.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Get Repay History](https://www.kucoin.com/docs-new/rest/margin-trading/debit/get-repay-history.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Get Interest History](https://www.kucoin.com/docs-new/rest/margin-trading/debit/get-interest-history.md): :::info[Description] +- Classic REST > Margin Trading > Debit [Modify Leverage](https://www.kucoin.com/docs-new/rest/margin-trading/debit/modify-leverage.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Get Loan Market](https://www.kucoin.com/docs-new/rest/margin-trading/credit/get-loan-market.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Get Loan Market Interest Rate](https://www.kucoin.com/docs-new/rest/margin-trading/credit/get-loan-market-interest-rate.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Purchase](https://www.kucoin.com/docs-new/rest/margin-trading/credit/purchase.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Modify Purchase](https://www.kucoin.com/docs-new/rest/margin-trading/credit/modify-purchase.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Get Purchase Orders](https://www.kucoin.com/docs-new/rest/margin-trading/credit/get-purchase-orders.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Redeem](https://www.kucoin.com/docs-new/rest/margin-trading/credit/redeem.md): :::info[Description] +- Classic REST > Margin Trading > Credit [Get Redeem Orders](https://www.kucoin.com/docs-new/rest/margin-trading/credit/get-redeem-orders.md): :::info[Description] +- Classic REST > Margin Trading > Risk Limit [Get Margin Risk Limit](https://www.kucoin.com/docs-new/rest/margin-trading/risk-limit/get-margin-risk-limit.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get Symbol](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-symbol.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get All Symbols](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-all-symbols.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get Ticker](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-ticker.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get All Tickers](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-all-tickers.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get Full OrderBook](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-full-orderbook.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Part OrderBook](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-part-orderbook.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Trade History](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-trade-history.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Klines](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-klines.md): :::info[Description] +- Classic REST > Futures Trading > Market Data [Get Mark Price](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-mark-price.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Spot Index Price](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-spot-index-price.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Interest Rate Index](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-interest-rate-index.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Premium Index](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-premium-index.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get 24hr stats](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-24hr-stats.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Server Time](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-server-time.md): :::info[Discription] +- Classic REST > Futures Trading > Market Data [Get Service Status](https://www.kucoin.com/docs-new/rest/futures-trading/market-data/get-service-status.md): :::info[Discription] +- Classic REST > Futures Trading > Orders [Add Order](https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Add Order Test](https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-order-test.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Batch Add Orders](https://www.kucoin.com/docs-new/rest/futures-trading/orders/batch-add-orders.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Add Take Profit And Stop Loss Order](https://www.kucoin.com/docs-new/rest/futures-trading/orders/add-take-profit-and-stop-loss-order.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Cancel Order By OrderId](https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-order-by-orderld.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Cancel Order By ClientOid](https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-order-by-clientoid.md): :::info[Description] +- Classic REST > Futures Trading > Orders [rest/futures-trading/orders/batch-cancel-orders](https://www.kucoin.com/docs-new/3470241e0.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Cancel All Orders](https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-all-orders.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Cancel All Stop orders](https://www.kucoin.com/docs-new/rest/futures-trading/orders/cancel-all-stop-orders.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Order By OrderId](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-by-orderld.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Order By ClientOid](https://www.kucoin.com/docs-new/rest/futures-trading/get-stop-order-by-clientoid.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Order List](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-order-list.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Recent Closed Orders](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-recent-closed-orders.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Stop Order List](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-stop-order-list.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Open Order Value](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-open-order-value.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Recent Trade History](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-recent-trade-history.md): :::info[Description] +- Classic REST > Futures Trading > Orders [Get Trade History](https://www.kucoin.com/docs-new/rest/futures-trading/orders/get-trade-history.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Margin Mode](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-margin-mode.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Switch Margin Mode](https://www.kucoin.com/docs-new/rest/futures-trading/positions/switch-margin-mode.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Batch Switch Margin Mode](https://www.kucoin.com/docs-new/rest/futures-trading/positions/batch-switch-margin-mode.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Position Mode](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-position-mode.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Switch Position Mode](https://www.kucoin.com/docs-new/rest/futures-trading/positions/switch-position-mode.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Max Open Size](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-max-open-size.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Position Details](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-position-details.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Position List](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-position-list.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Positions History](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-positions-history.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Max Withdraw Margin](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-max-withdraw-margin.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Cross Margin Leverage](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-cross-margin-leverage.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Modify Cross Margin Leverage](https://www.kucoin.com/docs-new/rest/futures-trading/positions/modify-cross-margin-leverage.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Add Isolated Margin](https://www.kucoin.com/docs-new/rest/futures-trading/positions/add-isolated-margin.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Remove Isolated Margin](https://www.kucoin.com/docs-new/rest/futures-trading/positions/remove-isolated-margin.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Cross Margin Risk Limit](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-cross-margin-risk-limit.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Get Cross Margin Requirement](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-cross-margin-requirement.md): :::info[Discription] +- Classic REST > Futures Trading > Positions [Get Isolated Margin Risk Limit](https://www.kucoin.com/docs-new/rest/futures-trading/positions/get-isolated-margin-risk-limit.md): :::info[Description] +- Classic REST > Futures Trading > Positions [Modify Isolated Margin Risk Limit](https://www.kucoin.com/docs-new/rest/futures-trading/positions/modify-isolated-margin-risk-limit.md): :::info[Description] +- Classic REST > Futures Trading > Funding Fees [Get Current Funding Rate](https://www.kucoin.com/docs-new/rest/futures-trading/funding-fees/get-current-funding-rate.md): :::info[Description] +- Classic REST > Futures Trading > Funding Fees [Get Public Funding History](https://www.kucoin.com/docs-new/rest/futures-trading/funding-fees/get-public-funding-history.md): :::info[Description] +- Classic REST > Futures Trading > Funding Fees [Get Private Funding History](https://www.kucoin.com/docs-new/rest/futures-trading/funding-fees/get-private-funding-history.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Purchase](https://www.kucoin.com/docs-new/rest/earn/purchase.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get Redeem Preview](https://www.kucoin.com/docs-new/rest/earn/get-redeem-preview.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Redeem](https://www.kucoin.com/docs-new/rest/earn/redeem.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get Savings Products](https://www.kucoin.com/docs-new/rest/earn/get-savings-products.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get Promotion Products](https://www.kucoin.com/docs-new/rest/earn/get-promotion-products.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get Staking Products](https://www.kucoin.com/docs-new/rest/earn/get-staking-products.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get KCS Staking Products](https://www.kucoin.com/docs-new/rest/earn/get-kcs-staking-products.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get ETH Staking Products](https://www.kucoin.com/docs-new/rest/earn/get-eth-staking-products.md): :::info[Description] +- Classic REST > Earn > Simple Earn [Get Account Holding](https://www.kucoin.com/docs-new/rest/earn/get-account-holding.md): :::info[Description] +- Classic REST > Earn > Structured Earn - Dual [Structured Product Purchase](https://www.kucoin.com/docs-new/rest/earn/structured-product-purchase.md): :::info[Description] +- Classic REST > Earn > Structured Earn - Dual [Get Dual Investment Products](https://www.kucoin.com/docs-new/rest/earn/get-dual-investment-products.md): :::info[Description] +- Classic REST > Earn > Structured Earn - Dual [Get Structured Product Orders](https://www.kucoin.com/docs-new/rest/earn/get-structured-product-orders.md): :::info[Description] +- Classic REST > VIP Lending [Get Collateral Ratio](https://www.kucoin.com/docs-new/rest/vip-lending/get-collateral-ratio.md): :::info[Description] +- Classic REST > VIP Lending [Get Loan Info](https://www.kucoin.com/docs-new/rest/vip-lending/get-account-detail.md): :::info[Description] +- Classic REST > VIP Lending [Get Accounts](https://www.kucoin.com/docs-new/rest/vip-lending/get-accounts.md): :::info[Description] +- Classic REST > Affiliate [Get Invited](https://www.kucoin.com/docs-new/rest/affiliate/get-invited.md): :::info[Description] +- Classic REST > Affiliate [Get Commission](https://www.kucoin.com/docs-new/rest/affiliate/get-commission.md): :::info[Description] +- Classic REST > Affiliate [Get Trade History](https://www.kucoin.com/docs-new/rest/affiliate/get-trade-history.md): :::info[Description] +- Classic REST > Affiliate [Get Transaction](https://www.kucoin.com/docs-new/rest/affiliate/get-transaction.md): :::info[Description] +- Classic REST > Affiliate [Get Kumining](https://www.kucoin.com/docs-new/rest/affiliate/get-kumining.md): :::info[Description] +- Classic REST > Broker > Broker Pro [Get Broker Rebate](https://www.kucoin.com/docs-new/rest/broker/api-broker/get-broker-rebate.md): :::info[Description] +- Classic REST > Broker > Broker Pro [Get Commission](https://www.kucoin.com/docs-new/rest/broker/api-broker/get-commission.md): :::info[Description] +- Classic REST > Broker > Broker Pro [Get User List](https://www.kucoin.com/docs-new/rest/broker/api-broker/get-user-list.md): :::info[Description] +- Classic REST > Broker > Broker Pro [Get User Transactions](https://www.kucoin.com/docs-new/rest/broker/api-broker/get-user-transactions.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Submit KYC](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/submit-kyc.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get KYC Status](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-kyc-status.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get KYC Status List](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-kyc-status-list.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Broker Info](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-broker-info.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Add sub-account](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/add-subaccount.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get sub-account](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-subaccount.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Add sub-account API](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/add-subaccount-api.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get sub-account API](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-subaccount-api.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Modify sub-account API](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/modify-subaccount-api.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Delete sub-account API](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/delete-subaccount-api.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Transfer](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/transfer.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Transfer History](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-transfer-history.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Deposit List](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-deposit-list.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Deposit Detail](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-deposit-detail.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Withdraw Detail](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-withdraw-detail.md): :::info[Description] +- Classic REST > Broker > Exchange Broker [Get Broker Rebate](https://www.kucoin.com/docs-new/rest/broker/exchange-broker/get-broker-rebate.md): :::info[Description] +- Classic REST > Copy Trading [Add Order](https://www.kucoin.com/docs-new/rest/copy-trading/add-order.md): :::info[Description] +- Classic REST > Copy Trading [Add Order Test](https://www.kucoin.com/docs-new/rest/copy-trading/add-order-test.md): :::info[Description] +- Classic REST > Copy Trading [Add Take Profit And Stop Loss Order](https://www.kucoin.com/docs-new/rest/copy-trading/add-take-profit-and-stop-loss-order.md): :::info[Description] +- Classic REST > Copy Trading [Cancel Order By OrderId](https://www.kucoin.com/docs-new/rest/copy-trading/cancel-order-by-orderid.md): :::info[Description] +- Classic REST > Copy Trading [Cancel Order By ClientOid](https://www.kucoin.com/docs-new/rest/copy-trading/cancel-order-by-clientoid.md): :::info[Description] +- Classic REST > Copy Trading [Get Max Open Size](https://www.kucoin.com/docs-new/rest/copy-trading/get-max-open-size.md): :::info[Description] +- Classic REST > Copy Trading [Get Max Withdraw Margin](https://www.kucoin.com/docs-new/rest/copy-trading/get-max-withdraw-margin.md): :::info[Description] +- Classic REST > Copy Trading [Add Isolated Margin](https://www.kucoin.com/docs-new/rest/copy-trading/add-isolated-margin.md): :::info[Description] +- Classic REST > Copy Trading [Remove Isolated Margin](https://www.kucoin.com/docs-new/rest/copy-trading/remove-isolated-margin.md): :::info[Description] +- Classic REST > Copy Trading [Modify Isolated Margin Risk Limit](https://www.kucoin.com/docs-new/rest/copy-trading/modify-isolated-margin-risk-limit.md): :::info[Description] +- Classic REST > Copy Trading [Modify Isolated Margin Auto-Deposit Status](https://www.kucoin.com/docs-new/rest/copy-trading/modify-isolated-margin-auto-deposit-status.md): :::info[Description] +- Classic REST > Copy Trading [Switch Margin Mode](https://www.kucoin.com/docs-new/rest/copy-trading/switch-margin-mode.md): :::info[Description] +- Classic REST > Copy Trading [Modify Cross Margin Leverage](https://www.kucoin.com/docs-new/rest/copy-trading/modify-cross-margin-leverage.md): :::info[Description] +- Classic REST > Copy Trading [Get Cross Margin Requirement](https://www.kucoin.com/docs-new/rest/copy-trading/get-cross-margin-requirement.md): :::info[Discription] +- Classic REST > Copy Trading [Switch Position Mode](https://www.kucoin.com/docs-new/rest/copy-trading/switch-position-mode.md): :::info[Description] +- Classic REST > Convert [Get Convert Symbol](https://www.kucoin.com/docs-new/rest/convert/get-convert-symbol.md): :::info[Description] +- Classic REST > Convert [Get Convert Currencies](https://www.kucoin.com/docs-new/rest/convert/get-convert-currencies.md): :::info[Description] +- Classic REST > Convert [Get Convert Quote](https://www.kucoin.com/docs-new/rest/convert/get-convert-quote.md): :::info[Description] +- Classic REST > Convert [Add Convert Order](https://www.kucoin.com/docs-new/rest/convert/add-convert-order.md): :::info[Description] +- Classic REST > Convert [Get Convert Order Detail](https://www.kucoin.com/docs-new/rest/convert/get-convert-order-detail.md): :::info[Description] +- Classic REST > Convert [Get Convert Order History](https://www.kucoin.com/docs-new/rest/convert/get-convert-order-history.md): :::info[Description] +- Classic REST > Convert [Add Convert Limit Order](https://www.kucoin.com/docs-new/rest/convert/add-convert-limit-order.md): :::info[Description] +- Classic REST > Convert [Get Convert Limit Quote](https://www.kucoin.com/docs-new/rest/convert/get-convert-limit-quote.md): :::info[Description] +- Classic REST > Convert [Get Convert Limit Order Detail](https://www.kucoin.com/docs-new/rest/convert/get-convert-limit-order-detail.md): :::info[Description] +- Classic REST > Convert [Get Convert Limit Orders](https://www.kucoin.com/docs-new/rest/convert/get-convert-limit-orders.md): :::info[Description] +- Classic REST > Convert [Cancel Convert Limit Order](https://www.kucoin.com/docs-new/rest/convert/cancel-convert-limit-order.md): :::info[Description] +- Classic WebSocket > Base Info [Get Public Token - Classic Spot/Margin](https://www.kucoin.com/docs-new/websocket-api/base-info/get-public-token-spot-margin.md): :::info[Description] +- Classic WebSocket > Base Info [Get Private Token - Classic Spot/Margin](https://www.kucoin.com/docs-new/websocket-api/base-info/get-private-token-spot-margin.md): :::info[Description] +- Classic WebSocket > Base Info [Get Public Token - Classic Futures](https://www.kucoin.com/docs-new/websocket-api/base-info/get-public-token-futures.md): :::info[Description] +- Classic WebSocket > Base Info [Get Private Token - Classic Futures](https://www.kucoin.com/docs-new/websocket-api/base-info/get-private-token-futures.md): :::info[Description] +- Classic WebSocket > Spot Trading > Public Channels [Ticker](https://www.kucoin.com/docs-new/3470063w0.md): ## Topic: /market/ticker:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [All Tickers](https://www.kucoin.com/docs-new/3470064w0.md): ## Topic: /market/ticker:all +- Classic WebSocket > Spot Trading > Public Channels [Orderbook - Level 1](https://www.kucoin.com/docs-new/3470067w0.md): ## Topic: /spotMarket/level1:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Orderbook - Level 5](https://www.kucoin.com/docs-new/3470069w0.md): ## Topic:/spotMarket/level2Depth5:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Orderbook - Level 50](https://www.kucoin.com/docs-new/3470070w0.md): ## Topic:/spotMarket/level2Depth50:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Orderbook - Increment](https://www.kucoin.com/docs-new/3470068w0.md): ## Topic:/market/level2:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Call Auction Orderbook - Level 50](https://www.kucoin.com/docs-new/3470137w0.md): ## Topic:/callauction/level2Depth50:{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Call Auction Data](https://www.kucoin.com/docs-new/3470138w0.md): ## Topic: /callauction/callauctionData:{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Klines](https://www.kucoin.com/docs-new/3470071w0.md): ## Topic:/market/candles:{symbol}_{type} +- Classic WebSocket > Spot Trading > Public Channels [Trade](https://www.kucoin.com/docs-new/3470072w0.md): ## Topic:/market/match:{symbol},{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Symbol Snapshot](https://www.kucoin.com/docs-new/3470065w0.md): ## Topic: /market/snapshot:{symbol} +- Classic WebSocket > Spot Trading > Public Channels [Market Snapshot ](https://www.kucoin.com/docs-new/3470066w0.md): ## Topic: /market/snapshot:{market} +- Classic WebSocket > Spot Trading > Private Channels [Order V2](https://www.kucoin.com/docs-new/3470073w0.md): ## Topic:/spotMarket/tradeOrdersV2 +- Classic WebSocket > Spot Trading > Private Channels [Order V1](https://www.kucoin.com/docs-new/3470074w0.md): ## Topic:/spotMarket/tradeOrders +- Classic WebSocket > Spot Trading > Private Channels [Balance](https://www.kucoin.com/docs-new/3470075w0.md): ## Topic:/account/balance +- Classic WebSocket > Spot Trading > Private Channels [Stop Order](https://www.kucoin.com/docs-new/3470139w0.md): ## Topic:/spotMarket/advancedOrders +- Classic WebSocket > Margin Trading > Public Channels [Index Price](https://www.kucoin.com/docs-new/3470076w0.md): ## Topic: /indicator/index:{symbol0},{symbol1} +- Classic WebSocket > Margin Trading > Public Channels [Mark Price](https://www.kucoin.com/docs-new/3470077w0.md): ## Topic:/indicator/markPrice:{symbol0},{symbol1} +- Classic WebSocket > Margin Trading > Private Channels [Order V2](https://www.kucoin.com/docs-new/3470256w0.md): ## Topic:/spotMarket/tradeOrdersV2 +- Classic WebSocket > Margin Trading > Private Channels [Order V1](https://www.kucoin.com/docs-new/3470257w0.md): ## Topic:/spotMarket/tradeOrders +- Classic WebSocket > Margin Trading > Private Channels [Balance](https://www.kucoin.com/docs-new/3470258w0.md): ## Topic:/account/balance +- Classic WebSocket > Margin Trading > Private Channels [Stop Order](https://www.kucoin.com/docs-new/3470259w0.md): ## Topic:/spotMarket/advancedOrders +- Classic WebSocket > Margin Trading > Private Channels [Cross Margin Position](https://www.kucoin.com/docs-new/3470078w0.md): ## Topic: /margin/position +- Classic WebSocket > Margin Trading > Private Channels [Isolated Margin Position](https://www.kucoin.com/docs-new/3470079w0.md): ## Topic: /margin/isolatedPosition:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Ticker V2](https://www.kucoin.com/docs-new/3470080w0.md): ## Topic: /contractMarket/tickerV2:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Ticker V1](https://www.kucoin.com/docs-new/3470081w0.md): ## Topic: /contractMarket/ticker:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Orderbook - Level 5](https://www.kucoin.com/docs-new/3470083w0.md): ## Topic: /contractMarket/level2Depth5:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Orderbook - Level 50](https://www.kucoin.com/docs-new/3470097w0.md): ## Topic: /contractMarket/level2Depth50:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Orderbook - Increment](https://www.kucoin.com/docs-new/3470082w0.md): ## Topic: /contractMarket/level2:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Klines](https://www.kucoin.com/docs-new/3470086w0.md): ## Topic: /contractMarket/limitCandle:{symbol}_{type} +- Classic WebSocket > Futures Trading > Public Channels [Trade](https://www.kucoin.com/docs-new/3470084w0.md): ## Topic: /contractMarket/execution:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Instrument](https://www.kucoin.com/docs-new/3470087w0.md): ## Topic: /contract/instrument:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Funding Fee Settlement](https://www.kucoin.com/docs-new/3470088w0.md): ## Topic: /contract/announcement:{symbol} +- Classic WebSocket > Futures Trading > Public Channels [Symbol Snapshot](https://www.kucoin.com/docs-new/3470089w0.md): ## Topic: /contractMarket/snapshot:{symbol} +- Classic WebSocket > Futures Trading > Private Channels [Orders](https://www.kucoin.com/docs-new/3470090w0.md): ## Topic: /contractMarket/tradeOrders +- Classic WebSocket > Futures Trading > Private Channels [Balance](https://www.kucoin.com/docs-new/3470092w0.md): ## Topic:/contractAccount/wallet +- Classic WebSocket > Futures Trading > Private Channels [Positions](https://www.kucoin.com/docs-new/3470093w0.md): ## Topic: /contract/positionAll +- Classic WebSocket > Futures Trading > Private Channels [Margin Mode](https://www.kucoin.com/docs-new/3470095w0.md): ## Topic: /contract/marginMode +- Classic WebSocket > Futures Trading > Private Channels [Cross Margin Leverage](https://www.kucoin.com/docs-new/3470096w0.md): ## Topic: /contract/crossLeverage +- Classic WebSocket > Futures Trading > Private Channels [Stop Orders](https://www.kucoin.com/docs-new/3470091w0.md): ## Topic: /contractMarket/advancedOrders +- Classic WebSocket > Add/Cancel Order [Add Order](https://www.kucoin.com/docs-new/3470252w0.md): :::info[Description] +- Classic WebSocket > Add/Cancel Order [Cancel Order](https://www.kucoin.com/docs-new/3470253w0.md): :::info[Description] +- Abandoned Endpoints > Account & Funding [Get sub-account List - Summary Info (V1)](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-subacconut-list-summary-info-v1.md): :::tip[] +- Abandoned Endpoints > Account & Funding [Get sub-account List - Spot Balance (V1)](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-subacconut-list-spot-balance-v1.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Get Deposit Addresses (V2)](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-deposit-addresses-v2.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Get Deposit Addresses - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-deposit-addresses-v1.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Sub-account Transfer](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/subaccount-transfer.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Get Deposit History - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-deposit-history-old.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Internal Transfer](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/inner-transfer.md): :::warning[Warning] +- Abandoned Endpoints > Account & Funding [Get Futures Account Transfer Out Ledger](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-futures-account-transfer-out-ledger.md): :::info[Description] +- Abandoned Endpoints > Account & Funding [Get Withdrawal History - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/get-withdrawal-history-old.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Futures Account Transfer Out](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/futures-account-transfer-out.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Futures Account Transfer In](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/futures-account-transfer-in.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Add Deposit Address - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/add-deposit-address-v1.md): :::tip[TIPS] +- Abandoned Endpoints > Account & Funding [Withdraw - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/account-funding/withdraw-v1.md): :::tip[TIPS] +- Abandoned Endpoints > Spot Trading > Orders [Add Order - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/add-order-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Add Order Test - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/add-order-test-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Batch Add Orders - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/batch-add-orders-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Cancel Order By OrderId - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/cancel-order-by-orderld-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Cancel Order By ClientOid - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/cancel-order-by-clientoid-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Batch Cancel Order - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/batch-cancel-order-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Orders List - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-orders-list-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Recent Orders List - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-recent-orders-list-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Order By OrderId - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-order-by-orderld-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Order By ClientOid - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-order-by-clientoid-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Trade History - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-trade-history-old.md): :::tip[] +- Abandoned Endpoints > Spot Trading > Orders [Get Recent Trade History - Old](https://www.kucoin.com/docs-new/abandoned-endpoints/spot-trading/orders/get-recent-trade-history-old.md): re +- Abandoned Endpoints > Margin Trading [Get ETF Info](https://www.kucoin.com/docs-new/abandoned-endpoints/rest/margin-trading/market-data/get-etf-info.md): :::info[Description] +- Abandoned Endpoints > Margin Trading [Get Account Detail - Margin](https://www.kucoin.com/docs-new/abandoned-endpoints/margin-trading/get-account-detail-margin.md): :::tip[TIPS] +- Abandoned Endpoints > Margin Trading [Add Order - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/margin-trading/add-order-v1.md): :::warning[Warning] +- Abandoned Endpoints > Margin Trading [Add Order Test - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/margin-trading/add-order-test-v1.md): :::warning[Warning] +- Abandoned Endpoints > Margin Trading [Get Account List - Isolated Margin - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/margin-trading/get-account-list-isolated-margin-v1.md): :::warning[Warning] +- Abandoned Endpoints > Margin Trading [Get Account Detail - Isolated Margin - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/margin-trading/get-account-detail-isolated-margin-v1.md): :::warning[Warning] +- Abandoned Endpoints > Futures Trading [Modify Isolated Margin Auto - Deposit Status](https://www.kucoin.com/docs-new/abandoned-endpoints/futures-trading/modify-isolated-margin-auto-deposit-status.md): :::tip[TIPS] +- Abandoned Endpoints > Futures Trading [Cancel All Orders - V1](https://www.kucoin.com/docs-new/abandoned-endpoints/futures-trading/cancel-all-orders-v1.md): :::tip[TIPS] +- Abandoned Endpoints > Futures Trading [Get Position Details - V1](https://www.kucoin.com/docs-new/3475249e0.md): :::info[Description] +- Abandoned Endpoints > Affiliate [Get Account](https://www.kucoin.com/docs-new/abandoned-endpoints/affiliate/get-account.md): :::info[Description] +- Abandoned Endpoints > Broker > Broker Pro [Get Broker Rebate](https://www.kucoin.com/docs-new/3470280e0.md): :::tip[TIPS] \ No newline at end of file diff --git a/docs/signal-contract-v2.md b/docs/signal-contract-v2.md new file mode 100644 index 0000000..f00e885 --- /dev/null +++ b/docs/signal-contract-v2.md @@ -0,0 +1,114 @@ +## Plan: Move volume computation from executor to fused_engine + +### Goal +fused_engine computes per-leg order parameters (`funds`/`size`), precision-rounded. +Executor becomes a thin dispatcher — validate+simulate (paper) or place+record (live). + +### New signal schema + +```json +{ + "type": "signal", + "live": false, + "legs": [ + {"pair": "BTC-USDT", "side": "buy", "funds": "5.01", "base_increment": "0.00001", "quote_increment": "0.01", "base_min": "0.0001"}, + {"pair": "ETH-BTC", "side": "sell", "size": "0.0495", "base_increment": "0.001", "quote_increment": "0.01", "base_min": "0.001"}, + {"pair": "ETH-USDT", "side": "sell", "size": "0.0498", "base_increment": "0.001", "quote_increment": "0.01", "base_min": "0.001"} + ], + "starting_volume": "5.01", + "predicted_bps": 12.5, + "books": [{"symbol": "BTC-USDT", "bids": [...], "asks": [...]}, ...], + "ts_ms": 1779400000000, + "book_ts_ms": 1779400000000, + "t_arrive_ms": 1779400000000, + "t_eval_ms": 1779400000000, + "triangle_key": ["USDT","BTC","ETH"], + "correlation_id": "abc123" +} +``` + +- `live=true`: no `books`, no `size`/`funds` — executor places leg 0 with `starting_volume`, KuCoin fills drive the chain +- `live=false`: `books` present for simulation, `funds`/`size` pre-computed, executor passes them straight to `order_test()` + +### fused_engine changes + +#### 1. Store symbol precision metadata (`symbols_api.c`) +Already fetches `/api/v2/symbols`. Add to `trading_pair_t`: +``` +char base_increment[32]; +char quote_increment[32]; +char base_min_size[32]; +``` +Parse from `baseIncrement`, `quoteIncrement`, `baseMinSize` fields in the API response. + +#### 2. Per-leg volume computation (`evaluate.c`) +After computing `max_volume` in evaluate_symbol, add a new function that runs the executor's current volume logic in C: + +``` +compute_leg_volumes( + triangle, books, max_volume, fee_rates, + out_leg_funds_or_size[3], + out_leg_side[3] +) +``` + +Steps (mirrors executor.py:550-608): +- `starting = cost_to_precision(max_volume, leg0.quote_increment)` +- For leg 0 (buy): `net = starting * (1 - fee)`, `base = floor(net / ask, base_inc)`, recompute `funds = cost_precision(base * ask, quote_inc)` +- For leg 1: `input = leg0.base_output`. Same buy/sell logic +- For leg 2: same +- Store `funds` for buys, `size` for sells + +The computation is pure arithmetic (no I/O): Decimal-style operations using `strtod`/`sprintf` with integer math or floating point with epsilon guards. Or use a lightweight bignum lib. + +#### 3. Signal JSON format (`evaluate.c` and `events.c`) +Update both `format_signal_json` (evaluate.c, unused today — keep for debugging) and `send_signal_to_executor` (events.c) to emit the new schema, including per-leg `funds`/`size` and increment fields. + +Remove `fee_rate` and `exchange_rate` from leg JSON — executor no longer needs them. + +#### 4. Live vs paper mode selection +Config: add `live_mode: bool` to config.yaml (default false). fused_engine reads it and conditionalizes signal content. + +### Executor changes (`executor.py`) + +#### 1. Remove dead code +- `get_symbol_meta()` and `SymbolMeta` (kucoin_api.py:226-228 + dataclass) +- Volume propagation (executor.py:550-558) +- Precision rounding per leg (executor.py:564-608) +- `_precheck_volume()` → simplify to just check `starting_volume >= min_size` per leg using the `base_min`/`base_increment` from the signal +- Fee computation in paper fill simulation (executor.py:823) → use fee_currency from signal leg +- `legs[i - 1].get("fee_rate")` → executor no longer knows fee rates, use from signal + +#### 2. New signal parsing +Extract `live`, `legs` with pre-computed `funds`/`size`, increment fields, `starting_volume`. + +#### 3. live=true path +- Leg 0: `order_place(funds=starting_volume)`, await fill +- Subsequent legs: `order_place(funds=actual_propagated)` — no, the actual fill drives the next leg. Keep current propagation (actual fill.filled_volume feeds next leg input) — this stays because KuCoin returns real fills. + +#### 4. live=false path (paper) +- Each leg: `order_test(funds=leg.funds)` or `order_test(size=leg.size)` — pass through +- Paper fill simulation: use signal `books` + leg `base_increment`/`quote_increment` to compute `deal_funds` ← this is the only volume math remaining in the executor +- Simulate: apply fee to base_or_quote, round to precision, compute effective deal_funds +- profit = `fills[2].deal_funds - fills[0].deal_funds` + +#### 5. Paper fill simulation (what stays) +The executor must still: +- Read `books[i].asks[0].price` / `bids[0].price` +- For buys: compute how much base you'd get for `funds` at that top-of-book price, after fee, rounded to `base_increment` +- For sells: compute how much quote you'd get for `size` at that top-of-book price, after fee, rounded to `quote_increment` +- This is ~20 lines per leg, no external dependencies + +### Migration order +1. Add precision fields to `trading_pair_t` and parse from API +2. Add volume computation in `evaluate.c` +3. Update signal JSON format (both functions) +4. Strip executor down +5. Test paper mode, then live mode + +### Risk: Decimal precision in C +The executor uses Python `Decimal` for exact precision. In C, we can: +- Use `double` with `ceil()`/`floor()` and `1e-10` epsilon guards (simple, adequate for crypto tick sizes) +- Or use integer math: multiply by 10^decimals, do integer rounding, convert back + +For crypto tick sizes (0.00001, 0.01, 0.1), doubles are precise enough. No need for bignum. diff --git a/executor/__init__.py b/executor/__init__.py new file mode 100644 index 0000000..11aedaa --- /dev/null +++ b/executor/__init__.py @@ -0,0 +1,9 @@ +""" +Executor package. + +Re-exports the Executor class used by the fused_engine process. +""" + +from executor.executor import Executor + +__all__ = ["Executor"] diff --git a/executor/__main__.py b/executor/__main__.py new file mode 100644 index 0000000..922a36c --- /dev/null +++ b/executor/__main__.py @@ -0,0 +1,132 @@ +""" +Executor process entry point. + +Starts the Unix-socket signal server, REST API control interface, +and orchestrates clean shutdown on SIGTERM/SIGINT. +""" +import asyncio +import signal +from pathlib import Path +from typing import Optional + +import structlog +import uvicorn +from common.log import configure_logging + +from executor.config import Settings +from executor.executor import Executor +from executor.kucoin_api import KuCoinAPI +from executor.rest_api import create_app +from executor.socket_server import SignalSocketServer +from executor.ws_client import KuCoinWSClient + + +async def main() -> None: + config_path = Path("config.yaml") + settings = await Settings.from_yaml(config_path) if config_path.exists() else Settings() + configure_logging(settings.executor.log_level) # file I/O handled by Executor's _DualLogger + + log = structlog.get_logger().bind(component="executor") + + log.info("executor_starting", live_mode=settings.live_mode) + + # Always initialise KuCoinAPI even in paper mode — symbol metadata is + # needed for size/precision validation regardless of execution mode. + api = KuCoinAPI( + api_key=settings.kucoin_api_key, + api_secret=settings.kucoin_api_secret, + api_passphrase=settings.kucoin_api_passphrase, + ) + await api.fetch_symbols() + + ws_client: Optional[KuCoinWSClient] = None + if settings.live_mode: + # Live mode requires the private WebSocket client to receive fill events. + ws_client = KuCoinWSClient( + kucoin_api=api, + private_token_url=settings.executor.private_token_url, + ) + + executor = Executor( + kucoin_api=api, + settings=settings.executor, + ws_client=ws_client, + log_file=settings.executor.log_file, + live_mode=settings.live_mode, + ) + await executor.start() + + should_exit = asyncio.Event() + + def shutdown_callback() -> None: + should_exit.set() + + rest_app = create_app(executor, shutdown_callback=shutdown_callback) + rest_config = uvicorn.Config( + rest_app, + host="127.0.0.1", + port=settings.executor.rest_port, + log_level="warning", + ) + rest_server = uvicorn.Server(rest_config) + + socket_server = SignalSocketServer( + socket_path=settings.executor.socket_path, + on_signal=executor.handle_signal, + ) + + socket_task: asyncio.Task | None = None + rest_task: asyncio.Task | None = None + exit_task: asyncio.Task | None = None + ws_task: asyncio.Task | None = None + + async def shutdown(sig: signal.Signals) -> None: + """Clean up on shutdown signal: pause executor, cancel tasks, close server.""" + log.info("shutdown_signal_received", signal=sig.name) + await executor.pause() + await executor.close() + if socket_task is not None and not socket_task.done(): + socket_task.cancel() + if rest_task is not None: + rest_server.should_exit = True + if ws_client is not None: + await ws_client.stop() + should_exit.set() + + loop = asyncio.get_running_loop() + # Register signal handlers so shutdown runs in the asyncio event loop + # rather than in a plain threading context. + for sig in (signal.SIGTERM, signal.SIGINT): + loop.add_signal_handler(sig, lambda s=sig: asyncio.create_task(shutdown(s))) + + socket_task = asyncio.create_task(socket_server.start()) + rest_task = asyncio.create_task(rest_server.serve()) + exit_task = asyncio.create_task(should_exit.wait()) + + if ws_client is not None: + ws_task = asyncio.create_task(ws_client.start()) + + log.info( + "executor_ready", + rest_endpoint=f"http://127.0.0.1:{settings.executor.rest_port}", + socket_path=str(settings.executor.socket_path), + live_mode=settings.live_mode, + ) + + tasks = {t for t in (socket_task, rest_task, exit_task, ws_task) if t is not None} + try: + done, pending = await asyncio.wait(tasks, return_when=asyncio.FIRST_COMPLETED) + except asyncio.CancelledError: + log.info("executor_cancelled") + finally: + rest_server.should_exit = True + for t in tasks: + if not t.done(): + await asyncio.wait({t}, timeout=3.0) + if not t.done(): + t.cancel() + log.info("executor_shutdown_complete") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/executor/config.py b/executor/config.py new file mode 100644 index 0000000..ba0d593 --- /dev/null +++ b/executor/config.py @@ -0,0 +1,89 @@ +""" +Executor configuration loaded from config.yaml. + +Defines settings for the triangular arbitrage executor including +Unix socket path, concurrency limits, KuCoin credentials, and logging. + +live_mode at the top level controls whether the executor places real +orders (live) or validates via order_test and simulates fills (paper). +""" +import asyncio +import logging +from decimal import Decimal +from pathlib import Path +from typing import Optional + +import yaml +from pydantic import BaseModel, Field +from pydantic_settings import BaseSettings + +log = logging.getLogger("executor-config") + + +class ExecutorSettings(BaseModel): + """Settings that control executor runtime behaviour.""" + + socket_path: Path = Field( + default=Path("/tmp/executor.sock"), + description="Unix domain socket path for fused_engine -> executor", + ) + concurrent_slots: int = Field(default=1, ge=1, description="Max concurrent triangle executions") + enforce_same_base_isolation: bool = Field( + default=True, + description="Block concurrent triangles sharing the same base currency", + ) + enforce_pair_isolation: bool = Field( + default=True, + description="Block concurrent triangles that share any trading pair symbol", + ) + log_file: Path = Field( + default=Path("/tmp/executor.log"), + description="Path to log file", + ) + log_level: str = Field(default="INFO", description="Logging level") + rest_port: int = Field( + default=8002, + description="HTTP REST API port (8000=fh_ob, 8001=oe_em)", + ) + initial_capital: dict[str, Decimal] = Field( + default_factory=lambda: {"USDT": Decimal("10")}, + description="Starting capital per currency. Caps the max_volume for each triangle's primary_quote.", + ) + private_token_url: str = Field( + default="https://api.kucoin.com/api/v1/bullet-private", + description="KuCoin private bullet token endpoint", + ) + fill_timeout_ms: float = Field( + default=1000, + description="Per-leg fill wait timeout in milliseconds", + ) + + +class Settings(BaseSettings): + """Top-level settings parsed from config.yaml.""" + + # live_mode is the master switch: False = paper (order_test + simulated fills), + # True = real orders on KuCoin. Set at top level of config.yaml. + live_mode: bool = Field(default=False, description="false = paper; true = live orders") + executor: ExecutorSettings = Field(default_factory=ExecutorSettings) + kucoin_api_key: str = Field(default="", description="KuCoin API key") + kucoin_api_secret: str = Field(default="", description="KuCoin API secret") + kucoin_api_passphrase: str = Field(default="", description="KuCoin API passphrase") + + @classmethod + async def from_yaml(cls, path: Path) -> "Settings": + """Load settings from a YAML file, ignoring unknown keys.""" + loop = asyncio.get_running_loop() + + def _read() -> dict: + with open(path) as f: + return yaml.safe_load(f) or {} + + data = await loop.run_in_executor(None, _read) + known = {"live_mode", "fused_engine", "executor", "kucoin_api_key", "kucoin_api_secret", "kucoin_api_passphrase"} + unknown = set(data.keys()) - known + if unknown: + log.warning("ignoring unknown config keys: %s", sorted(unknown)) + return cls(**data) + + model_config = {"env_prefix": "TRIArb_", "extra": "ignore"} diff --git a/executor/executor.py b/executor/executor.py new file mode 100644 index 0000000..faa83aa --- /dev/null +++ b/executor/executor.py @@ -0,0 +1,1001 @@ +""" +Triangular arbitrage executor. + +Handles incoming opportunity signals from oe_em, enforces concurrency and +isolation constraints, computes order sizes, and posts orders to KuCoin +(via order_test in paper mode or real orders in live mode). + +Signal contract +--------------- +Each signal dict carries: + legs list[dict] — 3 legs, each with pair, side, order_param, + base_min_size, fee_rate, fee_currency + books list[dict] — order book snapshots per leg (top-of-book) + starting_volume str — quote-currency amount to deploy into leg 0 + predicted_bps float — expected profit in basis points + primary_quote str — e.g. "USDT", used for capital capping & isolation + live bool — true = real orders, false = paper simulation + book_ts_ms int — when the order book was sampled (stale detection) + t_sock_arrive_ms int — when bytes arrived at SSL_read (true network arrival) + t_arrive_ms int — when parsing + book update completed + ts_ms int — when the signal was created + t_eval_ms int — when the signal was evaluated + _cancelled bool — set by cancel_execution to abort in-flight +""" +import asyncio +import contextlib +import json +import logging +import time +import uuid +from collections import deque +from dataclasses import dataclass, field +from datetime import datetime +from decimal import Decimal +from pathlib import Path +from typing import Optional + +import aiohttp +from aiohttp.connector import TCPConnector +import structlog + + +_D0 = Decimal("0") +_D1 = Decimal("1") +_D0_1 = Decimal("0.1") + + +class _DualLogger: + """ + Thin wrapper that mirrors structlog output to a plain-text file via an + async queue, keeping file I/O off the asyncio event loop. + + The plain-text log supplements structlog's JSON output (written to + stdout) with a human-readable format that is useful for manual inspection. + """ + + def __init__(self, structlog_logger, log_file: Optional[Path]) -> None: + self._sl = structlog_logger + self._log_file = log_file + self._queue: Optional[asyncio.Queue] = None + self._task: Optional[asyncio.Task] = None + if log_file: + self._queue = asyncio.Queue() + self._task = asyncio.create_task(self._writer_loop()) + + async def _writer_loop(self) -> None: + """Background task that drains the queue and writes lines to disk + via a thread-pool executor so the event loop never blocks on I/O.""" + loop = asyncio.get_running_loop() + log_file = self._log_file + + def _write(line: str) -> None: + with open(log_file, "a") as f: + f.write(line) + + while True: + item = None + try: + item = await self._queue.get() + except asyncio.CancelledError: + while not self._queue.empty(): + try: + self._queue.get_nowait() + self._queue.task_done() + except asyncio.QueueEmpty: + break + raise + except Exception: + continue + + self._queue.task_done() + + if item is None: + break + + try: + await loop.run_in_executor(None, _write, item) + except Exception: + pass + + @staticmethod + def _fmt_value(v: object) -> str: + if isinstance(v, (dict, list)): + return json.dumps(v, default=str, separators=(",", ":")) + return str(v) + + def _enqueue(self, level: str, event: str, **kw) -> None: + """Publish a log entry to structlog and, if a log file is set, to the queue.""" + sl_level = getattr(logging, level.upper(), logging.INFO) + if not self._sl.is_enabled_for(sl_level): + return + getattr(self._sl, level)(event, **kw) + if self._queue is None: + return + ts = f"{time.time():.0f}" + level_up = level.upper() + extras = " ".join( + f"{k}={self._fmt_value(v)}" + for k, v in kw.items() + if not k.startswith("_") + ) + line = f"[{ts}] [{level_up:5}] {event} {extras}\n" + try: + self._queue.put_nowait(line) + except asyncio.QueueFull: + pass + + def write_plain(self, text: str) -> None: + """Write a line directly to the plain-text log queue (no structlog side-effect).""" + if self._queue is not None: + try: + self._queue.put_nowait(text + "\n") + except asyncio.QueueFull: + pass + + def debug(self, event: str, **kw) -> None: + self._enqueue("debug", event, **kw) + + def info(self, event: str, **kw) -> None: + self._enqueue("info", event, **kw) + + def warning(self, event: str, **kw) -> None: + self._enqueue("warning", event, **kw) + + def error(self, event: str, **kw) -> None: + self._enqueue("error", event, **kw) + + async def close(self) -> None: + """Signal the writer to stop and wait for it to flush.""" + if self._queue is not None: + await self._queue.put(None) + await self._queue.join() + if self._task is not None: + self._task.cancel() + try: + await self._task + except asyncio.CancelledError: + pass + + +@dataclass +class LegFill: + """Record of a single leg's filled order.""" + leg: int + order_id: str + side: str + pair: str + input_currency: str + output_currency: str + fee_currency: str + filled_volume: Decimal + deal_funds: Decimal + avg_price: Decimal + fee: Decimal + latency_ms: float = 0.0 + + +@dataclass +class ExecutionReport: + """Summary of a triangle execution attempt, emitted after each fill or failure.""" + correlation_id: str + triangle_key: list[str] + status: str + fills: list[LegFill] + predicted_bps: float + ts_ms: int + timings: list[dict] = field(default_factory=list) + profit: float = 0.0 + effective_bps: float = 0.0 + error: str = "" + + +@dataclass +class InFlightExecution: + """Track a triangle execution that is currently in flight.""" + triangle_key: frozenset + pair_symbols: frozenset + primary_quote: str + correlation_id: str + signal: dict + started_ts_ms: int + last_trade_ts_ms: int = 0 + + +class Executor: + """ + Triangular arbitrage order executor. + + Receives signals from oe_em via a Unix-domain socket, checks volume and + concurrency constraints, then executes up to three legs in sequence. + """ + + def __init__( + self, + kucoin_api, + settings, + ws_client = None, + log_file: Optional[Path] = None, + live_mode: bool = False, + ) -> None: + self._api = kucoin_api + self._settings = settings + self._ws_client = ws_client + self._log_file = log_file + self._live_mode = live_mode + self._log = _DualLogger(structlog.get_logger().bind(component="executor"), log_file) + self._in_flight: dict[str, InFlightExecution] = {} + self._last_trade_ts_ms: dict[frozenset, int] = {} + self._reports: deque[ExecutionReport] = deque(maxlen=1000) + self._paused = False + self._pause_lock = asyncio.Lock() + self._isolation_lock = asyncio.Lock() + self._uptime_ns: int = time.monotonic_ns() + self._report_written = False + self._client_oid_to_order_id: dict[str, str] = {} + self._session: aiohttp.ClientSession | None = None + self._session_timeout = aiohttp.ClientTimeout(sock_connect=5, sock_read=10) + self._keepalive_task: asyncio.Task | None = None + + async def start(self) -> None: + """Pre-initialize and warm up the aiohttp session so the first trade is not slowed.""" + self._session = self._create_session() + async def _warm_up(): + try: + async with self._session.get("https://api.kucoin.com/api/v1/time") as resp: + await resp.text() + except Exception: + pass + await _warm_up() + + self._keepalive_task = asyncio.create_task(self._keepalive_loop()) + + _KEEPALIVE_INTERVAL = 15.0 + + def _create_session(self) -> aiohttp.ClientSession: + connector = TCPConnector( + limit=10, + limit_per_host=5, + force_close=False, + enable_cleanup_closed=True, + keepalive_timeout=60, + ttl_dns_cache=300, + ) + return aiohttp.ClientSession( + timeout=self._session_timeout, + connector=connector, + ) + + async def _keepalive_loop(self) -> None: + """Ping KuCoin periodically to keep the authenticated POST path warm.""" + while True: + try: + await asyncio.sleep(self._KEEPALIVE_INTERVAL) + if self._live_mode: + async with self._session.get("https://api.kucoin.com/api/v1/time") as resp: + await resp.text() + else: + await self._api.order_test( + session=self._session, + symbol="BTC-USDT", + side="buy", + order_type="market", + funds=Decimal("1"), + ) + except asyncio.CancelledError: + break + except Exception: + pass + + async def handle_signal(self, signal: dict) -> None: + """ + Public entry point for processing an opportunity signal. + + Catches all exceptions so they do not bubble into the socket server's + task chain; emits a failed ExecutionReport on error. + """ + try: + await self._handle_signal_impl(signal) + except asyncio.CancelledError: + raise + except BaseException as e: + correlation_id = signal.get("correlation_id", "") + error_msg = str(e) + self._log.error("signal_handler_error", error=error_msg, correlation_id=correlation_id) + self._emit_report(ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="failed", + fills=[], + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error=error_msg, + )) + + async def _handle_signal_impl(self, signal: dict) -> None: + """ + Internal signal processing pipeline. + + Steps (in order): + 1. Block if executor is paused. + 2. Validate triangle_key and legs. + 3. Reject stale signals (book_ts_ms older than last seen). + 4. Reject signals where volume is below any leg's minimum. + 5. Reject if no concurrency slot available. + 6. Add to _in_flight and run _execute_triangle. + """ + async with self._pause_lock: + if self._paused: + self._log.debug("signal_dropped_paused", correlation_id=signal.get("correlation_id", "")) + return + + correlation_id = signal.get("correlation_id", "") + triangle_key_list = signal.get("triangle_key", []) + triangle_key = frozenset(triangle_key_list) + primary_quote = signal.get("primary_quote", "") + legs = signal.get("legs", []) + book_ts_ms = signal.get("book_ts_ms", 0) + + pair_symbols = frozenset(leg.get("pair", "") for leg in legs if leg.get("pair")) + + if self._is_blocked(triangle_key, pair_symbols, primary_quote): + self._log.debug("signal_blocked", correlation_id=correlation_id, triangle_key=triangle_key_list) + return + + if len(legs) != 3: + self._log.warning("invalid_signal", correlation_id=correlation_id, msg="expected 3 legs") + return + + stale_ts = self._last_trade_ts_ms.get(triangle_key, 0) + if book_ts_ms > 0 and stale_ts > 0 and book_ts_ms < stale_ts: + self._log.debug("signal_discarded_stale", correlation_id=correlation_id, book_ts_ms=book_ts_ms, stale_ts=stale_ts) + return + + precheck_ok, min_required, leg_minima = self._precheck_volume(signal) + if not precheck_ok: + self._log.debug( + "signal_discarded_vol_too_small", + correlation_id=correlation_id, + starting_volume=str(signal.get("starting_volume", "")), + min_required=str(min_required), + leg_minima=leg_minima, + ) + return + + async with self._isolation_lock: + if self._session is None or self._session.closed: + self._session = self._create_session() + if len(self._in_flight) >= self._settings.concurrent_slots: + self._log.debug("signal_dropped_no_slot", correlation_id=correlation_id) + return + + if self._is_blocked(triangle_key, pair_symbols, primary_quote): + self._log.debug("signal_blocked", correlation_id=correlation_id, triangle_key=triangle_key_list) + return + + in_flight = InFlightExecution( + triangle_key=triangle_key, + pair_symbols=pair_symbols, + primary_quote=primary_quote, + correlation_id=correlation_id, + signal=signal, + started_ts_ms=int(time.time() * 1000), + ) + self._in_flight[correlation_id] = in_flight + + self._log.debug("execute_triangle_starting", correlation_id=correlation_id) + try: + await self._execute_triangle(correlation_id, signal, in_flight) + finally: + async with self._isolation_lock: + self._in_flight.pop(correlation_id, None) + + def _precheck_volume(self, signal: dict) -> tuple[bool, Decimal, dict[str, str]]: + """ + Verify the signal's starting volume can clear each leg's base_min_size. + + Uses the top-of-book price to convert quote-currency order_param to + base-currency for buy legs. This is a cheap rejection filter before + we commit to execution — avoids hitting the exchange with an order + that would be rejected for being below the minimum size. + """ + legs = signal.get("legs", []) + starting_volume = Decimal(str(signal.get("starting_volume", "0"))) + if not legs or starting_volume <= 0: + return (False, _D0_1, {}) + + books = signal.get("books", []) + for i, leg in enumerate(legs): + order_param = Decimal(str(leg.get("order_param", "0"))) + base_min = Decimal(str(leg.get("base_min_size", "0"))) + if order_param <= 0 or base_min <= 0: + continue + side = leg.get("side", "") + book = books[i] if i < len(books) else {} + if side == "buy": + asks = book.get("asks", []) + price = Decimal(str(asks[0]["price"])) if asks else _D0 + if price > 0 and order_param / price < base_min: + return (False, base_min, {leg.get("pair", ""): str(base_min)}) + else: + if order_param < base_min: + return (False, base_min, {leg.get("pair", ""): str(base_min)}) + return (True, _D0_1, {}) + + def _is_blocked(self, triangle_key: frozenset, pair_symbols: frozenset, primary_quote: str) -> bool: + """ + Return True if the given triangle_key, pair_symbols, or primary_quote + already has an in-flight execution (isolation enforcement). + """ + for inf in list(self._in_flight.values()): + if inf.triangle_key == triangle_key: + return True + if self._settings.enforce_same_base_isolation and inf.primary_quote == primary_quote: + return True + if self._settings.enforce_pair_isolation and pair_symbols & inf.pair_symbols: + return True + return False + + async def _execute_triangle( + self, correlation_id: str, signal: dict, in_flight: InFlightExecution + ) -> None: + """ + Execute the three legs of a triangular arbitrage signal. + + Live mode + --------- + Places real market orders on KuCoin via order_place and waits for + fill events from the WS client. Uses the incoming volume for leg 0 + and propagates the output of each leg as the input for the next. + + Paper mode + ---------- + Validates orders against KuCoin's order_test endpoint (ensures the + pair/size/funds are valid) then simulates fills from the order-book + snapshot attached to the signal. Fill quantities are computed by + walking the book at the top level — no real capital is committed. + + In both modes the signal's ``_cancelled`` flag is checked between + legs so cancel_execution takes effect promptly. All outcomes + (filled, failed, aborted) produce an ExecutionReport. + """ + exec_start_ts = time.perf_counter() + timings: list[dict] = [] + executor_receive_ts_ms = signal.get("_receiver_ts_ms") or int(time.time() * 1000) + signal_ts_ms = signal.get("ts_ms", 0) + book_ts_ms = signal.get("book_ts_ms", 0) + t_sock_arrive_ms = signal.get("t_sock_arrive_ms", 0) + t_arrive_ms = signal.get("t_arrive_ms", 0) + t_eval_ms = signal.get("t_eval_ms", 0) + if book_ts_ms > 0: + timings.append({"step": "t-2_book_snapshot", "elapsed_ms": -(executor_receive_ts_ms - book_ts_ms)}) + if t_sock_arrive_ms > 0: + timings.append({"step": "socket_arrived", "elapsed_ms": -(executor_receive_ts_ms - t_sock_arrive_ms)}) + if t_arrive_ms > 0: + timings.append({"step": "book_update_arrived", "elapsed_ms": -(executor_receive_ts_ms - t_arrive_ms)}) + if t_eval_ms > 0: + timings.append({"step": "t-1_eval_complete", "elapsed_ms": -(executor_receive_ts_ms - t_eval_ms)}) + if signal_ts_ms > 0: + timings.append({"step": "t_signal_created", "elapsed_ms": -(executor_receive_ts_ms - signal_ts_ms)}) + timings.append({"step": "signal_received", "elapsed_ms": 0.0}) + self._log.debug("execute_triangle_entered", correlation_id=correlation_id) + legs = signal.get("legs", []) + books = signal.get("books", []) + live = signal.get("live", False) + log_prefix = "" if live else "[PAPER] " + + fills: list[LegFill] = [] + + if self._session is None or self._session.closed: + self._session = self._create_session() + session = self._session + for i, leg in enumerate(legs): + if signal.get("_cancelled"): + self._log.info("execution_cancelled", correlation_id=correlation_id, completed_legs=len(fills)) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="cancelled", + ) + self._emit_report(report) + return + + pair = leg.get("pair", "") + side = leg.get("side", "") + order_param = Decimal(str(leg.get("order_param", "0"))) + base_min_size = Decimal(str(leg.get("base_min_size", "0"))) + fee_rate = Decimal(str(leg.get("fee_rate", "0.001"))) + fee_ccy = leg.get("fee_currency", "") + + base_ccy = pair.split("-")[0] + quote_ccy = pair.split("-")[-1] + + if side == "buy": + input_ccy = quote_ccy + output_ccy = base_ccy + else: + input_ccy = base_ccy + output_ccy = quote_ccy + latency_ms = 0.0 + + if live: + # --- LIVE MODE --- + client_oid = f"live-{correlation_id}-{i}-{uuid.uuid4().hex[:8]}" + t0 = time.perf_counter() + + if self._ws_client is None or not self._ws_client.is_connected: + self._log.error( + "live_mode_ws_not_connected", + correlation_id=correlation_id, + leg=i, + pair=pair, + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="failed", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="ws_not_connected", + ) + self._emit_report(report) + return + + order_fired_elapsed = (time.perf_counter() - exec_start_ts) * 1000 + timings.append({"step": f"leg{i}_order_fired", "elapsed_ms": round(order_fired_elapsed, 2)}) + + if i == 0: + input_vol = order_param + else: + prev = fills[i - 1] + if prev.side == "buy": + # Buy output is base asset: use filled_volume directly. + input_vol = prev.filled_volume + else: + # Sell output is quote: deduct fee before passing as next input. + input_vol = prev.filled_volume * (_D1 - fee_rate) + + if base_min_size > 0 and side == "sell" and input_vol < base_min_size: + self._log.info("execution_aborted_below_min", + correlation_id=correlation_id, leg=i, pair=pair, + base_vol=str(input_vol), min_base=str(base_min_size), + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="volume_below_minimum", + ) + self._emit_report(report) + return + + if side == "buy": + ok, err_msg, order_id = await self._api.order_place( + session=session, + symbol=pair, + side=side, + order_type="market", + funds=input_vol, + client_oid=client_oid, + ) + else: + ok, err_msg, order_id = await self._api.order_place( + session=session, + symbol=pair, + side=side, + order_type="market", + size=input_vol, + client_oid=client_oid, + ) + place_latency_ms = (time.perf_counter() - t0) * 1000 + self._log.info( + f"{log_prefix}order_placed", + correlation_id=correlation_id, + leg=i, + pair=pair, + order_id=order_id, + client_oid=client_oid, + place_latency_ms=round(place_latency_ms, 2), + ) + + if not ok: + self._log.error( + f"{log_prefix}order_rejected", + correlation_id=correlation_id, + leg=i, + pair=pair, + error=err_msg, + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="failed", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error=err_msg or "order_rejected", + ) + self._emit_report(report) + return + + self._client_oid_to_order_id[client_oid] = order_id or "" + + fill_timeout_ms = self._settings.fill_timeout_ms + fill_ok, fill_data = await self._ws_client.await_fill( + client_oid, fill_timeout_ms + ) + fill_latency_ms = (time.perf_counter() - t0) * 1000 + latency_ms = fill_latency_ms + + if signal.get("_cancelled"): + self._log.info( + "execution_cancelled", + correlation_id=correlation_id, + completed_legs=len(fills), + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="cancelled", + ) + self._emit_report(report) + return + + if not fill_ok: + elapsed_ms = (time.perf_counter() - exec_start_ts) * 1000 + self._log.error( + f"{log_prefix}fill_timeout", + correlation_id=correlation_id, + leg=i, + pair=pair, + client_oid=client_oid, + order_id=order_id, + fill_latency_ms=round(fill_latency_ms, 2), + total_elapsed_ms=round(elapsed_ms, 2), + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="failed", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error=f"fill_timeout_leg{i}", + ) + self._emit_report(report) + return + + fill_received_elapsed = (time.perf_counter() - exec_start_ts) * 1000 + timings.append({"step": f"leg{i}_fill_received", "elapsed_ms": round(fill_received_elapsed, 2)}) + order_id = fill_data.get("order_id", order_id or "") + total_size = fill_data.get("total_size", Decimal("0")) + total_funds = fill_data.get("total_funds", Decimal("0")) + weighted_avg_price = fill_data.get("weighted_avg_price", _D0) + + # Fall back to book top if WS didn't provide a price (defensive). + book_snapshot = books[i] if i < len(books) else {} + if weighted_avg_price <= 0: + if side == "buy": + asks = book_snapshot.get("asks", []) + weighted_avg_price = Decimal(str(asks[0]["price"])) if asks else _D0 + else: + bids = book_snapshot.get("bids", []) + weighted_avg_price = Decimal(str(bids[0]["price"])) if bids else _D0 + + avg_price = weighted_avg_price if weighted_avg_price > 0 else _D0 + # Estimate fee: KuCoin charges fee in the currency being received. + fee = ( + total_size * fee_rate + if fee_ccy == base_ccy + else total_funds * fee_rate + ) + + fills.append(LegFill( + leg=i, + order_id=order_id, + side=side, + pair=pair, + input_currency=input_ccy, + output_currency=output_ccy, + fee_currency=fee_ccy, + filled_volume=total_size if side == "buy" else total_funds, + deal_funds=total_funds, + avg_price=avg_price, + fee=fee, + latency_ms=latency_ms, + )) + in_flight.last_trade_ts_ms = int(time.time() * 1000) + continue + + # --- PAPER MODE --- + # The fused_engine already sized everything (per-leg order_param, + # fee rates, precision increments). We only validate via + # order_test and simulate fills from the attached books. + self._log.debug("order_test_calling", correlation_id=correlation_id, leg=i, pair=pair, side=side, order_param=str(order_param)) + t0 = time.perf_counter() + order_fired_elapsed = (t0 - exec_start_ts) * 1000 + timings.append({"step": f"leg{i}_order_fired", "elapsed_ms": round(order_fired_elapsed, 2)}) + + if side == "buy": + ok, err_msg, _ = await self._api.order_test( + session=session, + symbol=pair, + side=side, + order_type="market", + funds=order_param, + ) + else: + ok, err_msg, _ = await self._api.order_test( + session=session, + symbol=pair, + side=side, + order_type="market", + size=order_param, + ) + + latency_ms = (time.perf_counter() - t0) * 1000 + fill_elapsed = (time.perf_counter() - exec_start_ts) * 1000 + timings.append({"step": f"leg{i}_fill_received", "elapsed_ms": round(fill_elapsed, 2)}) + self._log._sl.info(f"{log_prefix}order_latency", correlation_id=correlation_id, leg=i, pair=pair, latency_ms=round(latency_ms, 2)) + + if not ok: + self._log.error(f"{log_prefix}order_rejected", correlation_id=correlation_id, leg=i, pair=pair, error=err_msg) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="failed", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error=err_msg or "order_rejected", + ) + self._emit_report(report) + return + + # Paper order succeeded — assign a synthetic order ID so the fill + # pipeline has something to track. + order_id = f"paper-{uuid.uuid4().hex[:12]}" + if signal.get("_cancelled"): + self._log.info("execution_cancelled", correlation_id=correlation_id, completed_legs=len(fills)) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="cancelled", + ) + self._emit_report(report) + return + + book_snapshot = books[i] if i < len(books) else {} + + # Simulate fill from top-of-book: use the best ask (buy) or best bid (sell). + if side == "buy": + asks = book_snapshot.get("asks", []) + price = Decimal(str(asks[0]["price"])) if asks else _D0 + # For a buy with funds=X, you get X/price base units. + base_vol = order_param / price if price > 0 else _D0 + deal_funds = order_param + fee = base_vol * fee_rate if fee_ccy == base_ccy else order_param * fee_rate + filled_volume = base_vol + + # Reject if simulated fill is below the exchange minimum. + if base_min_size > 0 and base_vol < base_min_size: + self._log.info("execution_aborted_below_min", + correlation_id=correlation_id, leg=i, pair=pair, + base_vol=str(base_vol), min_base=str(base_min_size), + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="volume_below_minimum", + ) + self._emit_report(report) + return + else: + bids = book_snapshot.get("bids", []) + price = Decimal(str(bids[0]["price"])) if bids else _D0 + # For a sell with size=X, you get X*price quote units. + base_vol = order_param + quote_vol = base_vol * price if price > 0 else _D0 + # Fee depends on whether KuCoin charges it in base or quote. + if fee_ccy == base_ccy: + fee = base_vol * fee_rate + deal_funds = quote_vol + else: + fee = quote_vol * fee_rate + deal_funds = quote_vol * (_D1 - fee_rate) + filled_volume = quote_vol + + if base_min_size > 0 and order_param < base_min_size: + self._log.info("execution_aborted_below_min", + correlation_id=correlation_id, leg=i, pair=pair, + base_vol=str(order_param), min_base=str(base_min_size), + ) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="aborted", + fills=fills, + predicted_bps=0.0, + ts_ms=int(time.time() * 1000), + error="volume_below_minimum", + ) + self._emit_report(report) + return + + avg_price = price + + fills.append(LegFill( + leg=i, + order_id=order_id, + side=side, + pair=pair, + input_currency=input_ccy, + output_currency=output_ccy, + fee_currency=fee_ccy, + filled_volume=filled_volume, + deal_funds=deal_funds, + avg_price=avg_price, + fee=fee, + latency_ms=latency_ms, + )) + in_flight.last_trade_ts_ms = int(time.time() * 1000) + + predicted_bps = signal.get("predicted_bps", 0.0) + # Compute actual profit in the primary quote currency. + # Leg 2 output: if buy, the received base (filled_volume); if sell, the received + # quote (deal_funds, already net when fee is in quote). + if fills[2].side == "buy": + leg2_out = fills[2].filled_volume + if fills[2].fee_currency == fills[2].output_currency: + leg2_out -= fills[2].fee + else: + leg2_out = fills[2].deal_funds + # Leg 0 input: if buy, quote spent (deal_funds); if sell, base sold. + if fills[0].side == "buy": + leg0_in = fills[0].deal_funds + else: + leg0_in = fills[0].filled_volume + profit = float(leg2_out - leg0_in) + effective_bps = (profit / float(leg0_in)) * 10000 if leg0_in else 0.0 + total_exec_ms = (time.perf_counter() - exec_start_ts) * 1000 + timings.append({"step": "execution_complete", "elapsed_ms": round(total_exec_ms, 2)}) + self._log._sl.info("execution_timing", correlation_id=correlation_id, timings=timings) + report = ExecutionReport( + correlation_id=correlation_id, + triangle_key=signal.get("triangle_key", []), + status="filled", + fills=fills, + predicted_bps=predicted_bps, + profit=profit, + effective_bps=effective_bps, + ts_ms=int(time.time() * 1000), + timings=timings, + ) + self._last_trade_ts_ms[in_flight.triangle_key] = report.ts_ms + self._emit_report(report) + + def _emit_report(self, report: ExecutionReport) -> None: + """Persist an ExecutionReport to the in-memory deque and write to the log file.""" + fills_lines = [] + for f in report.fills: + fills_lines.append( + f"L{f.leg}:{f.side} {f.pair} {f.input_currency}->{f.output_currency} " + f"{f.filled_volume}@{f.avg_price}(fee={f.fee} {f.fee_currency} lat={f.latency_ms:.1f}ms)" + ) + fills_repr = ", ".join(fills_lines) + self._reports.append(report) + error_suffix = f" | error={report.error}" if report.error else "" + profit_repr = f"profit={report.profit:.4f}" if report.status == "filled" else "" + timing_parts = " ".join(f"{t['step']}={t['elapsed_ms']:.1f}ms" for t in report.timings) if report.timings else "" + ts_iso = datetime.utcnow().strftime("%Y-%m-%dT%H:%M:%S.") + f"{report.ts_ms % 1000:03d}Z" + msg = ( + f"{ts_iso} {report.status.upper()} | corr={report.correlation_id} | " + f"triangle={report.triangle_key} | predicted_bps={report.predicted_bps:.2f} | " + f"effective_bps={report.effective_bps:.2f} | " + f"{profit_repr} | timings=[{timing_parts}] | fills=[{fills_repr}]{error_suffix}" + ) + self._log.write_plain(msg) + + async def cancel_execution(self, correlation_id: str) -> bool: + """ + Request cancellation of an in-flight execution by setting _cancelled + on the signal dict. Returns True if the execution was found. + """ + if correlation_id in self._in_flight: + self._log.info("cancel_requested", correlation_id=correlation_id) + self._in_flight[correlation_id].signal["_cancelled"] = True + return True + return False + + async def close(self) -> None: + """Close the aiohttp session and flush the log writer.""" + if self._keepalive_task is not None and not self._keepalive_task.done(): + self._keepalive_task.cancel() + try: + await self._keepalive_task + except asyncio.CancelledError: + pass + self._keepalive_task = None + if self._session is not None and not self._session.closed: + await self._session.close() + await self._log.close() + + async def pause(self) -> None: + """Block the executor from accepting new signals.""" + async with self._pause_lock: + self._paused = True + self._log.info("executor_paused") + + async def resume(self) -> None: + """Unblock the executor to start accepting signals again.""" + async with self._pause_lock: + self._paused = False + self._log.info("executor_resumed") + + def get_uptime_seconds(self) -> float: + """Return process uptime in seconds (monotonic clock, not wall time).""" + return (time.monotonic_ns() - self._uptime_ns) / 1e9 + + def set_concurrent_slots(self, slots: int) -> None: + """ + Dynamically adjust the maximum number of concurrent in-flight triangles. + Thread-safe: updates self._settings.concurrent_slots only. + """ + self._settings.concurrent_slots = slots + self._log.info("concurrent_slots_updated", slots=slots) + + def get_in_flight(self) -> list[dict]: + return [ + { + "correlation_id": inf.correlation_id, + "triangle_key": list(inf.triangle_key), + "pair_symbols": list(inf.pair_symbols), + "primary_quote": inf.primary_quote, + "started_ts_ms": inf.started_ts_ms, + } + for inf in self._in_flight.values() + ] + + def get_reports(self, limit: int = 50) -> list[dict]: + reports = list(self._reports)[-limit:] + return [ + { + "correlation_id": r.correlation_id, + "triangle_key": r.triangle_key, + "status": r.status, + "fills": [{"leg": f.leg, "vol": str(f.filled_volume), "deal_funds": str(f.deal_funds), "price": str(f.avg_price), "fee": str(f.fee), "fee_currency": f.fee_currency} for f in r.fills], + "predicted_bps": r.predicted_bps, + "effective_bps": r.effective_bps, + "ts_ms": r.ts_ms, + **({"error": r.error} if r.error else {}), + } + for r in reports + ] + + def get_config(self) -> dict: + return { + "live_mode": self._live_mode, + "concurrent_slots": self._settings.concurrent_slots, + "enforce_same_base_isolation": self._settings.enforce_same_base_isolation, + "socket_path": str(self._settings.socket_path), + } diff --git a/executor/kucoin_api.py b/executor/kucoin_api.py new file mode 100644 index 0000000..6b4612c --- /dev/null +++ b/executor/kucoin_api.py @@ -0,0 +1,434 @@ +""" +KuCoin REST API client for the executor. + +Covers symbol metadata fetch, HF order-test endpoint for paper mode, +real order placement for live mode, and private WebSocket token +acquisition required by ws_client.py. +""" +import aiohttp +import base64 +import hmac +import hashlib +import json +import time +import uuid +import structlog +from decimal import Decimal +from typing import Optional + +logger = structlog.get_logger().bind(component="executor-kucoin") + +KUCoin_SYMBOLS_URL = "https://api.kucoin.com/api/v1/symbols" +KUCoin_ORDER_TEST_URL = "https://api.kucoin.com/api/v1/hf/orders/test" +KUCoin_ORDER_PLACE_URL = "https://api.kucoin.com/api/v1/hf/orders" +KUCoin_SERVER_TIME_URL = "https://api.kucoin.com/api/v1/time" +KUCoin_BULLET_PRIVATE_URL = "https://api.kucoin.com/api/v1/bullet-private" + + +def _signRequest(timestamp: str, method: str, path: str, secret: str, data: str = "") -> str: + """ + Compute the HMAC-SHA256 signature for a KuCoin API request. + + Parameters + ---------- + timestamp : str + Millisecond Unix timestamp. + method : str + HTTP method (e.g. "POST"). + path : str + API endpoint path (e.g. "/api/v1/hf/orders/test"). + secret : str + API secret as returned by the user. + data : str + Request body. Empty string for GET requests. + + Returns + ------- + str + Base64-encoded HMAC-SHA256 digest suitable for the KC-API-SIGN header. + """ + # KuCoin signs timestamp + method + path + body concatenated. + message = timestamp + method + path + data + mac = hmac.new(secret.encode("utf-8"), message.encode("utf-8"), hashlib.sha256) + return base64.b64encode(mac.digest()).decode("utf-8") + + +def _encryptPassphrase(passphrase: str, secret: str) -> str: + """ + Encrypt the API passphrase for KuCoin. + + KuCoin requires the passphrase to be encrypted with HMAC-SHA256 + using the API secret as the key, then base64-encoded. + + Returns + ------- + str + Base64-encoded encrypted passphrase for the KC-API-PASSPHRASE header. + """ + mac = hmac.new(secret.encode("utf-8"), passphrase.encode("utf-8"), hashlib.sha256) + return base64.b64encode(mac.digest()).decode("utf-8") + + +class SymbolMeta: + """ + Cached metadata for a single KuCoin trading pair. + + Fetched once at startup from /api/v1/symbols and held in memory + for the lifetime of the process. + """ + + def __init__( + self, + symbol: str, + base: str, + quote: str, + base_min_size: Decimal, + quote_min_size: Decimal, + base_increment: Decimal, + quote_increment: Decimal, + min_funds: Decimal, + taker_fee: Decimal, + maker_fee: Decimal, + incr_min_size: Decimal, + base_precision: int, + quote_precision: int, + ) -> None: + self.symbol = symbol + self.base = base + self.quote = quote + self.base_min_size = base_min_size + self.quote_min_size = quote_min_size + self.base_increment = base_increment + self.quote_increment = quote_increment + self.min_funds = min_funds + self.taker_fee = taker_fee + self.maker_fee = maker_fee + self.incr_min_size = incr_min_size + self.base_precision = base_precision + self.quote_precision = quote_precision + + + +def _cost_to_precision(amount: Decimal, quote_increment: Decimal) -> Decimal: + """ + Round a quote-currency amount *up* to the nearest valid increment. + + KuCoin requires quote amounts to be multiples of quote_increment. When + computing the minimum order size in quote currency we therefore round up + so we never underestimate the minimum. + """ + if quote_increment <= 0: + return amount + mult = Decimal("1") / quote_increment + return (amount * mult).to_integral_value(rounding="ROUND_UP") / mult + + +def _amount_to_precision( + amount: Decimal, + base_increment: Decimal, + round_down: bool = False, +) -> Decimal: + """ + Round a base-currency amount to the nearest valid increment. + + Use round_down=True for sell orders so the resulting size never + exceeds the available balance. Use round_down=False (default) for + buy orders and minimum-size computations where rounding up is safe. + """ + if base_increment <= 0: + return amount + mult = Decimal("1") / base_increment + rounding = "ROUND_DOWN" if round_down else "ROUND_UP" + return (amount * mult).to_integral_value(rounding=rounding) / mult + + +class KuCoinAPI: + """ + Thin client for KuCoin REST API calls needed by the executor. + + Handles HMAC signing, symbol metadata caching, order placement + (live) and order validation (paper), plus private token fetch + for the WebSocket client. + """ + + def __init__(self, api_key: str = "", api_secret: str = "", api_passphrase: str = "") -> None: + self._api_key = api_key + self._api_secret = api_secret + self._api_passphrase = api_passphrase + # Pre-encrypt the passphrase at init time so we don't recompute per request. + self._encrypted_passphrase = _encryptPassphrase(api_passphrase, api_secret) if api_passphrase and api_secret else "" + self._symbols: dict[str, SymbolMeta] = {} + self._log = logger + + async def fetch_symbols(self) -> None: + """ + Fetch all trading pair metadata from KuCoin and populate _symbols. + + Logs a warning for any symbol that fails to parse and skips it. + """ + async with aiohttp.ClientSession() as session: + async with session.get(KUCoin_SYMBOLS_URL) as resp: + resp.raise_for_status() + payload = await resp.json() + + for item in payload.get("data", []): + symbol = item.get("symbol", "") + base = item.get("baseCurrency", "") + quote = item.get("quoteCurrency", "") + if not all([symbol, base, quote]): + continue + + raw_base_min = item.get("baseMinSize") or "0" + raw_quote_min = item.get("quoteMinSize") or "0" + raw_base_inc = item.get("baseIncrement") or "0" + raw_quote_inc = item.get("quoteIncrement") or "0" + raw_min_funds = item.get("minFunds") or "0" + raw_maker = item.get("makerFeeRate") or "0" + raw_taker = item.get("takerFeeRate") or "0" + raw_incr_min = item.get("incrMinSize") or "0" + raw_base_prec = item.get("basePrecision") or "0" + raw_quote_prec = item.get("quotePrecision") or "0" + + try: + base_min_size = Decimal(raw_base_min) + quote_min_size = Decimal(raw_quote_min) + base_increment = Decimal(raw_base_inc) + quote_increment = Decimal(raw_quote_inc) + min_funds = Decimal(raw_min_funds) + taker_fee = Decimal(raw_taker) + maker_fee = Decimal(raw_maker) + incr_min_size = Decimal(raw_incr_min) + base_precision = int(raw_base_prec) if raw_base_prec else 0 + quote_precision = int(raw_quote_prec) if raw_quote_prec else 0 + except Exception as e: + self._log.warning("symbol_field_parse_error", symbol=symbol, error=str(e), + baseMinSize=repr(raw_base_min), quoteMinSize=repr(raw_quote_min), + baseIncrement=repr(raw_base_inc), quoteIncrement=repr(raw_quote_inc), + minFunds=repr(raw_min_funds), makerFeeRate=repr(raw_maker), + takerFeeRate=repr(raw_taker), incrMinSize=repr(raw_incr_min), + basePrecision=repr(raw_base_prec), quotePrecision=repr(raw_quote_prec)) + continue + + self._symbols[symbol] = SymbolMeta( + symbol=symbol, + base=base, + quote=quote, + base_min_size=base_min_size, + quote_min_size=quote_min_size, + base_increment=base_increment, + quote_increment=quote_increment, + min_funds=min_funds, + taker_fee=taker_fee, + maker_fee=maker_fee, + incr_min_size=incr_min_size, + base_precision=base_precision, + quote_precision=quote_precision, + ) + + self._log.info("symbols_loaded", count=len(self._symbols)) + + def get_symbol_meta(self, symbol: str) -> Optional[SymbolMeta]: + """Return cached SymbolMeta for a pair, or None if not yet loaded.""" + return self._symbols.get(symbol) + + async def order_test( + self, + session: aiohttp.ClientSession, + symbol: str, + side: str, + order_type: str, + price: Optional[Decimal] = None, + size: Optional[Decimal] = None, + funds: Optional[Decimal] = None, + ) -> tuple[bool, str, Optional[str]]: + """ + Validate an order against KuCoin's paper-trading endpoint. + + In paper mode the executor uses this instead of a real order so that + fill simulation can proceed without risking capital. + + Parameters + ---------- + session : aiohttp.ClientSession + Shared session for connection pooling. + symbol : str + KuCoin symbol e.g. "BTC-USDT". + side : str + "buy" or "sell". + order_type : str + Order type string (e.g. "market"). + price, size, funds : Optional[Decimal] + Order parameters; at least one must be provided. + + Returns + ------- + tuple[bool, str, Optional[str]] + (success, error_message, order_id). order_id is populated on success. + """ + timestamp = str(int(time.time() * 1000)) + path = "/api/v1/hf/orders/test" + body: dict = { + "symbol": symbol, + "type": order_type, + "side": side, + "clientOid": f"paper-{timestamp}-{uuid.uuid4().hex[:8]}", + } + if price is not None: + body["price"] = str(price) + if size is not None: + body["size"] = str(size) + if funds is not None: + body["funds"] = str(funds) + + raw_body = json.dumps(body, separators=(",", ":")) + sign = _signRequest(timestamp, "POST", path, self._api_secret, raw_body) + headers = { + "KC-API-TIMESTAMP": timestamp, + "KC-API-SIGN": sign, + "KC-API-KEY": self._api_key, + "KC-API-PASSPHRASE": self._encrypted_passphrase, + "KC-API-SIGN-TYPE": "2", + "KC-API-KEY-VERSION": "3", + "Content-Type": "application/json", + } + + try: + async with session.post( + KUCoin_ORDER_TEST_URL, + data=raw_body.encode(), + headers=headers, + ) as resp: + text = await resp.text() + if resp.status == 200: + data = json.loads(text) + order_id = data.get("data", {}).get("orderId", "") + return True, "", order_id + else: + data = json.loads(text) + code = data.get("code", "") + msg = data.get("msg", text) + return False, f"{code}: {msg}", None + except (json.JSONDecodeError, ValueError) as e: + return False, f"invalid_response: {e}", None + except (aiohttp.ClientError, OSError) as e: + return False, f"http_error: {e}", None + + async def order_place( + self, + session: aiohttp.ClientSession, + symbol: str, + side: str, + order_type: str, + price: Optional[Decimal] = None, + size: Optional[Decimal] = None, + funds: Optional[Decimal] = None, + client_oid: str = "", + ) -> tuple[bool, str, Optional[str]]: + """ + Place a real market order on KuCoin. + + Parameters + ---------- + session : aiohttp.ClientSession + Shared session for connection pooling. + symbol : str + KuCoin symbol e.g. "BTC-USDT". + side : str + "buy" or "sell". + order_type : str + Order type string (e.g. "market"). + price, size, funds : Optional[Decimal] + Order parameters; at least one must be provided. + client_oid : str + Client-order ID for matching with WS fill events. + + Returns + ------- + tuple[bool, str, Optional[str]] + (success, error_message, order_id). order_id is populated on success. + """ + timestamp = str(int(time.time() * 1000)) + path = "/api/v1/hf/orders" + body: dict = { + "symbol": symbol, + "type": order_type, + "side": side, + "clientOid": client_oid or f"live-{timestamp}-{uuid.uuid4().hex[:8]}", + } + if price is not None: + body["price"] = str(price) + if size is not None: + body["size"] = str(size) + if funds is not None: + body["funds"] = str(funds) + + raw_body = json.dumps(body, separators=(",", ":")) + sign = _signRequest(timestamp, "POST", path, self._api_secret, raw_body) + headers = { + "KC-API-TIMESTAMP": timestamp, + "KC-API-SIGN": sign, + "KC-API-KEY": self._api_key, + "KC-API-PASSPHRASE": self._encrypted_passphrase, + "KC-API-SIGN-TYPE": "2", + "KC-API-KEY-VERSION": "3", + "Content-Type": "application/json", + } + + try: + async with session.post( + KUCoin_ORDER_PLACE_URL, + data=raw_body.encode(), + headers=headers, + ) as resp: + text = await resp.text() + self._log.info("order_place_raw_response", status=resp.status, response=text[:300]) + data = json.loads(text) + if resp.status == 200 and data.get("code") == "200000": + order_id = data.get("data", {}).get("orderId", "") + return True, "", order_id + else: + code = data.get("code", resp.status) + msg = data.get("msg", text) + return False, f"{code}: {msg}", None + except (json.JSONDecodeError, ValueError) as e: + return False, f"invalid_response: {e}", None + except (aiohttp.ClientError, OSError) as e: + return False, f"http_error: {e}", None + + async def get_private_token(self, session: aiohttp.ClientSession) -> Optional[dict]: + """ + Request a private WebSocket token from KuCoin. + + Returns the full data dict from the bullet-private response, containing + 'token', 'instanceServers' with endpoint, pingInterval, pingTimeout. + Returns None on error. + """ + timestamp = str(int(time.time() * 1000)) + path = "/api/v1/bullet-private" + sign = _signRequest(timestamp, "POST", path, self._api_secret, "") + headers = { + "KC-API-TIMESTAMP": timestamp, + "KC-API-SIGN": sign, + "KC-API-KEY": self._api_key, + "KC-API-PASSPHRASE": self._encrypted_passphrase, + "KC-API-SIGN-TYPE": "2", + "KC-API-KEY-VERSION": "3", + "Content-Type": "application/json", + } + + try: + async with session.post( + KUCoin_BULLET_PRIVATE_URL, + data=b"", + headers=headers, + ) as resp: + if resp.status == 200: + data = await resp.json() + return data.get("data") + else: + text = await resp.text() + self._log.error("private_token_failed", status=resp.status, response=text[:200]) + return None + except (aiohttp.ClientError, OSError) as e: + self._log.error("private_token_http_error", error=str(e)) + return None diff --git a/executor/rest_api.py b/executor/rest_api.py new file mode 100644 index 0000000..68478b7 --- /dev/null +++ b/executor/rest_api.py @@ -0,0 +1,171 @@ +""" +FastAPI control interface for the executor. + +Exposes endpoints for status inspection, configuration changes, execution +cancellation, and pause/resume. Intended for operator use; not used in the +normal signal flow. +""" +from typing import Optional + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel + +from executor.executor import Executor + + +class ConfigResponse(BaseModel): + """Current executor configuration.""" + live_mode: bool + concurrent_slots: int + enforce_same_base_isolation: bool + socket_path: str + + +class ConfigPatchRequest(BaseModel): + """Request body for configuration update endpoints.""" + live_mode: Optional[bool] = None + concurrent_slots: Optional[int] = None + enforce_same_base_isolation: Optional[bool] = None + + +class ConfigPatchResponse(BaseModel): + """Response after a configuration update, echoing the new values.""" + ok: bool + live_mode: Optional[bool] = None + concurrent_slots: Optional[int] = None + enforce_same_base_isolation: Optional[bool] = None + + +class PauseResponse(BaseModel): + """Response after a pause request.""" + ok: bool + + +class ResumeResponse(BaseModel): + """Response after a resume request.""" + ok: bool + + +class CancelResponse(BaseModel): + """Response after a cancellation request.""" + ok: bool + message: str + + +class StatusResponse(BaseModel): + """Runtime status of the executor.""" + status: str + version: str + live_mode: bool + slots_used: int + slots_total: int + uptime_seconds: float + + +class ShutdownResponse(BaseModel): + """Response after a shutdown request.""" + ok: bool + + +def create_app(executor: Executor, shutdown_callback) -> FastAPI: + """ + Build the FastAPI application and wire all routes to the executor. + + Parameters + ---------- + executor : Executor + The live Executor instance to control. + shutdown_callback : callable + Called when /api/v1/shutdown is hit to begin clean shutdown. + + Returns + ------- + FastAPI + Configured app ready to be passed to uvicorn. + """ + app = FastAPI(title="Executor API", description="Control interface for the triangular arbitrage executor") + + @app.get("/api/v1/status", response_model=StatusResponse) + async def get_status() -> StatusResponse: + config = executor.get_config() + in_flight = executor.get_in_flight() + return StatusResponse( + status="ok", + version="0.1.0", + live_mode=config["live_mode"], + slots_used=len(in_flight), + slots_total=config["concurrent_slots"], + uptime_seconds=executor.get_uptime_seconds(), + ) + + @app.get("/api/v1/config", response_model=ConfigResponse) + async def get_config() -> ConfigResponse: + cfg = executor.get_config() + return ConfigResponse( + paper_mode=cfg["paper_mode"], + concurrent_slots=cfg["concurrent_slots"], + enforce_same_base_isolation=cfg["enforce_same_base_isolation"], + socket_path=cfg["socket_path"], + ) + + @app.patch("/api/v1/config/live_mode", response_model=ConfigPatchResponse) + async def patch_live_mode(req: ConfigPatchRequest) -> ConfigPatchResponse: + if req.live_mode is None: + raise HTTPException(status_code=400, detail="live_mode required") + executor._live_mode = req.live_mode + return ConfigPatchResponse(ok=True, live_mode=req.live_mode) + + @app.patch("/api/v1/config/concurrent_slots", response_model=ConfigPatchResponse) + async def patch_concurrent_slots(req: ConfigPatchRequest) -> ConfigPatchResponse: + if req.concurrent_slots is None or req.concurrent_slots < 1: + raise HTTPException(status_code=400, detail="concurrent_slots must be >= 1") + executor.set_concurrent_slots(req.concurrent_slots) + return ConfigPatchResponse(ok=True, concurrent_slots=req.concurrent_slots) + + @app.patch("/api/v1/config/enforce_same_base_isolation", response_model=ConfigPatchResponse) + async def patch_isolation(req: ConfigPatchRequest) -> ConfigPatchResponse: + if req.enforce_same_base_isolation is None: + raise HTTPException(status_code=400, detail="enforce_same_base_isolation required") + executor._settings.enforce_same_base_isolation = req.enforce_same_base_isolation + return ConfigPatchResponse(ok=True, enforce_same_base_isolation=req.enforce_same_base_isolation) + + @app.get("/api/v1/executions") + async def get_executions() -> list[dict]: + return executor.get_in_flight() + + @app.get("/api/v1/executions/{correlation_id}") + async def get_execution(correlation_id: str) -> dict: + in_flight = executor.get_in_flight() + for inf in in_flight: + if inf["correlation_id"] == correlation_id: + return inf + raise HTTPException(status_code=404, detail="Execution not found") + + @app.post("/api/v1/cancel/{correlation_id}", response_model=CancelResponse) + async def cancel_execution(correlation_id: str) -> CancelResponse: + ok = await executor.cancel_execution(correlation_id) + if ok: + return CancelResponse(ok=True, message=f"Cancellation requested for {correlation_id}") + raise HTTPException(status_code=404, detail="Execution not found") + + @app.post("/api/v1/pause", response_model=PauseResponse) + async def pause() -> PauseResponse: + await executor.pause() + return PauseResponse(ok=True) + + @app.post("/api/v1/resume", response_model=ResumeResponse) + async def resume() -> ResumeResponse: + await executor.resume() + return ResumeResponse(ok=True) + + @app.post("/api/v1/shutdown", response_model=ShutdownResponse) + async def shutdown() -> ShutdownResponse: + await executor.pause() + shutdown_callback() + return ShutdownResponse(ok=True) + + @app.get("/api/v1/reports") + async def get_reports(limit: int = 50) -> list[dict]: + return executor.get_reports(limit=limit) + + return app diff --git a/executor/socket_server.py b/executor/socket_server.py new file mode 100644 index 0000000..fbafd2e --- /dev/null +++ b/executor/socket_server.py @@ -0,0 +1,100 @@ +""" +Unix-domain socket server that receives opportunity signals from oe_em. + +Each JSON line on the socket is parsed and dispatched as an asyncio task +to avoid blocking the reader. +""" +import asyncio +import json +import time +from pathlib import Path +import structlog + +logger = structlog.get_logger().bind(component="signal_socket_server") + + +class SignalSocketServer: + """ + Accepts JSON-serialized signals over a Unix domain socket. + + Every valid "signal" message is wrapped in create_task so processing + is concurrent and a slow handler never blocks new connections. + """ + + def __init__(self, socket_path: Path, on_signal) -> None: + self._socket_path = socket_path + self._on_signal = on_signal + self._log = logger + self._server: asyncio.Server | None = None + self._running = False + + async def start(self) -> None: + """Remove any stale socket file and start accepting connections.""" + if self._socket_path.exists(): + self._socket_path.unlink() + + self._running = True + self._server = await asyncio.start_unix_server( + self._accept_client, + path=str(self._socket_path), + ) + self._log.info("signal_socket_server_started", path=str(self._socket_path)) + async with self._server: + await self._server.serve_forever() + + async def stop(self) -> None: + """Stop the server and remove the socket file.""" + self._running = False + if self._server: + self._server.close() + await self._server.wait_closed() + if self._socket_path.exists(): + self._socket_path.unlink() + self._log.info("signal_socket_server_stopped") + + async def _accept_client( + self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter + ) -> None: + """ + Handle one client connection: read lines, parse JSON, dispatch signals. + + The client is assumed to be oe_em's SignalSocketClient. Any line that + is not JSON or is not type="signal" is silently ignored. + """ + self._log.info("client_connected", addr=writer.get_extra_info("peername")) + try: + while self._running: + try: + line = await reader.readline() + except (ConnectionResetError, BrokenPipeError, asyncio.CancelledError): + break + except Exception: + break + if not line: + break + + arrived_ms = int(time.time() * 1000) + + try: + data = json.loads(line.decode()) + except (json.JSONDecodeError, UnicodeDecodeError) as e: + self._log.warning("invalid_json", line=line[:50], error=str(e)) + continue + + if data.get("type") == "signal": + data["_receiver_ts_ms"] = arrived_ms + asyncio.create_task(self._on_signal(data)) + else: + self._log.debug("ignored_non_signal", type=data.get("type")) + + except asyncio.CancelledError: + pass + except Exception as e: + self._log.warning("client_error", error=str(e)) + finally: + writer.close() + try: + await asyncio.wait_for(writer.wait_closed(), timeout=1.0) + except Exception: + pass + self._log.info("client_disconnected") \ No newline at end of file diff --git a/executor/ws_client.py b/executor/ws_client.py new file mode 100644 index 0000000..e816da5 --- /dev/null +++ b/executor/ws_client.py @@ -0,0 +1,406 @@ +""" +KuCoin private WebSocket client for fill event delivery. + +Manages the private WebSocket connection, authenticates via bullet-private, +subscribes to /spotMarket/tradeOrdersV2, and dispatches fill events to +waiting executor coroutines. + +KuCoin market orders placed with ``funds`` often complete with a tiny +unfilled remainder, emitting ``canceled`` + ``status=done`` rather than +``filled``. The message handler in ``_handle_message`` treats this +terminal combination as a successful fill when match events have been +accumulated. +""" +import asyncio +import json +import time +import uuid +from decimal import Decimal +from typing import Optional + +import aiohttp +import structlog +import websockets + +from executor.kucoin_api import KuCoinAPI + +logger = structlog.get_logger().bind(component="executor-ws") +_D0 = Decimal("0") + + +class FillAccumulator: + """Accumulate match events for a single order, compute aggregated totals.""" + + def __init__(self, client_oid: str, order_id: str = "") -> None: + self.client_oid = client_oid + self.order_id = order_id + self.total_size = _D0 + self.total_funds = _D0 + self.match_count = 0 + self.side = "" + self.symbol = "" + + def add_match(self, data: dict) -> None: + match_price = Decimal(str(data.get("matchPrice", "0"))) + match_size = Decimal(str(data.get("matchSize", "0"))) + self.total_size += match_size + self.total_funds += match_price * match_size + self.match_count += 1 + if not self.side: + self.side = data.get("side", "") + if not self.symbol: + self.symbol = data.get("symbol", "") + if not self.order_id: + self.order_id = data.get("orderId", "") + + @property + def weighted_avg_price(self) -> Decimal: + if self.total_size <= 0: + return _D0 + return self.total_funds / self.total_size + + def to_dict(self) -> dict: + return { + "total_size": self.total_size, + "total_funds": self.total_funds, + "weighted_avg_price": self.weighted_avg_price, + "match_count": self.match_count, + "order_id": self.order_id, + "side": self.side, + "symbol": self.symbol, + } + + +class KuCoinWSClient: + """ + Private WebSocket client for KuCoin execution events. + + Subscribes to /spotMarket/tradeOrdersV2 (global topic) and dispatches + fill events to awaiting executor coroutines via await_fill(). + """ + + def __init__( + self, + kucoin_api: KuCoinAPI, + private_token_url: str = "https://api.kucoin.com/api/v1/bullet-private", + reconnect_base_delay: float = 1.0, + reconnect_max_delay: float = 30.0, + ) -> None: + self._api = kucoin_api + self._private_token_url = private_token_url + self._reconnect_base_delay = reconnect_base_delay + self._reconnect_max_delay = reconnect_max_delay + self._reconnect_delay = reconnect_base_delay + self._log = logger + self._running = False + self._ws: Optional[websockets.WebSocketClientProtocol] = None + self._connected = False + self._ping_interval: float = 18.0 + self._ping_timeout: float = 10.0 + self._fill_futures: dict[str, asyncio.Future] = {} + self._accumulators: dict[str, FillAccumulator] = {} + self._worker_task: Optional[asyncio.Task] = None + self._subscribe_ack_event: Optional[asyncio.Event] = None + self._subscribe_ack_id: Optional[str] = None + + @property + def is_connected(self) -> bool: + return self._connected + + async def start(self) -> None: + """Start the WebSocket connection worker with reconnection loop.""" + self._running = True + self._worker_task = asyncio.create_task(self._connection_worker()) + try: + await self._worker_task + except asyncio.CancelledError: + pass + + async def stop(self) -> None: + """Stop the WebSocket connection and resolve any pending futures.""" + self._running = False + for future in self._fill_futures.values(): + if not future.done(): + future.set_result((False, {})) + self._fill_futures.clear() + self._accumulators.clear() + if self._worker_task is not None and not self._worker_task.done(): + self._worker_task.cancel() + if self._ws is not None: + try: + await self._ws.close() + except Exception: + pass + self._connected = False + self._log.debug("ws_client_stopped") + + async def await_fill( + self, client_oid: str, timeout_ms: float + ) -> tuple[bool, dict]: + """ + Wait for the order identified by client_oid to be fully filled. + + Parameters + ---------- + client_oid : str + The client-order ID used when placing the order. + timeout_ms : float + Maximum wait time in milliseconds. + + Returns + ------- + tuple[bool, dict] + (success, aggregated_fill_data) on fill. + (False, {}) on timeout, failure, or disconnected. + """ + if not self._connected: + self._log.warning( + "await_fill_not_connected", + client_oid=client_oid, + ) + return (False, {}) + + future: asyncio.Future = asyncio.get_event_loop().create_future() + self._fill_futures[client_oid] = future + + try: + await asyncio.wait_for(future, timeout=timeout_ms / 1000.0) + except asyncio.TimeoutError: + self._fill_futures.pop(client_oid, None) + self._log.warning( + "fill_timeout", + client_oid=client_oid, + timeout_ms=timeout_ms, + accumulator=( + self._accumulators.get(client_oid).to_dict() + if client_oid in self._accumulators + else None + ), + ) + return (False, {}) + except asyncio.CancelledError: + self._fill_futures.pop(client_oid, None) + raise + + result = future.result() + self._fill_futures.pop(client_oid, None) + if client_oid in self._accumulators: + del self._accumulators[client_oid] + return result + + async def _connection_worker(self) -> None: + """Main connection loop with exponential backoff reconnection.""" + while self._running: + try: + await self._connect_and_run() + except asyncio.CancelledError: + break + except Exception as e: + if not self._running: + break + self._connected = False + self._log.warning( + "ws_reconnecting", + error=str(e), + delay=self._reconnect_delay, + ) + await asyncio.sleep(self._reconnect_delay) + self._reconnect_delay = min( + self._reconnect_delay * 2, + self._reconnect_max_delay, + ) + + async def _connect_and_run(self) -> None: + """Authenticate, connect, subscribe, and run the message loop.""" + async with aiohttp.ClientSession() as session: + token_data = await self._api.get_private_token(session) + if not token_data: + raise RuntimeError("Failed to obtain private token") + + token = token_data.get("token", "") + servers = token_data.get("instanceServers", []) + if not servers: + raise RuntimeError("No instance servers in token response") + + server = servers[0] + endpoint = server.get("endpoint", "") + self._ping_interval = server.get("pingInterval", 18000) / 1000.0 + self._ping_timeout = server.get("pingTimeout", 10000) / 1000.0 + + ws_url = f"{endpoint}?token={token}&connectId={uuid.uuid4()}" + self._log.debug("ws_connecting", url=ws_url[:80]) + + self._ws = await websockets.connect( + ws_url, + ping_interval=self._ping_interval, + ping_timeout=self._ping_timeout, + ) + self._connected = True + self._reconnect_delay = self._reconnect_base_delay + self._log.info("ws_connected") + + sub_task = asyncio.create_task(self._subscribe()) + + try: + async for msg in self._ws: + await self._handle_message(msg) + except websockets.ConnectionClosed as e: + self._log.warning( + "ws_connection_closed", + code=e.code, + reason=e.reason, + ) + except asyncio.CancelledError: + sub_task.cancel() + raise + except Exception as e: + self._log.error("ws_message_loop_error", error=str(e)) + finally: + self._connected = False + + async def _subscribe(self) -> None: + """Subscribe to the global tradeOrdersV2 topic.""" + if self._ws is None: + return + + ack_id = int(time.time() * 1000) + self._subscribe_ack_id = str(ack_id) + self._subscribe_ack_event = asyncio.Event() + + sub_msg = { + "id": ack_id, + "type": "subscribe", + "topic": "/spotMarket/tradeOrdersV2", + "response": True, + "privateChannel": "true", + } + + await self._ws.send(json.dumps(sub_msg)) + self._log.info("subscribe_sent", topic="/spotMarket/tradeOrdersV2") + + try: + await asyncio.wait_for(self._subscribe_ack_event.wait(), timeout=15.0) + self._log.info("subscription_confirmed", topic="/spotMarket/tradeOrdersV2") + except asyncio.TimeoutError: + self._log.warning("subscription_ack_timeout", topic="/spotMarket/tradeOrdersV2") + + async def _handle_message(self, msg: str) -> None: + """Parse incoming WS message and dispatch fill events.""" + try: + data = json.loads(msg) + except json.JSONDecodeError: + self._log.warning("ws_raw_message_parse_error", raw=msg[:500]) + return + + msg_type = data.get("type") + + if msg_type == "welcome": + return + + if msg_type == "pong": + return + + if msg_type == "ack": + ack_id = str(data.get("id", "")) + if ack_id == self._subscribe_ack_id and self._subscribe_ack_event is not None: + self._subscribe_ack_event.set() + self._subscribe_ack_event = None + self._subscribe_ack_id = None + return + + if msg_type != "message": + return + + subject = data.get("subject", "") + if subject != "orderChange": + return + + payload = data.get("data", {}) + event_type = payload.get("type", "") + client_oid = payload.get("clientOid", "") + order_id = payload.get("orderId", "") + status = payload.get("status", "") + + if not client_oid: + return + + if event_type == "match": + if client_oid not in self._accumulators: + self._accumulators[client_oid] = FillAccumulator(client_oid, order_id) + self._accumulators[client_oid].add_match(payload) + + elif event_type == "filled" and status == "done": + if client_oid in self._accumulators: + acc = self._accumulators[client_oid] + acc.order_id = order_id or acc.order_id + fill_data = acc.to_dict() + self._log.debug( + "fill_received", + client_oid=client_oid, + order_id=order_id, + total_size=fill_data["total_size"], + total_funds=fill_data["total_funds"], + avg_price=fill_data["weighted_avg_price"], + match_count=fill_data["match_count"], + ) + else: + # Shouldn't happen in normal flow, but handle defensively. + fill_data = { + "total_size": Decimal(str(payload.get("filledSize", "0"))), + "total_funds": _D0, + "weighted_avg_price": _D0, + "match_count": 0, + "order_id": order_id, + "side": payload.get("side", ""), + "symbol": payload.get("symbol", ""), + } + self._log.warning( + "filled_without_matches", + client_oid=client_oid, + order_id=order_id, + ) + + if client_oid in self._fill_futures: + future = self._fill_futures[client_oid] + if not future.done(): + future.set_result((True, fill_data)) + + elif event_type in ("canceled", "failed"): + self._log.warning( + "ws_terminal_event_full_payload", + client_oid=client_oid, + event_type=event_type, + status=status, + full_payload=json.dumps(payload, indent=2), + ) + # Market orders with `funds` send type="canceled" + status="done" when + # the order completes with a tiny remainder. If we have accumulated + # matches, this is actually a successful fill. + if ( + event_type == "canceled" + and status == "done" + and client_oid in self._accumulators + ): + acc = self._accumulators[client_oid] + if acc.match_count > 0: + acc.order_id = order_id or acc.order_id + fill_data = acc.to_dict() + self._log.info( + "fill_via_cancel_done", + client_oid=client_oid, + order_id=order_id, + total_size=fill_data["total_size"], + total_funds=fill_data["total_funds"], + avg_price=fill_data["weighted_avg_price"], + match_count=fill_data["match_count"], + ) + if client_oid in self._fill_futures: + future = self._fill_futures[client_oid] + if not future.done(): + future.set_result((True, fill_data)) + return + + if client_oid in self._fill_futures: + future = self._fill_futures[client_oid] + if not future.done(): + future.set_result((False, {})) diff --git a/fh_ob/__init__.py b/fh_ob/__init__.py new file mode 100644 index 0000000..49de5a9 --- /dev/null +++ b/fh_ob/__init__.py @@ -0,0 +1,15 @@ +"""Feed Handler + Order Book Mirror.""" + +from fh_ob.ws_client import KuCoinWSClient +from fh_ob.book_store import BookStore, OrderBookTop5, BookLevel +from fh_ob.socket_server import SocketServer +from fh_ob.rest_server import create_app + +__all__ = [ + "KuCoinWSClient", + "BookStore", + "OrderBookTop5", + "BookLevel", + "SocketServer", + "create_app", +] \ No newline at end of file diff --git a/fh_ob/__main__.py b/fh_ob/__main__.py new file mode 100644 index 0000000..ee1f2ff --- /dev/null +++ b/fh_ob/__main__.py @@ -0,0 +1,87 @@ +import asyncio +import signal +from pathlib import Path + +import structlog +import uvicorn + +from common.config import Settings +from common.log import configure_logging +from fh_ob.book_store import BookStore +from fh_ob.rest_server import create_app +from fh_ob.socket_server import SocketServer +from fh_ob.ws_client import KuCoinWSClient + + +async def main() -> None: + config_path = Path("config.yaml") + settings = await Settings.from_yaml(config_path) if config_path.exists() else Settings() + configure_logging(settings.fh_ob.log_level, settings.fh_ob.log_file) + log = structlog.get_logger().bind(component="fh_ob") + + log.info("fh_ob_starting", symbols=settings.fh_ob.symbols) + + book_store = BookStore() + socket_server = SocketServer(settings.fh_ob.socket_path) + + async def on_book_update(book): + try: + await socket_server.broadcast(book) + except Exception: + pass + + ws_client = KuCoinWSClient( + settings=settings.fh_ob, + book_store=book_store, + on_book_update=on_book_update, + ) + + rest_app = create_app( + book_store, + get_socket_clients=socket_server.client_count, + get_subscribed_count=ws_client.subscribed_count, + is_connected=ws_client.is_connected, + add_symbol=ws_client.add_symbol, + remove_symbol=ws_client.remove_symbol, + get_symbols=ws_client.get_symbols, + get_reconnect_stats=ws_client.reconnect_stats, + ) + rest_config = uvicorn.Config( + rest_app, + host=settings.fh_ob.rest_host, + port=settings.fh_ob.rest_port, + log_level="warning", + ) + rest_server = uvicorn.Server(rest_config) + + async def shutdown(sig: signal.Signals) -> None: + log.info("shutdown_signal_received", signal=sig.name) + await ws_client.stop() + await socket_server.stop() + rest_config.should_exit = True + + loop = asyncio.get_running_loop() + for sig in (signal.SIGTERM, signal.SIGINT): + loop.add_signal_handler(sig, lambda s=sig: asyncio.create_task(shutdown(s))) + + ws_task = asyncio.create_task(ws_client.start()) + socket_task = asyncio.create_task(socket_server.start()) + rest_task = asyncio.create_task(rest_server.serve()) + + log.info( + "fh_ob_ready", + rest_endpoint=f"http://{settings.fh_ob.rest_host}:{settings.fh_ob.rest_port}", + socket_path=str(settings.fh_ob.socket_path), + ) + + try: + await asyncio.gather(ws_task, socket_task, rest_task) + except asyncio.CancelledError: + log.info("fh_ob_cancelled") + except Exception as e: + log.error("fh_ob_error", error=str(e)) + raise + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/fh_ob/book_store.py b/fh_ob/book_store.py new file mode 100644 index 0000000..0080245 --- /dev/null +++ b/fh_ob/book_store.py @@ -0,0 +1,70 @@ +import time +from dataclasses import dataclass, field +from typing import Optional + +import structlog + +logger = structlog.get_logger() + + +@dataclass +class BookLevel: + price: float + size: float + + @classmethod + def from_list(cls, data: list) -> "BookLevel": + return cls(price=float(data[0]), size=float(data[1])) + + def to_dict(self) -> dict: + return {"price": self.price, "size": self.size} + + +@dataclass +class OrderBookTop5: + symbol: str + bids: list[BookLevel] = field(default_factory=list) + asks: list[BookLevel] = field(default_factory=list) + ts_ms: int = 0 + + def to_dict(self) -> dict: + return { + "symbol": self.symbol, + "bids": [b.to_dict() for b in self.bids], + "asks": [a.to_dict() for a in self.asks], + "ts_ms": self.ts_ms, + } + + +class BookStore: + def __init__(self) -> None: + self._books: dict[str, OrderBookTop5] = {} + self._log = logger.bind(component="book_store") + + def update(self, raw: dict) -> Optional[OrderBookTop5]: + topic = raw.get("topic", "") + data = raw.get("data", {}) + + topic_suffix = topic.split(":")[-1] if ":" in topic else "" + symbol = topic_suffix.split(",")[0].strip() if topic_suffix else "" + asks_raw = data.get("asks", []) + bids_raw = data.get("bids", []) + + if not symbol: + return None + + ts_ms = int(data.get("time", time.time() * 1000)) + + bids = [BookLevel.from_list(b) for b in bids_raw[:1]] + asks = [BookLevel.from_list(a) for a in asks_raw[:1]] + + book = OrderBookTop5(symbol=symbol, bids=bids, asks=asks, ts_ms=ts_ms) + self._books[symbol] = book + + return book + + def get(self, symbol: str) -> Optional[OrderBookTop5]: + return self._books.get(symbol) + + def get_all(self) -> dict[str, OrderBookTop5]: + return self._books.copy() \ No newline at end of file diff --git a/fh_ob/rest_server.py b/fh_ob/rest_server.py new file mode 100644 index 0000000..ef99e38 --- /dev/null +++ b/fh_ob/rest_server.py @@ -0,0 +1,110 @@ +from typing import Callable, Optional + +from fastapi import FastAPI, HTTPException +from pydantic import BaseModel + +from fh_ob.book_store import BookStore, OrderBookTop5 + + +class BookLevelResponse(BaseModel): + price: str + size: str + + +class OrderBookResponse(BaseModel): + symbol: str + bids: list[BookLevelResponse] + asks: list[BookLevelResponse] + ts_ms: int + + +class HealthResponse(BaseModel): + status: str + books_tracked: int + socket_clients: int + subscribed_symbols: int + connected: bool + last_update_ms: Optional[int] = None + reconnect_count: int = 0 + last_reconnect_ms: Optional[int] = None + + +class SymbolOpRequest(BaseModel): + symbol: str + + +class SymbolsResponse(BaseModel): + symbols: list[str] + + +def create_app( + book_store: BookStore, + get_socket_clients: Optional[Callable[[], int]] = None, + get_subscribed_count: Optional[Callable[[], int]] = None, + is_connected: Optional[Callable[[], bool]] = None, + add_symbol: Optional[Callable[[str], bool]] = None, + remove_symbol: Optional[Callable[[str], bool]] = None, + get_symbols: Optional[Callable[[], list[str]]] = None, + get_reconnect_stats: Optional[Callable[[], tuple[int, int]]] = None, +) -> FastAPI: + app = FastAPI(title="FH+OB Debug API", description="Dev-only debug endpoint") + + @app.get("/book/{symbol}", response_model=OrderBookResponse) + async def get_book(symbol: str) -> OrderBookResponse: + book = book_store.get(symbol) + if book is None: + raise HTTPException(status_code=404, detail=f"No book data for {symbol}") + return OrderBookResponse( + symbol=book.symbol, + bids=[BookLevelResponse(price=str(b.price), size=str(b.size)) for b in book.bids], + asks=[BookLevelResponse(price=str(a.price), size=str(a.size)) for a in book.asks], + ts_ms=book.ts_ms, + ) + + @app.get("/books", response_model=dict[str, OrderBookResponse]) + async def get_all_books() -> dict[str, OrderBookResponse]: + books = book_store.get_all() + return { + symbol: OrderBookResponse( + symbol=book.symbol, + bids=[BookLevelResponse(price=str(b.price), size=str(b.size)) for b in book.bids], + asks=[BookLevelResponse(price=str(a.price), size=str(a.size)) for a in book.asks], + ts_ms=book.ts_ms, + ) + for symbol, book in books.items() + } + + @app.get("/symbols") + async def list_symbols(): + return SymbolsResponse(symbols=get_symbols() if get_symbols else []) + + @app.post("/symbols") + async def add_sym(req: SymbolOpRequest): + if add_symbol and add_symbol(req.symbol): + return SymbolsResponse(symbols=get_symbols() if get_symbols else []) + raise HTTPException(status_code=400, detail="Symbol not found or already subscribed") + + @app.delete("/symbols/{symbol}") + async def rm_sym(symbol: str): + if remove_symbol and remove_symbol(symbol): + return SymbolsResponse(symbols=get_symbols() if get_symbols else []) + raise HTTPException(status_code=404, detail="Symbol not found or not subscribed") + + @app.get("/health", response_model=HealthResponse) + async def health() -> HealthResponse: + books = book_store.get_all() + latest_ts = max((b.ts_ms for b in books.values()), default=None) + reconnects, last_reconnect_ms = get_reconnect_stats() if get_reconnect_stats else (0, None) + + return HealthResponse( + status="ok" if (is_connected and is_connected()) else "degraded", + books_tracked=len(books), + socket_clients=get_socket_clients() if get_socket_clients else 0, + subscribed_symbols=get_subscribed_count() if get_subscribed_count else 0, + connected=is_connected() if is_connected else False, + last_update_ms=latest_ts, + reconnect_count=reconnects, + last_reconnect_ms=last_reconnect_ms, + ) + + return app \ No newline at end of file diff --git a/fh_ob/socket_server.py b/fh_ob/socket_server.py new file mode 100644 index 0000000..591505a --- /dev/null +++ b/fh_ob/socket_server.py @@ -0,0 +1,95 @@ +from typing import Optional + +import asyncio +import json +from pathlib import Path + +import structlog + +from fh_ob.book_store import OrderBookTop5 + + +class SocketServer: + def __init__(self, socket_path: Path) -> None: + self._socket_path = socket_path + self._log = structlog.get_logger().bind(component="socket_server") + self._clients: set[asyncio.StreamWriter] = set() + self._server: Optional[asyncio.Server] = None + + async def start(self) -> None: + if self._socket_path.exists(): + self._socket_path.unlink() + + self._server = await asyncio.start_unix_server( + self._accept_client, + path=str(self._socket_path), + ) + self._log.info("socket_server_started", path=str(self._socket_path)) + + async def stop(self) -> None: + if self._server: + self._server.close() + await self._server.wait_closed() + if self._socket_path.exists(): + self._socket_path.unlink() + self._log.info("socket_server_stopped") + + def client_count(self) -> int: + return len(self._clients) + + async def _accept_client( + self, reader: asyncio.StreamReader, writer: asyncio.StreamWriter + ) -> None: + self._clients.add(writer) + self._log.info("client_connected", addr=writer.get_extra_info("peername")) + try: + while True: + try: + line = await reader.readline() + except (ConnectionResetError, BrokenPipeError, asyncio.CancelledError): + break + except Exception: + break + if not line: + break + except asyncio.CancelledError: + pass + except Exception: + pass + finally: + self._clients.discard(writer) + writer.close() + try: + await asyncio.wait_for(writer.wait_closed(), timeout=1.0) + except (asyncio.CancelledError, Exception): + pass + self._log.info("client_disconnected") + + async def broadcast(self, book: OrderBookTop5) -> None: + if not self._clients: + return + + msg_bytes = json.dumps(book.to_dict(), separators=(",", ":")).encode() + b"\n" + + clients_snapshot = list(self._clients) + bad = set() + for w in clients_snapshot: + try: + w.write(msg_bytes) + except Exception as e: + self._log.warning("broadcast_write_failed", error=str(e)) + bad.add(w) + + if not clients_snapshot: + return + + drain_results = await asyncio.gather( + *(w.drain() for w in clients_snapshot), + return_exceptions=True, + ) + for w, res in zip(clients_snapshot, drain_results): + if isinstance(res, Exception): + self._log.warning("broadcast_drain_failed", error=str(res)) + bad.add(w) + + self._clients -= bad \ No newline at end of file diff --git a/fh_ob/ws_client.py b/fh_ob/ws_client.py new file mode 100644 index 0000000..7f540e0 --- /dev/null +++ b/fh_ob/ws_client.py @@ -0,0 +1,271 @@ +import asyncio +import json +import time +import uuid +from dataclasses import dataclass, field +from typing import Callable, Optional, Awaitable + +import aiohttp +import structlog +import websockets + +from common.config import FHobSettings +from fh_ob.book_store import BookStore, OrderBookTop5 + + +@dataclass +class _WorkerState: + symbols: set[str] = field(default_factory=set) + command_queue: asyncio.Queue = field(default_factory=asyncio.Queue) + ws_id: int = 0 + reconnect_count: int = 0 + last_reconnect_ts_ms: int = 0 + connection_active: bool = False + + +class KuCoinWSClient: + def __init__( + self, + settings: FHobSettings, + book_store: BookStore, + on_book_update: Optional[Callable[[OrderBookTop5], None | Awaitable[None]]] = None, + ) -> None: + self._settings = settings + self._book_store = book_store + self._on_book_update_callback = on_book_update + self._log = structlog.get_logger().bind(component="ws_client") + self._running = False + self._reconnect_delay = settings.reconnect_base_delay + self._subscription_events: dict[str, asyncio.Event] = {} + self._workers: list[_WorkerState] = [] + self._worker_tasks: list[asyncio.Task] = [] + self._http_session: Optional[aiohttp.ClientSession] = None + + async def start(self) -> None: + self._running = True + self._workers.clear() + self._worker_tasks.clear() + self._http_session = aiohttp.ClientSession() + symbol_list = list(self._settings.symbols) + for i in range(0, len(symbol_list) or 1, 400): + group = set(symbol_list[i : i + 400]) + ws_id = len(self._workers) + 1 + state = _WorkerState(symbols=group, ws_id=ws_id) + self._workers.append(state) + for state in self._workers: + task = asyncio.create_task(self._connection_worker(state)) + self._worker_tasks.append(task) + try: + await asyncio.gather(*self._worker_tasks) + except asyncio.CancelledError: + pass + self._log.debug("all_workers_stopped") + + async def stop(self) -> None: + self._running = False + for t in self._worker_tasks: + t.cancel() + if self._worker_tasks: + await asyncio.wait(self._worker_tasks, timeout=5) + if self._http_session and not self._http_session.closed: + await self._http_session.close() + self._log.debug("ws_client_stopped") + + def is_connected(self) -> bool: + return any(w.connection_active for w in self._workers) + + def subscribed_count(self) -> int: + return sum(len(w.symbols) for w in self._workers) + + def reconnect_stats(self) -> tuple[int, int]: + """Return (total_reconnects, timestamp_ms of last reconnect) across all workers.""" + total = sum(w.reconnect_count for w in self._workers) + latest = max((w.last_reconnect_ts_ms for w in self._workers), default=0) + return total, latest + + def get_symbols(self) -> list[str]: + result = [] + for w in self._workers: + result.extend(w.symbols) + return result + + def add_symbol(self, symbol: str) -> bool: + if not self._workers: + return False + if any(symbol in w.symbols for w in self._workers): + return False + self._settings.symbols.append(symbol) + eligible = [w for w in self._workers if len(w.symbols) < 400] + if not eligible: + self._log.warning("all_workers_full", symbol=symbol) + return False + worker = min(eligible, key=lambda w: len(w.symbols)) + worker.symbols.add(symbol) + worker.command_queue.put_nowait(("subscribe", symbol)) + return True + + def remove_symbol(self, symbol: str) -> bool: + found = False + for worker in self._workers: + if symbol in worker.symbols: + worker.symbols.discard(symbol) + found = True + break + if not found: + return False + self._settings.symbols.remove(symbol) + return True + + async def _connection_worker(self, state: _WorkerState) -> None: + while self._running: + try: + token, instance = await self._get_public_token() + self._ping_interval = instance.get("pingInterval", 18000) / 1000.0 + ws = await websockets.connect( + instance["endpoint"] + f"?token={token}&connectId={uuid.uuid4()}-{state.ws_id}", + ping_interval=None, + ) + self._log.debug("ws_connected", ws_id=state.ws_id) + self._reconnect_delay = self._settings.reconnect_base_delay + state.connection_active = True + + ping_task = asyncio.create_task(self._ping_loop(ws, state.ws_id)) + + async def reader() -> None: + try: + async for msg in ws: + await self._handle_message(msg) + except websockets.ConnectionClosed as e: + self._log.warning("reader_connection_closed", ws_id=state.ws_id, code=e.code, reason=e.reason) + except asyncio.CancelledError: + raise + except Exception as e: + self._log.error("reader_unexpected_error", ws_id=state.ws_id, error=str(e)) + + reader_task = asyncio.create_task(reader()) + + try: + if state.symbols: + await self._send_subscribe(ws, list(state.symbols), state.ws_id) + + while True: + cmd = await state.command_queue.get() + if cmd is None: + break + action, symbol = cmd + if action == "subscribe": + self._log.debug( + "subscribing_dynamic", + symbol=symbol, + ws_id=state.ws_id, + ) + await self._send_subscribe(ws, [symbol], state.ws_id) + except asyncio.CancelledError: + raise + except websockets.ConnectionClosed as e: + self._log.warning("ws_disconnected", ws_id=state.ws_id, code=e.code, reason=e.reason) + except Exception as e: + self._log.error("command_loop_error", ws_id=state.ws_id, error=str(e)) + finally: + state.connection_active = False + ping_task.cancel() + reader_task.cancel() + try: + await reader_task + except asyncio.CancelledError: + pass + except asyncio.CancelledError: + break + except Exception as e: + if not self._running: + break + state.connection_active = False + state.reconnect_count += 1 + state.last_reconnect_ts_ms = int(time.time() * 1000) + self._log.warning( + "ws_reconnecting", + ws_id=state.ws_id, + reconnect_count=state.reconnect_count, + error=str(e), + ) + await asyncio.sleep(self._reconnect_delay) + self._reconnect_delay = min( + self._reconnect_delay * 2, + self._settings.reconnect_max_delay, + ) + + self._log.debug("worker_exiting", ws_id=state.ws_id) + + async def _get_public_token(self) -> tuple[str, dict]: + self._log.debug("fetching_public_token", url=self._settings.token_url) + async with self._http_session.post(self._settings.token_url) as resp: + data = await resp.json() + token = data["data"]["token"] + instance = data["data"]["instanceServers"][0] + self._log.debug("public_token_received", ping_interval_ms=instance.get("pingInterval")) + return token, instance + + async def _send_subscribe(self, ws, symbols: list[str], ws_id: int) -> None: + for i in range(0, len(symbols), 100): + batch = symbols[i : i + 100] + topic = "/spotMarket/level2Depth5:" + ",".join(batch) + ack_id = str(uuid.uuid4()) + evt = asyncio.Event() + self._subscription_events[ack_id] = evt + sub_msg = { + "id": ack_id, + "type": "subscribe", + "topic": topic, + "response": True, + } + self._log.debug("subscribing", topic=topic[:80], ws_id=ws_id) + await ws.send(json.dumps(sub_msg)) + try: + await asyncio.wait_for(evt.wait(), timeout=self._reconnect_delay) + except asyncio.TimeoutError: + self._log.warning("subscription_ack_timeout", topic=topic[:80], ws_id=ws_id) + raise + + async def _ping_loop(self, ws, ws_id: int) -> None: + while self._running: + await asyncio.sleep(self._ping_interval) + try: + await ws.ping() + except Exception: + self._log.warning("ping_failed", ws_id=ws_id) + break + + async def _handle_message(self, msg: str) -> None: + try: + data = json.loads(msg) + except json.JSONDecodeError: + self._log.warning("invalid_json", msg=msg[:100]) + return + + msg_type = data.get("type") + + if msg_type == "welcome": + self._log.debug("ws_welcome") + return + + if msg_type == "pong": + return + + if msg_type == "ack": + ack_id = data.get("id") + self._log.debug("subscription_ack", topic=data.get("topic"), ack_id=ack_id) + if ack_id in self._subscription_events: + self._subscription_events[ack_id].set() + del self._subscription_events[ack_id] + return + + topic = data.get("topic", "") + + if msg_type == "message" and "level2Depth5" in topic: + book = self._book_store.update(data) + if book and self._on_book_update_callback: + result = self._on_book_update_callback(book) + if asyncio.iscoroutine(result): + asyncio.create_task(result) + elif topic: + self._log.warning("ws_unexpected_message", type=msg_type, topic=topic) diff --git a/oe_em/__init__.py b/oe_em/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/oe_em/__main__.py b/oe_em/__main__.py new file mode 100644 index 0000000..2c36576 --- /dev/null +++ b/oe_em/__main__.py @@ -0,0 +1,223 @@ +""" +Opportunity engine entry point. + +Initialises the order-book consumer, triangle index, and signal socket client; +starts background tasks for book consumption and periodic stats logging; shuts +down cleanly on SIGTERM/SIGINT. +""" +import asyncio +import signal +from pathlib import Path + +import aiohttp +import structlog + +from common.log import configure_logging +from oe_em.book_consumer import BookConsumer +from oe_em.config import Settings +from oe_em.kucoin_api import KuCoinAPI +from oe_em.opportunity import OpportunityEngine +from oe_em.risk import RiskManager +from oe_em.socket_client import SignalSocketClient +from oe_em.triangle_enum import TradingPair, enumerate_triangles + + +async def sync_symbols_with_fh_ob( + fh_ob_url: str, + needed_symbols: set[str], + http_session: aiohttp.ClientSession, + log, +) -> set[str]: + """ + Ensure fh_ob is subscribed to every symbol needed by the triangle index. + + Fetches the current subscription list from fh_ob, posts any missing symbols, + and returns the full set of subscribed symbols. + """ + get_url = f"{fh_ob_url}/symbols" + async with http_session.get(get_url) as resp: + resp.raise_for_status() + data = await resp.json() + + current_symbols = set(data.get("symbols", [])) + missing = needed_symbols - current_symbols + + if missing: + log.info("syncing_symbols", missing=len(missing), current=len(current_symbols)) + for sym in missing: + post_url = f"{fh_ob_url}/symbols" + payload = {"symbol": sym} + async with http_session.post(post_url, json=payload) as post_resp: + if post_resp.status == 400: + log.warning("symbol_cannot_be_subscribed", symbol=sym) + else: + log.debug("symbol_subscribed", symbol=sym) + + return current_symbols | missing + + +async def main() -> None: + config_path = Path("config.yaml") + settings = await Settings.from_yaml(config_path) if config_path.exists() else Settings() + configure_logging(settings.oe_em.log_level, settings.oe_em.log_file) + + log = structlog.get_logger().bind(component="oe_em") + + log.info("oe_em_starting") + + api = KuCoinAPI() + await api.fetch_pairs_and_fees() + + pair_list = [ + TradingPair( + symbol=p["symbol"], + base=p["base"], + quote=p["quote"], + fee_currency=p.get("fee_currency", ""), + ) + for p in api.get_all_pairs() + ] + excluded = set(settings.oe_em.excluded_currencies) + if excluded: + pair_list = [p for p in pair_list if p.base not in excluded and p.quote not in excluded] + log.info("pairs_loaded", count=len(pair_list), excluded=len(excluded)) + + fee_table = api._fee_table + triangle_index = enumerate_triangles( + pair_list, + fee_table, + hold_currencies=settings.oe_em.hold_currencies, + ) + log.info("triangles_enumerated", count=len(triangle_index.triangles)) + + needed_symbols = set() + for tri in triangle_index.triangles: + needed_symbols.update(tri.pair_symbols) + + async with aiohttp.ClientSession() as http_session: + subscribed = await sync_symbols_with_fh_ob( + settings.oe_em.fh_ob_url, + needed_symbols, + http_session, + log, + ) + + book_consumer = BookConsumer( + socket_path=settings.oe_em.socket_path, + on_update=lambda symbol, book: None, + ) + + signal_client: SignalSocketClient | None = None + signal_reconnect_task: asyncio.Task | None = None + + if settings.oe_em.send_signals: + signal_client = SignalSocketClient(socket_path=settings.oe_em.executor_socket_path) + + async def send_signal(signal_payload: dict) -> None: + """Forward a signal payload to the executor's Unix socket.""" + if signal_client: + await signal_client.send_signal(signal_payload) + + opp_engine = OpportunityEngine( + book_consumer=book_consumer, + triangle_index=triangle_index, + signal_threshold_bps=settings.oe_em.signal_threshold_bps, + log_path=settings.oe_em.opportunity_log_path, + kcs_discount_active=settings.oe_em.kcs_discount_active, + cooldown_seconds=settings.oe_em.cooldown_seconds, + on_signal=send_signal if settings.oe_em.send_signals else None, + ) + + risk_mgr = RiskManager() + + async def on_book_update(symbol: str, book) -> None: + """Callback invoked by BookConsumer whenever a subscribed book is refreshed.""" + if risk_mgr.should_continue(): + opp_engine.evaluate_triangles_for_pair(symbol) + + book_consumer.set_on_update(on_book_update) + + fh_ob_url = settings.oe_em.fh_ob_url + async with aiohttp.ClientSession() as http_session: + async with http_session.get(f"{fh_ob_url}/symbols") as resp: + resp.raise_for_status() + data = await resp.json() + symbols_now = set(data.get("symbols", [])) + missing = needed_symbols - symbols_now + if missing: + log.warning("symbols_not_subscribed_after_sync", count=len(missing)) + for sym in missing: + log.warning("unavailable_symbol", symbol=sym) + + if signal_client: + signal_reconnect_task = await signal_client.start() + log.info("signal_client_connecting", socket_path=str(settings.oe_em.executor_socket_path)) + + log.info( + "oe_em_ready", + triangles=len(triangle_index.triangles), + subscribed=len(symbols_now), + threshold_bps=settings.oe_em.signal_threshold_bps, + hold_currencies=settings.oe_em.hold_currencies, + send_signals=settings.oe_em.send_signals, + ) + + consumer_task = asyncio.create_task(book_consumer.start()) + + async def stats_loop() -> None: + """ + Periodically log evaluation stats so the operator can monitor the engine. + + Runs until cancelled. Suppressed by setting stats_interval_seconds <= 0. + """ + interval = settings.oe_em.stats_interval_seconds + if interval <= 0: + return + while True: + await asyncio.sleep(interval) + try: + s = opp_engine.get_stats() + books_tracked = sum( + 1 for t in triangle_index.triangles + if book_consumer.get_book(t.legs[0].pair.symbol) is not None + ) + except Exception as e: + log.error("stats_error", error=str(e)) + continue + log.info("stats", **{ + "triangles_evaluated": s.triangles_evaluated, + "signals_fired": s.signals_fired, + "books_tracked": books_tracked, + "subscribed": len(book_consumer._books), + "best_net_bps": f"{s.best_net_bps:.2f}", + "best_legs": s.best_legs, + }) + + stats_task = asyncio.create_task(stats_loop()) + + def shutdown(sig: signal.Signals) -> None: + """Begin graceful shutdown: stop book consumer, cancel stats, close signal client.""" + log.info("shutdown_signal_received", signal=sig.name) + asyncio.create_task(book_consumer.stop()) + stats_task.cancel() + if signal_reconnect_task: + signal_reconnect_task.cancel() + if signal_client: + asyncio.create_task(signal_client.close()) + + loop = asyncio.get_running_loop() + for sig in (signal.SIGTERM, signal.SIGINT): + loop.add_signal_handler(sig, lambda s=sig: shutdown(s)) + + tasks = [consumer_task, stats_task] + if signal_reconnect_task: + tasks.append(signal_reconnect_task) + + try: + await asyncio.gather(*tasks) + except asyncio.CancelledError: + log.info("oe_em_cancelled") + + +if __name__ == "__main__": + asyncio.run(main()) \ No newline at end of file diff --git a/oe_em/book_consumer.py b/oe_em/book_consumer.py new file mode 100644 index 0000000..b38b6a9 --- /dev/null +++ b/oe_em/book_consumer.py @@ -0,0 +1,205 @@ +""" +Order-book consumer for the opportunity engine. + +Connects to fh_ob's Unix-domain socket and receives JSON-serialized top-5 +order-book snapshots. On each update the registered on_update callback is +invoked, which triggers triangle evaluation in OpportunityEngine. + +The consumer maintains an in-memory snapshot of the last seen book for each +symbol, accessible via get_book(). +""" +import asyncio +import json +from dataclasses import dataclass, field +from pathlib import Path +from typing import Callable, Optional, Awaitable + +import structlog + +logger = structlog.get_logger().bind(component="book_consumer") + + +@dataclass +class BookLevel: + """ + A single price level in an order book. + + Attributes + ---------- + price, size : float + Price and available size at this level. + """ + + price: float + size: float + + @classmethod + def from_dict(cls, data: dict) -> "BookLevel": + return cls( + price=float(data["price"]), + size=float(data["size"]), + ) + + +@dataclass +class OrderBookTop5: + """ + Top-5 bid/ask snapshot for a single symbol. + + Attributes + ---------- + symbol : str + KuCoin symbol e.g. "BTC-USDT". + bids : list[BookLevel] + Best bids, most aggressive first. + asks : list[BookLevel] + Best asks, most aggressive first. + ts_ms : int + Timestamp (ms) of the snapshot from fh_ob. + """ + + symbol: str + bids: list[BookLevel] = field(default_factory=list) + asks: list[BookLevel] = field(default_factory=list) + ts_ms: int = 0 + + @classmethod + def from_json(cls, data: dict) -> "OrderBookTop5": + bids = [BookLevel.from_dict(b) for b in data.get("bids", [])] + asks = [BookLevel.from_dict(a) for a in data.get("asks", [])] + return cls( + symbol=data.get("symbol", ""), + bids=bids, + asks=asks, + ts_ms=data.get("ts_ms", 0), + ) + + +class BookConsumer: + """ + Consumes order-book snapshots from fh_ob and dispatches them to OpportunityEngine. + + Maintains a socket connection until EOF or error, then reconnects + automatically. Book updates are pushed to an internal queue; a dedicated + worker drains the queue and calls on_update, keeping the reader loop + non-blocking. + """ + + def __init__( + self, + socket_path: Path, + on_update: Callable[[str, OrderBookTop5], None | Awaitable[None]], + ) -> None: + self._socket_path = socket_path + self._on_update = on_update + self._running = False + self._books: dict[str, OrderBookTop5] = {} + self._log = logger + self._queue: asyncio.Queue[str] = asyncio.Queue(maxsize=2048) + self._queued: set[str] = set() + self._worker_task: Optional[asyncio.Task] = None + + def get_book(self, symbol: str) -> Optional[OrderBookTop5]: + """Return the last known book for a symbol, or None if not yet received.""" + return self._books.get(symbol) + + def set_on_update(self, callback: Callable[[str, OrderBookTop5], None]) -> None: + """Replace the on_update callback. Used when the callback needs a + reference to an object that does not yet exist at construction time.""" + self._on_update = callback + + async def start(self) -> None: + """ + Connect to fh_ob and run the consume loop until stop() is called. + + On unexpected disconnection a 1-second backoff is applied before + reconnecting. Interrupted cleanly by CancelledError. + """ + self._running = True + self._worker_task = asyncio.create_task(self._worker()) + while self._running: + try: + await self._connect() + except asyncio.CancelledError: + break + except Exception as e: + self._log.warning("connection_error", error=str(e)) + await asyncio.sleep(1.0) + if self._worker_task: + self._worker_task.cancel() + try: + await self._worker_task + except asyncio.CancelledError: + pass + + async def stop(self) -> None: + """Request the consume loop to exit on the next iteration.""" + self._running = False + + async def _worker(self) -> None: + """Drain the update queue and call on_update for each symbol.""" + while self._running: + try: + symbol = await asyncio.wait_for(self._queue.get(), timeout=0.5) + except asyncio.TimeoutError: + continue + except asyncio.CancelledError: + break + self._queued.discard(symbol) + book = self._books.get(symbol) + if not book: + continue + try: + result = self._on_update(symbol, book) + if asyncio.iscoroutine(result): + await result + except Exception as e: + self._log.error("on_update_error", symbol=symbol, error=str(e)) + + async def _connect(self) -> None: + """ + Open the Unix socket, read and queue messages until EOF or error. + + Each JSON line is parsed into an OrderBookTop5, stored in self._books, + and the symbol is pushed to the queue for the worker to evaluate. + The reader never blocks on evaluation. + """ + reader, writer = await asyncio.open_unix_connection(path=str(self._socket_path)) + self._log.info("connected", path=str(self._socket_path)) + + try: + while self._running: + try: + line = await reader.readline() + except asyncio.CancelledError: + raise + except Exception as e: + self._log.error("socket_read_error", error=str(e)) + break + + if not line: + self._log.warning("socket_eof") + break + + try: + data = json.loads(line.decode()) + except (json.JSONDecodeError, UnicodeDecodeError) as e: + self._log.warning("invalid_json", line=line[:50], error=str(e)) + continue + + book = OrderBookTop5.from_json(data) + if not book.symbol: + continue + + self._books[book.symbol] = book + if book.symbol not in self._queued: + self._queued.add(book.symbol) + try: + self._queue.put_nowait(book.symbol) + except asyncio.QueueFull: + self._queued.discard(book.symbol) + + finally: + writer.close() + await writer.wait_closed() + self._log.info("disconnected") \ No newline at end of file diff --git a/oe_em/config.py b/oe_em/config.py new file mode 100644 index 0000000..b6c44d6 --- /dev/null +++ b/oe_em/config.py @@ -0,0 +1,90 @@ +""" +Configuration schema for the opportunity engine (oe_em). + +Parsed from config.yaml into OeEmSettings. Controls logging, signal +thresholds, the fee discount flag, symbol subscription, and the socket +path to the executor. +""" +import asyncio +from pathlib import Path +from typing import Optional + +import yaml +from pydantic import BaseModel, Field +from pydantic_settings import BaseSettings + + +class OeEmSettings(BaseModel): + """Settings that control oe_em's runtime behaviour.""" + + fh_ob_url: str = Field( + default="http://127.0.0.1:8000", + description="REST URL of fh_ob server", + ) + socket_path: Path = Field( + default=Path("/tmp/fh_ob.sock"), + description="Unix domain socket path for fh_ob", + ) + log_level: str = Field(default="INFO", description="Logging level") + log_file: Path = Field( + default=Path("/tmp/oe_em.log"), + description="Path to log file. Logs are written here in addition to stdout.", + ) + signal_threshold_bps: float = Field( + default=0.2, + description="Minimum net return in basis points to fire a signal", + ) + opportunity_log_path: Path = Field( + default=Path("/tmp/opportunities.log"), + description="Path to log detected opportunities", + ) + stats_interval_seconds: float = Field( + default=60.0, + description="Seconds between stats log lines. 0 to disable.", + ) + cooldown_seconds: float = Field( + default=0.0, + description="Deprecated — use executor's in-flight blocking instead. " + "Kept here for operational flexibility; set to 0.", + ) + excluded_currencies: list[str] = Field( + default_factory=list, + description="Currencies to exclude from triangle enumeration", + ) + hold_currencies: list[str] = Field( + default=["USDT"], + description="Currencies held as capital. Only triangles starting and ending in one of these are evaluated.", + ) + kcs_discount_active: bool = Field( + default=False, + description="If true, all taker fees are multiplied by 0.8 (KCS 20% fee discount)", + ) + executor_socket_path: Path = Field( + default=Path("/tmp/executor.sock"), + description="Unix domain socket path for executor", + ) + send_signals: bool = Field( + default=False, + description="If true, emit signals to executor socket when opportunities are found", + ) + + +class Settings(BaseSettings): + """Top-level settings parsed from config.yaml.""" + + oe_em: OeEmSettings = Field(default_factory=OeEmSettings) + fh_ob_url: Optional[str] = None + + @classmethod + async def from_yaml(cls, path: Path) -> "Settings": + """Load settings from a YAML file.""" + loop = asyncio.get_running_loop() + + def _read() -> dict: + with open(path) as f: + return yaml.safe_load(f) + + data = await loop.run_in_executor(None, _read) + return cls(**data) + + model_config = {"env_prefix": "TRIArb_", "extra": "ignore"} \ No newline at end of file diff --git a/oe_em/kucoin_api.py b/oe_em/kucoin_api.py new file mode 100644 index 0000000..204822e --- /dev/null +++ b/oe_em/kucoin_api.py @@ -0,0 +1,96 @@ +""" +KuCoin API client for the opportunity engine. + +Fetches trading pair metadata (symbol, base, quote, fees, feeCurrency) +and builds an in-memory fee table keyed by base currency. This data is +used to construct the triangle index and to populate fee_currency in +signal payloads. +""" +import aiohttp +import structlog + +logger = structlog.get_logger().bind(component="kucoin_api") + +KUCoin_SYMBOLs_URL = "https://api.kucoin.com/api/v1/symbols" + +DEFAULT_FEES = { + "BTC": {"maker": 0.0010, "taker": 0.0010}, + "ETH": {"maker": 0.0010, "taker": 0.0010}, + "USDT": {"maker": 0.0010, "taker": 0.0010}, + "USDC": {"maker": 0.0010, "taker": 0.0010}, +} + + +class KuCoinAPI: + """ + Fetch and cache KuCoin pair metadata and per-currency fee rates. + + Used at startup to build the fee table required by triangle enumeration. + """ + + def __init__(self) -> None: + self._fee_table: dict[str, dict[str, float]] = {} + self._pairs: dict[str, dict] = {} + self._log = logger + + async def fetch_pairs_and_fees(self) -> None: + """ + Fetch all symbols from KuCoin, populate _pairs and _fee_table. + + Logs warnings for any symbol that cannot be parsed and skips it. + Sets feeCurrency to the empty string when absent in the API response. + """ + async with aiohttp.ClientSession() as session: + async with session.get(KUCoin_SYMBOLs_URL) as resp: + resp.raise_for_status() + payload = await resp.json() + + for item in payload.get("data", []): + symbol = item.get("symbol", "") + base = item.get("baseCurrency", "") + quote = item.get("quoteCurrency", "") + maker_fee = float(item.get("makerFeeRate", 0)) + taker_fee = float(item.get("takerFeeRate", 0)) + enable_trading = item.get("enableTrading", False) + + if not all([symbol, base, quote]): + continue + + fee_currency = item.get("feeCurrency") or "" + self._pairs[symbol] = { + "symbol": symbol, + "base": base, + "quote": quote, + "maker_fee": maker_fee, + "taker_fee": taker_fee, + "enable_trading": enable_trading, + "fee_currency": fee_currency, + } + + if base not in self._fee_table: + self._fee_table[base] = { + "maker": maker_fee if maker_fee > 0 else DEFAULT_FEES.get(base, {}).get("maker", 0.0010), + "taker": taker_fee if taker_fee > 0 else DEFAULT_FEES.get(base, {}).get("taker", 0.0010), + } + + self._log.info("fee_table_loaded", bases=len(self._fee_table), pairs=len(self._pairs)) + + def get_fee(self, symbol: str, side: str) -> float: + """ + Return the taker fee rate for the base currency of a given symbol. + + Falls back to DEFAULT_FEES when the base is not in the fee table. + """ + if symbol not in self._pairs: + return 0.0010 + base = self._pairs[symbol]["base"] + fee_data = self._fee_table.get(base, DEFAULT_FEES.get(base, {"maker": 0.0010, "taker": 0.0010})) + return fee_data.get(side, 0.0010) + + def get_pair_info(self, symbol: str) -> dict | None: + """Return the full info dict for a symbol, or None if not loaded.""" + return self._pairs.get(symbol) + + def get_all_pairs(self) -> list[dict]: + """Return all pairs where enable_trading is True.""" + return [p for p in self._pairs.values() if p["enable_trading"]] \ No newline at end of file diff --git a/oe_em/opportunity.py b/oe_em/opportunity.py new file mode 100644 index 0000000..245344e --- /dev/null +++ b/oe_em/opportunity.py @@ -0,0 +1,408 @@ +""" +Opportunity detection engine. + +Evaluates all triangles involving a given symbol on every order-book update, +computes the net return after fees, and fires a signal when the return exceeds +the configured threshold. Supports KCS fee discounts and per-triangle cooldowns +to avoid flooding the executor with duplicate signals. +""" +import asyncio +import time +import uuid +from dataclasses import dataclass +from pathlib import Path +from typing import Optional, Callable + +import structlog + +from oe_em.book_consumer import BookConsumer +from oe_em.triangle_enum import Triangle, TriangleLeg, TriangleIndex + + +KCS_FEE_DISCOUNT = 0.8 + + +logger = structlog.get_logger().bind(component="opportunity") + + +def max_volume_for_triangle( + triangle: Triangle, + book_consumer: BookConsumer, + primary_quote: str, + fee_mult: float = 1.0, +) -> Optional[float]: + """Compute max volume — kept for backward compatibility, but _build_full now does this inline.""" + return None + + +@dataclass +class OpportunitySignal: + """ + A detected profitable triangular arbitrage opportunity. + + Emitted to the signal client when net_return_bps exceeds the threshold. + """ + triangle: Triangle + direction: str + net_return_bps: float + max_volume: float + leg_details: list[dict] + ts_ms: int + book_ts_ms: int + books: list[dict] + + +@dataclass +class Stats: + """ + Running statistics counters for opportunity evaluation. + + Updated on every evaluate_triangles_for_pair call and returned by + get_stats(). + """ + triangles_evaluated: int = 0 + signals_fired: int = 0 + books_missing: int = 0 + books_full: int = 0 + best_net_bps: float = -999999.0 + worst_net_bps: float = 999999.0 + last_eval_ts_ms: int = 0 + best_legs: str = "" + worst_legs: str = "" + + +@dataclass +class _EvalResult: + """ + Intermediate result of triangle evaluation. + + Attributes + ---------- + net_return_bps : float + Net return after fees in basis points. + max_volume : float + Maximum safe input volume for the triangle. + leg_details : list[dict] + Per-leg dictionary suitable for serialising into a signal payload. + book_ts_ms : int + Timestamp (ms) of the oldest order book used in the evaluation. + books : list[dict] + Serialised top-of-book for each leg, in order. + """ + + net_return_bps: float + max_volume: float + leg_details: list[dict] + book_ts_ms: int + books: list[dict] + + def leg_str(self) -> str: + return " -> ".join( + f"{d['pair']}({d['input_currency']}->{d['output_currency']})" for d in self.leg_details + ) + + +class OpportunityEngine: + """ + Detects and reports triangular arbitrage opportunities. + + On every order-book update (triggered via the on_update callback) the engine + evaluates every triangle that involves the updated symbol. If the net + return after fees exceeds signal_threshold_bps and the cooldown for that + triangle has elapsed, a signal is dispatched to the executor via the + on_signal callback. + """ + + def __init__( + self, + book_consumer: BookConsumer, + triangle_index: TriangleIndex, + signal_threshold_bps: float, + log_path: Path, + kcs_discount_active: bool = False, + cooldown_seconds: float = 5.0, + on_signal: Optional[callable] = None, + ) -> None: + self._book_consumer = book_consumer + self._triangle_index = triangle_index + self._threshold_bps = signal_threshold_bps + self._log_path = log_path + self._fee_mult = KCS_FEE_DISCOUNT if kcs_discount_active else 1.0 + self._cooldown_seconds = cooldown_seconds + self._last_signal_ts: dict[frozenset[str], float] = {} + self._log = logger + self._stats = Stats() + self._on_signal = on_signal + self._net_cache: dict[frozenset[str], tuple[float, tuple[int, int, int]]] = {} + + def _compute_net_only( + self, + triangle: Triangle, + ) -> tuple[Optional[float], int]: + """ + Compute net return BPS and min book ts_ms without building books/leg_details. + + Returns (net_return_bps, book_ts_ms) or (None, 0) if any book is missing. + Used for fast-path threshold filtering before expensive serialization. + """ + cumulative = 1.0 + book_ts_ms = 0 + + for leg in triangle.legs: + book = self._book_consumer.get_book(leg.pair.symbol) + if not book: + return None, 0 + + if leg.input_currency == leg.pair.base: + level = book.bids[0] if book.bids else None + if not level: + return None, 0 + rate = level.price + else: + level = book.asks[0] if book.asks else None + if not level: + return None, 0 + rate = 1.0 / level.price + + fee_factor = 1.0 - leg.taker_fee * self._fee_mult + cumulative *= rate * fee_factor + + if book_ts_ms == 0 or book.ts_ms < book_ts_ms: + book_ts_ms = book.ts_ms + + net_return = (cumulative - 1.0) * 10000 + return net_return, book_ts_ms + + def _build_full( + self, + triangle: Triangle, + ) -> Optional[_EvalResult]: + """ + Single-pass evaluation: compute net return, build leg_details/books, + and compute max_volume — all in one loop over the triangle's legs. + """ + cumulative = 1.0 + max_v0_list: list[float] = [] + cumulative_mult = 1.0 + leg_details = [] + books: list[dict] = [] + book_ts_ms = 0 + + for leg in triangle.legs: + book = self._book_consumer.get_book(leg.pair.symbol) + if not book: + return None + + if leg.input_currency == leg.pair.base: + level = book.bids[0] if book.bids else None + if not level: + return None + max_input = level.size + rate = level.price + else: + level = book.asks[0] if book.asks else None + if not level: + return None + max_input = level.size * level.price + rate = 1.0 / level.price + + fee_factor = 1.0 - leg.taker_fee * self._fee_mult + cumulative *= rate * fee_factor + + if cumulative_mult > 0: + max_v0_list.append(max_input / cumulative_mult) + cumulative_mult *= rate * fee_factor + + leg_details.append({ + "pair": leg.pair.symbol, + "input_currency": leg.input_currency, + "output_currency": leg.output_currency, + "exchange_rate": rate, + "fee_rate": leg.taker_fee, + "fee_currency": leg.pair.fee_currency, + }) + + books.append({ + "symbol": book.symbol, + "bids": [ + {"price": b.price, "size": b.size} for b in book.bids + ], + "asks": [ + {"price": a.price, "size": a.size} for a in book.asks + ], + "ts_ms": book.ts_ms, + }) + + if book_ts_ms == 0 or book.ts_ms < book_ts_ms: + book_ts_ms = book.ts_ms + + net_return = (cumulative - 1.0) * 10000 + max_volume = min(max_v0_list) if max_v0_list else 0.0 + return _EvalResult( + net_return_bps=net_return, + max_volume=max_volume, + leg_details=leg_details, + book_ts_ms=book_ts_ms, + books=books, + ) + + def evaluate_triangles_for_pair(self, symbol: str) -> list[OpportunitySignal]: + """ + Evaluate all triangles that include the given symbol. + + Called by the book consumer's on_update callback whenever an order book + is refreshed. Updates stats, emits signals for triangles that clear the + threshold and cooldown, and returns the list of signals (primarily for + use in tests). + """ + triangles = self._triangle_index.get_triangles_for_pair(symbol) + signals: list[OpportunitySignal] = [] + now_ts_ms = int(time.time() * 1000) + + for triangle in triangles: + cache_key = triangle.currencies + leg_books = [self._book_consumer.get_book(leg.pair.symbol) for leg in triangle.legs] + + if any(b is None for b in leg_books): + self._stats.triangles_evaluated += 1 + self._stats.books_missing += 1 + self._stats.last_eval_ts_ms = now_ts_ms + continue + + current_ts = tuple(b.ts_ms for b in leg_books) + cached = self._net_cache.get(cache_key) + + if cached and cached[1] == current_ts: + net_bps = cached[0] + book_ts_ms = min(current_ts) + else: + try: + net_bps, book_ts_ms = self._compute_net_only(triangle) + except Exception as e: + self._log.error("triangle_compute_error", triangle=str(triangle.currencies), error=str(e)) + self._stats.triangles_evaluated += 1 + self._stats.last_eval_ts_ms = now_ts_ms + continue + if net_bps is not None: + self._net_cache[cache_key] = (net_bps, current_ts) + + self._stats.triangles_evaluated += 1 + if net_bps is None: + self._stats.books_missing += 1 + self._stats.last_eval_ts_ms = now_ts_ms + continue + + self._stats.books_full += 1 + + if net_bps > self._stats.best_net_bps: + self._stats.best_net_bps = net_bps + if net_bps < self._stats.worst_net_bps: + self._stats.worst_net_bps = net_bps + + if net_bps <= self._threshold_bps: + self._stats.last_eval_ts_ms = now_ts_ms + continue + + try: + result = self._build_full(triangle) + except Exception as e: + self._log.error("triangle_compute_full_error", triangle=str(triangle.currencies), error=str(e)) + continue + if result is None: + continue + + sig = OpportunitySignal( + triangle=triangle, + direction="forward", + net_return_bps=net_bps, + max_volume=result.max_volume, + leg_details=result.leg_details, + ts_ms=now_ts_ms, + book_ts_ms=result.book_ts_ms, + books=result.books, + ) + signals.append(sig) + self._stats.signals_fired += 1 + now = time.time() + last = self._last_signal_ts.get(triangle.currencies, 0.0) + if now - last >= self._cooldown_seconds: + self._last_signal_ts[triangle.currencies] = now + self._notify_opportunity(sig) + + self._stats.last_eval_ts_ms = now_ts_ms + + return signals + + def get_stats(self) -> Stats: + """ + Return a snapshot of the current stats counters. + + The returned Stats object is a copy; the internal counters continue + to accumulate. + """ + return Stats( + triangles_evaluated=self._stats.triangles_evaluated, + signals_fired=self._stats.signals_fired, + books_missing=self._stats.books_missing, + books_full=self._stats.books_full, + best_net_bps=self._stats.best_net_bps, + worst_net_bps=self._stats.worst_net_bps, + last_eval_ts_ms=self._stats.last_eval_ts_ms, + best_legs=self._stats.best_legs, + worst_legs=self._stats.worst_legs, + ) + + def _notify_opportunity(self, sig: OpportunitySignal) -> None: + """ + Log the opportunity and dispatch the signal to the executor. + + The signal is sent over a Unix-domain socket via the on_signal callback + (which is the send_signal coroutine of SignalSocketClient). A done + callback is attached so any exception raised inside the receiver is + logged rather than propagating silently. + """ + ts = sig.ts_ms + direction = sig.direction + net_bps = sig.net_return_bps + leg_str = " -> ".join( + f"{ld['pair']}({ld['input_currency']}->{ld['output_currency']})" for ld in sig.leg_details + ) + + msg = ( + f"[{ts}] OPPORTUNITY FOUND | " + f"direction={direction} | " + f"net_return={net_bps:.2f} bps | " + f"max_volume={sig.max_volume} | " + f"legs: {leg_str}" + ) + + self._log.info("opportunity_detected", **{ + "ts_ms": ts, + "book_ts_ms": sig.book_ts_ms, + "direction": direction, + "net_return_bps": net_bps, + "legs": leg_str, + "max_volume": str(sig.max_volume), + }) + + if self._on_signal: + signal_payload = { + "type": "signal", + "correlation_id": str(uuid.uuid4()), + "triangle_key": list(sig.triangle.currencies), + "primary_quote": sig.triangle.primary_quote, + "legs": sig.leg_details, + "predicted_bps": net_bps, + "max_volume": str(sig.max_volume), + "ts_ms": ts, + "book_ts_ms": sig.book_ts_ms, + # books: full top-5 order books per leg — reserved for future + # volume-extension logic (analyze deeper levels to compute how + # far profit shrinks when volume is increased beyond top-of-book). + "books": sig.books, + } + try: + task = asyncio.create_task(self._on_signal(signal_payload)) + task.add_done_callback(lambda t: t.exception() and self._log.warning("on_signal_error", error=str(t.exception()))) + except Exception as e: + self._log.warning("on_signal_error", error=str(e)) \ No newline at end of file diff --git a/oe_em/risk.py b/oe_em/risk.py new file mode 100644 index 0000000..22172b6 --- /dev/null +++ b/oe_em/risk.py @@ -0,0 +1,26 @@ +""" +Placeholder risk management module for the opportunity engine. + +The RiskManager provides a hook for future risk checks (position limits, +daily loss gates, etc.). Currently it is a pass-through: should_continue() +always returns True. +""" +import structlog + +logger = structlog.get_logger().bind(component="risk") + + +class RiskManager: + """ + Enumerates and checks risk constraints before opportunity evaluation. + + Currently a stub that accepts all opportunities. Replace should_continue() + with real checks as needed. + """ + + def __init__(self) -> None: + self._log = logger + + def should_continue(self) -> bool: + """Return True if evaluation should proceed; False to skip this cycle.""" + return True \ No newline at end of file diff --git a/oe_em/socket_client.py b/oe_em/socket_client.py new file mode 100644 index 0000000..8ae7366 --- /dev/null +++ b/oe_em/socket_client.py @@ -0,0 +1,113 @@ +""" +Unix-domain socket client for sending opportunity signals to the executor. + +Connects to the executor's SignalSocketServer and keeps the connection open for +burst sending. If the connection is lost the background reconnect loop will +retry every 2 seconds. All send operations are non-blocking: a warning is +logged if the underlying writer is not connected rather than raising. +""" +import asyncio +import json +import uuid +from pathlib import Path + +import structlog + +logger = structlog.get_logger().bind(component="signal_socket_client") + + +class SignalSocketClient: + """ + Non-blocking signal sender that maintains a persistent Unix-socket connection. + + The caller invokes send_signal() for each opportunity; the client serialises + the payload and writes it to the socket. If the socket is not connected + (e.g. after a server restart) the signal is dropped with a warning log. + """ + + def __init__(self, socket_path: Path) -> None: + self._socket_path = socket_path + self._log = logger + self._writer: asyncio.StreamWriter | None = None + self._running = False + self._reconnect_task: asyncio.Task | None = None + + async def start(self) -> asyncio.Task: + """Start the background reconnect loop and return the task.""" + self._running = True + self._reconnect_task = asyncio.create_task(self._reconnect_loop()) + return self._reconnect_task + + async def _reconnect_loop(self) -> None: + """ + Attempt to connect and then wait for the connection to close. + + On connection failure a 2-second backoff is applied before retrying. + The loop exits when self._running becomes False (see close()). + """ + while self._running: + try: + reader, writer = await asyncio.open_unix_connection(path=str(self._socket_path)) + self._writer = writer + self._log.info("connected", path=str(self._socket_path)) + try: + await writer.wait_closed() + except Exception: + pass + except (ConnectionRefusedError, FileNotFoundError) as e: + if not self._running: + break + self._log.warning("connection_retrying", error=str(e)) + await asyncio.sleep(2.0) + except Exception as e: + self._log.error("reconnect_error", error=str(e)) + await asyncio.sleep(5.0) + finally: + self._writer = None + + async def send_signal(self, signal: dict) -> None: + """ + Serialise a signal dict and write it to the socket. + + If the socket is not connected this is a no-op (logged as warning). + The correlation_id is assigned here if not already set. + """ + writer = self._writer + if not writer: + self._log.warning("not_connected") + return + + correlation_id = signal.get("correlation_id", "") or str(uuid.uuid4()) + signal["correlation_id"] = correlation_id + + msg = json.dumps(signal) + "\n" + try: + writer.write(msg.encode()) + await writer.drain() + self._log.debug("signal_sent", correlation_id=correlation_id) + except Exception as e: + self._log.error("signal_send_failed", correlation_id=correlation_id, error=str(e)) + + async def close(self) -> None: + """ + Stop the reconnect loop and close the writer if open. + + Safe to call multiple times; after close() any send_signal() call + will be a no-op. + """ + self._running = False + if self._reconnect_task: + self._reconnect_task.cancel() + try: + await self._reconnect_task + except asyncio.CancelledError: + pass + self._reconnect_task = None + writer = self._writer + if writer: + self._writer = None + writer.close() + try: + await writer.wait_closed() + except Exception: + pass diff --git a/oe_em/triangle_enum.py b/oe_em/triangle_enum.py new file mode 100644 index 0000000..775c7f1 --- /dev/null +++ b/oe_em/triangle_enum.py @@ -0,0 +1,291 @@ +""" +Triangle enumeration for triangular arbitrage. + +Provides the core data structures (TradingPair, TriangleLeg, Triangle, +TriangleIndex) and the enumerate_triangles() function that enumerates all +valid triangles from a list of TradingPairs using a fee table. + +A triangle is a directed cycle of three currencies c1 → c2 → c3 → c1 where +each leg corresponds to a tradable pair. The hold currency (primary quote) +is the currency that enters and exits the cycle; it must be one of the three +currencies and is typically USDT or USDC. +""" +from dataclasses import dataclass, field +from typing import Optional + +import structlog + +logger = structlog.get_logger().bind(component="triangle_enum") + + +@dataclass(frozen=True) +class TradingPair: + """ + A single tradable currency pair on KuCoin. + + Attributes + ---------- + symbol : str + KuCoin symbol e.g. "BTC-USDT". + base : str + Base currency code e.g. "BTC". + quote : str + Quote currency code e.g. "USDT". + fee_currency : str + Currency in which fees are denominated for this pair (from KuCoin's + feeCurrency field). Included in signal payloads so the executor + can interpret fee amounts correctly. + """ + + symbol: str + base: str + quote: str + fee_currency: str = "" + + @classmethod + def from_api_response(cls, data: dict) -> Optional["TradingPair"]: + """ + Parse a KuCoin /symbols API response entry into a TradingPair. + + Returns None if enableTrading is not True or if required fields + are missing. + """ + if data.get("enableTrading") is not True: + return None + symbol = data.get("symbol", "") + base = data.get("baseCurrency", "") + quote = data.get("quoteCurrency", "") + if not all([symbol, base, quote]): + return None + return cls(symbol=symbol, base=base, quote=quote, fee_currency=data.get("feeCurrency", "")) + + @property + def currency_pair(self) -> frozenset[str]: + """The unordered set of the two currencies in this pair.""" + return frozenset([self.base, self.quote]) + + +@dataclass +class TriangleLeg: + """ + One directed hop in a triangle: input_currency → output_currency via a pair. + + Attributes + ---------- + pair : TradingPair + The trading pair used for this leg. + input_currency : str + Currency entering this leg. + output_currency : str + Currency leaving this leg. + maker_fee, taker_fee : float + Fee rates (fraction) for this leg's base currency. + """ + + pair: TradingPair + input_currency: str + output_currency: str + maker_fee: float + taker_fee: float + + +@dataclass +class Triangle: + """ + A complete triangular arbitrage cycle. + + Attributes + ---------- + legs : list[TriangleLeg] + The three directed hops (must sum to identity: c1 → c2 → c3 → c1). + currencies : frozenset[str] + The three distinct currency codes in the cycle. + pair_symbols : frozenset[str] + The three KuCoin symbols involved. + primary_quote : str + The hold currency that enters and exits the cycle. All minimum order + sizes and volumes are expressed in terms of this currency. + """ + + legs: list[TriangleLeg] = field(default_factory=list) + currencies: frozenset[str] = field(default_factory=frozenset()) + pair_symbols: frozenset[str] = field(default_factory=frozenset()) + primary_quote: str = "" + + +@dataclass +class TriangleIndex: + """ + Inverted index of triangles by pair symbol. + + Allows O(1) lookup of all triangles that involve a given symbol, which is + the primary query pattern used by OpportunityEngine on every book update. + """ + + triangles: list[Triangle] = field(default_factory=list) + by_pair: dict[str, list[Triangle]] = field(default_factory=dict) + + def get_triangles_for_pair(self, symbol: str) -> list[Triangle]: + """Return all triangles that include the given symbol.""" + return self.by_pair.get(symbol, []) + + +def _build_pair_map(pairs: list[TradingPair]) -> dict[frozenset[str], TradingPair]: + """ + Build a mapping from unordered currency pair (frozenset) to TradingPair. + + Used to look up pairs by their two currencies regardless of direction. + """ + pair_map: dict[frozenset[str], TradingPair] = {} + for p in pairs: + pair_map[p.currency_pair] = p + return pair_map + + +def _build_edge_map(pairs: list[TradingPair]) -> dict[str, list[frozenset[str]]]: + """ + Build an adjacency map: currency → list of currency pairs involving that currency. + + This is the graph representation used by enumerate_triangles to efficiently + find paths of length 2 (c1 → c2 → c3) without enumerating all O(n²) pairs. + """ + edge_map: dict[str, list[frozenset[str]]] = {} + for p in pairs: + for c in [p.base, p.quote]: + if c not in edge_map: + edge_map[c] = [] + edge_map[c].append(p.currency_pair) + return edge_map + + +def _build_legs( + c1: str, c2: str, c3: str, + pair_map: dict[frozenset[str], TradingPair], + fee_table: dict[str, dict[str, float]], +) -> list[TriangleLeg]: + """ + Construct the three TriangleLegs for the cycle c1 → c2 → c3 → c1. + + Looks up each leg's pair via pair_map (keyed by unordered currencies) and + resolves fees from fee_table using the base currency of each pair. + """ + default_fee = {"maker": 0.0010, "taker": 0.0010} + + def fee_for(base: str, side: str) -> float: + return fee_table.get(base, default_fee).get(side, 0.0010) + + p1 = pair_map[frozenset([c1, c2])] + p2 = pair_map[frozenset([c2, c3])] + p3 = pair_map[frozenset([c3, c1])] + + leg1 = TriangleLeg( + pair=p1, + input_currency=c1, + output_currency=c2, + maker_fee=fee_for(p1.base, "maker"), + taker_fee=fee_for(p1.base, "taker"), + ) + leg2 = TriangleLeg( + pair=p2, + input_currency=c2, + output_currency=c3, + maker_fee=fee_for(p2.base, "maker"), + taker_fee=fee_for(p2.base, "taker"), + ) + leg3 = TriangleLeg( + pair=p3, + input_currency=c3, + output_currency=c1, + maker_fee=fee_for(p3.base, "maker"), + taker_fee=fee_for(p3.base, "taker"), + ) + return [leg1, leg2, leg3] + + +def enumerate_triangles( + pairs: list[TradingPair], + fee_table: dict[str, dict[str, float]], + hold_currencies: Optional[list[str]] = None, +) -> TriangleIndex: + """ + Enumerate all valid triangular arbitrage cycles from a list of TradingPairs. + + A valid triangle must: + - Contain exactly three distinct currencies. + - Include at least one hold currency (default: ["USDT"]), which becomes + the primary_quote / entry/exit currency. + - Have all three legs (c1→c2, c2→c3, c3→c1) represent tradable pairs. + + Parameters + ---------- + pairs : list[TradingPair] + All known trading pairs (filtered to enableTrading == True by the caller). + fee_table : dict[str, dict[str, float]] + Per-base-currency fee rates as returned by oe_em.kucoin_api. + hold_currencies : list[str] or None + Currencies that may serve as the entry/exit point. Defaults to ["USDT"]. + + Returns + ------- + TriangleIndex + Contains all triangles and an inverted index by symbol for fast lookup. + """ + if hold_currencies is None: + hold_currencies = ["USDT"] + hold_set = set(hold_currencies) + + pair_map = _build_pair_map(pairs) + edge_map = _build_edge_map(pairs) + + triangles: list[Triangle] = [] + by_pair: dict[str, list[Triangle]] = {} + seen: set[frozenset[str]] = set() + + all_currencies = sorted(edge_map.keys()) + + for c1 in all_currencies: + for c2_edge in edge_map.get(c1, []): + c2 = next(x for x in c2_edge if x != c1) + for c3_edge in edge_map.get(c2, []): + c3 = next(x for x in c3_edge if x != c2) + if c3 == c1: + continue + if c3_edge == c2_edge: + continue + if frozenset([c1, c3]) not in pair_map: + continue + currencies = frozenset([c1, c2, c3]) + if currencies in seen: + continue + seen.add(currencies) + + in_triangle = hold_set & currencies + if not in_triangle: + continue + + for hold_curr in in_triangle: + others = [c for c in [c1, c2, c3] if c != hold_curr] + for x, y in [(others[0], others[1]), (others[1], others[0])]: + legs = _build_legs(hold_curr, x, y, pair_map, fee_table) + pair_symbols = frozenset([ + legs[0].pair.symbol, + legs[1].pair.symbol, + legs[2].pair.symbol, + ]) + + triangle = Triangle( + legs=legs, + currencies=currencies, + pair_symbols=pair_symbols, + primary_quote=hold_curr, + ) + triangles.append(triangle) + + for sym in pair_symbols: + if sym not in by_pair: + by_pair[sym] = [] + by_pair[sym].append(triangle) + + logger.info("triangles_enumerated", total=len(triangles), indexed_pairs=len(by_pair)) + + return TriangleIndex(triangles=triangles, by_pair=by_pair) \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..abaea51 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,29 @@ +[project] +name = "triangular-arb" +version = "0.1.0" +description = "Triangular arbitrage bot for KuCoin" +readme = "README.md" +requires-python = ">=3.11" +dependencies = [ + "websockets>=12.0", + "aiohttp>=3.9", + "structlog>=24.0", + "PyYAML>=6.0", + "fastapi>=0.110", + "uvicorn>=0.27", + "pydantic>=2.0", + "pydantic-settings>=2.0", +] + +[project.optional-dependencies] +dev = [ + "pytest>=8.0", + "pytest-asyncio>=0.23", +] + +[build-system] +requires = ["setuptools>=61.0"] +build-backend = "setuptools.build_meta" + +[tool.setuptools.packages.find] +where = ["."] \ No newline at end of file diff --git a/response.txt b/response.txt new file mode 100644 index 0000000..2d0c0ad --- /dev/null +++ b/response.txt @@ -0,0 +1 @@ +{"code":"200000","data":[{"symbol":"AVA-USDT","name":"AVA-USDT","baseCurrency":"AVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"FET-BTC","name":"FET-BTC","baseCurrency":"FET","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"FET-ETH","name":"FET-ETH","baseCurrency":"FET","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ANKR-BTC","name":"ANKR-BTC","baseCurrency":"ANKR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XMR-BTC","name":"XMR-BTC","baseCurrency":"XMR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XMR-ETH","name":"XMR-ETH","baseCurrency":"XMR","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.001","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CRO-BTC","name":"CRO-BTC","baseCurrency":"CRO","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MTV-USDT","name":"MTV-USDT","baseCurrency":"MTV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TEL-USDT","name":"TEL-USDT","baseCurrency":"TEL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TT-USDT","name":"TT-USDT","baseCurrency":"TT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1662022800000},{"symbol":"XMR-USDT","name":"XMR-USDT","baseCurrency":"XMR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ATOM-BTC","name":"ATOM-BTC","baseCurrency":"ATOM","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ATOM-ETH","name":"ATOM-ETH","baseCurrency":"ATOM","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ATOM-USDT","name":"ATOM-USDT","baseCurrency":"ATOM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETN-USDT","name":"ETN-USDT","baseCurrency":"ETN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1726221600000},{"symbol":"WAN-USDT","name":"WAN-USDT","baseCurrency":"WAN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.00000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1732860000000,"callauctionSecondStageStartTime":1732865400000,"callauctionThirdStageStartTime":1732866900000,"tradingStartTime":1732867200000},{"symbol":"VSYS-USDT","name":"VSYS-USDT","baseCurrency":"VSYS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CHR-USDT","name":"CHR-USDT","baseCurrency":"CHR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"COTI-USDT","name":"COTI-USDT","baseCurrency":"COTI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BNB-BTC","name":"BNB-BTC","baseCurrency":"BNB","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BNB-USDT","name":"BNB-USDT","baseCurrency":"BNB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ALGO-BTC","name":"ALGO-BTC","baseCurrency":"ALGO","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ALGO-ETH","name":"ALGO-ETH","baseCurrency":"ALGO","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ALGO-USDT","name":"ALGO-USDT","baseCurrency":"ALGO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XEM-USDT","name":"XEM-USDT","baseCurrency":"XEM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XTZ-BTC","name":"XTZ-BTC","baseCurrency":"XTZ","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XTZ-USDT","name":"XTZ-USDT","baseCurrency":"XTZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ZEC-BTC","name":"ZEC-BTC","baseCurrency":"ZEC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ZEC-USDT","name":"ZEC-USDT","baseCurrency":"ZEC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ADA-BTC","name":"ADA-BTC","baseCurrency":"ADA","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ADA-USDT","name":"ADA-USDT","baseCurrency":"ADA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ARPA-USDT","name":"ARPA-USDT","baseCurrency":"ARPA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CHZ-BTC","name":"CHZ-BTC","baseCurrency":"CHZ","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CHZ-USDT","name":"CHZ-USDT","baseCurrency":"CHZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WIN-BTC","name":"WIN-BTC","baseCurrency":"WIN","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1000","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000000001","priceIncrement":"0.000000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WIN-USDT","name":"WIN-USDT","baseCurrency":"WIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BTT-USDT","name":"BTT-USDT","baseCurrency":"BTT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"30000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1643101200000},{"symbol":"ONE-USDT","name":"ONE-USDT","baseCurrency":"ONE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LUNA-USDT","name":"LUNA-USDT","baseCurrency":"LUNA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653735600000},{"symbol":"WIN-TRX","name":"WIN-TRX","baseCurrency":"WIN","quoteCurrency":"TRX","feeCurrency":"TRX","market":"ALTS","baseMinSize":"10000","quoteMinSize":"10","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"10","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DAG-USDT","name":"DAG-USDT","baseCurrency":"DAG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KPOL-USDT","name":"KPOL-USDT","baseCurrency":"KPOL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1698825600000},{"symbol":"KSM-USDT","name":"KSM-USDT","baseCurrency":"KSM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DASH-USDT","name":"DASH-USDT","baseCurrency":"DASH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SENSO-USDT","name":"SENSO-USDT","baseCurrency":"SENSO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XDB-USDT","name":"XDB-USDT","baseCurrency":"XDB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DGB-USDT","name":"DGB-USDT","baseCurrency":"DGB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"STX-BTC","name":"STX-BTC","baseCurrency":"STX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"STX-USDT","name":"STX-USDT","baseCurrency":"STX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"COMP-USDT","name":"COMP-USDT","baseCurrency":"COMP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CRO-USDT","name":"CRO-USDT","baseCurrency":"CRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"EWT-BTC","name":"EWT-BTC","baseCurrency":"EWT","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WAVES-USDT","name":"WAVES-USDT","baseCurrency":"WAVES","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WAVES-BTC","name":"WAVES-BTC","baseCurrency":"WAVES","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.01","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MLK-USDT","name":"MLK-USDT","baseCurrency":"MLK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"JST-USDT","name":"JST-USDT","baseCurrency":"JST","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SUKU-USDT","name":"SUKU-USDT","baseCurrency":"SUKU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DIA-USDT","name":"DIA-USDT","baseCurrency":"DIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LINK-BTC","name":"LINK-BTC","baseCurrency":"LINK","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LINK-USDT","name":"LINK-USDT","baseCurrency":"LINK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOT-USDT","name":"DOT-USDT","baseCurrency":"DOT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOT-BTC","name":"DOT-BTC","baseCurrency":"DOT","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"EWT-USDT","name":"EWT-USDT","baseCurrency":"EWT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CKB-BTC","name":"CKB-BTC","baseCurrency":"CKB","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CKB-USDT","name":"CKB-USDT","baseCurrency":"CKB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"UMA-USDT","name":"UMA-USDT","baseCurrency":"UMA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ALEPH-USDT","name":"ALEPH-USDT","baseCurrency":"ALEPH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VELO-USDT","name":"VELO-USDT","baseCurrency":"VELO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"5","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SUN-USDT","name":"SUN-USDT","baseCurrency":"SUN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1625558401000},{"symbol":"YFI-USDT","name":"YFI-USDT","baseCurrency":"YFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.000001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"UNI-USDT","name":"UNI-USDT","baseCurrency":"UNI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"UOS-USDT","name":"UOS-USDT","baseCurrency":"UOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"NIM-USDT","name":"NIM-USDT","baseCurrency":"NIM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DEGO-USDT","name":"DEGO-USDT","baseCurrency":"DEGO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"FIL-USDT","name":"FIL-USDT","baseCurrency":"FIL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AAVE-USDT","name":"AAVE-USDT","baseCurrency":"AAVE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AAVE-BTC","name":"AAVE-BTC","baseCurrency":"AAVE","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"IOST-ETH","name":"IOST-ETH","baseCurrency":"IOST","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KCS-USDT","name":"KCS-USDT","baseCurrency":"KCS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SNX-ETH","name":"SNX-ETH","baseCurrency":"SNX","quoteCurrency":"ETH","feeCurrency":"ETH","market":"DeFi","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00000001","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KCS-ETH","name":"KCS-ETH","baseCurrency":"KCS","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.01","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TEL-BTC","name":"TEL-BTC","baseCurrency":"TEL","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"100","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XYO-ETH","name":"XYO-ETH","baseCurrency":"XYO","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"10","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VET-BTC","name":"VET-BTC","baseCurrency":"VET","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KCS-BTC","name":"KCS-BTC","baseCurrency":"KCS","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ONT-BTC","name":"ONT-BTC","baseCurrency":"ONT","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WAN-BTC","name":"WAN-BTC","baseCurrency":"WAN","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KNC-ETH","name":"KNC-ETH","baseCurrency":"KNC","quoteCurrency":"ETH","feeCurrency":"ETH","market":"DeFi","baseMinSize":"0.1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LTC-USDT","name":"LTC-USDT","baseCurrency":"LTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BCHSV-USDT","name":"BSV-USDT","baseCurrency":"BSV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TRAC-ETH","name":"TRAC-ETH","baseCurrency":"TRAC","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"QTUM-USDT","name":"QTUM-USDT","baseCurrency":"QTUM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"1.4","callauctionPriceCeiling":"8.5","callauctionFirstStageStartTime":1731301200000,"callauctionSecondStageStartTime":1731307200000,"callauctionThirdStageStartTime":1731308100000,"tradingStartTime":1731308400000},{"symbol":"BCHSV-BTC","name":"BSV-BTC","baseCurrency":"BSV","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XLM-USDT","name":"XLM-USDT","baseCurrency":"XLM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"IOTX-ETH","name":"IOTX-ETH","baseCurrency":"IOTX","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TRX-BTC","name":"TRX-BTC","baseCurrency":"TRX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KNC-BTC","name":"KNC-BTC","baseCurrency":"KNC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MANA-ETH","name":"MANA-ETH","baseCurrency":"MANA","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETC-USDT","name":"ETC-USDT","baseCurrency":"ETC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.000001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XRP-USDC","name":"XRP-USDC","baseCurrency":"XRP","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XYO-BTC","name":"XYO-BTC","baseCurrency":"XYO","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XLM-ETH","name":"XLM-ETH","baseCurrency":"XLM","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETH-USDT","name":"ETH-USDT","baseCurrency":"ETH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"999999999","baseIncrement":"0.0000001","quoteIncrement":"0.000001","priceIncrement":"0.01","priceLimitRate":"0.01","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BCHSV-ETH","name":"BSV-ETH","baseCurrency":"BSV","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.001","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TRX-ETH","name":"TRX-ETH","baseCurrency":"TRX","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XLM-BTC","name":"XLM-BTC","baseCurrency":"XLM","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETC-ETH","name":"ETC-ETH","baseCurrency":"ETC","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.01","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XRP-BTC","name":"XRP-BTC","baseCurrency":"XRP","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SNX-USDT","name":"SNX-USDT","baseCurrency":"SNX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"IOTX-BTC","name":"IOTX-BTC","baseCurrency":"IOTX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LTC-ETH","name":"LTC-ETH","baseCurrency":"LTC","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.001","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XRP-KCS","name":"XRP-KCS","baseCurrency":"XRP","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.1","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LTC-KCS","name":"LTC-KCS","baseCurrency":"LTC","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.001","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TEL-ETH","name":"TEL-ETH","baseCurrency":"TEL","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"100","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"USDT-USDC","name":"USDT-USDC","baseCurrency":"USDT","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETH-USDC","name":"ETH-USDC","baseCurrency":"ETH","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"999999999","baseIncrement":"0.0000001","quoteIncrement":"0.0001","priceIncrement":"0.01","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AVA-BTC","name":"AVA-BTC","baseCurrency":"AVA","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BTC-USDT","name":"BTC-USDT","baseCurrency":"BTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.00001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00000001","quoteIncrement":"0.000001","priceIncrement":"0.1","priceLimitRate":"0.01","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XRP-USDT","name":"XRP-USDT","baseCurrency":"XRP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VET-ETH","name":"VET-ETH","baseCurrency":"VET","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"10","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETH-BTC","name":"ETH-BTC","baseCurrency":"ETH","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.0001","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"999999999","baseIncrement":"0.0000001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.000001","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"TRX-USDT","name":"TRX-USDT","baseCurrency":"TRX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ONT-USDT","name":"ONT-USDT","baseCurrency":"ONT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DASH-ETH","name":"DASH-ETH","baseCurrency":"DASH","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.0001","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AVA-ETH","name":"AVA-ETH","baseCurrency":"AVA","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LTC-BTC","name":"LTC-BTC","baseCurrency":"LTC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"XRP-ETH","name":"XRP-ETH","baseCurrency":"XRP","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VET-USDT","name":"VET-USDT","baseCurrency":"VET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SNX-BTC","name":"SNX-BTC","baseCurrency":"SNX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"NEO-BTC","name":"NEO-BTC","baseCurrency":"NEO","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.00001","baseMaxSize":"100000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"NEO-USDT","name":"NEO-USDT","baseCurrency":"NEO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.000001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ETC-BTC","name":"ETC-BTC","baseCurrency":"ETC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BTC-USDC","name":"BTC-USDC","baseCurrency":"BTC","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.00001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00000001","quoteIncrement":"0.0001","priceIncrement":"0.1","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DASH-BTC","name":"DASH-BTC","baseCurrency":"DASH","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.0001","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00000001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ZIL-ETH","name":"ZIL-ETH","baseCurrency":"ZIL","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"1","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BCH-BTC","name":"BCH-BTC","baseCurrency":"BCH","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.0001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VSYS-BTC","name":"VSYS-BTC","baseCurrency":"VSYS","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000000001","priceIncrement":"0.000000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731064500000},{"symbol":"BCH-USDT","name":"BCH-USDT","baseCurrency":"BCH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SHR-USDT","name":"SHR-USDT","baseCurrency":"SHR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ROSE-USDT","name":"ROSE-USDT","baseCurrency":"ROSE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"USDC-USDT","name":"USDC-USDT","baseCurrency":"USDC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.01","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"PLU-USDT","name":"PLU-USDT","baseCurrency":"PLU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"GRT-USDT","name":"GRT-USDT","baseCurrency":"GRT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"1INCH-USDT","name":"1INCH-USDT","baseCurrency":"1INCH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"API3-USDT","name":"API3-USDT","baseCurrency":"API3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"HTR-USDT","name":"HTR-USDT","baseCurrency":"HTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WBTC-BTC","name":"WBTC-BTC","baseCurrency":"WBTC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.0001","quoteMinSize":"0.0001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LTC-USDC","name":"LTC-USDC","baseCurrency":"LTC","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BCH-USDC","name":"BCH-USDC","baseCurrency":"BCH","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"HYDRA-USDT","name":"HYDRA-USDT","baseCurrency":"HYDRA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CRV-USDT","name":"CRV-USDT","baseCurrency":"CRV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SUSHI-USDT","name":"SUSHI-USDT","baseCurrency":"SUSHI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BCHSV-USDC","name":"BSV-USDC","baseCurrency":"BSV","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ZEN-USDT","name":"ZEN-USDT","baseCurrency":"ZEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ADA-USDC","name":"ADA-USDC","baseCurrency":"ADA","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LRC-USDT","name":"LRC-USDT","baseCurrency":"LRC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"LINK-USDC","name":"LINK-USDC","baseCurrency":"LINK","quoteCurrency":"USDC","feeCurrency":"USDC","market":"DeFi","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KLV-USDT","name":"KLV-USDT","baseCurrency":"KLV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KLV-BTC","name":"KLV-BTC","baseCurrency":"KLV","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"THETA-USDT","name":"THETA-USDT","baseCurrency":"THETA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"QNT-USDT","name":"QNT-USDT","baseCurrency":"QNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BAT-USDT","name":"BAT-USDT","baseCurrency":"BAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOGE-USDT","name":"DOGE-USDT","baseCurrency":"DOGE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOGE-USDC","name":"DOGE-USDC","baseCurrency":"DOGE","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DAO-USDT","name":"DAO-USDT","baseCurrency":"DAO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOGE-BTC","name":"DOGE-BTC","baseCurrency":"DOGE","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.02","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"CAKE-USDT","name":"CAKE-USDT","baseCurrency":"CAKE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ORAI-USDT","name":"ORAI-USDT","baseCurrency":"ORAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MASK-USDT","name":"MASK-USDT","baseCurrency":"MASK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KLV-TRX","name":"KLV-TRX","baseCurrency":"KLV","quoteCurrency":"TRX","feeCurrency":"TRX","market":"ALTS","baseMinSize":"1","quoteMinSize":"10","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"10","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"PHA-USDT","name":"PHA-USDT","baseCurrency":"PHA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ADA-KCS","name":"ADA-KCS","baseCurrency":"ADA","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.01","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOT-KCS","name":"DOT-KCS","baseCurrency":"DOT","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BNB-KCS","name":"BNB-KCS","baseCurrency":"BNB","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.01","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DOGE-KCS","name":"DOGE-KCS","baseCurrency":"DOGE","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"1","quoteMinSize":"0.01","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"GAS-USDT","name":"GAS-USDT","baseCurrency":"GAS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AVAX-USDT","name":"AVAX-USDT","baseCurrency":"AVAX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"AVAX-BTC","name":"AVAX-BTC","baseCurrency":"AVAX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KRL-BTC","name":"KRL-BTC","baseCurrency":"KRL","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"KRL-USDT","name":"KRL-USDT","baseCurrency":"KRL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ENJ-USDT","name":"ENJ-USDT","baseCurrency":"ENJ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MANA-USDT","name":"MANA-USDT","baseCurrency":"MANA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SKEY-USDT","name":"SKEY-USDT","baseCurrency":"SKEY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"IOST-USDT","name":"IOST-USDT","baseCurrency":"IOST","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ORBS-USDT","name":"ORBS-USDT","baseCurrency":"ORBS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ANKR-USDT","name":"ANKR-USDT","baseCurrency":"ANKR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"SAND-USDT","name":"SAND-USDT","baseCurrency":"SAND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"VAI-USDT","name":"VAI-USDT","baseCurrency":"VAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648540800000},{"symbol":"FLUX-USDT","name":"FLUX-USDT","baseCurrency":"FLUX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"ZIL-USDT","name":"ZIL-USDT","baseCurrency":"ZIL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"DODO-USDT","name":"DODO-USDT","baseCurrency":"DODO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"MAN-USDT","name":"MAN-USDT","baseCurrency":"MAN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BAX-USDT","name":"BAX-USDT","baseCurrency":"BAX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"BOSON-USDT","name":"BOSON-USDT","baseCurrency":"BOSON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"PUNDIX-USDT","name":"PUNDIX-USDT","baseCurrency":"PUNDIX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"WAX-USDT","name":"WAXP-USDT","baseCurrency":"WAXP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"HAI-USDT","name":"HAI-USDT","baseCurrency":"HAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1619085600000},{"symbol":"FORTH-USDT","name":"FORTH-USDT","baseCurrency":"FORTH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":null},{"symbol":"GHX-USDT","name":"GHX-USDT","baseCurrency":"GHX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1619686801000},{"symbol":"TOWER-USDT","name":"TOWER-USDT","baseCurrency":"TOWER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1619776800000},{"symbol":"XDC-USDT","name":"XDC-USDT","baseCurrency":"XDC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"DeFi","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620385201000},{"symbol":"XDC-ETH","name":"XDC-ETH","baseCurrency":"XDC","quoteCurrency":"ETH","feeCurrency":"ETH","market":"DeFi","baseMinSize":"1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620385200000},{"symbol":"SHIB-USDT","name":"SHIB-USDT","baseCurrency":"SHIB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"17000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620630000000},{"symbol":"ICP-USDT","name":"ICP-USDT","baseCurrency":"ICP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620720000000},{"symbol":"ICP-BTC","name":"ICP-BTC","baseCurrency":"ICP","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620720000000},{"symbol":"CELO-USDT","name":"CELO-USDT","baseCurrency":"CELO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620813600000},{"symbol":"ELA-USDT","name":"ELA-USDT","baseCurrency":"ELA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620889201000},{"symbol":"OGN-USDT","name":"OGN-USDT","baseCurrency":"OGN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620986401000},{"symbol":"OGN-BTC","name":"OGN-BTC","baseCurrency":"OGN","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1620986400000},{"symbol":"TLOS-USDT","name":"TLOS-USDT","baseCurrency":"TLOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1621245601000},{"symbol":"GLQ-USDT","name":"GLQ-USDT","baseCurrency":"GLQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1621328400000},{"symbol":"PYR-USDT","name":"PYR-USDT","baseCurrency":"PYR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1622023201000},{"symbol":"PROM-USDT","name":"PROM-USDT","baseCurrency":"PROM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1754042400000},{"symbol":"ELON-USDT","name":"ELON-USDT","baseCurrency":"ELON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1622192400000},{"symbol":"POLS-USDT","name":"POLS-USDT","baseCurrency":"POLS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1622800800000},{"symbol":"GMEE-USDT","name":"GMEE-USDT","baseCurrency":"GMEE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1623229201000},{"symbol":"SFUND-USDT","name":"SFUND-USDT","baseCurrency":"SFUND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.439","callauctionFirstStageStartTime":1760691600000,"callauctionSecondStageStartTime":1760694600000,"callauctionThirdStageStartTime":1760694900000,"tradingStartTime":1760695200000},{"symbol":"XAVA-USDT","name":"XAVA-USDT","baseCurrency":"XAVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1623321000000},{"symbol":"NFT-USDT","name":"NFT-USDT","baseCurrency":"NFT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"26000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1623402000000},{"symbol":"NFT-TRX","name":"NFT-TRX","baseCurrency":"NFT","quoteCurrency":"TRX","feeCurrency":"TRX","market":"ALTS","baseMinSize":"100000","quoteMinSize":"10","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"10","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1623402001000},{"symbol":"AIOZ-USDT","name":"AIOZ-USDT","baseCurrency":"AIOZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1623834001000},{"symbol":"LPT-USDT","name":"LPT-USDT","baseCurrency":"LPT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1625047201000},{"symbol":"SOUL-USDT","name":"SOUL-USDT","baseCurrency":"SOUL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1625644800000},{"symbol":"NEAR-USDT","name":"NEAR-USDT","baseCurrency":"NEAR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1625824801000},{"symbol":"NEAR-BTC","name":"NEAR-BTC","baseCurrency":"NEAR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1625824801000},{"symbol":"CFG-USDT","name":"CFG-USDT","baseCurrency":"CFG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1626282001000},{"symbol":"AXS-USDT","name":"AXS-USDT","baseCurrency":"AXS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1626429601000},{"symbol":"ROUTE-USDT","name":"ROUTE-USDT","baseCurrency":"ROUTE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1725436800000},{"symbol":"XDC-BTC","name":"XDC-BTC","baseCurrency":"XDC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"DeFi","baseMinSize":"10","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1627380000000},{"symbol":"ERG-USDT","name":"ERG-USDT","baseCurrency":"ERG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628157600000},{"symbol":"ERG-BTC","name":"ERG-BTC","baseCurrency":"ERG","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628157600000},{"symbol":"SOL-USDT","name":"SOL-USDT","baseCurrency":"SOL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628071200000},{"symbol":"SLP-USDT","name":"SLP-USDT","baseCurrency":"SLP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628074800000},{"symbol":"XCH-USDT","name":"XCH-USDT","baseCurrency":"XCH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628244000000},{"symbol":"MTL-USDT","name":"MTL-USDT","baseCurrency":"MTL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628762400000},{"symbol":"IOTX-USDT","name":"IOTX-USDT","baseCurrency":"IOTX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628766000000},{"symbol":"GALAX-USDT","name":"GALA-USDT","baseCurrency":"GALA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628845200000},{"symbol":"REQ-USDT","name":"REQ-USDT","baseCurrency":"REQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1628848800000},{"symbol":"QI-USDT","name":"QI-USDT","baseCurrency":"QI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1629374400000},{"symbol":"XPR-USDT","name":"XPR-USDT","baseCurrency":"XPR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1629777600000},{"symbol":"MOVR-USDT","name":"MOVR-USDT","baseCurrency":"MOVR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630054800000},{"symbol":"WOO-USDT","name":"WOO-USDT","baseCurrency":"WOO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630317600000},{"symbol":"WILD-USDT","name":"WILD-USDT","baseCurrency":"WILD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630393200000},{"symbol":"OXT-USDT","name":"OXT-USDT","baseCurrency":"OXT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631523600000},{"symbol":"BAL-USDT","name":"BAL-USDT","baseCurrency":"BAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630661400000},{"symbol":"STORJ-USDT","name":"STORJ-USDT","baseCurrency":"STORJ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630663200000},{"symbol":"STORJ-ETH","name":"STORJ-ETH","baseCurrency":"STORJ","quoteCurrency":"ETH","feeCurrency":"ETH","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.00001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630663200000},{"symbol":"YGG-USDT","name":"YGG-USDT","baseCurrency":"YGG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1630922400000},{"symbol":"SKL-USDT","name":"SKL-USDT","baseCurrency":"SKL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631005200000},{"symbol":"NMR-USDT","name":"NMR-USDT","baseCurrency":"NMR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631008800000},{"symbol":"TRB-USDT","name":"TRB-USDT","baseCurrency":"TRB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631091600000},{"symbol":"DYDX-USDT","name":"DYDX-USDT","baseCurrency":"DYDX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631160000000},{"symbol":"XYO-USDT","name":"XYO-USDT","baseCurrency":"XYO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631167200000},{"symbol":"GTC-USDT","name":"GTC-USDT","baseCurrency":"GTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631178000000},{"symbol":"RLC-USDT","name":"RLC-USDT","baseCurrency":"RLC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631264400000},{"symbol":"RLC-BTC","name":"RLC-BTC","baseCurrency":"RLC","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631264400000},{"symbol":"XPRT-USDT","name":"XPRT-USDT","baseCurrency":"XPRT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631610000000},{"symbol":"EGLD-USDT","name":"EGLD-USDT","baseCurrency":"EGLD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631613600000},{"symbol":"EGLD-BTC","name":"EGLD-BTC","baseCurrency":"EGLD","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631613600000},{"symbol":"HBAR-USDT","name":"HBAR-USDT","baseCurrency":"HBAR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631610000000},{"symbol":"HBAR-BTC","name":"HBAR-BTC","baseCurrency":"HBAR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631610000000},{"symbol":"FLOW-USDT","name":"FLOW-USDT","baseCurrency":"FLOW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631613600000},{"symbol":"NKN-USDT","name":"NKN-USDT","baseCurrency":"NKN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1631696400000},{"symbol":"DMTR-USDT","name":"DMTR-USDT","baseCurrency":"DMTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632301200000},{"symbol":"CTSI-USDT","name":"CTSI-USDT","baseCurrency":"CTSI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632387600000},{"symbol":"ALICE-USDT","name":"ALICE-USDT","baseCurrency":"ALICE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632391200000},{"symbol":"ILV-USDT","name":"ILV-USDT","baseCurrency":"ILV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632477600000},{"symbol":"BAND-USDT","name":"BAND-USDT","baseCurrency":"BAND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632474000000},{"symbol":"FTT-USDT","name":"FTT-USDT","baseCurrency":"FTT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632477600000},{"symbol":"P2P-USDT","name":"P2P-USDT","baseCurrency":"P2P","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.000676","callauctionFirstStageStartTime":1760342400000,"callauctionSecondStageStartTime":1760345400000,"callauctionThirdStageStartTime":1760345700000,"tradingStartTime":1760346000000},{"symbol":"TLM-USDT","name":"TLM-USDT","baseCurrency":"TLM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632740400000},{"symbol":"DEXE-USDT","name":"DEXE-USDT","baseCurrency":"DEXE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632736800000},{"symbol":"RUNE-USDT","name":"RUNE-USDT","baseCurrency":"RUNE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632819600000},{"symbol":"RUNE-BTC","name":"RUNE-BTC","baseCurrency":"RUNE","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632819600000},{"symbol":"C98-USDT","name":"C98-USDT","baseCurrency":"C98","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1632992400000},{"symbol":"PUSH-USDT","name":"PUSH-USDT","baseCurrency":"PUSH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634029200000},{"symbol":"AGLD-USDT","name":"AGLD-USDT","baseCurrency":"AGLD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634202000000},{"symbol":"NAKA-USDT","name":"NAKA-USDT","baseCurrency":"NAKA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634302800000},{"symbol":"REEF-USDT","name":"REEF-USDT","baseCurrency":"REEF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634634000000},{"symbol":"INJ-USDT","name":"INJ-USDT","baseCurrency":"INJ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634724000000},{"symbol":"INJ-BTC","name":"INJ-BTC","baseCurrency":"INJ","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1634724000000},{"symbol":"AR-USDT","name":"AR-USDT","baseCurrency":"AR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635238800000},{"symbol":"AR-BTC","name":"AR-BTC","baseCurrency":"AR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.01","quoteMinSize":"0.00001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635238800000},{"symbol":"JASMY-USDT","name":"JASMY-USDT","baseCurrency":"JASMY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635321600000},{"symbol":"SUPER-USDT","name":"SUPER-USDT","baseCurrency":"SUPER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635411600000},{"symbol":"CPOOL-USDT","name":"CPOOL-USDT","baseCurrency":"CPOOL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635426000000},{"symbol":"MTRG-USDT","name":"MTRG-USDT","baseCurrency":"MTRG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635847200000},{"symbol":"SHIB-DOGE","name":"SHIB-DOGE","baseCurrency":"SHIB","quoteCurrency":"DOGE","feeCurrency":"DOGE","market":"ALTS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1635832800000},{"symbol":"QUICK-USDT","name":"QUICK-USDT","baseCurrency":"QUICK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1707382800000},{"symbol":"DATA-USDT","name":"DATA-USDT","baseCurrency":"DATA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636020000000},{"symbol":"ISP-USDT","name":"ISP-USDT","baseCurrency":"ISP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636106400000},{"symbol":"CERE-USDT","name":"CERE-USDT","baseCurrency":"CERE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636380000000},{"symbol":"PAXG-USDT","name":"PAXG-USDT","baseCurrency":"PAXG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636534800000},{"symbol":"PAXG-BTC","name":"PAXG-BTC","baseCurrency":"PAXG","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.0001","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636534800000},{"symbol":"AUDIO-USDT","name":"AUDIO-USDT","baseCurrency":"AUDIO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636538400000},{"symbol":"ENS-USDT","name":"ENS-USDT","baseCurrency":"ENS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636527600000},{"symbol":"ATA-USDT","name":"ATA-USDT","baseCurrency":"ATA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636624800000},{"symbol":"DPR-USDT","name":"DPR-USDT","baseCurrency":"DPR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1636696800000},{"symbol":"TWT-USDT","name":"TWT-USDT","baseCurrency":"TWT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637139600000},{"symbol":"TWT-BTC","name":"TWT-BTC","baseCurrency":"TWT","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637139600000},{"symbol":"ADX-USDT","name":"ADX-USDT","baseCurrency":"ADX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637143200000},{"symbol":"GLM-USDT","name":"GLM-USDT","baseCurrency":"GLM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637226000000},{"symbol":"NUM-USDT","name":"NUM-USDT","baseCurrency":"NUM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637240400000},{"symbol":"TRADE-USDT","name":"TRADE-USDT","baseCurrency":"TRADE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637316000000},{"symbol":"LIKE-USDT","name":"LIKE-USDT","baseCurrency":"LIKE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637661600000},{"symbol":"KAVA-USDT","name":"KAVA-USDT","baseCurrency":"KAVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637748000000},{"symbol":"SFP-USDT","name":"SFP-USDT","baseCurrency":"SFP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637744400000},{"symbol":"RSR-USDT","name":"RSR-USDT","baseCurrency":"RSR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637834400000},{"symbol":"RSR-BTC","name":"RSR-BTC","baseCurrency":"RSR","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"10","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1637834400000},{"symbol":"IMX-USDT","name":"IMX-USDT","baseCurrency":"IMX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1638176400000},{"symbol":"GODS-USDT","name":"GODS-USDT","baseCurrency":"GODS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1638180000000},{"symbol":"POND-USDT","name":"POND-USDT","baseCurrency":"POND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1638435600000},{"symbol":"VR-USDT","name":"VR-USDT","baseCurrency":"VR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1638450000000},{"symbol":"CREDI-USDT","name":"CREDI-USDT","baseCurrency":"CREDI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1639044000000},{"symbol":"TRVL-USDT","name":"TRVL-USDT","baseCurrency":"TRVL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1639044000000},{"symbol":"XEC-USDT","name":"XEC-USDT","baseCurrency":"XEC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1639382400000},{"symbol":"HEART-USDT","name":"HEART-USDT","baseCurrency":"HEART","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1639396800000},{"symbol":"GAFI-USDT","name":"GAFI-USDT","baseCurrency":"GAFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1639569600000},{"symbol":"PEOPLE-USDT","name":"PEOPLE-USDT","baseCurrency":"PEOPLE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1640174400000},{"symbol":"CWEB-USDT","name":"CWEB-USDT","baseCurrency":"CWEB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1640858400000},{"symbol":"IOTA-USDT","name":"IOTA-USDT","baseCurrency":"IOTA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1640941200000},{"symbol":"IOTA-BTC","name":"IOTA-BTC","baseCurrency":"IOTA","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"0.1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1640941200000},{"symbol":"HNT-USDT","name":"HNT-USDT","baseCurrency":"HNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1641373200000},{"symbol":"REVU-USDT","name":"REVU-USDT","baseCurrency":"REVU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1641556800000},{"symbol":"GLMR-USDT","name":"GLMR-USDT","baseCurrency":"GLMR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1641909600000},{"symbol":"CTC-USDT","name":"CTC-USDT","baseCurrency":"CTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1642068000000},{"symbol":"ASTR-USDT","name":"ASTR-USDT","baseCurrency":"ASTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1642669200000},{"symbol":"CVX-USDT","name":"CVX-USDT","baseCurrency":"CVX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1643796000000},{"symbol":"AMP-USDT","name":"AMP-USDT","baseCurrency":"AMP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1643882401000},{"symbol":"XNO-USDT","name":"XNO-USDT","baseCurrency":"XNO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1645603200000},{"symbol":"MARS4-USDT","name":"MARS4-USDT","baseCurrency":"MARS4","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1646049600000},{"symbol":"TFUEL-USDT","name":"TFUEL-USDT","baseCurrency":"TFUEL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1646211600000},{"symbol":"METIS-USDT","name":"METIS-USDT","baseCurrency":"METIS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1646301600000},{"symbol":"APE-USDT","name":"APE-USDT","baseCurrency":"APE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1647523800000},{"symbol":"GMT-USDT","name":"GMT-USDT","baseCurrency":"GMT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1647597600000},{"symbol":"BICO-USDT","name":"BICO-USDT","baseCurrency":"BICO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648198800000},{"symbol":"STG-USDT","name":"STG-USDT","baseCurrency":"STG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648195200000},{"symbol":"BNC-USDT","name":"BNC-USDT","baseCurrency":"BNC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648720800000},{"symbol":"CFX-USDT","name":"CFX-USDT","baseCurrency":"CFX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648800000000},{"symbol":"XCN-USDT","name":"XCN-USDT","baseCurrency":"XCN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1648890000000},{"symbol":"ALPINE-USDT","name":"ALPINE-USDT","baseCurrency":"ALPINE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1649836800000},{"symbol":"T-USDT","name":"T-USDT","baseCurrency":"T","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650013200000},{"symbol":"NYM-USDT","name":"NYM-USDT","baseCurrency":"NYM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650013200000},{"symbol":"SPA-USDT","name":"SPA-USDT","baseCurrency":"SPA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650373201000},{"symbol":"SWFTC-USDT","name":"SWFTC-USDT","baseCurrency":"SWFTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650618000000},{"symbol":"CELR-USDT","name":"CELR-USDT","baseCurrency":"CELR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650873600000},{"symbol":"AURORA-USDT","name":"AURORA-USDT","baseCurrency":"AURORA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650880800000},{"symbol":"KNC-USDT","name":"KNC-USDT","baseCurrency":"KNC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1650963600000},{"symbol":"OVR-USDT","name":"OVR-USDT","baseCurrency":"OVR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651140000000},{"symbol":"SYS-USDT","name":"SYS-USDT","baseCurrency":"SYS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651143600000},{"symbol":"BRISE-USDT","name":"BRISE-USDT","baseCurrency":"BRISE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000000","quoteMinSize":"0.1","baseMaxSize":"61500000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651226400000},{"symbol":"BSW-USDT","name":"BSW-USDT","baseCurrency":"BSW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651827600000},{"symbol":"FITFI-USDT","name":"FITFI-USDT","baseCurrency":"FITFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651824000000},{"symbol":"AKT-USDT","name":"AKT-USDT","baseCurrency":"AKT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1651910400000},{"symbol":"SIN-USDT","name":"SIN-USDT","baseCurrency":"SIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652086800000},{"symbol":"BOBA-USDT","name":"BOBA-USDT","baseCurrency":"BOBA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652173200000},{"symbol":"BFC-USDT","name":"BFC-USDT","baseCurrency":"BFC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652259600000},{"symbol":"MBL-USDT","name":"MBL-USDT","baseCurrency":"MBL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652432400000},{"symbol":"DUSK-USDT","name":"DUSK-USDT","baseCurrency":"DUSK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652436000000},{"symbol":"USDD-USDT","name":"USDD-USDT","baseCurrency":"USDD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652781601000},{"symbol":"USDD-USDC","name":"USDD-USDC","baseCurrency":"USDD","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.07","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1652781600000},{"symbol":"APE-USDC","name":"APE-USDC","baseCurrency":"APE","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653292800000},{"symbol":"AVAX-USDC","name":"AVAX-USDC","baseCurrency":"AVAX","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653292800000},{"symbol":"SHIB-USDC","name":"SHIB-USDC","baseCurrency":"SHIB","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653296400000},{"symbol":"TRX-USDC","name":"TRX-USDC","baseCurrency":"TRX","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653379200000},{"symbol":"NEAR-USDC","name":"NEAR-USDC","baseCurrency":"NEAR","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653379200000},{"symbol":"ZIL-USDC","name":"ZIL-USDC","baseCurrency":"ZIL","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653382800000},{"symbol":"SOL-USDC","name":"SOL-USDC","baseCurrency":"SOL","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653292800000},{"symbol":"ACH-USDT","name":"ACH-USDT","baseCurrency":"ACH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653465600000},{"symbol":"SCRT-USDT","name":"SCRT-USDT","baseCurrency":"SCRT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653472800000},{"symbol":"CCD-USDT","name":"CCD-USDT","baseCurrency":"CCD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653642000000},{"symbol":"LUNC-USDT","name":"LUNC-USDT","baseCurrency":"LUNC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653584401000},{"symbol":"LUNC-USDC","name":"LUNC-USDC","baseCurrency":"LUNC","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653584400000},{"symbol":"USTC-USDT","name":"USTC-USDT","baseCurrency":"USTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653584400000},{"symbol":"USTC-USDC","name":"USTC-USDC","baseCurrency":"USTC","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653584401000},{"symbol":"GMT-USDC","name":"GMT-USDC","baseCurrency":"GMT","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653897600000},{"symbol":"DOT-USDC","name":"DOT-USDC","baseCurrency":"DOT","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653897600000},{"symbol":"RUNE-USDC","name":"RUNE-USDC","baseCurrency":"RUNE","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653901200000},{"symbol":"ATOM-USDC","name":"ATOM-USDC","baseCurrency":"ATOM","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653901200000},{"symbol":"BNB-USDC","name":"BNB-USDC","baseCurrency":"BNB","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653984000000},{"symbol":"JASMY-USDC","name":"JASMY-USDC","baseCurrency":"JASMY","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653984000000},{"symbol":"KCS-USDC","name":"KCS-USDC","baseCurrency":"KCS","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653984000000},{"symbol":"ALGO-USDC","name":"ALGO-USDC","baseCurrency":"ALGO","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653987600000},{"symbol":"LUNA-USDC","name":"LUNA-USDC","baseCurrency":"LUNA","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1653735600000},{"symbol":"OP-USDT","name":"OP-USDT","baseCurrency":"OP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1654018200000},{"symbol":"OP-USDC","name":"OP-USDC","baseCurrency":"OP","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1654018200000},{"symbol":"ICX-USDT","name":"ICX-USDT","baseCurrency":"ICX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1655460000000},{"symbol":"BTC-BRL","name":"BTC-BRL","baseCurrency":"BTC","quoteCurrency":"BRL","feeCurrency":"BRL","market":"FIAT","baseMinSize":"0.000001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00001","quoteIncrement":"0.1","priceIncrement":"0.1","priceLimitRate":"0.08","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1671789600000},{"symbol":"ETH-BRL","name":"ETH-BRL","baseCurrency":"ETH","quoteCurrency":"BRL","feeCurrency":"BRL","market":"FIAT","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.1","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1671789600000},{"symbol":"USDT-BRL","name":"USDT-BRL","baseCurrency":"USDT","quoteCurrency":"BRL","feeCurrency":"BRL","market":"FIAT","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1671789600000},{"symbol":"WELL-USDT","name":"WELL-USDT","baseCurrency":"WELL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1655971200000},{"symbol":"FORT-USDT","name":"FORT-USDT","baseCurrency":"FORT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1656064800000},{"symbol":"USDP-USDT","name":"USDP-USDT","baseCurrency":"USDP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1656403200000},{"symbol":"USDD-TRX","name":"USDD-TRX","baseCurrency":"USDD","quoteCurrency":"TRX","feeCurrency":"TRX","market":"ALTS","baseMinSize":"0.1","quoteMinSize":"10","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"10","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1656406800000},{"symbol":"BTC-EUR","name":"BTC-EUR","baseCurrency":"BTC","quoteCurrency":"EUR","feeCurrency":"EUR","market":"FIAT","baseMinSize":"0.00001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677826800000},{"symbol":"ETH-EUR","name":"ETH-EUR","baseCurrency":"ETH","quoteCurrency":"EUR","feeCurrency":"EUR","market":"FIAT","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677826800000},{"symbol":"USDT-EUR","name":"USDT-EUR","baseCurrency":"USDT","quoteCurrency":"EUR","feeCurrency":"EUR","market":"FIAT","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.01","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677826800000},{"symbol":"CSPR-USDT","name":"CSPR-USDT","baseCurrency":"CSPR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1656496800000},{"symbol":"WEMIX-USDT","name":"WEMIX-USDT","baseCurrency":"WEMIX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1656579600000},{"symbol":"LDO-USDT","name":"LDO-USDT","baseCurrency":"LDO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1657274400000},{"symbol":"LDO-USDC","name":"LDO-USDC","baseCurrency":"LDO","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1657274400000},{"symbol":"FIDA-USDT","name":"FIDA-USDT","baseCurrency":"FIDA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1658484000000},{"symbol":"ETC-USDC","name":"ETC-USDC","baseCurrency":"ETC","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1660298400000},{"symbol":"RVN-USDT","name":"RVN-USDT","baseCurrency":"RVN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1661940000000},{"symbol":"PIX-USDT","name":"PIX-USDT","baseCurrency":"PIX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1663668000000},{"symbol":"ETHW-USDT","name":"ETHW-USDT","baseCurrency":"ETHW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1664182800000},{"symbol":"ACQ-USDT","name":"ACQ-USDT","baseCurrency":"ACQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1664377200000},{"symbol":"GMX-USDT","name":"GMX-USDT","baseCurrency":"GMX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1665741600000},{"symbol":"POKT-USDT","name":"POKT-USDT","baseCurrency":"POKT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1666170000000},{"symbol":"APT-USDT","name":"APT-USDT","baseCurrency":"APT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1666141200000},{"symbol":"EUL-USDT","name":"EUL-USDT","baseCurrency":"EUL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1666778400000},{"symbol":"TON-USDT","name":"TON-USDT","baseCurrency":"TON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1666864800000},{"symbol":"HFT-USDT","name":"HFT-USDT","baseCurrency":"HFT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1667829600000},{"symbol":"AZERO-USDT","name":"AZERO-USDT","baseCurrency":"AZERO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1668506400000},{"symbol":"NAVI-USDT","name":"NAVI-USDT","baseCurrency":"NAVI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1669723200000},{"symbol":"BDX-USDT","name":"BDX-USDT","baseCurrency":"BDX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673344800000},{"symbol":"BDX-BTC","name":"BDX-BTC","baseCurrency":"BDX","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673344800000},{"symbol":"FLR-USDT","name":"FLR-USDT","baseCurrency":"FLR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673330400000},{"symbol":"FLR-USDC","name":"FLR-USDC","baseCurrency":"FLR","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673330400000},{"symbol":"OSMO-USDT","name":"OSMO-USDT","baseCurrency":"OSMO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673604000000},{"symbol":"MAGIC-USDT","name":"MAGIC-USDT","baseCurrency":"MAGIC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1673949600000},{"symbol":"RPL-USDT","name":"RPL-USDT","baseCurrency":"RPL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1674205200000},{"symbol":"HIGH-USDT","name":"HIGH-USDT","baseCurrency":"HIGH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1675850400000},{"symbol":"TRAC-USDT","name":"TRAC-USDT","baseCurrency":"TRAC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676012400000},{"symbol":"BLUR-USDT","name":"BLUR-USDT","baseCurrency":"BLUR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676399400000},{"symbol":"WAXL-USDT","name":"WAXL-USDT","baseCurrency":"wAXL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676455200000},{"symbol":"FLOKI-USDT","name":"FLOKI-USDT","baseCurrency":"FLOKI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676624400000},{"symbol":"SSV-USDT","name":"SSV-USDT","baseCurrency":"SSV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676534400000},{"symbol":"FLOKI-USDC","name":"FLOKI-USDC","baseCurrency":"FLOKI","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676624400000},{"symbol":"ACS-USDT","name":"ACS-USDT","baseCurrency":"ACS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676480400000},{"symbol":"FET-USDT","name":"FET-USDT","baseCurrency":"FET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1676890800000},{"symbol":"SIDUS-USDT","name":"SIDUS-USDT","baseCurrency":"SIDUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677232800000},{"symbol":"RDNT-USDT","name":"RDNT-USDT","baseCurrency":"RDNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677578400000},{"symbol":"SYN-USDT","name":"SYN-USDT","baseCurrency":"SYN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677574800000},{"symbol":"GNS-USDT","name":"GNS-USDT","baseCurrency":"GNS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677574800000},{"symbol":"BLZ-USDT","name":"BLZ-USDT","baseCurrency":"BLZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1677664800000},{"symbol":"NXRA-USDT","name":"NXRA-USDT","baseCurrency":"NXRA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1723622400000},{"symbol":"MINA-USDT","name":"MINA-USDT","baseCurrency":"MINA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1678269600000},{"symbol":"XRD-USDT","name":"XRD-USDT","baseCurrency":"XRD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1678262400000},{"symbol":"LQTY-USDT","name":"LQTY-USDT","baseCurrency":"LQTY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1678960800000},{"symbol":"ID-USDT","name":"ID-USDT","baseCurrency":"ID","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1679486400000},{"symbol":"ARB-USDT","name":"ARB-USDT","baseCurrency":"ARB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1679576400000},{"symbol":"HMND-USDT","name":"HMND-USDT","baseCurrency":"HMND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1680170400000},{"symbol":"MYRIA-USDT","name":"MYRIA-USDT","baseCurrency":"MYRIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1680768000000},{"symbol":"SD-USDT","name":"SD-USDT","baseCurrency":"SD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1680861600000},{"symbol":"CGPT-USDT","name":"CGPT-USDT","baseCurrency":"CGPT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1681128000000},{"symbol":"STRAX-USDT","name":"STRAX-USDT","baseCurrency":"STRAX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713776400000},{"symbol":"AGI-USDT","name":"AGI-USDT","baseCurrency":"AGI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.06","callauctionFirstStageStartTime":1764061200000,"callauctionSecondStageStartTime":1764064200000,"callauctionThirdStageStartTime":1764064500000,"tradingStartTime":1764064800000},{"symbol":"OTK-USDT","name":"OTK-USDT","baseCurrency":"OTK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1681293600000},{"symbol":"BABYDOGE-USDT","name":"BABYDOGE-USDT","baseCurrency":"BABYDOGE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000000","quoteMinSize":"0.1","baseMaxSize":"100000000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000000001","priceIncrement":"0.000000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1681898400000},{"symbol":"PZP-USDT","name":"PZP-USDT","baseCurrency":"PZP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1729148400000},{"symbol":"LOCUS-USDT","name":"LOCUS-USDT","baseCurrency":"LOCUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1682071200000},{"symbol":"ZPAY-USDT","name":"ZPAY-USDT","baseCurrency":"ZPAY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1682341200000},{"symbol":"SUI-USDT","name":"SUI-USDT","baseCurrency":"SUI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1683115200000},{"symbol":"KAS-USDT","name":"KAS-USDT","baseCurrency":"KAS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1683367200000},{"symbol":"PEPE-USDT","name":"PEPE-USDT","baseCurrency":"PEPE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"60000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1683291000000},{"symbol":"CETUS-USDT","name":"CETUS-USDT","baseCurrency":"CETUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1683712800000},{"symbol":"TURBOS-USDT","name":"TURBOS-USDT","baseCurrency":"TURBOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1684144800000},{"symbol":"LMWR-USDT","name":"LMWR-USDT","baseCurrency":"LMWR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1684238400000},{"symbol":"LADYS-USDT","name":"LADYS-USDT","baseCurrency":"LADYS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1684749600000},{"symbol":"OBI-USDT","name":"OBI-USDT","baseCurrency":"OBI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1685361600000},{"symbol":"EDU-USDT","name":"EDU-USDT","baseCurrency":"EDU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1685523600000},{"symbol":"ORDI-USDT","name":"ORDI-USDT","baseCurrency":"ORDI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1685613600000},{"symbol":"VOLT-USDT","name":"VOLT-USDT","baseCurrency":"VOLT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000000","quoteMinSize":"0.1","baseMaxSize":"26000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1685707200000},{"symbol":"MAV-USDT","name":"MAV-USDT","baseCurrency":"MAV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1687939200000},{"symbol":"XEN-USDT","name":"XEN-USDT","baseCurrency":"XEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1687946400000},{"symbol":"PENDLE-USDT","name":"PENDLE-USDT","baseCurrency":"PENDLE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1688378400000},{"symbol":"DCK-USDT","name":"DCK-USDT","baseCurrency":"DCK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1689854400000},{"symbol":"LYX-USDT","name":"LYX-USDT","baseCurrency":"LYX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1690192800000},{"symbol":"WLD-USDT","name":"WLD-USDT","baseCurrency":"WLD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1690189200000},{"symbol":"SEI-USDT","name":"SEI-USDT","baseCurrency":"SEI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1692100800000},{"symbol":"PYUSD-USDT","name":"PYUSD-USDT","baseCurrency":"PYUSD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1695290400000},{"symbol":"ISLM-USDT","name":"ISLM-USDT","baseCurrency":"ISLM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"160000","quoteMaxSize":"50000","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1696932000000},{"symbol":"BIGTIME-USDT","name":"BIGTIME-USDT","baseCurrency":"BIGTIME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1697112000000},{"symbol":"ARKM-USDT","name":"ARKM-USDT","baseCurrency":"ARKM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1697709600000},{"symbol":"TIA-USDT","name":"TIA-USDT","baseCurrency":"TIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1698765300000},{"symbol":"CYBER-USDT","name":"CYBER-USDT","baseCurrency":"CYBER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1698829200000},{"symbol":"MEME-USDT","name":"MEME-USDT","baseCurrency":"MEME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1698998400000},{"symbol":"TOKEN-USDT","name":"TOKEN-USDT","baseCurrency":"TOKEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1699005600000},{"symbol":"POL-USDT","name":"POL-USDT","baseCurrency":"POL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1699516800000},{"symbol":"SATS-USDT","name":"SATS-USDT","baseCurrency":"SATS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000000","quoteMinSize":"0.1","baseMaxSize":"100000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1699524000000},{"symbol":"PYTH-USDT","name":"PYTH-USDT","baseCurrency":"PYTH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700488800000},{"symbol":"RATS-USDT","name":"RATS-USDT","baseCurrency":"RATS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700481600000},{"symbol":"WBTC-USDT","name":"WBTC-USDT","baseCurrency":"WBTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.00001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700640000000},{"symbol":"DCR-USDT","name":"DCR-USDT","baseCurrency":"DCR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700645400000},{"symbol":"ZRX-USDT","name":"ZRX-USDT","baseCurrency":"ZRX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700647200000},{"symbol":"FLIP-USDT","name":"FLIP-USDT","baseCurrency":"FLIP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700740800000},{"symbol":"UQC-USDT","name":"UQC-USDT","baseCurrency":"UQC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.05","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"3","callauctionPriceCeiling":"6.5","callauctionFirstStageStartTime":1700726400000,"callauctionSecondStageStartTime":1700787600000,"callauctionThirdStageStartTime":null,"tradingStartTime":1700794800000},{"symbol":"LSK-USDT","name":"LSK-USDT","baseCurrency":"LSK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700816400000},{"symbol":"DENT-USDT","name":"DENT-USDT","baseCurrency":"DENT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700818200000},{"symbol":"QKC-USDT","name":"QKC-USDT","baseCurrency":"QKC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1700820000000},{"symbol":"BONK-USDT","name":"BONK-USDT","baseCurrency":"BONK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1701165600000},{"symbol":"MNT-USDT","name":"MNT-USDT","baseCurrency":"MNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1701338400000},{"symbol":"INSP-USDT","name":"INSP-USDT","baseCurrency":"INSP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1701856800000},{"symbol":"AUCTION-USDT","name":"AUCTION-USDT","baseCurrency":"AUCTION","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1701943200000},{"symbol":"JTO-USDT","name":"JTO-USDT","baseCurrency":"JTO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1701964800000},{"symbol":"VANRY-USDT","name":"VANRY-USDT","baseCurrency":"VANRY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1702544400000},{"symbol":"MNDE-USDT","name":"MNDE-USDT","baseCurrency":"MNDE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1702893600000},{"symbol":"COQ-USDT","name":"COQ-USDT","baseCurrency":"COQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1702897200000},{"symbol":"POLYX-USDT","name":"POLYX-USDT","baseCurrency":"POLYX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1702983600000},{"symbol":"TAO-USDT","name":"TAO-USDT","baseCurrency":"TAO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1703062800000},{"symbol":"ARTY-USDT","name":"ARTY-USDT","baseCurrency":"ARTY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1703167200000},{"symbol":"MYRO-USDT","name":"MYRO-USDT","baseCurrency":"MYRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1703667600000},{"symbol":"RAY-USDT","name":"RAY-USDT","baseCurrency":"RAY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1704362400000},{"symbol":"ALEX-USDT","name":"ALEX-USDT","baseCurrency":"ALEX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1704445200000},{"symbol":"XAI-USDT","name":"XAI-USDT","baseCurrency":"XAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1704794400000},{"symbol":"NFP-USDT","name":"NFP-USDT","baseCurrency":"NFP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1704963600000},{"symbol":"ORCA-USDT","name":"ORCA-USDT","baseCurrency":"ORCA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705050000000},{"symbol":"KACE-USDT","name":"kACE-USDT","baseCurrency":"kACE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705053600000},{"symbol":"NEON-USDT","name":"NEON-USDT","baseCurrency":"NEON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705312800000},{"symbol":"MANTA-USDT","name":"MANTA-USDT","baseCurrency":"MANTA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705572000000},{"symbol":"ONDO-USDT","name":"ONDO-USDT","baseCurrency":"ONDO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705579200000},{"symbol":"WIF-USDT","name":"WIF-USDT","baseCurrency":"WIF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.1","callauctionPriceCeiling":"2.2","callauctionFirstStageStartTime":1705581000000,"callauctionSecondStageStartTime":1705582200000,"callauctionThirdStageStartTime":null,"tradingStartTime":1705582800000},{"symbol":"SAROS-USDT","name":"SAROS-USDT","baseCurrency":"SAROS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1705662000000},{"symbol":"GTAI-USDT","name":"GTAI-USDT","baseCurrency":"GTAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706176800000},{"symbol":"KALT-USDT","name":"KALT-USDT","baseCurrency":"kALT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706176800000},{"symbol":"WEN-USDT","name":"WEN-USDT","baseCurrency":"WEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706605200000},{"symbol":"ZETA-USDT","name":"ZETA-USDT","baseCurrency":"ZETA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706756400000},{"symbol":"DEFI-USDT","name":"DEFI-USDT","baseCurrency":"DEFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706695200000},{"symbol":"JUP-USDT","name":"JUP-USDT","baseCurrency":"JUP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706713200000},{"symbol":"BMX-USDT","name":"BMX-USDT","baseCurrency":"BMX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1706868000000},{"symbol":"MAVIA-USDT","name":"MAVIA-USDT","baseCurrency":"MAVIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1707220800000},{"symbol":"DYM-USDT","name":"DYM-USDT","baseCurrency":"DYM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1707238800000},{"symbol":"NAVX-USDT","name":"NAVX-USDT","baseCurrency":"NAVX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1707307200000},{"symbol":"PIXEL-USDT","name":"PIXEL-USDT","baseCurrency":"PIXEL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1708336800000},{"symbol":"STRK-USDT","name":"STRK-USDT","baseCurrency":"STRK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1708430400000},{"symbol":"BCUT-USDT","name":"BCUT-USDT","baseCurrency":"BCUT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1708434000000},{"symbol":"TADA-USDT","name":"TADA-USDT","baseCurrency":"TADA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"100000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1708596000000},{"symbol":"PORTAL-USDT","name":"PORTAL-USDT","baseCurrency":"PORTAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1709200800000},{"symbol":"QORPO-USDT","name":"QORPO-USDT","baseCurrency":"QORPO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1709200800000},{"symbol":"KAS-BTC","name":"KAS-BTC","baseCurrency":"KAS","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1709715600000},{"symbol":"TUSD-USDT","name":"TUSD-USDT","baseCurrency":"TUSD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1709794800000},{"symbol":"SCA-USDT","name":"SCA-USDT","baseCurrency":"SCA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1709892000000},{"symbol":"NIBI-USDT","name":"NIBI-USDT","baseCurrency":"NIBI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1710230400000},{"symbol":"AEVO-USDT","name":"AEVO-USDT","baseCurrency":"AEVO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1710324000000},{"symbol":"HTX-USDT","name":"HTX-USDT","baseCurrency":"HTX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"100000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1710406800000},{"symbol":"BOME-USDT","name":"BOME-USDT","baseCurrency":"BOME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1710511200000},{"symbol":"ETHFI-USDT","name":"ETHFI-USDT","baseCurrency":"ETHFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1710763200000},{"symbol":"MPC-USDT","name":"MPC-USDT","baseCurrency":"MPC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.1","callauctionFirstStageStartTime":1752130800000,"callauctionSecondStageStartTime":1752133800000,"callauctionThirdStageStartTime":1752134100000,"tradingStartTime":1752134400000},{"symbol":"ZKJ-USDT","name":"ZKJ-USDT","baseCurrency":"ZKJ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1717754400000},{"symbol":"GMRX-USDT","name":"GMRX-USDT","baseCurrency":"GMRX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1711447200000},{"symbol":"VENOM-USDT","name":"VENOM-USDT","baseCurrency":"VENOM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1711623600000},{"symbol":"ENA-USDT","name":"ENA-USDT","baseCurrency":"ENA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712044800000},{"symbol":"USDE-USDT","name":"USDE-USDT","baseCurrency":"USDe","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712044800000},{"symbol":"W-USDT","name":"W-USDT","baseCurrency":"W","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712145600000},{"symbol":"MEW-USDT","name":"MEW-USDT","baseCurrency":"MEW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712149200000},{"symbol":"ZEUS-USDT","name":"ZEUS-USDT","baseCurrency":"ZEUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712246400000},{"symbol":"AERO-USDT","name":"AERO-USDT","baseCurrency":"AERO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712307600000},{"symbol":"TRUF-USDT","name":"TRUF-USDT","baseCurrency":"TRUF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712653200000},{"symbol":"G3-USDT","name":"G3-USDT","baseCurrency":"G3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712656800000},{"symbol":"TNSR-USDT","name":"TNSR-USDT","baseCurrency":"TNSR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712589300000},{"symbol":"ESE-USDT","name":"ESE-USDT","baseCurrency":"ESE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712829600000},{"symbol":"SQR-USDT","name":"SQR-USDT","baseCurrency":"SQR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712833200000},{"symbol":"FOXY-USDT","name":"FOXY-USDT","baseCurrency":"FOXY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1712908800000},{"symbol":"PRCL-USDT","name":"PRCL-USDT","baseCurrency":"PRCL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713272400000},{"symbol":"MAPO-USDT","name":"MAPO-USDT","baseCurrency":"MAPO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1714294800000},{"symbol":"MERL-USDT","name":"MERL-USDT","baseCurrency":"MERL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713520800000},{"symbol":"DEGEN-USDT","name":"DEGEN-USDT","baseCurrency":"DEGEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713434400000},{"symbol":"KARRAT-USDT","name":"KARRAT-USDT","baseCurrency":"KARRAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713812400000},{"symbol":"VINU-USDT","name":"VINU-USDT","baseCurrency":"VINU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.000000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713535200000},{"symbol":"LL-USDT","name":"LL-USDT","baseCurrency":"LL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713945600000},{"symbol":"SAFE-USDT","name":"SAFE-USDT","baseCurrency":"SAFE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1713853500000},{"symbol":"RIO-USDT","name":"RIO-USDT","baseCurrency":"RIO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1714122000000},{"symbol":"REZ-USDT","name":"REZ-USDT","baseCurrency":"REZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1714478400000},{"symbol":"KMNO-USDT","name":"KMNO-USDT","baseCurrency":"KMNO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1714478400000},{"symbol":"ZBCN-USDT","name":"ZBCN-USDT","baseCurrency":"ZBCN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1714640400000},{"symbol":"WSDM-USDT","name":"WSDM-USDT","baseCurrency":"WSDM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715684400000},{"symbol":"BB-USDT","name":"BB-USDT","baseCurrency":"BB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715594400000},{"symbol":"CTA-USDT","name":"CTA-USDT","baseCurrency":"CTA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"1000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715760000000},{"symbol":"DRIFT-USDT","name":"DRIFT-USDT","baseCurrency":"DRIFT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"1000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715860800000},{"symbol":"NOT-USDT","name":"NOT-USDT","baseCurrency":"NOT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715860800000},{"symbol":"SQD-USDT","name":"SQD-USDT","baseCurrency":"SQD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1715932800000},{"symbol":"MONPRO-USDT","name":"MONPRO-USDT","baseCurrency":"MONPRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.09","callauctionFirstStageStartTime":1758787200000,"callauctionSecondStageStartTime":1758790200000,"callauctionThirdStageStartTime":1758790500000,"tradingStartTime":1758790800000},{"symbol":"TAIKO-USDT","name":"TAIKO-USDT","baseCurrency":"TAIKO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1717592400000},{"symbol":"LKI-USDT","name":"LKI-USDT","baseCurrency":"LKI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1717664400000},{"symbol":"BRETT-USDT","name":"BRETT-USDT","baseCurrency":"BRETT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1717664400000},{"symbol":"IO-USDT","name":"IO-USDT","baseCurrency":"IO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718107200000},{"symbol":"UNA-USDT","name":"UNA-USDT","baseCurrency":"UNA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718186400000},{"symbol":"ATH-USDT","name":"ATH-USDT","baseCurrency":"ATH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718186400000},{"symbol":"COOKIE-USDT","name":"COOKIE-USDT","baseCurrency":"COOKIE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718272800000},{"symbol":"ARTFI-USDT","name":"ARTFI-USDT","baseCurrency":"ARTFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718622000000},{"symbol":"ZK-USDT","name":"ZK-USDT","baseCurrency":"ZK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718611200000},{"symbol":"OORT-USDT","name":"OORT-USDT","baseCurrency":"OORT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718704800000},{"symbol":"ZRO-USDT","name":"ZRO-USDT","baseCurrency":"ZRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718884800000},{"symbol":"LISTA-USDT","name":"LISTA-USDT","baseCurrency":"LISTA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1718877600000},{"symbol":"NRN-USDT","name":"NRN-USDT","baseCurrency":"NRN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1719216000000},{"symbol":"BLAST-USDT","name":"BLAST-USDT","baseCurrency":"BLAST","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1719414000000},{"symbol":"ZEX-USDT","name":"ZEX-USDT","baseCurrency":"ZEX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1719482400000},{"symbol":"NATIX-USDT","name":"NATIX-USDT","baseCurrency":"NATIX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1719914400000},{"symbol":"MOG-USDT","name":"MOG-USDT","baseCurrency":"MOG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1720080000000},{"symbol":"XR-USDT","name":"XR-USDT","baseCurrency":"XR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1720684800000},{"symbol":"MOCA-USDT","name":"MOCA-USDT","baseCurrency":"MOCA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1720692000000},{"symbol":"UXLINK-USDT","name":"UXLINK-USDT","baseCurrency":"UXLINK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.088","callauctionFirstStageStartTime":1763114400000,"callauctionSecondStageStartTime":1763117400000,"callauctionThirdStageStartTime":1763117700000,"tradingStartTime":1763118000000},{"symbol":"ANYONE-USDT","name":"ANYONE-USDT","baseCurrency":"ANYONE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1721293200000},{"symbol":"BANANA-USDT","name":"BANANA-USDT","baseCurrency":"BANANA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1721390400000},{"symbol":"AVAIL-USDT","name":"AVAIL-USDT","baseCurrency":"AVAIL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1721736000000},{"symbol":"LRDS-USDT","name":"LRDS-USDT","baseCurrency":"LRDS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1721826000000},{"symbol":"L3-USDT","name":"L3-USDT","baseCurrency":"L3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1722333600000},{"symbol":"CXT-USDT","name":"CXT-USDT","baseCurrency":"CXT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1722502800000},{"symbol":"G-USDT","name":"G-USDT","baseCurrency":"G","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724054400000},{"symbol":"RENDER-USDT","name":"RENDER-USDT","baseCurrency":"RENDER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724227200000},{"symbol":"CAT-USDT","name":"CAT-USDT","baseCurrency":"CAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"100000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724335200000},{"symbol":"POPCAT-USDT","name":"POPCAT-USDT","baseCurrency":"POPCAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724338800000},{"symbol":"DOGS-USDT","name":"DOGS-USDT","baseCurrency":"DOGS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724673600000},{"symbol":"ORDER-USDT","name":"ORDER-USDT","baseCurrency":"ORDER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1724666400000},{"symbol":"SUNDOG-USDT","name":"SUNDOG-USDT","baseCurrency":"SUNDOG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1725357600000},{"symbol":"ROOBEE-USDT","name":"ROOBEE-USDT","baseCurrency":"ROOBEE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1725350400000},{"symbol":"CATI-USDT","name":"CATI-USDT","baseCurrency":"CATI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1726826400000},{"symbol":"TURBO-USDT","name":"TURBO-USDT","baseCurrency":"TURBO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1726480800000},{"symbol":"NEIROCTO-USDT","name":"NEIROCTO-USDT","baseCurrency":"NEIROCTO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1726563600000},{"symbol":"SKY-USDT","name":"SKY-USDT","baseCurrency":"SKY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"1000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1727870400000},{"symbol":"HMSTR-USDT","name":"HMSTR-USDT","baseCurrency":"HMSTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1727352000000},{"symbol":"MOODENG-USDT","name":"MOODENG-USDT","baseCurrency":"MOODENG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1727434800000},{"symbol":"EIGEN-USDT","name":"EIGEN-USDT","baseCurrency":"EIGEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1727757000000},{"symbol":"CHO-USDT","name":"CHO-USDT","baseCurrency":"CHO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728374400000},{"symbol":"PONKE-USDT","name":"PONKE-USDT","baseCurrency":"PONKE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728468000000},{"symbol":"CARV-USDT","name":"CARV-USDT","baseCurrency":"CARV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728547200000},{"symbol":"HIPPO-USDT","name":"HIPPO-USDT","baseCurrency":"HIPPO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728554400000},{"symbol":"PUFFER-USDT","name":"PUFFER-USDT","baseCurrency":"PUFFER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728907200000},{"symbol":"WMTX-USDT","name":"WMTX-USDT","baseCurrency":"WMTX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728892800000},{"symbol":"DEEP-USDT","name":"DEEP-USDT","baseCurrency":"DEEP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728900000000},{"symbol":"RMV-USDT","name":"RMV-USDT","baseCurrency":"RMV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1728892800000},{"symbol":"DBR-USDT","name":"DBR-USDT","baseCurrency":"DBR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1729152000000},{"symbol":"X-USDT","name":"X-USDT","baseCurrency":"X","quoteCurrency":"USDT","feeCurrency":"USDT","market":"TON","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1729771200000},{"symbol":"SCR-USDT","name":"SCR-USDT","baseCurrency":"SCR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1729584000000},{"symbol":"USDC-EUR","name":"USDC-EUR","baseCurrency":"USDC","quoteCurrency":"EUR","feeCurrency":"EUR","market":"FIAT","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.04","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731481200000},{"symbol":"GOAT-USDT","name":"GOAT-USDT","baseCurrency":"GOAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1729857600000},{"symbol":"GRASS-USDT","name":"GRASS-USDT","baseCurrency":"GRASS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730124000000},{"symbol":"KAIA-USDT","name":"KAIA-USDT","baseCurrency":"KAIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730444400000},{"symbol":"ARCA-USDT","name":"ARCA-USDT","baseCurrency":"ARCA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730718000000},{"symbol":"ACTSOL-USDT","name":"ACTSOL-USDT","baseCurrency":"ACTSOL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730714400000},{"symbol":"COW-USDT","name":"COW-USDT","baseCurrency":"COW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730894400000},{"symbol":"SWELL-USDT","name":"SWELL-USDT","baseCurrency":"SWELL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1730973600000},{"symbol":"CVC-USDT","name":"CVC-USDT","baseCurrency":"CVC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.025","callauctionPriceCeiling":"0.6","callauctionFirstStageStartTime":1731045600000,"callauctionSecondStageStartTime":1731047400000,"callauctionThirdStageStartTime":1731048900000,"tradingStartTime":1731049200000},{"symbol":"PEAQ-USDT","name":"PEAQ-USDT","baseCurrency":"PEAQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731402000000},{"symbol":"PNUT-USDT","name":"PNUT-USDT","baseCurrency":"PNUT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731326400000},{"symbol":"NS-USDT","name":"NS-USDT","baseCurrency":"NS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731582000000},{"symbol":"HSK-USDT","name":"HSK-USDT","baseCurrency":"HSK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732615200000},{"symbol":"NPC-USDT","name":"NPC-USDT","baseCurrency":"NPC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731924000000},{"symbol":"BAN-USDT","name":"BAN-USDT","baseCurrency":"BAN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1731927600000},{"symbol":"MORPHO-USDT","name":"MORPHO-USDT","baseCurrency":"MORPHO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732183200000},{"symbol":"MEMEFI-USDT","name":"MEMEFI-USDT","baseCurrency":"MEMEFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732280400000},{"symbol":"RWA-USDT","name":"RWA-USDT","baseCurrency":"RWA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732528800000},{"symbol":"WOD-USDT","name":"WOD-USDT","baseCurrency":"WOD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732705200000},{"symbol":"READY-USDT","name":"READY-USDT","baseCurrency":"READY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732618800000},{"symbol":"FLUX-USDC","name":"FLUX-USDC","baseCurrency":"FLUX","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732608000000},{"symbol":"SYRUP-USDT","name":"SYRUP-USDT","baseCurrency":"SYRUP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732618800000},{"symbol":"SUPRA-USDT","name":"SUPRA-USDT","baseCurrency":"SUPRA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732712400000},{"symbol":"LUMIA-USDT","name":"LUMIA-USDT","baseCurrency":"LUMIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732694400000},{"symbol":"MAJOR-USDT","name":"MAJOR-USDT","baseCurrency":"MAJOR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732795200000},{"symbol":"CHILLGUY-USDT","name":"CHILLGUY-USDT","baseCurrency":"CHILLGUY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732708800000},{"symbol":"VIRTUAL-USDT","name":"VIRTUAL-USDT","baseCurrency":"VIRTUAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1732881600000},{"symbol":"TOSHI-USDT","name":"TOSHI-USDT","baseCurrency":"TOSHI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733220000000},{"symbol":"XION-USDT","name":"XION-USDT","baseCurrency":"XION","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733392800000},{"symbol":"SPX-USDT","name":"SPX-USDT","baseCurrency":"SPX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733306400000},{"symbol":"AVAAI-USDT","name":"AVAAI-USDT","baseCurrency":"AVAAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733396400000},{"symbol":"GIGA-USDT","name":"GIGA-USDT","baseCurrency":"GIGA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"0.15","callauctionFirstStageStartTime":1733396400000,"callauctionSecondStageStartTime":1733398800000,"callauctionThirdStageStartTime":1733399700000,"tradingStartTime":1733400000000},{"symbol":"F-USDT","name":"F-USDT","baseCurrency":"F","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733479200000},{"symbol":"DOGEGOV-USDT","name":"DOGEGOV-USDT","baseCurrency":"DOGEGOV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733482800000},{"symbol":"HYPE-USDT","name":"HYPE-USDT","baseCurrency":"HYPE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733583600000},{"symbol":"MOVE-USDT","name":"MOVE-USDT","baseCurrency":"MOVE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733745600000},{"symbol":"ZEREBRO-USDT","name":"ZEREBRO-USDT","baseCurrency":"ZEREBRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733742000000},{"symbol":"U2U-USDT","name":"U2U-USDT","baseCurrency":"U2U","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733824800000},{"symbol":"ME-USDT","name":"ME-USDT","baseCurrency":"ME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733839200000},{"symbol":"BLUE-USDT","name":"BLUE-USDT","baseCurrency":"BLUE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1733911200000},{"symbol":"CHEQ-USDT","name":"CHEQ-USDT","baseCurrency":"CHEQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"0.3","callauctionFirstStageStartTime":1733904000000,"callauctionSecondStageStartTime":1733906400000,"callauctionThirdStageStartTime":1733907300000,"tradingStartTime":1733907600000},{"symbol":"HOLD-USDT","name":"HOLD-USDT","baseCurrency":"HOLD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734001200000},{"symbol":"LINGO-USDT","name":"LINGO-USDT","baseCurrency":"LINGO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734015600000},{"symbol":"KOMA-USDT","name":"KOMA-USDT","baseCurrency":"KOMA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734350400000},{"symbol":"USUAL-USDT","name":"USUAL-USDT","baseCurrency":"USUAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734519600000},{"symbol":"ISLAND-USDT","name":"ISLAND-USDT","baseCurrency":"ISLAND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734447600000},{"symbol":"STREAM-USDT","name":"STREAM-USDT","baseCurrency":"STREAM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734440400000},{"symbol":"PENGU-USDT","name":"PENGU-USDT","baseCurrency":"PENGU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734444000000},{"symbol":"FUEL-USDT","name":"FUEL-USDT","baseCurrency":"FUEL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734602400000},{"symbol":"ITHACA-USDT","name":"ITHACA-USDT","baseCurrency":"ITHACA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734602400000},{"symbol":"HPOS10I-USDT","name":"HPOS10I-USDT","baseCurrency":"HPOS10I","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734595200000},{"symbol":"FARTCOIN-USDT","name":"FARTCOIN-USDT","baseCurrency":"FARTCOIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1734595200000,"callauctionSecondStageStartTime":1734597900000,"callauctionThirdStageStartTime":1734598500000,"tradingStartTime":1734598800000},{"symbol":"EYWA-USDT","name":"EYWA-USDT","baseCurrency":"EYWA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734692400000},{"symbol":"PURR-USDT","name":"PURR-USDT","baseCurrency":"PURR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1734703200000},{"symbol":"GRIFFAIN-USDT","name":"GRIFFAIN-USDT","baseCurrency":"GRIFFAIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.71","callauctionFirstStageStartTime":1735030800000,"callauctionSecondStageStartTime":1735033500000,"callauctionThirdStageStartTime":1735034100000,"tradingStartTime":1735034400000},{"symbol":"AIXBT-USDT","name":"AIXBT-USDT","baseCurrency":"AIXBT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.0245","callauctionFirstStageStartTime":1735034400000,"callauctionSecondStageStartTime":1735037100000,"callauctionThirdStageStartTime":1735037700000,"tradingStartTime":1735038000000},{"symbol":"FB-USDT","name":"FB-USDT","baseCurrency":"FB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"9","callauctionFirstStageStartTime":1735632000000,"callauctionSecondStageStartTime":1735634700000,"callauctionThirdStageStartTime":1735635300000,"tradingStartTime":1735635600000},{"symbol":"MILADYCULT-USDT","name":"MILADYCULT-USDT","baseCurrency":"MILADYCULT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1735556400000},{"symbol":"REKT-USDT","name":"REKT-USDT","baseCurrency":"REKT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1735639200000},{"symbol":"BIO-USDT","name":"BIO-USDT","baseCurrency":"BIO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1735898400000},{"symbol":"LAVA-USDT","name":"LAVA-USDT","baseCurrency":"LAVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736416800000},{"symbol":"ARCSOL-USDT","name":"ARCSOL-USDT","baseCurrency":"ARCSOL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.6","callauctionFirstStageStartTime":1735819200000,"callauctionSecondStageStartTime":1735821900000,"callauctionThirdStageStartTime":1735822500000,"tradingStartTime":1735822800000},{"symbol":"SWARMS-USDT","name":"SWARMS-USDT","baseCurrency":"SWARMS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1735905600000,"callauctionSecondStageStartTime":1735908300000,"callauctionThirdStageStartTime":1735908900000,"tradingStartTime":1735909200000},{"symbol":"VANA-USDT","name":"VANA-USDT","baseCurrency":"VANA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"3","callauctionPriceCeiling":"100","callauctionFirstStageStartTime":1735981200000,"callauctionSecondStageStartTime":1735983900000,"callauctionThirdStageStartTime":1735984500000,"tradingStartTime":1735984800000},{"symbol":"SONIC-USDT","name":"SONIC-USDT","baseCurrency":"SONIC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736251200000},{"symbol":"GAMEAI-USDT","name":"GAMEAI-USDT","baseCurrency":"GAMEAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.886","callauctionFirstStageStartTime":1736254800000,"callauctionSecondStageStartTime":1736257500000,"callauctionThirdStageStartTime":1736258100000,"tradingStartTime":1736258400000},{"symbol":"XTER-USDT","name":"XTER-USDT","baseCurrency":"XTER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736330400000},{"symbol":"ACX-USDT","name":"ACX-USDT","baseCurrency":"ACX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"1000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736334000000},{"symbol":"CLOUD-USDT","name":"CLOUD-USDT","baseCurrency":"CLOUD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1736323200000,"callauctionSecondStageStartTime":1736325900000,"callauctionThirdStageStartTime":1736326500000,"tradingStartTime":1736326800000},{"symbol":"PAAL-USDT","name":"PAAL-USDT","baseCurrency":"PAAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736416800000},{"symbol":"LOFI-USDT","name":"LOFI-USDT","baseCurrency":"LOFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1736503200000},{"symbol":"DUCK-USDT","name":"DUCK-USDT","baseCurrency":"DUCK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737021600000},{"symbol":"NC-USDT","name":"NC-USDT","baseCurrency":"NC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737108000000},{"symbol":"GPS-USDT","name":"GPS-USDT","baseCurrency":"GPS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737021600000},{"symbol":"SOLV-USDT","name":"SOLV-USDT","baseCurrency":"SOLV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737108000000},{"symbol":"OBT-USDT","name":"OBT-USDT","baseCurrency":"OBT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737367200000},{"symbol":"TRUMP-USDT","name":"TRUMP-USDT","baseCurrency":"TRUMP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"100","callauctionFirstStageStartTime":1737205200000,"callauctionSecondStageStartTime":1737208200000,"callauctionThirdStageStartTime":1737208500000,"tradingStartTime":1737208800000},{"symbol":"J-USDT","name":"J-USDT","baseCurrency":"J","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737540000000},{"symbol":"CHIRP-USDT","name":"CHIRP-USDT","baseCurrency":"CHIRP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737381600000},{"symbol":"MELANIA-USDT","name":"MELANIA-USDT","baseCurrency":"MELANIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"36.85","callauctionFirstStageStartTime":1737349200000,"callauctionSecondStageStartTime":1737352200000,"callauctionThirdStageStartTime":1737352500000,"tradingStartTime":1737352800000},{"symbol":"PLUME-USDT","name":"PLUME-USDT","baseCurrency":"PLUME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737450000000},{"symbol":"ALU-USDT","name":"ALU-USDT","baseCurrency":"ALU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737453600000},{"symbol":"ANIME-USDT","name":"ANIME-USDT","baseCurrency":"ANIME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737640800000},{"symbol":"ANLOG-USDT","name":"ANLOG-USDT","baseCurrency":"ANLOG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1739185200000},{"symbol":"SLC-USDT","name":"SLC-USDT","baseCurrency":"SLC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.16","callauctionFirstStageStartTime":1737540000000,"callauctionSecondStageStartTime":1737543000000,"callauctionThirdStageStartTime":1737543300000,"tradingStartTime":1737727200000},{"symbol":"VTHO-USDT","name":"VTHO-USDT","baseCurrency":"VTHO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.03331","callauctionFirstStageStartTime":1737550800000,"callauctionSecondStageStartTime":1737553800000,"callauctionThirdStageStartTime":1737554100000,"tradingStartTime":1737554400000},{"symbol":"S-USDT","name":"S-USDT","baseCurrency":"S","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1737615600000,"callauctionSecondStageStartTime":1737618600000,"callauctionThirdStageStartTime":1737618900000,"tradingStartTime":1737619200000},{"symbol":"EMYC-USDT","name":"EMYC-USDT","baseCurrency":"EMYC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1737640800000},{"symbol":"S-USDC","name":"S-USDC","baseCurrency":"S","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1737615600000,"callauctionSecondStageStartTime":1737618600000,"callauctionThirdStageStartTime":1737618900000,"tradingStartTime":1737619200000},{"symbol":"VINE-USDT","name":"VINE-USDT","baseCurrency":"VINE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1737874800000,"callauctionSecondStageStartTime":1737877800000,"callauctionThirdStageStartTime":1737878100000,"tradingStartTime":1737878400000},{"symbol":"D-USDT","name":"D-USDT","baseCurrency":"D","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1737961200000,"callauctionSecondStageStartTime":1737964200000,"callauctionThirdStageStartTime":1737964500000,"tradingStartTime":1737964800000},{"symbol":"VVV-USDT","name":"VVV-USDT","baseCurrency":"VVV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"86.15","callauctionFirstStageStartTime":1738054800000,"callauctionSecondStageStartTime":1738057800000,"callauctionThirdStageStartTime":1738058100000,"tradingStartTime":1738058400000},{"symbol":"JELLYJELLY-USDT","name":"JELLYJELLY-USDT","baseCurrency":"JELLYJELLY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1738234800000,"callauctionSecondStageStartTime":1738237800000,"callauctionThirdStageStartTime":1738238100000,"tradingStartTime":1738238400000},{"symbol":"BERA-USDT","name":"BERA-USDT","baseCurrency":"BERA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1738846800000},{"symbol":"CHEEMS-USDT","name":"CHEEMS-USDT","baseCurrency":"CHEEMS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000000001","callauctionPriceCeiling":"0.0000036925","callauctionFirstStageStartTime":1739192400000,"callauctionSecondStageStartTime":1739195400000,"callauctionThirdStageStartTime":1739195700000,"tradingStartTime":1739196000000},{"symbol":"TSTBSC-USDT","name":"TSTBSC-USDT","baseCurrency":"TSTBSC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.8","callauctionFirstStageStartTime":1739188800000,"callauctionSecondStageStartTime":1739191800000,"callauctionThirdStageStartTime":1739192100000,"tradingStartTime":1739192400000},{"symbol":"IP-USDT","name":"IP-USDT","baseCurrency":"IP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1739437200000},{"symbol":"LAYER-USDT","name":"LAYER-USDT","baseCurrency":"LAYER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1765530000000,"callauctionSecondStageStartTime":1765533000000,"callauctionThirdStageStartTime":1765533300000,"tradingStartTime":1765533600000},{"symbol":"DIN-USDT","name":"DIN-USDT","baseCurrency":"DIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1739534400000},{"symbol":"XOXO-USDT","name":"XOXO-USDT","baseCurrency":"XOXO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.00000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1739538000000},{"symbol":"RIZ-USDT","name":"RIZ-USDT","baseCurrency":"RIZ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1740142800000},{"symbol":"RONIN-USDT","name":"RONIN-USDT","baseCurrency":"RONIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1739872800000},{"symbol":"SUI-USDC","name":"SUI-USDC","baseCurrency":"SUI","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"16","callauctionFirstStageStartTime":1740034800000,"callauctionSecondStageStartTime":1740037800000,"callauctionThirdStageStartTime":1740038100000,"tradingStartTime":1740038400000},{"symbol":"PEPE-USDC","name":"PEPE-USDC","baseCurrency":"PEPE","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"60000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00000001","callauctionPriceCeiling":"0.00000475","callauctionFirstStageStartTime":1740038400000,"callauctionSecondStageStartTime":1740041400000,"callauctionThirdStageStartTime":1740041700000,"tradingStartTime":1740042000000},{"symbol":"VR-USDC","name":"VR-USDC","baseCurrency":"VR","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.045","callauctionFirstStageStartTime":1740042000000,"callauctionSecondStageStartTime":1740045000000,"callauctionThirdStageStartTime":1740045300000,"tradingStartTime":1740045600000},{"symbol":"KAITO-USDT","name":"KAITO-USDT","baseCurrency":"KAITO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":null,"callauctionPriceCeiling":null,"callauctionFirstStageStartTime":null,"callauctionSecondStageStartTime":null,"callauctionThirdStageStartTime":null,"tradingStartTime":1740056400000},{"symbol":"B3-USDT","name":"B3-USDT","baseCurrency":"B3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.037","callauctionFirstStageStartTime":1740124800000,"callauctionSecondStageStartTime":1740127800000,"callauctionThirdStageStartTime":1740128100000,"tradingStartTime":1740128400000},{"symbol":"SFI-USDT","name":"SFI-USDT","baseCurrency":"SFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.6","callauctionFirstStageStartTime":1740470400000,"callauctionSecondStageStartTime":1740473400000,"callauctionThirdStageStartTime":1740473700000,"tradingStartTime":1740474000000},{"symbol":"SHELL-USDT","name":"SHELL-USDT","baseCurrency":"SHELL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"6.12","callauctionFirstStageStartTime":1740654000000,"callauctionSecondStageStartTime":1740657000000,"callauctionThirdStageStartTime":1740657300000,"tradingStartTime":1740657600000},{"symbol":"FWOG-USDT","name":"FWOG-USDT","baseCurrency":"FWOG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.68","callauctionFirstStageStartTime":1740733200000,"callauctionSecondStageStartTime":1740736200000,"callauctionThirdStageStartTime":1740736500000,"tradingStartTime":1740736800000},{"symbol":"ROAM-USDT","name":"ROAM-USDT","baseCurrency":"ROAM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1741251600000,"callauctionSecondStageStartTime":1741254600000,"callauctionThirdStageStartTime":1741254900000,"tradingStartTime":1741255200000},{"symbol":"HEI-USDT","name":"HEI-USDT","baseCurrency":"HEI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5.5","callauctionFirstStageStartTime":1740988800000,"callauctionSecondStageStartTime":1740991800000,"callauctionThirdStageStartTime":1740992100000,"tradingStartTime":1740992400000},{"symbol":"REACT-USDT","name":"REACT-USDT","baseCurrency":"REACT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.555","callauctionFirstStageStartTime":1741161600000,"callauctionSecondStageStartTime":1741164600000,"callauctionThirdStageStartTime":1741164900000,"tradingStartTime":1741165200000},{"symbol":"REDSTONE-USDT","name":"REDSTONE-USDT","baseCurrency":"REDSTONE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"20","callauctionFirstStageStartTime":1741262400000,"callauctionSecondStageStartTime":1741265400000,"callauctionThirdStageStartTime":1741265700000,"tradingStartTime":1741266000000},{"symbol":"HONEY-USDT","name":"HONEY-USDT","baseCurrency":"HONEY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.452","callauctionFirstStageStartTime":1741244400000,"callauctionSecondStageStartTime":1741247400000,"callauctionThirdStageStartTime":1741247700000,"tradingStartTime":1741248000000},{"symbol":"LVVA-USDT","name":"LVVA-USDT","baseCurrency":"LVVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.04","callauctionFirstStageStartTime":1741687200000,"callauctionSecondStageStartTime":1741690200000,"callauctionThirdStageStartTime":1741690500000,"tradingStartTime":1741690800000},{"symbol":"TRUMP-USDC","name":"TRUMP-USDC","baseCurrency":"TRUMP","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"104","callauctionFirstStageStartTime":1741676400000,"callauctionSecondStageStartTime":1741679400000,"callauctionThirdStageStartTime":1741679700000,"tradingStartTime":1741680000000},{"symbol":"JUP-USDC","name":"JUP-USDC","baseCurrency":"JUP","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4.92","callauctionFirstStageStartTime":1741680000000,"callauctionSecondStageStartTime":1741683000000,"callauctionThirdStageStartTime":1741683300000,"tradingStartTime":1741683600000},{"symbol":"ONDO-USDC","name":"ONDO-USDC","baseCurrency":"ONDO","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1741683600000,"callauctionSecondStageStartTime":1741686600000,"callauctionThirdStageStartTime":1741686900000,"tradingStartTime":1741687200000},{"symbol":"PAWS-USDT","name":"PAWS-USDT","baseCurrency":"PAWS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.01","callauctionFirstStageStartTime":1744797600000,"callauctionSecondStageStartTime":1744800600000,"callauctionThirdStageStartTime":1744800900000,"tradingStartTime":1744801200000},{"symbol":"MUBARAK-USDT","name":"MUBARAK-USDT","baseCurrency":"MUBARAK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.27","callauctionFirstStageStartTime":1742205600000,"callauctionSecondStageStartTime":1742208600000,"callauctionThirdStageStartTime":1742208900000,"tradingStartTime":1742209200000},{"symbol":"TAO-USDC","name":"TAO-USDC","baseCurrency":"TAO","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"2456","callauctionFirstStageStartTime":1742281200000,"callauctionSecondStageStartTime":1742284200000,"callauctionThirdStageStartTime":1742284500000,"tradingStartTime":1742284800000},{"symbol":"XMR-USDC","name":"XMR-USDC","baseCurrency":"XMR","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"2100","callauctionFirstStageStartTime":1742284800000,"callauctionSecondStageStartTime":1742287800000,"callauctionThirdStageStartTime":1742288100000,"tradingStartTime":1742288400000},{"symbol":"HBAR-USDC","name":"HBAR-USDC","baseCurrency":"HBAR","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.86","callauctionFirstStageStartTime":1742288400000,"callauctionSecondStageStartTime":1742291400000,"callauctionThirdStageStartTime":1742291700000,"tradingStartTime":1742292000000},{"symbol":"WIF-USDC","name":"WIF-USDC","baseCurrency":"WIF","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4.75","callauctionFirstStageStartTime":1742292000000,"callauctionSecondStageStartTime":1742295000000,"callauctionThirdStageStartTime":1742295300000,"tradingStartTime":1742295600000},{"symbol":"BMT-USDT","name":"BMT-USDT","baseCurrency":"BMT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2.85","callauctionFirstStageStartTime":1742302800000,"callauctionSecondStageStartTime":1742305800000,"callauctionThirdStageStartTime":1742306100000,"tradingStartTime":1742306400000},{"symbol":"TUT-USDT","name":"TUT-USDT","baseCurrency":"TUT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.24","callauctionFirstStageStartTime":1742367600000,"callauctionSecondStageStartTime":1742370600000,"callauctionThirdStageStartTime":1742370900000,"tradingStartTime":1742371200000},{"symbol":"EPIC-USDT","name":"EPIC-USDT","baseCurrency":"EPIC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"13","callauctionFirstStageStartTime":1742544000000,"callauctionSecondStageStartTime":1742547000000,"callauctionThirdStageStartTime":1742547300000,"tradingStartTime":1742781600000},{"symbol":"BR-USDT","name":"BR-USDT","baseCurrency":"BR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1742551200000,"callauctionSecondStageStartTime":1742554200000,"callauctionThirdStageStartTime":1742554500000,"tradingStartTime":1742554800000},{"symbol":"SIREN-USDT","name":"SIREN-USDT","baseCurrency":"SIREN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.75","callauctionFirstStageStartTime":1742547600000,"callauctionSecondStageStartTime":1742550600000,"callauctionThirdStageStartTime":1742550900000,"tradingStartTime":1742551200000},{"symbol":"NIL-USDT","name":"NIL-USDT","baseCurrency":"NIL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1742817600000,"callauctionSecondStageStartTime":1742820600000,"callauctionThirdStageStartTime":1742820900000,"tradingStartTime":1742821200000},{"symbol":"PARTI-USDT","name":"PARTI-USDT","baseCurrency":"PARTI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1742904000000,"callauctionSecondStageStartTime":1742907000000,"callauctionThirdStageStartTime":1742907300000,"tradingStartTime":1742907600000},{"symbol":"XLM-USDC","name":"XLM-USDC","baseCurrency":"XLM","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1742886000000,"callauctionSecondStageStartTime":1742889000000,"callauctionThirdStageStartTime":1742889300000,"tradingStartTime":1742889600000},{"symbol":"TON-USDC","name":"TON-USDC","baseCurrency":"TON","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"36","callauctionFirstStageStartTime":1742889600000,"callauctionSecondStageStartTime":1742892600000,"callauctionThirdStageStartTime":1742892900000,"tradingStartTime":1742893200000},{"symbol":"ENA-USDC","name":"ENA-USDC","baseCurrency":"ENA","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1742893200000,"callauctionSecondStageStartTime":1742896200000,"callauctionThirdStageStartTime":1742896500000,"tradingStartTime":1742896800000},{"symbol":"WAL-USDT","name":"WAL-USDT","baseCurrency":"WAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1743066000000,"callauctionSecondStageStartTime":1743069000000,"callauctionThirdStageStartTime":1743069300000,"tradingStartTime":1743069600000},{"symbol":"INJ-USDC","name":"INJ-USDC","baseCurrency":"INJ","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"100","callauctionFirstStageStartTime":1743058800000,"callauctionSecondStageStartTime":1743061800000,"callauctionThirdStageStartTime":1743062100000,"tradingStartTime":1743062400000},{"symbol":"HYPE-USDC","name":"HYPE-USDC","baseCurrency":"HYPE","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"150","callauctionFirstStageStartTime":1743062400000,"callauctionSecondStageStartTime":1743065400000,"callauctionThirdStageStartTime":1743065700000,"tradingStartTime":1743066000000},{"symbol":"FARTCOIN-USDC","name":"FARTCOIN-USDC","baseCurrency":"FARTCOIN","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"6","callauctionFirstStageStartTime":1743066000000,"callauctionSecondStageStartTime":1743069000000,"callauctionThirdStageStartTime":1743069300000,"tradingStartTime":1743069600000},{"symbol":"KILO-USDT","name":"KILO-USDT","baseCurrency":"KILO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1743076800000,"callauctionSecondStageStartTime":1743079800000,"callauctionThirdStageStartTime":1743080100000,"tradingStartTime":1743080400000},{"symbol":"GUN-USDT","name":"GUN-USDT","baseCurrency":"GUN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1743422400000,"callauctionSecondStageStartTime":1743425400000,"callauctionThirdStageStartTime":1743425700000,"tradingStartTime":1743426000000},{"symbol":"ZND-USDT","name":"ZND-USDT","baseCurrency":"ZND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1743595200000,"callauctionSecondStageStartTime":1743598200000,"callauctionThirdStageStartTime":1743598500000,"tradingStartTime":1743598800000},{"symbol":"STO-USDT","name":"STO-USDT","baseCurrency":"STO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3.75","callauctionFirstStageStartTime":1743670800000,"callauctionSecondStageStartTime":1743672000000,"callauctionThirdStageStartTime":1743672300000,"tradingStartTime":1743672600000},{"symbol":"TAI-USDT","name":"TAI-USDT","baseCurrency":"TAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.35","callauctionFirstStageStartTime":1744016400000,"callauctionSecondStageStartTime":1744019400000,"callauctionThirdStageStartTime":1744019700000,"tradingStartTime":1744020000000},{"symbol":"KERNEL-USDT","name":"KERNEL-USDT","baseCurrency":"KERNEL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1744628400000,"callauctionSecondStageStartTime":1744631400000,"callauctionThirdStageStartTime":1744631700000,"tradingStartTime":1744632000000},{"symbol":"BABY-USDT","name":"BABY-USDT","baseCurrency":"BABY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1744275600000,"callauctionSecondStageStartTime":1744278600000,"callauctionThirdStageStartTime":1744278900000,"tradingStartTime":1744279200000},{"symbol":"PROMPT-USDT","name":"PROMPT-USDT","baseCurrency":"PROMPT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1744286400000,"callauctionSecondStageStartTime":1744289400000,"callauctionThirdStageStartTime":1744289700000,"tradingStartTime":1744290000000},{"symbol":"WCT-USDT","name":"WCT-USDT","baseCurrency":"WCT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1744711200000,"callauctionSecondStageStartTime":1744714200000,"callauctionThirdStageStartTime":1744714500000,"tradingStartTime":1744714800000},{"symbol":"HYPER-USDT","name":"HYPER-USDT","baseCurrency":"HYPER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1745323200000,"callauctionSecondStageStartTime":1745326200000,"callauctionThirdStageStartTime":1745326500000,"tradingStartTime":1745326800000},{"symbol":"DOLO-USDT","name":"DOLO-USDT","baseCurrency":"DOLO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1745496000000,"callauctionSecondStageStartTime":1745499000000,"callauctionThirdStageStartTime":1745499300000,"tradingStartTime":1745499600000},{"symbol":"ZORA-USDT","name":"ZORA-USDT","baseCurrency":"ZORA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.1","callauctionFirstStageStartTime":1745409600000,"callauctionSecondStageStartTime":1745412600000,"callauctionThirdStageStartTime":1745412900000,"tradingStartTime":1745413200000},{"symbol":"INIT-USDT","name":"INIT-USDT","baseCurrency":"INIT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"7","callauctionFirstStageStartTime":1745488800000,"callauctionSecondStageStartTime":1745491800000,"callauctionThirdStageStartTime":1745492100000,"tradingStartTime":1745492400000},{"symbol":"CLANKER-USDT","name":"CLANKER-USDT","baseCurrency":"CLANKER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"500","callauctionFirstStageStartTime":1745409600000,"callauctionSecondStageStartTime":1745412600000,"callauctionThirdStageStartTime":1745412900000,"tradingStartTime":1745413200000},{"symbol":"TROLL-USDT","name":"TROLL-USDT","baseCurrency":"TROLL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.18","callauctionFirstStageStartTime":1745492400000,"callauctionSecondStageStartTime":1745495400000,"callauctionThirdStageStartTime":1745495700000,"tradingStartTime":1745496000000},{"symbol":"HAEDAL-USDT","name":"HAEDAL-USDT","baseCurrency":"HAEDAL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.75","callauctionFirstStageStartTime":1745924400000,"callauctionSecondStageStartTime":1745927400000,"callauctionThirdStageStartTime":1745927700000,"tradingStartTime":1745928000000},{"symbol":"SIGN-USDT","name":"SIGN-USDT","baseCurrency":"SIGN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1745834400000,"callauctionSecondStageStartTime":1745837400000,"callauctionThirdStageStartTime":1745837700000,"tradingStartTime":1745838000000},{"symbol":"B2-USDT","name":"B2-USDT","baseCurrency":"B2","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1746010800000,"callauctionSecondStageStartTime":1746013800000,"callauctionThirdStageStartTime":1746014100000,"tradingStartTime":1746014400000},{"symbol":"ADX-USDC","name":"ADX-USDC","baseCurrency":"ADX","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1745996400000,"callauctionSecondStageStartTime":1745999400000,"callauctionThirdStageStartTime":1745999700000,"tradingStartTime":1746000000000},{"symbol":"TEL-USDC","name":"TEL-USDC","baseCurrency":"TEL","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.0535","callauctionFirstStageStartTime":1746000000000,"callauctionSecondStageStartTime":1746003000000,"callauctionThirdStageStartTime":1746003300000,"tradingStartTime":1746003600000},{"symbol":"NAKA-USDC","name":"NAKA-USDC","baseCurrency":"NAKA","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3.83","callauctionFirstStageStartTime":1746003600000,"callauctionSecondStageStartTime":1746006600000,"callauctionThirdStageStartTime":1746006900000,"tradingStartTime":1746007200000},{"symbol":"SXT-USDT","name":"SXT-USDT","baseCurrency":"SXT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1746705600000,"callauctionSecondStageStartTime":1746708600000,"callauctionThirdStageStartTime":1746708900000,"tradingStartTime":1746709200000},{"symbol":"HOUSE-USDT","name":"HOUSE-USDT","baseCurrency":"HOUSE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.55","callauctionFirstStageStartTime":1746612000000,"callauctionSecondStageStartTime":1746615000000,"callauctionThirdStageStartTime":1746615300000,"tradingStartTime":1746615600000},{"symbol":"SHM-USDT","name":"SHM-USDT","baseCurrency":"SHM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.004","callauctionFirstStageStartTime":1763020800000,"callauctionSecondStageStartTime":1763023800000,"callauctionThirdStageStartTime":1763024100000,"tradingStartTime":1763024400000},{"symbol":"DOOD-USDT","name":"DOOD-USDT","baseCurrency":"DOOD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1746792300000,"callauctionSecondStageStartTime":1746795300000,"callauctionThirdStageStartTime":1746795600000,"tradingStartTime":1746795900000},{"symbol":"USELESS-USDT","name":"USELESS-USDT","baseCurrency":"USELESS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1747126800000,"callauctionSecondStageStartTime":1747129800000,"callauctionThirdStageStartTime":1747130100000,"tradingStartTime":1747130400000},{"symbol":"NXPC-USDT","name":"NXPC-USDT","baseCurrency":"NXPC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1747285200000,"callauctionSecondStageStartTime":1747288200000,"callauctionThirdStageStartTime":1747288500000,"tradingStartTime":1747288800000},{"symbol":"PRAI-USDT","name":"PRAI-USDT","baseCurrency":"PRAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1747227600000,"callauctionSecondStageStartTime":1747230600000,"callauctionThirdStageStartTime":1747230900000,"tradingStartTime":1747231200000},{"symbol":"GIZA-USDT","name":"GIZA-USDT","baseCurrency":"GIZA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1747742400000,"callauctionSecondStageStartTime":1747745400000,"callauctionThirdStageStartTime":1747745700000,"tradingStartTime":1747746000000},{"symbol":"AWE-USDT","name":"AWE-USDT","baseCurrency":"AWE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.7","callauctionFirstStageStartTime":1747810800000,"callauctionSecondStageStartTime":1747813800000,"callauctionThirdStageStartTime":1747814100000,"tradingStartTime":1747814400000},{"symbol":"AGT-USDT","name":"AGT-USDT","baseCurrency":"AGT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1747825200000,"callauctionSecondStageStartTime":1747828200000,"callauctionThirdStageStartTime":1747828500000,"tradingStartTime":1747828800000},{"symbol":"USD1-USDT","name":"USD1-USDT","baseCurrency":"USD1","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.02","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.95","callauctionPriceCeiling":"1.05","callauctionFirstStageStartTime":1747821600000,"callauctionSecondStageStartTime":1747824600000,"callauctionThirdStageStartTime":1747824900000,"tradingStartTime":1747825200000},{"symbol":"SOON-USDT","name":"SOON-USDT","baseCurrency":"SOON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1747994400000,"callauctionSecondStageStartTime":1747997400000,"callauctionThirdStageStartTime":1747997700000,"tradingStartTime":1747998000000},{"symbol":"HUMA-USDT","name":"HUMA-USDT","baseCurrency":"HUMA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"10","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1748260800000,"callauctionSecondStageStartTime":1748263800000,"callauctionThirdStageStartTime":1748264100000,"tradingStartTime":1748264400000},{"symbol":"SOPH-USDT","name":"SOPH-USDT","baseCurrency":"SOPH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1748433600000,"callauctionSecondStageStartTime":1748436600000,"callauctionThirdStageStartTime":1748436900000,"tradingStartTime":1748437200000},{"symbol":"B-USD1","name":"B-USD1","baseCurrency":"B","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1748340000000,"callauctionSecondStageStartTime":1748343000000,"callauctionThirdStageStartTime":1748343300000,"tradingStartTime":1748343600000},{"symbol":"A-USDT","name":"A-USDT","baseCurrency":"A","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1748415600000,"callauctionSecondStageStartTime":1748418600000,"callauctionThirdStageStartTime":1748418900000,"tradingStartTime":1748419200000},{"symbol":"A-USDC","name":"A-USDC","baseCurrency":"A","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1748415600000,"callauctionSecondStageStartTime":1748418600000,"callauctionThirdStageStartTime":1748418900000,"tradingStartTime":1748419200000},{"symbol":"A-BTC","name":"A-BTC","baseCurrency":"A","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.1","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000000001","callauctionPriceCeiling":"0.00007","callauctionFirstStageStartTime":1748419200000,"callauctionSecondStageStartTime":1748422200000,"callauctionThirdStageStartTime":1748422500000,"tradingStartTime":1748422800000},{"symbol":"SOL-KCS","name":"SOL-KCS","baseCurrency":"SOL","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"0.001","quoteMinSize":"0.001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"150","callauctionFirstStageStartTime":1748502000000,"callauctionSecondStageStartTime":1748505000000,"callauctionThirdStageStartTime":1748505300000,"tradingStartTime":1748505600000},{"symbol":"SUI-KCS","name":"SUI-KCS","baseCurrency":"SUI","quoteCurrency":"KCS","feeCurrency":"KCS","market":"KCS","baseMinSize":"1","quoteMinSize":"0.001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1748505600000,"callauctionSecondStageStartTime":1748508600000,"callauctionThirdStageStartTime":1748508900000,"tradingStartTime":1748509200000},{"symbol":"LAT-USDT","name":"LAT-USDT","baseCurrency":"LAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.043","callauctionFirstStageStartTime":1748595600000,"callauctionSecondStageStartTime":1748598600000,"callauctionThirdStageStartTime":1748598900000,"tradingStartTime":1748599200000},{"symbol":"EDGEN-USDT","name":"EDGEN-USDT","baseCurrency":"EDGEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1748856600000,"callauctionSecondStageStartTime":1748859600000,"callauctionThirdStageStartTime":1748859900000,"tradingStartTime":1748860200000},{"symbol":"PRO-USDT","name":"PRO-USDT","baseCurrency":"PRO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1748955600000,"callauctionSecondStageStartTime":1748958600000,"callauctionThirdStageStartTime":1748958900000,"tradingStartTime":1748959200000},{"symbol":"LA-USDT","name":"LA-USDT","baseCurrency":"LA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1749034800000,"callauctionSecondStageStartTime":1749037800000,"callauctionThirdStageStartTime":1749038100000,"tradingStartTime":1749038400000},{"symbol":"MOODENG-USDC","name":"MOODENG-USDC","baseCurrency":"MOODENG","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1749193200000,"callauctionSecondStageStartTime":1749196200000,"callauctionThirdStageStartTime":1749196500000,"tradingStartTime":1749196800000},{"symbol":"FET-USDC","name":"FET-USDC","baseCurrency":"FET","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"7.5","callauctionFirstStageStartTime":1749196800000,"callauctionSecondStageStartTime":1749199800000,"callauctionThirdStageStartTime":1749200100000,"tradingStartTime":1749200400000},{"symbol":"KAS-USDC","name":"KAS-USDC","baseCurrency":"KAS","quoteCurrency":"USDC","feeCurrency":"USDC","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.8","callauctionFirstStageStartTime":1749200400000,"callauctionSecondStageStartTime":1749203400000,"callauctionThirdStageStartTime":1749203700000,"tradingStartTime":1749204000000},{"symbol":"FLOCK-USDT","name":"FLOCK-USDT","baseCurrency":"FLOCK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2.1","callauctionFirstStageStartTime":1749202800000,"callauctionSecondStageStartTime":1749203400000,"callauctionThirdStageStartTime":1749203700000,"tradingStartTime":1749204000000},{"symbol":"SKATE-USDT","name":"SKATE-USDT","baseCurrency":"SKATE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"7","callauctionFirstStageStartTime":1749459600000,"callauctionSecondStageStartTime":1749462600000,"callauctionThirdStageStartTime":1749462900000,"tradingStartTime":1749463200000},{"symbol":"HOME-USDT","name":"HOME-USDT","baseCurrency":"HOME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1749549600000,"callauctionSecondStageStartTime":1749552600000,"callauctionThirdStageStartTime":1749552900000,"tradingStartTime":1749553200000},{"symbol":"RESOLV-USDT","name":"RESOLV-USDT","baseCurrency":"RESOLV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1749556800000,"callauctionSecondStageStartTime":1749559800000,"callauctionThirdStageStartTime":1749560100000,"tradingStartTime":1749560400000},{"symbol":"HYPE-KCS","name":"HYPE-KCS","baseCurrency":"HYPE","quoteCurrency":"KCS","feeCurrency":"KCS","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"35","callauctionFirstStageStartTime":1749715200000,"callauctionSecondStageStartTime":1749718200000,"callauctionThirdStageStartTime":1749718500000,"tradingStartTime":1749718800000},{"symbol":"GOMINING-USDT","name":"GOMINING-USDT","baseCurrency":"GOMINING","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.45","callauctionFirstStageStartTime":1750064400000,"callauctionSecondStageStartTime":1750067400000,"callauctionThirdStageStartTime":1750067700000,"tradingStartTime":1750068000000},{"symbol":"SPK-USDT","name":"SPK-USDT","baseCurrency":"SPK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1750147200000,"callauctionSecondStageStartTime":1750150200000,"callauctionThirdStageStartTime":1750150500000,"tradingStartTime":1750150800000},{"symbol":"MAT-USDT","name":"MAT-USDT","baseCurrency":"MAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1750330800000,"callauctionSecondStageStartTime":1750333800000,"callauctionThirdStageStartTime":1750334100000,"tradingStartTime":1750334400000},{"symbol":"H-USDT","name":"H-USDT","baseCurrency":"H","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.1","callauctionFirstStageStartTime":1750838400000,"callauctionSecondStageStartTime":1750841400000,"callauctionThirdStageStartTime":1750841700000,"tradingStartTime":1750842000000},{"symbol":"MGO-USDT","name":"MGO-USDT","baseCurrency":"MGO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1750752000000,"callauctionSecondStageStartTime":1750755000000,"callauctionThirdStageStartTime":1750755300000,"tradingStartTime":1750755600000},{"symbol":"DMC-USDT","name":"DMC-USDT","baseCurrency":"DMC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.25","callauctionFirstStageStartTime":1750759200000,"callauctionSecondStageStartTime":1750762200000,"callauctionThirdStageStartTime":1750762500000,"tradingStartTime":1750762800000},{"symbol":"NEWT-USDT","name":"NEWT-USDT","baseCurrency":"NEWT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1750770000000,"callauctionSecondStageStartTime":1750773000000,"callauctionThirdStageStartTime":1750773300000,"tradingStartTime":1750773600000},{"symbol":"SAHARA-USDT","name":"SAHARA-USDT","baseCurrency":"SAHARA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1750935600000,"callauctionSecondStageStartTime":1750938600000,"callauctionThirdStageStartTime":1750938900000,"tradingStartTime":1750939200000},{"symbol":"XAUT-USDT","name":"XAUT-USDT","baseCurrency":"XAUT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"30000","callauctionFirstStageStartTime":1750845600000,"callauctionSecondStageStartTime":1750848600000,"callauctionThirdStageStartTime":1750848900000,"tradingStartTime":1750849200000},{"symbol":"LOT-USDT","name":"LOT-USDT","baseCurrency":"LOT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1750842000000,"callauctionSecondStageStartTime":1750845000000,"callauctionThirdStageStartTime":1750845300000,"tradingStartTime":1750845600000},{"symbol":"CESS-USDT","name":"CESS-USDT","baseCurrency":"CESS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1750928400000,"callauctionSecondStageStartTime":1750931400000,"callauctionThirdStageStartTime":1750931700000,"tradingStartTime":1750932000000},{"symbol":"NODE-USDT","name":"NODE-USDT","baseCurrency":"NODE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1751274000000,"callauctionSecondStageStartTime":1751277000000,"callauctionThirdStageStartTime":1751277300000,"tradingStartTime":1751277600000},{"symbol":"ECHO-USDT","name":"ECHO-USDT","baseCurrency":"ECHO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1751454000000,"callauctionSecondStageStartTime":1751457000000,"callauctionThirdStageStartTime":1751457300000,"tradingStartTime":1751457600000},{"symbol":"ICNT-USDT","name":"ICNT-USDT","baseCurrency":"ICNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3.58","callauctionFirstStageStartTime":1751533200000,"callauctionSecondStageStartTime":1751536200000,"callauctionThirdStageStartTime":1751536500000,"tradingStartTime":1751536800000},{"symbol":"CROSS-USDT","name":"CROSS-USDT","baseCurrency":"CROSS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1751613300000,"callauctionSecondStageStartTime":1751616300000,"callauctionThirdStageStartTime":1751616600000,"tradingStartTime":1751616900000},{"symbol":"AIN-USDT","name":"AIN-USDT","baseCurrency":"AIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1751706000000,"callauctionSecondStageStartTime":1751709000000,"callauctionThirdStageStartTime":1751709300000,"tradingStartTime":1751709600000},{"symbol":"BULLA-USDT","name":"BULLA-USDT","baseCurrency":"BULLA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.7","callauctionFirstStageStartTime":1751961600000,"callauctionSecondStageStartTime":1751964600000,"callauctionThirdStageStartTime":1751964900000,"tradingStartTime":1751965200000},{"symbol":"BLUM-USDT","name":"BLUM-USDT","baseCurrency":"BLUM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.62","callauctionFirstStageStartTime":1751972400000,"callauctionSecondStageStartTime":1751975400000,"callauctionThirdStageStartTime":1751975700000,"tradingStartTime":1751976000000},{"symbol":"MORI-USDT","name":"MORI-USDT","baseCurrency":"MORI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.7","callauctionFirstStageStartTime":1752138600000,"callauctionSecondStageStartTime":1752141000000,"callauctionThirdStageStartTime":1752141300000,"tradingStartTime":1752141600000},{"symbol":"VELVET-USDT","name":"VELVET-USDT","baseCurrency":"VELVET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4.5","callauctionFirstStageStartTime":1752145200000,"callauctionSecondStageStartTime":1752148200000,"callauctionThirdStageStartTime":1752148500000,"tradingStartTime":1752148800000},{"symbol":"C-USDT","name":"C-USDT","baseCurrency":"C","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1752490800000,"callauctionSecondStageStartTime":1752493800000,"callauctionThirdStageStartTime":1752494100000,"tradingStartTime":1752494400000},{"symbol":"PUMP-USDT","name":"PUMP-USDT","baseCurrency":"PUMP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1752508800000,"callauctionSecondStageStartTime":1752511800000,"callauctionThirdStageStartTime":1752512100000,"tradingStartTime":1752512400000},{"symbol":"VSN-USDT","name":"VSN-USDT","baseCurrency":"VSN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1752663600000,"callauctionSecondStageStartTime":1752666600000,"callauctionThirdStageStartTime":1752666900000,"tradingStartTime":1752667200000},{"symbol":"ES-USDT","name":"ES-USDT","baseCurrency":"ES","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1752656400000,"callauctionSecondStageStartTime":1752659400000,"callauctionThirdStageStartTime":1752659700000,"tradingStartTime":1752660000000},{"symbol":"RION-USDT","name":"RION-USDT","baseCurrency":"RION","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"15","callauctionFirstStageStartTime":1752670800000,"callauctionSecondStageStartTime":1752673800000,"callauctionThirdStageStartTime":1752674100000,"tradingStartTime":1752674400000},{"symbol":"TRN-USDT","name":"TRN-USDT","baseCurrency":"TRN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.000001","priceLimitRate":"0.1","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1752768000000,"callauctionSecondStageStartTime":1752771000000,"callauctionThirdStageStartTime":1752771300000,"tradingStartTime":1752771600000},{"symbol":"ERA-USDT","name":"ERA-USDT","baseCurrency":"ERA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1752762600000,"callauctionSecondStageStartTime":1752765600000,"callauctionThirdStageStartTime":1752765900000,"tradingStartTime":1752766200000},{"symbol":"MANYU-USDT","name":"MANYU-USDT","baseCurrency":"MANYU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000000","quoteMinSize":"0.1","baseMaxSize":"10000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00000000001","priceIncrement":"0.00000000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00000000001","callauctionPriceCeiling":"0.0000003","callauctionFirstStageStartTime":1752832800000,"callauctionSecondStageStartTime":1752835800000,"callauctionThirdStageStartTime":1752836100000,"tradingStartTime":1752836400000},{"symbol":"ZKWASM-USDT","name":"ZKWASM-USDT","baseCurrency":"ZKWASM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1753182000000,"callauctionSecondStageStartTime":1753185000000,"callauctionThirdStageStartTime":1753185300000,"tradingStartTime":1753185600000},{"symbol":"ASP-USDT","name":"ASP-USDT","baseCurrency":"ASP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1753354800000,"callauctionSecondStageStartTime":1753357800000,"callauctionThirdStageStartTime":1753358100000,"tradingStartTime":1753358400000},{"symbol":"XNY-USDT","name":"XNY-USDT","baseCurrency":"XNY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1753272000000,"callauctionSecondStageStartTime":1753275000000,"callauctionThirdStageStartTime":1753275300000,"tradingStartTime":1753275600000},{"symbol":"XU3O8-USDT","name":"XU3O8-USDT","baseCurrency":"XU3O8","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"6","callauctionFirstStageStartTime":1753340400000,"callauctionSecondStageStartTime":1753343400000,"callauctionThirdStageStartTime":1753343700000,"tradingStartTime":1753344000000},{"symbol":"ELP-USDT","name":"ELP-USDT","baseCurrency":"ELP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.57","callauctionFirstStageStartTime":1753354800000,"callauctionSecondStageStartTime":1753357800000,"callauctionThirdStageStartTime":1753358100000,"tradingStartTime":1753358400000},{"symbol":"A47-USDT","name":"A47-USDT","baseCurrency":"A47","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.25","callauctionFirstStageStartTime":1753693200000,"callauctionSecondStageStartTime":1753696200000,"callauctionThirdStageStartTime":1753696500000,"tradingStartTime":1753696800000},{"symbol":"URANUS-USDT","name":"URANUS-USDT","baseCurrency":"URANUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4.7","callauctionFirstStageStartTime":1753700400000,"callauctionSecondStageStartTime":1753703400000,"callauctionThirdStageStartTime":1753703700000,"tradingStartTime":1753704000000},{"symbol":"TREE-USDT","name":"TREE-USDT","baseCurrency":"TREE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1753794000000,"callauctionSecondStageStartTime":1753797000000,"callauctionThirdStageStartTime":1753797300000,"tradingStartTime":1753797600000},{"symbol":"IKA-USDT","name":"IKA-USDT","baseCurrency":"IKA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.25","callauctionFirstStageStartTime":1753779600000,"callauctionSecondStageStartTime":1753782600000,"callauctionThirdStageStartTime":1753782900000,"tradingStartTime":1753783200000},{"symbol":"GAIA-USDT","name":"GAIA-USDT","baseCurrency":"GAIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1753862400000,"callauctionSecondStageStartTime":1753865400000,"callauctionThirdStageStartTime":1753865700000,"tradingStartTime":1753866000000},{"symbol":"NOBODY-USDT","name":"NOBODY-USDT","baseCurrency":"NOBODY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.3","callauctionFirstStageStartTime":1753956000000,"callauctionSecondStageStartTime":1753959000000,"callauctionThirdStageStartTime":1753959300000,"tradingStartTime":1753959600000},{"symbol":"A2Z-USDT","name":"A2Z-USDT","baseCurrency":"A2Z","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.04","callauctionFirstStageStartTime":1754035200000,"callauctionSecondStageStartTime":1754038200000,"callauctionThirdStageStartTime":1754038500000,"tradingStartTime":1754038800000},{"symbol":"AIO-USDT","name":"AIO-USDT","baseCurrency":"AIO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1754128800000,"callauctionSecondStageStartTime":1754131800000,"callauctionThirdStageStartTime":1754132100000,"tradingStartTime":1754132400000},{"symbol":"SUP-USDT","name":"SUP-USDT","baseCurrency":"SUP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1754388000000,"callauctionSecondStageStartTime":1754391000000,"callauctionThirdStageStartTime":1754391300000,"tradingStartTime":1754391600000},{"symbol":"TOWNS-USDT","name":"TOWNS-USDT","baseCurrency":"TOWNS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.79","callauctionFirstStageStartTime":1754400600000,"callauctionSecondStageStartTime":1754403600000,"callauctionThirdStageStartTime":1754403900000,"tradingStartTime":1754404200000},{"symbol":"PROVE-USDT","name":"PROVE-USDT","baseCurrency":"PROVE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1754409600000,"callauctionSecondStageStartTime":1754412600000,"callauctionThirdStageStartTime":1754412900000,"tradingStartTime":1754413200000},{"symbol":"PEPE-KCS","name":"PEPE-KCS","baseCurrency":"PEPE","quoteCurrency":"KCS","feeCurrency":"KCS","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.001","baseMaxSize":"60000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.08","minFunds":"0.001","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000000001","callauctionPriceCeiling":"0.00001","callauctionFirstStageStartTime":1754550000000,"callauctionSecondStageStartTime":1754553000000,"callauctionThirdStageStartTime":1754553300000,"tradingStartTime":1754553600000},{"symbol":"IN-USDT","name":"IN-USDT","baseCurrency":"IN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1754557200000,"callauctionSecondStageStartTime":1754560200000,"callauctionThirdStageStartTime":1754560500000,"tradingStartTime":1754560800000},{"symbol":"DSYNC-USDT","name":"DSYNC-USDT","baseCurrency":"DSYNC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1754902800000,"callauctionSecondStageStartTime":1754905800000,"callauctionThirdStageStartTime":1754906100000,"tradingStartTime":1754906400000},{"symbol":"SNEK-USDT","name":"SNEK-USDT","baseCurrency":"SNEK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.045","callauctionFirstStageStartTime":1755007200000,"callauctionSecondStageStartTime":1755010200000,"callauctionThirdStageStartTime":1755010500000,"tradingStartTime":1755010800000},{"symbol":"WAI-USDT","name":"WAI-USDT","baseCurrency":"WAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1754985600000,"callauctionSecondStageStartTime":1754988600000,"callauctionThirdStageStartTime":1754988900000,"tradingStartTime":1754989200000},{"symbol":"PROPS-USDT","name":"PROPS-USDT","baseCurrency":"PROPS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.35","callauctionFirstStageStartTime":1755079200000,"callauctionSecondStageStartTime":1755082200000,"callauctionThirdStageStartTime":1755082500000,"tradingStartTime":1755082800000},{"symbol":"PUBLIC-USDT","name":"PUBLIC-USDT","baseCurrency":"PUBLIC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1755243000000,"callauctionSecondStageStartTime":1755246000000,"callauctionThirdStageStartTime":1755246300000,"tradingStartTime":1755246600000},{"symbol":"EGL1-USDT","name":"EGL1-USDT","baseCurrency":"EGL1","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.77","callauctionFirstStageStartTime":1755594000000,"callauctionSecondStageStartTime":1755597000000,"callauctionThirdStageStartTime":1755597300000,"tradingStartTime":1755597600000},{"symbol":"ALKIMI-USDT","name":"ALKIMI-USDT","baseCurrency":"ALKIMI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.82","callauctionFirstStageStartTime":1755597600000,"callauctionSecondStageStartTime":1755600600000,"callauctionThirdStageStartTime":1755600900000,"tradingStartTime":1755601200000},{"symbol":"BLOCKST-USD1","name":"BLOCKST-USD1","baseCurrency":"BLOCKST","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1755687600000,"callauctionSecondStageStartTime":1755690600000,"callauctionThirdStageStartTime":1755690900000,"tradingStartTime":1755691200000},{"symbol":"SAPIEN-USDT","name":"SAPIEN-USDT","baseCurrency":"SAPIEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1755705600000,"callauctionSecondStageStartTime":1755708600000,"callauctionThirdStageStartTime":1755708900000,"tradingStartTime":1755709200000},{"symbol":"AKE-USDT","name":"AKE-USDT","baseCurrency":"AKE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.04","callauctionFirstStageStartTime":1755774000000,"callauctionSecondStageStartTime":1755777000000,"callauctionThirdStageStartTime":1755777300000,"tradingStartTime":1755777600000},{"symbol":"ARIA-USDT","name":"ARIA-USDT","baseCurrency":"ARIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1755777600000,"callauctionSecondStageStartTime":1755780600000,"callauctionThirdStageStartTime":1755780900000,"tradingStartTime":1755781200000},{"symbol":"BAS-USDT","name":"BAS-USDT","baseCurrency":"BAS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.13","callauctionFirstStageStartTime":1755759600000,"callauctionSecondStageStartTime":1755762600000,"callauctionThirdStageStartTime":1755762900000,"tradingStartTime":1755763200000},{"symbol":"YZY-USDT","name":"YZY-USDT","baseCurrency":"YZY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"20","callauctionFirstStageStartTime":1755752400000,"callauctionSecondStageStartTime":1755755400000,"callauctionThirdStageStartTime":1755755700000,"tradingStartTime":1755756000000},{"symbol":"XPIN-USDT","name":"XPIN-USDT","baseCurrency":"XPIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.03","callauctionFirstStageStartTime":1755867600000,"callauctionSecondStageStartTime":1755870600000,"callauctionThirdStageStartTime":1755870900000,"tradingStartTime":1755871200000},{"symbol":"BERT-USDT","name":"BERT-USDT","baseCurrency":"BERT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.7","callauctionFirstStageStartTime":1755856800000,"callauctionSecondStageStartTime":1755859800000,"callauctionThirdStageStartTime":1755860100000,"tradingStartTime":1755860400000},{"symbol":"BTR-USDT","name":"BTR-USDT","baseCurrency":"BTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1756288800000,"callauctionSecondStageStartTime":1756291800000,"callauctionThirdStageStartTime":1756292100000,"tradingStartTime":1756292400000},{"symbol":"AI3-USDT","name":"AI3-USDT","baseCurrency":"AI3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1756299600000,"callauctionSecondStageStartTime":1756302600000,"callauctionThirdStageStartTime":1756302900000,"tradingStartTime":1756303200000},{"symbol":"CAMP-USDT","name":"CAMP-USDT","baseCurrency":"CAMP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1756281600000,"callauctionSecondStageStartTime":1756284600000,"callauctionThirdStageStartTime":1756284900000,"tradingStartTime":1756285200000},{"symbol":"BTC-USD1","name":"BTC-USD1","baseCurrency":"BTC","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"0.000001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.000001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"153300","callauctionFirstStageStartTime":1756710000000,"callauctionSecondStageStartTime":1756713000000,"callauctionThirdStageStartTime":1756713300000,"tradingStartTime":1756713600000},{"symbol":"ETH-USD1","name":"ETH-USD1","baseCurrency":"ETH","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"6600","callauctionFirstStageStartTime":1756713600000,"callauctionSecondStageStartTime":1756716600000,"callauctionThirdStageStartTime":1756716900000,"tradingStartTime":1756717200000},{"symbol":"KORI-USDT","name":"KORI-USDT","baseCurrency":"KORI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.152","callauctionFirstStageStartTime":1756458000000,"callauctionSecondStageStartTime":1756461000000,"callauctionThirdStageStartTime":1756461300000,"tradingStartTime":1756461600000},{"symbol":"XLAB-USDT","name":"XLAB-USDT","baseCurrency":"XLAB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"1000000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000000001","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000000001","callauctionPriceCeiling":"0.0005","callauctionFirstStageStartTime":1756448100000,"callauctionSecondStageStartTime":1756451100000,"callauctionThirdStageStartTime":1756451400000,"tradingStartTime":1756451700000},{"symbol":"WLFI-USDT","name":"WLFI-USDT","baseCurrency":"WLFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.03","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"25","callauctionFirstStageStartTime":1756728000000,"callauctionSecondStageStartTime":1756731000000,"callauctionThirdStageStartTime":1756731300000,"tradingStartTime":1756731600000},{"symbol":"WLFI-USD1","name":"WLFI-USD1","baseCurrency":"WLFI","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"25","callauctionFirstStageStartTime":1756728000000,"callauctionSecondStageStartTime":1756731000000,"callauctionThirdStageStartTime":1756731300000,"tradingStartTime":1756731600000},{"symbol":"Q-USDT","name":"Q-USDT","baseCurrency":"Q","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1756796400000,"callauctionSecondStageStartTime":1756799400000,"callauctionThirdStageStartTime":1756799700000,"tradingStartTime":1756800000000},{"symbol":"SOMI-USDT","name":"SOMI-USDT","baseCurrency":"SOMI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"70","callauctionFirstStageStartTime":1756819800000,"callauctionSecondStageStartTime":1756822800000,"callauctionThirdStageStartTime":1756823100000,"tradingStartTime":1756823400000},{"symbol":"PTB-USDT","name":"PTB-USDT","baseCurrency":"PTB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1756900800000,"callauctionSecondStageStartTime":1756903800000,"callauctionThirdStageStartTime":1756904100000,"tradingStartTime":1756904400000},{"symbol":"U-USDT","name":"U-USDT","baseCurrency":"U","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1756972800000,"callauctionSecondStageStartTime":1756975800000,"callauctionThirdStageStartTime":1756976100000,"tradingStartTime":1756976400000},{"symbol":"RARI-USDT","name":"RARI-USDT","baseCurrency":"RARI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1756987200000,"callauctionSecondStageStartTime":1756990200000,"callauctionThirdStageStartTime":1756990500000,"tradingStartTime":1756990800000},{"symbol":"EGL1-USD1","name":"EGL1-USD1","baseCurrency":"EGL1","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.08","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.45","callauctionFirstStageStartTime":1756980000000,"callauctionSecondStageStartTime":1756983000000,"callauctionThirdStageStartTime":1756983300000,"tradingStartTime":1756983600000},{"symbol":"ART-USDT","name":"ART-USDT","baseCurrency":"ART","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.08","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1757415600000,"callauctionSecondStageStartTime":1757418600000,"callauctionThirdStageStartTime":1757418900000,"tradingStartTime":1757419200000},{"symbol":"OPEN-USDT","name":"OPEN-USDT","baseCurrency":"OPEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1757332800000,"callauctionSecondStageStartTime":1757335800000,"callauctionThirdStageStartTime":1757336100000,"tradingStartTime":1757336400000},{"symbol":"AVNT-USDT","name":"AVNT-USDT","baseCurrency":"AVNT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3.5","callauctionFirstStageStartTime":1757422800000,"callauctionSecondStageStartTime":1757425800000,"callauctionThirdStageStartTime":1757426100000,"tradingStartTime":1757426400000},{"symbol":"SWTCH-USDT","name":"SWTCH-USDT","baseCurrency":"SWTCH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1757419200000,"callauctionSecondStageStartTime":1757422200000,"callauctionThirdStageStartTime":1757422500000,"tradingStartTime":1757422800000},{"symbol":"LINEA-USDT","name":"LINEA-USDT","baseCurrency":"LINEA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1757512800000,"callauctionSecondStageStartTime":1757515800000,"callauctionThirdStageStartTime":1757516100000,"tradingStartTime":1757516400000},{"symbol":"XRP-USD1","name":"XRP-USD1","baseCurrency":"XRP","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1757574000000,"callauctionSecondStageStartTime":1757577000000,"callauctionThirdStageStartTime":1757577300000,"tradingStartTime":1757577600000},{"symbol":"SOL-USD1","name":"SOL-USD1","baseCurrency":"SOL","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"675","callauctionFirstStageStartTime":1757574000000,"callauctionSecondStageStartTime":1757577000000,"callauctionThirdStageStartTime":1757577300000,"tradingStartTime":1757577600000},{"symbol":"ADA-USD1","name":"ADA-USD1","baseCurrency":"ADA","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1757574000000,"callauctionSecondStageStartTime":1757577000000,"callauctionThirdStageStartTime":1757577300000,"tradingStartTime":1757577600000},{"symbol":"TRUMP-USD1","name":"TRUMP-USD1","baseCurrency":"TRUMP","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"26","callauctionFirstStageStartTime":1757577600000,"callauctionSecondStageStartTime":1757580600000,"callauctionThirdStageStartTime":1757580900000,"tradingStartTime":1757581200000},{"symbol":"DOGE-USD1","name":"DOGE-USD1","baseCurrency":"DOGE","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.75","callauctionFirstStageStartTime":1757577600000,"callauctionSecondStageStartTime":1757580600000,"callauctionThirdStageStartTime":1757580900000,"tradingStartTime":1757581200000},{"symbol":"POP-USDT","name":"POP-USDT","baseCurrency":"POP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.1","callauctionFirstStageStartTime":1757502000000,"callauctionSecondStageStartTime":1757505000000,"callauctionThirdStageStartTime":1757505300000,"tradingStartTime":1757505600000},{"symbol":"HOLO-USDT","name":"HOLO-USDT","baseCurrency":"HOLO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1757588400000,"callauctionSecondStageStartTime":1757591400000,"callauctionThirdStageStartTime":1757591700000,"tradingStartTime":1757592000000},{"symbol":"UB-USDT","name":"UB-USDT","baseCurrency":"UB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.3","callauctionFirstStageStartTime":1757664000000,"callauctionSecondStageStartTime":1757667000000,"callauctionThirdStageStartTime":1757667300000,"tradingStartTime":1757667600000},{"symbol":"ZKC-USDT","name":"ZKC-USDT","baseCurrency":"ZKC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1757941200000,"callauctionSecondStageStartTime":1757944200000,"callauctionThirdStageStartTime":1757944500000,"tradingStartTime":1757944800000},{"symbol":"COLS-USDT","name":"COLS-USDT","baseCurrency":"COLS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.3","callauctionFirstStageStartTime":1757916000000,"callauctionSecondStageStartTime":1757919000000,"callauctionThirdStageStartTime":1757919300000,"tradingStartTime":1757919600000},{"symbol":"XL1-USDT","name":"XL1-USDT","baseCurrency":"XL1","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.0395","callauctionFirstStageStartTime":1758024000000,"callauctionSecondStageStartTime":1758027000000,"callauctionThirdStageStartTime":1758027300000,"tradingStartTime":1758027600000},{"symbol":"VLR-USDT","name":"VLR-USDT","baseCurrency":"VLR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.125","callauctionFirstStageStartTime":1758020400000,"callauctionSecondStageStartTime":1758023400000,"callauctionThirdStageStartTime":1758023700000,"tradingStartTime":1758024000000},{"symbol":"PORTALS-USDT","name":"PORTALS-USDT","baseCurrency":"PORTALS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1758020400000,"callauctionSecondStageStartTime":1758023400000,"callauctionThirdStageStartTime":1758023700000,"tradingStartTime":1758024000000},{"symbol":"MAIGA-USDT","name":"MAIGA-USDT","baseCurrency":"MAIGA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1758106800000,"callauctionSecondStageStartTime":1758109800000,"callauctionThirdStageStartTime":1758110100000,"tradingStartTime":1758110400000},{"symbol":"BARD-USDT","name":"BARD-USDT","baseCurrency":"BARD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5.3","callauctionFirstStageStartTime":1758783600000,"callauctionSecondStageStartTime":1758786600000,"callauctionThirdStageStartTime":1758786900000,"tradingStartTime":1758787200000},{"symbol":"NUMI-USDT","name":"NUMI-USDT","baseCurrency":"NUMI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.2","callauctionFirstStageStartTime":1758438000000,"callauctionSecondStageStartTime":1758441000000,"callauctionThirdStageStartTime":1758441300000,"tradingStartTime":1758441600000},{"symbol":"SYND-USDT","name":"SYND-USDT","baseCurrency":"SYND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1758304800000,"callauctionSecondStageStartTime":1758307800000,"callauctionThirdStageStartTime":1758308100000,"tradingStartTime":1758308400000},{"symbol":"0G-USDT","name":"0G-USDT","baseCurrency":"0G","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1758531600000,"callauctionSecondStageStartTime":1758534600000,"callauctionThirdStageStartTime":1758534900000,"tradingStartTime":1758535200000},{"symbol":"XAN-USDT","name":"XAN-USDT","baseCurrency":"XAN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.4","callauctionFirstStageStartTime":1759136400000,"callauctionSecondStageStartTime":1759139400000,"callauctionThirdStageStartTime":1759139700000,"tradingStartTime":1759140000000},{"symbol":"GAIN-USDT","name":"GAIN-USDT","baseCurrency":"GAIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.045","callauctionFirstStageStartTime":1760428800000,"callauctionSecondStageStartTime":1760431800000,"callauctionThirdStageStartTime":1760432100000,"tradingStartTime":1760432400000},{"symbol":"ASTER-USDT","name":"ASTER-USDT","baseCurrency":"ASTER","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":true,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1758700800000,"callauctionSecondStageStartTime":1758703800000,"callauctionThirdStageStartTime":1758704100000,"tradingStartTime":1758704400000},{"symbol":"PIN-USDT","name":"PIN-USDT","baseCurrency":"PIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2.3","callauctionFirstStageStartTime":1758711600000,"callauctionSecondStageStartTime":1758714600000,"callauctionThirdStageStartTime":1758714900000,"tradingStartTime":1758715200000},{"symbol":"XPL-USDT","name":"XPL-USDT","baseCurrency":"XPL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1758801600000,"callauctionSecondStageStartTime":1758804600000,"callauctionThirdStageStartTime":1758804900000,"tradingStartTime":1758805200000},{"symbol":"STBL-USDT","name":"STBL-USDT","baseCurrency":"STBL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5.7","callauctionFirstStageStartTime":1758783600000,"callauctionSecondStageStartTime":1758786600000,"callauctionThirdStageStartTime":1758786900000,"tradingStartTime":1758787200000},{"symbol":"HANA-USDT","name":"HANA-USDT","baseCurrency":"HANA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1758888000000,"callauctionSecondStageStartTime":1758891000000,"callauctionThirdStageStartTime":1758891300000,"tradingStartTime":1758891600000},{"symbol":"MIRA-USDT","name":"MIRA-USDT","baseCurrency":"MIRA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1758884400000,"callauctionSecondStageStartTime":1758887400000,"callauctionThirdStageStartTime":1758887700000,"tradingStartTime":1758888000000},{"symbol":"LIGHT-USDT","name":"LIGHT-USDT","baseCurrency":"LIGHT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"20.4","callauctionFirstStageStartTime":1758974400000,"callauctionSecondStageStartTime":1758977400000,"callauctionThirdStageStartTime":1758977700000,"tradingStartTime":1758978000000},{"symbol":"VFY-USDT","name":"VFY-USDT","baseCurrency":"VFY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1759230000000,"callauctionSecondStageStartTime":1759233000000,"callauctionThirdStageStartTime":1759233300000,"tradingStartTime":1759233600000},{"symbol":"FF-USDT","name":"FF-USDT","baseCurrency":"FF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1759147200000,"callauctionSecondStageStartTime":1759150200000,"callauctionThirdStageStartTime":1759150500000,"tradingStartTime":1759150800000},{"symbol":"EDEN-USDT","name":"EDEN-USDT","baseCurrency":"EDEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1759226400000,"callauctionSecondStageStartTime":1759229400000,"callauctionThirdStageStartTime":1759229700000,"tradingStartTime":1759230000000},{"symbol":"TRUTH-USDT","name":"TRUTH-USDT","baseCurrency":"TRUTH","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1759320000000,"callauctionSecondStageStartTime":1759323000000,"callauctionThirdStageStartTime":1759323300000,"tradingStartTime":1759323600000},{"symbol":"2Z-USDT","name":"2Z-USDT","baseCurrency":"2Z","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1759406400000,"callauctionSecondStageStartTime":1759409400000,"callauctionThirdStageStartTime":1759409700000,"tradingStartTime":1759410000000},{"symbol":"P-USDT","name":"P-USDT","baseCurrency":"P","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1759489200000,"callauctionSecondStageStartTime":1759492200000,"callauctionThirdStageStartTime":1759492500000,"tradingStartTime":1759492800000},{"symbol":"CYPR-USDT","name":"CYPR-USDT","baseCurrency":"CYPR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1759654800000,"callauctionSecondStageStartTime":1759657800000,"callauctionThirdStageStartTime":1759658100000,"tradingStartTime":1759658400000},{"symbol":"MF-USDT","name":"MF-USDT","baseCurrency":"MF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1759755600000,"callauctionSecondStageStartTime":1759758600000,"callauctionThirdStageStartTime":1759758900000,"tradingStartTime":1759759200000},{"symbol":"LYN-USDT","name":"LYN-USDT","baseCurrency":"LYN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1759730400000,"callauctionSecondStageStartTime":1759733400000,"callauctionThirdStageStartTime":1759733700000,"tradingStartTime":1759734000000},{"symbol":"KGEN-USDT","name":"KGEN-USDT","baseCurrency":"KGEN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1759845600000,"callauctionSecondStageStartTime":1759848600000,"callauctionThirdStageStartTime":1759848900000,"tradingStartTime":1759849200000},{"symbol":"KLINK-USDT","name":"KLINK-USDT","baseCurrency":"KLINK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1759831200000,"callauctionSecondStageStartTime":1759834200000,"callauctionThirdStageStartTime":1759834500000,"tradingStartTime":1759834800000},{"symbol":"PIPE-USDT","name":"PIPE-USDT","baseCurrency":"PIPE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1759932000000,"callauctionSecondStageStartTime":1759935000000,"callauctionThirdStageStartTime":1759935300000,"tradingStartTime":1759935600000},{"symbol":"GIGGLE-USDT","name":"GIGGLE-USDT","baseCurrency":"GIGGLE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"270","callauctionFirstStageStartTime":1760086800000,"callauctionSecondStageStartTime":1760089800000,"callauctionThirdStageStartTime":1760090100000,"tradingStartTime":1760090400000},{"symbol":"CLO-USDT","name":"CLO-USDT","baseCurrency":"CLO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1760443200000,"callauctionSecondStageStartTime":1760446200000,"callauctionThirdStageStartTime":1760446500000,"tradingStartTime":1760446800000},{"symbol":"LAB-USDT","name":"LAB-USDT","baseCurrency":"LAB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1760439600000,"callauctionSecondStageStartTime":1760442600000,"callauctionThirdStageStartTime":1760442900000,"tradingStartTime":1760443200000},{"symbol":"FLK-USDT","name":"FLK-USDT","baseCurrency":"FLK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"6","callauctionFirstStageStartTime":1760439600000,"callauctionSecondStageStartTime":1760442600000,"callauctionThirdStageStartTime":1760442900000,"tradingStartTime":1760443200000},{"symbol":"ANOME-USDT","name":"ANOME-USDT","baseCurrency":"ANOME","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1760691600000,"callauctionSecondStageStartTime":1760694600000,"callauctionThirdStageStartTime":1760694900000,"tradingStartTime":1760695200000},{"symbol":"ENSO-USDT","name":"ENSO-USDT","baseCurrency":"ENSO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1760428800000,"callauctionSecondStageStartTime":1760431800000,"callauctionThirdStageStartTime":1760432100000,"tradingStartTime":1760432400000},{"symbol":"NOM-USDT","name":"NOM-USDT","baseCurrency":"NOM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.056","callauctionFirstStageStartTime":1760443200000,"callauctionSecondStageStartTime":1760446200000,"callauctionThirdStageStartTime":1760446500000,"tradingStartTime":1760446800000},{"symbol":"WBAI-USDT","name":"WBAI-USDT","baseCurrency":"WBAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1760526000000,"callauctionSecondStageStartTime":1760529000000,"callauctionThirdStageStartTime":1760529300000,"tradingStartTime":1760529600000},{"symbol":"RECALL-USDT","name":"RECALL-USDT","baseCurrency":"RECALL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1760526300000,"callauctionSecondStageStartTime":1760529300000,"callauctionThirdStageStartTime":1760529600000,"tradingStartTime":1760529900000},{"symbol":"YB-USDT","name":"YB-USDT","baseCurrency":"YB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1760522400000,"callauctionSecondStageStartTime":1760525400000,"callauctionThirdStageStartTime":1760525700000,"tradingStartTime":1760526000000},{"symbol":"XMN-USDT","name":"XMN-USDT","baseCurrency":"XMN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.12","callauctionFirstStageStartTime":1760515200000,"callauctionSecondStageStartTime":1760518200000,"callauctionThirdStageStartTime":1760518500000,"tradingStartTime":1760518800000},{"symbol":"ZBT-USDT","name":"ZBT-USDT","baseCurrency":"ZBT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"7.5","callauctionFirstStageStartTime":1760702400000,"callauctionSecondStageStartTime":1760705400000,"callauctionThirdStageStartTime":1760705700000,"tradingStartTime":1760706000000},{"symbol":"RVV-USDT","name":"RVV-USDT","baseCurrency":"RVV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.3","callauctionFirstStageStartTime":1760792400000,"callauctionSecondStageStartTime":1760795400000,"callauctionThirdStageStartTime":1760795700000,"tradingStartTime":1760796000000},{"symbol":"BLUAI-USDT","name":"BLUAI-USDT","baseCurrency":"BLUAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1761044400000,"callauctionSecondStageStartTime":1761047400000,"callauctionThirdStageStartTime":1761047700000,"tradingStartTime":1761048000000},{"symbol":"TURTLE-USDT","name":"TURTLE-USDT","baseCurrency":"TURTLE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1761141600000,"callauctionSecondStageStartTime":1761144600000,"callauctionThirdStageStartTime":1761144900000,"tradingStartTime":1761145200000},{"symbol":"MET-USDT","name":"MET-USDT","baseCurrency":"MET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"25","callauctionFirstStageStartTime":1761224400000,"callauctionSecondStageStartTime":1761227400000,"callauctionThirdStageStartTime":1761227700000,"tradingStartTime":1761228000000},{"symbol":"LMTS-USDT","name":"LMTS-USDT","baseCurrency":"LMTS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1761206400000,"callauctionSecondStageStartTime":1761209400000,"callauctionThirdStageStartTime":1761209700000,"tradingStartTime":1761210000000},{"symbol":"COMMON-USDT","name":"COMMON-USDT","baseCurrency":"COMMON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1761566400000,"callauctionSecondStageStartTime":1761569400000,"callauctionThirdStageStartTime":1761569700000,"tradingStartTime":1761570000000},{"symbol":"IAG-USDT","name":"IAG-USDT","baseCurrency":"IAG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.32","callauctionFirstStageStartTime":1761656400000,"callauctionSecondStageStartTime":1761659400000,"callauctionThirdStageStartTime":1761659700000,"tradingStartTime":1761660000000},{"symbol":"PIGGY-USDT","name":"PIGGY-USDT","baseCurrency":"PIGGY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.155","callauctionFirstStageStartTime":1769752800000,"callauctionSecondStageStartTime":1769755800000,"callauctionThirdStageStartTime":1769756100000,"tradingStartTime":1769756400000},{"symbol":"EAT-USDT","name":"EAT-USDT","baseCurrency":"EAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.75","callauctionFirstStageStartTime":1761739200000,"callauctionSecondStageStartTime":1761742200000,"callauctionThirdStageStartTime":1761742500000,"tradingStartTime":1761742800000},{"symbol":"BOS-USDT","name":"BOS-USDT","baseCurrency":"BOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.475","callauctionFirstStageStartTime":1761735600000,"callauctionSecondStageStartTime":1761738600000,"callauctionThirdStageStartTime":1761738900000,"tradingStartTime":1761739200000},{"symbol":"KBEAT-USDT","name":"KBEAT-USDT","baseCurrency":"KBEAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1761987600000,"callauctionSecondStageStartTime":1761990600000,"callauctionThirdStageStartTime":1761990900000,"tradingStartTime":1761991200000},{"symbol":"KITE-USDT","name":"KITE-USDT","baseCurrency":"KITE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1762171200000,"callauctionSecondStageStartTime":1762174200000,"callauctionThirdStageStartTime":1762174500000,"tradingStartTime":1762174800000},{"symbol":"TEAFI-USDT","name":"TEAFI-USDT","baseCurrency":"TEAFI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1769677200000,"callauctionSecondStageStartTime":1769680200000,"callauctionThirdStageStartTime":1769680500000,"tradingStartTime":1769680800000},{"symbol":"PLAI-USDT","name":"PLAI-USDT","baseCurrency":"PLAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1762254000000,"callauctionSecondStageStartTime":1762257000000,"callauctionThirdStageStartTime":1762257300000,"tradingStartTime":1762257600000},{"symbol":"MMT-USDT","name":"MMT-USDT","baseCurrency":"MMT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1762254000000,"callauctionSecondStageStartTime":1762257000000,"callauctionThirdStageStartTime":1762257300000,"tradingStartTime":1762257600000},{"symbol":"TRUST-USDT","name":"TRUST-USDT","baseCurrency":"TRUST","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1762336800000,"callauctionSecondStageStartTime":1762339800000,"callauctionThirdStageStartTime":1762340100000,"tradingStartTime":1762340400000},{"symbol":"UAI-USDT","name":"UAI-USDT","baseCurrency":"UAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"1000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1762430400000,"callauctionSecondStageStartTime":1762433400000,"callauctionThirdStageStartTime":1762433700000,"tradingStartTime":1762434000000},{"symbol":"FOLKS-USDT","name":"FOLKS-USDT","baseCurrency":"FOLKS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"100","callauctionFirstStageStartTime":1762430400000,"callauctionSecondStageStartTime":1762433400000,"callauctionThirdStageStartTime":1762433700000,"tradingStartTime":1762434000000},{"symbol":"CC-USDT","name":"CC-USDT","baseCurrency":"CC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"7.5","callauctionFirstStageStartTime":1762754400000,"callauctionSecondStageStartTime":1762757400000,"callauctionThirdStageStartTime":1762757700000,"tradingStartTime":1762758000000},{"symbol":"EQTY-USDT","name":"EQTY-USDT","baseCurrency":"EQTY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.018","callauctionFirstStageStartTime":1762761600000,"callauctionSecondStageStartTime":1762764600000,"callauctionThirdStageStartTime":1762764900000,"tradingStartTime":1762765200000},{"symbol":"ELIZAOS-USDT","name":"ELIZAOS-USDT","baseCurrency":"ELIZAOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.026","callauctionFirstStageStartTime":1762768800000,"callauctionSecondStageStartTime":1762771800000,"callauctionThirdStageStartTime":1762772100000,"tradingStartTime":1762772400000},{"symbol":"APR-USDT","name":"APR-USDT","baseCurrency":"APR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"0.85","callauctionFirstStageStartTime":1762765200000,"callauctionSecondStageStartTime":1762768200000,"callauctionThirdStageStartTime":1762768500000,"tradingStartTime":1762768800000},{"symbol":"JCT-USDT","name":"JCT-USDT","baseCurrency":"JCT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.1","callauctionFirstStageStartTime":1762772400000,"callauctionSecondStageStartTime":1762775400000,"callauctionThirdStageStartTime":1762775700000,"tradingStartTime":1762776000000},{"symbol":"ALLO-USDT","name":"ALLO-USDT","baseCurrency":"ALLO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"12.5","callauctionFirstStageStartTime":1762862400000,"callauctionSecondStageStartTime":1762865400000,"callauctionThirdStageStartTime":1762865700000,"tradingStartTime":1762866000000},{"symbol":"PUNDIAI-USDT","name":"PUNDIAI-USDT","baseCurrency":"PUNDIAI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2.55","callauctionFirstStageStartTime":1763103600000,"callauctionSecondStageStartTime":1763106600000,"callauctionThirdStageStartTime":1763106900000,"tradingStartTime":1763107200000},{"symbol":"SUT-USDT","name":"SUT-USDT","baseCurrency":"SUT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1763542800000,"callauctionSecondStageStartTime":1763545800000,"callauctionThirdStageStartTime":1763546100000,"tradingStartTime":1763546400000},{"symbol":"BOB-USDT","name":"BOB-USDT","baseCurrency":"BOB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1763643600000,"callauctionSecondStageStartTime":1763646600000,"callauctionThirdStageStartTime":1763646900000,"tradingStartTime":1763647200000},{"symbol":"PLAY-USDT","name":"PLAY-USDT","baseCurrency":"PLAY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"100000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.27","callauctionFirstStageStartTime":1763715600000,"callauctionSecondStageStartTime":1763718600000,"callauctionThirdStageStartTime":1763718900000,"tradingStartTime":1763719200000},{"symbol":"MON-USDT","name":"MON-USDT","baseCurrency":"MON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1763992800000,"callauctionSecondStageStartTime":1763995800000,"callauctionThirdStageStartTime":1763996100000,"tradingStartTime":1763996400000},{"symbol":"IRYS-USDT","name":"IRYS-USDT","baseCurrency":"IRYS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1764072000000,"callauctionSecondStageStartTime":1764075000000,"callauctionThirdStageStartTime":1764075300000,"tradingStartTime":1764075600000},{"symbol":"USDG-USDT","name":"USDG-USDT","baseCurrency":"USDG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1.2","callauctionFirstStageStartTime":1764147600000,"callauctionSecondStageStartTime":1764150600000,"callauctionThirdStageStartTime":1764150900000,"tradingStartTime":1764151200000},{"symbol":"BTC-USDG","name":"BTC-USDG","baseCurrency":"BTC","quoteCurrency":"USDG","feeCurrency":"USDG","market":"USDS","baseMinSize":"0.00001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.00001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"105000","callauctionFirstStageStartTime":1764147600000,"callauctionSecondStageStartTime":1764150600000,"callauctionThirdStageStartTime":1764150900000,"tradingStartTime":1764151200000},{"symbol":"SEEK-USDT","name":"SEEK-USDT","baseCurrency":"SEEK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":true,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"30","callauctionFirstStageStartTime":1764932400000,"callauctionSecondStageStartTime":1764935400000,"callauctionThirdStageStartTime":1764935700000,"tradingStartTime":1764936000000},{"symbol":"STABLE-USDT","name":"STABLE-USDT","baseCurrency":"STABLE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1765195200000,"callauctionSecondStageStartTime":1765198200000,"callauctionThirdStageStartTime":1765198500000,"tradingStartTime":1765198800000},{"symbol":"NIGHT-USDT","name":"NIGHT-USDT","baseCurrency":"NIGHT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1765270800000,"callauctionSecondStageStartTime":1765273800000,"callauctionThirdStageStartTime":1765274100000,"tradingStartTime":1765274400000},{"symbol":"WET-USDT","name":"WET-USDT","baseCurrency":"WET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1765288800000,"callauctionSecondStageStartTime":1765291800000,"callauctionThirdStageStartTime":1765292100000,"tradingStartTime":1765292400000},{"symbol":"ADI-USDT","name":"ADI-USDT","baseCurrency":"ADI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"15","callauctionFirstStageStartTime":1765278000000,"callauctionSecondStageStartTime":1765281000000,"callauctionThirdStageStartTime":1765281300000,"tradingStartTime":1765281600000},{"symbol":"KYO-USDT","name":"KYO-USDT","baseCurrency":"KYO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1765353600000,"callauctionSecondStageStartTime":1765356600000,"callauctionThirdStageStartTime":1765356900000,"tradingStartTime":1765357200000},{"symbol":"US-USDT","name":"US-USDT","baseCurrency":"US","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1765454400000,"callauctionSecondStageStartTime":1765457400000,"callauctionThirdStageStartTime":1765457700000,"tradingStartTime":1765458000000},{"symbol":"CYS-USDT","name":"CYS-USDT","baseCurrency":"CYS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1765443600000,"callauctionSecondStageStartTime":1765446600000,"callauctionThirdStageStartTime":1765446900000,"tradingStartTime":1765447200000},{"symbol":"UDS-USDT","name":"UDS-USDT","baseCurrency":"UDS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1765875600000,"callauctionSecondStageStartTime":1765878600000,"callauctionThirdStageStartTime":1765878900000,"tradingStartTime":1765879200000},{"symbol":"THQ-USDT","name":"THQ-USDT","baseCurrency":"THQ","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1765893600000,"callauctionSecondStageStartTime":1765896600000,"callauctionThirdStageStartTime":1765896900000,"tradingStartTime":1765897200000},{"symbol":"IR-USDT","name":"IR-USDT","baseCurrency":"IR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1765969200000,"callauctionSecondStageStartTime":1765972200000,"callauctionThirdStageStartTime":1765972500000,"tradingStartTime":1765972800000},{"symbol":"SCOR-USDT","name":"SCOR-USDT","baseCurrency":"SCOR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1765962000000,"callauctionSecondStageStartTime":1765965000000,"callauctionThirdStageStartTime":1765965300000,"tradingStartTime":1765965600000},{"symbol":"VOOI-USDT","name":"VOOI-USDT","baseCurrency":"VOOI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"8","callauctionFirstStageStartTime":1766059200000,"callauctionSecondStageStartTime":1766062200000,"callauctionThirdStageStartTime":1766062500000,"tradingStartTime":1766062800000},{"symbol":"ZKP-USDT","name":"ZKP-USDT","baseCurrency":"ZKP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1766145600000,"callauctionSecondStageStartTime":1766148600000,"callauctionThirdStageStartTime":1766148900000,"tradingStartTime":1766149200000},{"symbol":"MIN-USDT","name":"MIN-USDT","baseCurrency":"MIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.08","callauctionFirstStageStartTime":1766048400000,"callauctionSecondStageStartTime":1766051400000,"callauctionThirdStageStartTime":1766051700000,"tradingStartTime":1766052000000},{"symbol":"ZIG-USDT","name":"ZIG-USDT","baseCurrency":"ZIG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.6","callauctionFirstStageStartTime":1766062800000,"callauctionSecondStageStartTime":1766065800000,"callauctionThirdStageStartTime":1766066100000,"tradingStartTime":1766066400000},{"symbol":"TTD-USDT","name":"TTD-USDT","baseCurrency":"TTD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1766221200000,"callauctionSecondStageStartTime":1766224200000,"callauctionThirdStageStartTime":1766224500000,"tradingStartTime":1766224800000},{"symbol":"LIT-USDT","name":"LIT-USDT","baseCurrency":"LIT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1768483800000,"callauctionSecondStageStartTime":1768486800000,"callauctionThirdStageStartTime":1768487100000,"tradingStartTime":1768487400000},{"symbol":"BTG-USDT","name":"BTG-USDT","baseCurrency":"BTG","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.001","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"22.59","callauctionFirstStageStartTime":1767322800000,"callauctionSecondStageStartTime":1767325800000,"callauctionThirdStageStartTime":1767326100000,"tradingStartTime":1767326400000},{"symbol":"ESIM-USDT","name":"ESIM-USDT","baseCurrency":"ESIM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4","callauctionFirstStageStartTime":1767614400000,"callauctionSecondStageStartTime":1767617400000,"callauctionThirdStageStartTime":1767617700000,"tradingStartTime":1767618000000},{"symbol":"BREV-USDT","name":"BREV-USDT","baseCurrency":"BREV","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1767704400000,"callauctionSecondStageStartTime":1767707400000,"callauctionThirdStageStartTime":1767707700000,"tradingStartTime":1767708000000},{"symbol":"RAIN-USDT","name":"RAIN-USDT","baseCurrency":"RAIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.025","callauctionFirstStageStartTime":1767690000000,"callauctionSecondStageStartTime":1767693000000,"callauctionThirdStageStartTime":1767693300000,"tradingStartTime":1767693600000},{"symbol":"ZTC-USDT","name":"ZTC-USDT","baseCurrency":"ZTC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.4762","callauctionFirstStageStartTime":1767783600000,"callauctionSecondStageStartTime":1767786600000,"callauctionThirdStageStartTime":1767786900000,"tradingStartTime":1767787200000},{"symbol":"DN-USDT","name":"DN-USDT","baseCurrency":"DN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"40","callauctionFirstStageStartTime":1767949200000,"callauctionSecondStageStartTime":1767952200000,"callauctionThirdStageStartTime":1767952500000,"tradingStartTime":1767952800000},{"symbol":"BNRENSHENG-USDT","name":"币安人生-USDT","baseCurrency":"币安人生","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.6","callauctionFirstStageStartTime":1767945600000,"callauctionSecondStageStartTime":1767948600000,"callauctionThirdStageStartTime":1767948900000,"tradingStartTime":1767949200000},{"symbol":"FUN-USDT","name":"FUN-USDT","baseCurrency":"FUN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1768482000000,"callauctionSecondStageStartTime":1768485000000,"callauctionThirdStageStartTime":1768485300000,"tradingStartTime":1768485600000},{"symbol":"FOGO-USDT","name":"FOGO-USDT","baseCurrency":"FOGO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1768482000000,"callauctionSecondStageStartTime":1768485000000,"callauctionThirdStageStartTime":1768485300000,"tradingStartTime":1768485600000},{"symbol":"ULTIMA-USDT","name":"ULTIMA-USDT","baseCurrency":"ULTIMA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"69000","callauctionFirstStageStartTime":1768550400000,"callauctionSecondStageStartTime":1768553400000,"callauctionThirdStageStartTime":1768553700000,"tradingStartTime":1768554000000},{"symbol":"ELSA-USDT","name":"ELSA-USDT","baseCurrency":"ELSA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.0001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1768896000000,"callauctionSecondStageStartTime":1768899000000,"callauctionThirdStageStartTime":1768899300000,"tradingStartTime":1768899600000},{"symbol":"ACU-USDT","name":"ACU-USDT","baseCurrency":"ACU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"3","callauctionFirstStageStartTime":1768906800000,"callauctionSecondStageStartTime":1768909800000,"callauctionThirdStageStartTime":1768910100000,"tradingStartTime":1768910400000},{"symbol":"SKR-USDT","name":"SKR-USDT","baseCurrency":"SKR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1768957200000,"callauctionSecondStageStartTime":1768960200000,"callauctionThirdStageStartTime":1768960500000,"tradingStartTime":1768960800000},{"symbol":"GWEI-USDT","name":"GWEI-USDT","baseCurrency":"GWEI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1769000400000,"callauctionSecondStageStartTime":1769003400000,"callauctionThirdStageStartTime":1769003700000,"tradingStartTime":1769004000000},{"symbol":"FIGHT-USDT","name":"FIGHT-USDT","baseCurrency":"FIGHT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1769083200000,"callauctionSecondStageStartTime":1769086200000,"callauctionThirdStageStartTime":1769086500000,"tradingStartTime":1769086800000},{"symbol":"SENT-USDT","name":"SENT-USDT","baseCurrency":"SENT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1769079600000,"callauctionSecondStageStartTime":1769082600000,"callauctionThirdStageStartTime":1769082900000,"tradingStartTime":1769083200000},{"symbol":"IMU-USDT","name":"IMU-USDT","baseCurrency":"IMU","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.7","callauctionFirstStageStartTime":1769086800000,"callauctionSecondStageStartTime":1769089800000,"callauctionThirdStageStartTime":1769090100000,"tradingStartTime":1769090400000},{"symbol":"SPACE-USDT","name":"SPACE-USDT","baseCurrency":"SPACE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1769166000000,"callauctionSecondStageStartTime":1769169000000,"callauctionThirdStageStartTime":1769169300000,"tradingStartTime":1769169600000},{"symbol":"SPACE-USD1","name":"SPACE-USD1","baseCurrency":"SPACE","quoteCurrency":"USD1","feeCurrency":"USD1","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":null,"isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.2","callauctionFirstStageStartTime":1769166000000,"callauctionSecondStageStartTime":1769169000000,"callauctionThirdStageStartTime":1769169300000,"tradingStartTime":1769169600000},{"symbol":"PYBOBO-USDT","name":"PYBOBO-USDT","baseCurrency":"PYBOBO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.00255","callauctionFirstStageStartTime":1769158800000,"callauctionSecondStageStartTime":1769161800000,"callauctionThirdStageStartTime":1769162100000,"tradingStartTime":1769162400000},{"symbol":"BIRB-USDT","name":"BIRB-USDT","baseCurrency":"BIRB","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1769601600000,"callauctionSecondStageStartTime":1769604600000,"callauctionThirdStageStartTime":1769604900000,"tradingStartTime":1769605200000},{"symbol":"KIN-USDT","name":"KIN-USDT","baseCurrency":"KIN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1769767200000,"callauctionSecondStageStartTime":1769770200000,"callauctionThirdStageStartTime":1769770500000,"tradingStartTime":1769770800000},{"symbol":"ZAMA-USDT","name":"ZAMA-USDT","baseCurrency":"ZAMA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1770033600000,"callauctionSecondStageStartTime":1770036600000,"callauctionThirdStageStartTime":1770036900000,"tradingStartTime":1770037200000},{"symbol":"PVT-USDT","name":"PVT-USDT","baseCurrency":"PVT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.00895","callauctionFirstStageStartTime":1769770800000,"callauctionSecondStageStartTime":1769773800000,"callauctionThirdStageStartTime":1769774100000,"tradingStartTime":1769774400000},{"symbol":"INX-USDT","name":"INX-USDT","baseCurrency":"INX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1769796000000,"callauctionSecondStageStartTime":1769799000000,"callauctionThirdStageStartTime":1769799300000,"tradingStartTime":1769799600000},{"symbol":"TRIA-USDT","name":"TRIA-USDT","baseCurrency":"TRIA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.8","callauctionFirstStageStartTime":1770109200000,"callauctionSecondStageStartTime":1770112200000,"callauctionThirdStageStartTime":1770112500000,"tradingStartTime":1770112800000},{"symbol":"WARD-USDT","name":"WARD-USDT","baseCurrency":"WARD","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1770202800000,"callauctionSecondStageStartTime":1770205800000,"callauctionThirdStageStartTime":1770206100000,"tradingStartTime":1770206400000},{"symbol":"RNBW-USDT","name":"RNBW-USDT","baseCurrency":"RNBW","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1770307200000,"callauctionSecondStageStartTime":1770310200000,"callauctionThirdStageStartTime":1770310500000,"tradingStartTime":1770310800000},{"symbol":"MOVA-USDT","name":"MOVA-USDT","baseCurrency":"MOVA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"50","callauctionFirstStageStartTime":1770368400000,"callauctionSecondStageStartTime":1770371400000,"callauctionThirdStageStartTime":1770371700000,"tradingStartTime":1770372000000},{"symbol":"9BIT-USDT","name":"9BIT-USDT","baseCurrency":"9BIT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.07","callauctionFirstStageStartTime":1770640200000,"callauctionSecondStageStartTime":1770643200000,"callauctionThirdStageStartTime":1770643500000,"tradingStartTime":1770643800000},{"symbol":"FRAX-USDT","name":"FRAX-USDT","baseCurrency":"FRAX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.0001","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"7.25","callauctionFirstStageStartTime":1770710400000,"callauctionSecondStageStartTime":1770713400000,"callauctionThirdStageStartTime":1770713700000,"tradingStartTime":1770714000000},{"symbol":"UP-USDT","name":"UP-USDT","baseCurrency":"UP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1770739200000,"callauctionSecondStageStartTime":1770742200000,"callauctionThirdStageStartTime":1770742500000,"tradingStartTime":1770742800000},{"symbol":"ESP-USDT","name":"ESP-USDT","baseCurrency":"ESP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1770897600000,"callauctionSecondStageStartTime":1770900600000,"callauctionThirdStageStartTime":1770900900000,"tradingStartTime":1770901200000},{"symbol":"AZTEC-USDT","name":"AZTEC-USDT","baseCurrency":"AZTEC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1770876000000,"callauctionSecondStageStartTime":1770879000000,"callauctionThirdStageStartTime":1770879300000,"tradingStartTime":1770879600000},{"symbol":"BNKR-USDT","name":"BNKR-USDT","baseCurrency":"BNKR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.0038965","callauctionFirstStageStartTime":1770973200000,"callauctionSecondStageStartTime":1770976200000,"callauctionThirdStageStartTime":1770976500000,"tradingStartTime":1770976800000},{"symbol":"CRTR-USDT","name":"CRTR-USDT","baseCurrency":"CRTR","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1771840800000,"callauctionSecondStageStartTime":1771843800000,"callauctionThirdStageStartTime":1771844100000,"tradingStartTime":1771844400000},{"symbol":"ROBO-USDT","name":"ROBO-USDT","baseCurrency":"ROBO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1772182800000,"callauctionSecondStageStartTime":1772185800000,"callauctionThirdStageStartTime":1772186100000,"tradingStartTime":1772186400000},{"symbol":"IDOS-USDT","name":"IDOS-USDT","baseCurrency":"IDOS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2.5","callauctionFirstStageStartTime":1772715600000,"callauctionSecondStageStartTime":1772718600000,"callauctionThirdStageStartTime":1772718900000,"tradingStartTime":1772719200000},{"symbol":"NOON-USDT","name":"NOON-USDT","baseCurrency":"NOON","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1772712000000,"callauctionSecondStageStartTime":1772715000000,"callauctionThirdStageStartTime":1772715300000,"tradingStartTime":1772715600000},{"symbol":"GF-USDT","name":"GF-USDT","baseCurrency":"GF","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.05","callauctionFirstStageStartTime":1772794800000,"callauctionSecondStageStartTime":1772797800000,"callauctionThirdStageStartTime":1772798100000,"tradingStartTime":1772798400000},{"symbol":"NEXI-USDT","name":"NEXI-USDT","baseCurrency":"NEXI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1773050400000,"callauctionSecondStageStartTime":1773053400000,"callauctionThirdStageStartTime":1773053700000,"tradingStartTime":1773054000000},{"symbol":"MANTRA-USDT","name":"MANTRA-USDT","baseCurrency":"MANTRA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.055","callauctionFirstStageStartTime":1773115200000,"callauctionSecondStageStartTime":1773118200000,"callauctionThirdStageStartTime":1773118500000,"tradingStartTime":1773118800000},{"symbol":"MANTRA-BTC","name":"MANTRA-BTC","baseCurrency":"MANTRA","quoteCurrency":"BTC","feeCurrency":"BTC","market":"BTC","baseMinSize":"1","quoteMinSize":"0.000001","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.0000000001","priceIncrement":"0.0000000001","priceLimitRate":"0.05","minFunds":"0.000001","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000000001","callauctionPriceCeiling":"0.00000077","callauctionFirstStageStartTime":1773115800000,"callauctionSecondStageStartTime":1773118200000,"callauctionThirdStageStartTime":1773118500000,"tradingStartTime":1773118800000},{"symbol":"SN3-USDT","name":"SN3-USDT","baseCurrency":"SN3","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.00001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1773212400000,"callauctionSecondStageStartTime":1773215400000,"callauctionThirdStageStartTime":1773215700000,"tradingStartTime":1773216000000},{"symbol":"KAT-USDT","name":"KAT-USDT","baseCurrency":"KAT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1773835200000,"callauctionSecondStageStartTime":1773838200000,"callauctionThirdStageStartTime":1773838500000,"tradingStartTime":1773838800000},{"symbol":"XAUM-USDT","name":"XAUM-USDT","baseCurrency":"XAUM","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.0001","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.0001","quoteIncrement":"0.01","priceIncrement":"0.01","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.01","callauctionPriceCeiling":"7500","callauctionFirstStageStartTime":1773738000000,"callauctionSecondStageStartTime":1773741000000,"callauctionThirdStageStartTime":1773741300000,"tradingStartTime":1773741600000},{"symbol":"ION-USDT","name":"ION-USDT","baseCurrency":"ION","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.000001","priceIncrement":"0.0000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.006045","callauctionFirstStageStartTime":1774342800000,"callauctionSecondStageStartTime":1774345800000,"callauctionThirdStageStartTime":1774346100000,"tradingStartTime":1774346400000},{"symbol":"PRL-USDT","name":"PRL-USDT","baseCurrency":"PRL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1774432800000,"callauctionSecondStageStartTime":1774435800000,"callauctionThirdStageStartTime":1774436100000,"tradingStartTime":1774436400000},{"symbol":"WL-USDT","name":"WL-USDT","baseCurrency":"WL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1774947600000,"callauctionSecondStageStartTime":1774950600000,"callauctionThirdStageStartTime":1774950900000,"tradingStartTime":1774951200000},{"symbol":"BASED-USDT","name":"BASED-USDT","baseCurrency":"BASED","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.00001","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1774861200000,"callauctionSecondStageStartTime":1774864200000,"callauctionThirdStageStartTime":1774864500000,"tradingStartTime":1774864800000},{"symbol":"EDGE-USDT","name":"EDGE-USDT","baseCurrency":"EDGE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"10","callauctionFirstStageStartTime":1774956600000,"callauctionSecondStageStartTime":1774959600000,"callauctionThirdStageStartTime":1774959900000,"tradingStartTime":1774960200000},{"symbol":"MEZO-USDT","name":"MEZO-USDT","baseCurrency":"MEZO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1775048400000,"callauctionSecondStageStartTime":1775051400000,"callauctionThirdStageStartTime":1775051700000,"tradingStartTime":1775052000000},{"symbol":"USDS-USDT","name":"USDS-USDT","baseCurrency":"USDS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"2","callauctionFirstStageStartTime":1775826000000,"callauctionSecondStageStartTime":1775829000000,"callauctionThirdStageStartTime":1775829300000,"tradingStartTime":1775829600000},{"symbol":"OFC-USDT","name":"OFC-USDT","baseCurrency":"OFC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1775725200000,"callauctionSecondStageStartTime":1775728200000,"callauctionThirdStageStartTime":1775728500000,"tradingStartTime":1775728800000},{"symbol":"RAVE-USDT","name":"RAVE-USDT","baseCurrency":"RAVE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.01","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"90","callauctionFirstStageStartTime":1776405600000,"callauctionSecondStageStartTime":1776408600000,"callauctionThirdStageStartTime":1776408900000,"tradingStartTime":1776409200000},{"symbol":"CHIP-USDT","name":"CHIP-USDT","baseCurrency":"CHIP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.01","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1776773700000,"callauctionSecondStageStartTime":1776775800000,"callauctionThirdStageStartTime":1776776100000,"tradingStartTime":1776776400000},{"symbol":"STAY-USDT","name":"STAY-USDT","baseCurrency":"STAY","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10000","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.01","priceIncrement":"0.00000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0000001","callauctionPriceCeiling":"0.0075","callauctionFirstStageStartTime":1776942000000,"callauctionSecondStageStartTime":1776945000000,"callauctionThirdStageStartTime":1776945300000,"tradingStartTime":1776945600000},{"symbol":"BLEND-USDT","name":"BLEND-USDT","baseCurrency":"BLEND","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1777032000000,"callauctionSecondStageStartTime":1777035000000,"callauctionThirdStageStartTime":1777035300000,"tradingStartTime":1777035600000},{"symbol":"PROS-USDT","name":"PROS-USDT","baseCurrency":"PROS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"5","callauctionFirstStageStartTime":1777377600000,"callauctionSecondStageStartTime":1777380600000,"callauctionThirdStageStartTime":1777380900000,"tradingStartTime":1777381200000},{"symbol":"ACN-USDT","name":"ACN-USDT","baseCurrency":"ACN","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.01","priceIncrement":"0.000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000001","callauctionPriceCeiling":"0.0266","callauctionFirstStageStartTime":1777446000000,"callauctionSecondStageStartTime":1777449000000,"callauctionThirdStageStartTime":1777449300000,"tradingStartTime":1777449600000},{"symbol":"AI-USDT","name":"AI-USDT","baseCurrency":"AI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.5","callauctionFirstStageStartTime":1777456800000,"callauctionSecondStageStartTime":1777459800000,"callauctionThirdStageStartTime":1777460100000,"tradingStartTime":1777460400000},{"symbol":"ASSET-USDT","name":"ASSET-USDT","baseCurrency":"ASSET","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1777557600000,"callauctionSecondStageStartTime":1777560600000,"callauctionThirdStageStartTime":1777560900000,"tradingStartTime":1777561200000},{"symbol":"MEGA-USDT","name":"MEGA-USDT","baseCurrency":"MEGA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"4.675","callauctionFirstStageStartTime":1777543200000,"callauctionSecondStageStartTime":1777546200000,"callauctionThirdStageStartTime":1777546500000,"tradingStartTime":1777546800000},{"symbol":"GENIUS-USDT","name":"GENIUS-USDT","baseCurrency":"GENIUS","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"4.5","callauctionFirstStageStartTime":1777554000000,"callauctionSecondStageStartTime":1777557000000,"callauctionThirdStageStartTime":1777557300000,"tradingStartTime":1777557600000},{"symbol":"BILL-USDT","name":"BILL-USDT","baseCurrency":"BILL","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1777878000000,"callauctionSecondStageStartTime":1777881000000,"callauctionThirdStageStartTime":1777881300000,"tradingStartTime":1777881600000},{"symbol":"TAC-USDT","name":"TAC-USDT","baseCurrency":"TAC","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.0633","callauctionFirstStageStartTime":1777971600000,"callauctionSecondStageStartTime":1777974600000,"callauctionThirdStageStartTime":1777974900000,"tradingStartTime":1777975200000},{"symbol":"METADAO-USDT","name":"METADAO-USDT","baseCurrency":"METADAO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"0.1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.001","callauctionPriceCeiling":"15","callauctionFirstStageStartTime":1778058000000,"callauctionSecondStageStartTime":1778061000000,"callauctionThirdStageStartTime":1778061300000,"tradingStartTime":1778061600000},{"symbol":"KAIO-USDT","name":"KAIO-USDT","baseCurrency":"KAIO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1778068800000,"callauctionSecondStageStartTime":1778071800000,"callauctionThirdStageStartTime":1778072100000,"tradingStartTime":1778072400000},{"symbol":"SHARE-USDT","name":"SHARE-USDT","baseCurrency":"SHARE","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"1","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.01","quoteIncrement":"0.01","priceIncrement":"0.0001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"25","callauctionFirstStageStartTime":1778230800000,"callauctionSecondStageStartTime":1778233800000,"callauctionThirdStageStartTime":1778234100000,"tradingStartTime":1778234400000},{"symbol":"NXT-USDT","name":"NXT-USDT","baseCurrency":"NXT","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1778576400000,"callauctionSecondStageStartTime":1778579400000,"callauctionThirdStageStartTime":1778579700000,"tradingStartTime":1778580000000},{"symbol":"BABYSHARK-USDT","name":"BABYSHARK-USDT","baseCurrency":"BABYSHARK","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.1153","callauctionFirstStageStartTime":1778742000000,"callauctionSecondStageStartTime":1778745000000,"callauctionThirdStageStartTime":1778745300000,"tradingStartTime":1778745600000},{"symbol":"HOOLI-USDT","name":"HOOLI-USDT","baseCurrency":"HOOLI","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.0001","callauctionPriceCeiling":"1","callauctionFirstStageStartTime":1778835600000,"callauctionSecondStageStartTime":1778838600000,"callauctionThirdStageStartTime":1778838900000,"tradingStartTime":1778839200000},{"symbol":"ATWO-USDT","name":"ATWO-USDT","baseCurrency":"ATWO","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.75","callauctionFirstStageStartTime":1779102000000,"callauctionSecondStageStartTime":1779105000000,"callauctionThirdStageStartTime":1779105300000,"tradingStartTime":1779105600000},{"symbol":"ZEST-USDT","name":"ZEST-USDT","baseCurrency":"ZEST","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"1.5","callauctionFirstStageStartTime":1779192000000,"callauctionSecondStageStartTime":1779195000000,"callauctionThirdStageStartTime":1779195300000,"tradingStartTime":1779195600000},{"symbol":"AKITA-USDT","name":"AKITA-USDT","baseCurrency":"AKITA","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.0711","callauctionFirstStageStartTime":1779267600000,"callauctionSecondStageStartTime":1779270600000,"callauctionThirdStageStartTime":1779270900000,"tradingStartTime":1779271200000},{"symbol":"NEX-USDT","name":"NEX-USDT","baseCurrency":"NEX","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"100000","quoteMinSize":"0.1","baseMaxSize":"100000000000","quoteMaxSize":"99999999","baseIncrement":"1","quoteIncrement":"0.01","priceIncrement":"0.000000001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.000000001","callauctionPriceCeiling":"0.00005","callauctionFirstStageStartTime":1779285600000,"callauctionSecondStageStartTime":1779288600000,"callauctionThirdStageStartTime":1779288900000,"tradingStartTime":1779289200000},{"symbol":"HPP-USDT","name":"HPP-USDT","baseCurrency":"HPP","quoteCurrency":"USDT","feeCurrency":"USDT","market":"USDS","baseMinSize":"10","quoteMinSize":"0.1","baseMaxSize":"10000000000","quoteMaxSize":"99999999","baseIncrement":"0.1","quoteIncrement":"0.01","priceIncrement":"0.00001","priceLimitRate":"0.05","minFunds":"0.1","isMarginEnabled":false,"enableTrading":true,"st":false,"callauctionIsEnabled":false,"callauctionPriceFloor":"0.00001","callauctionPriceCeiling":"0.16","callauctionFirstStageStartTime":1779346800000,"callauctionSecondStageStartTime":1779349800000,"callauctionThirdStageStartTime":1779350100000,"tradingStartTime":1779350400000}]} \ No newline at end of file diff --git a/scripts/install.sh b/scripts/install.sh new file mode 100755 index 0000000..4602184 --- /dev/null +++ b/scripts/install.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJECT_DIR="$(dirname "$SCRIPT_DIR")" + +# System build dependencies +sudo apt-get update -qq +sudo apt-get install -y -qq \ + cmake build-essential pkg-config \ + libssl-dev libyaml-dev + +# Python virtualenv (for executor) +python3 -m venv "$PROJECT_DIR/.venv" +source "$PROJECT_DIR/.venv/bin/activate" +pip install --upgrade pip +pip install -e "$PROJECT_DIR[dev]" + +# Build fused_engine C binary +cd "$PROJECT_DIR" +mkdir -p build +cd build +cmake ../src -DCMAKE_BUILD_TYPE=Release +make -j"$(nproc)" + +echo "Done. Activate Python venv with: source $PROJECT_DIR/.venv/bin/activate" diff --git a/session b/session new file mode 100644 index 0000000..e89fede --- /dev/null +++ b/session @@ -0,0 +1 @@ +opencode -s ses_1b4ebb4cdffey1e1nSPwzXAwbn diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt new file mode 100644 index 0000000..1d82c54 --- /dev/null +++ b/src/CMakeLists.txt @@ -0,0 +1,21 @@ +cmake_minimum_required(VERSION 3.22) +project(fused_engine C) + +set(CMAKE_C_STANDARD 17) +set(CMAKE_C_STANDARD_REQUIRED ON) + +find_package(OpenSSL REQUIRED) +find_package(PkgConfig REQUIRED) +pkg_check_modules(YAML REQUIRED yaml-0.1) + +file(GLOB SRCS "*.c") +list(REMOVE_ITEM SRCS "${CMAKE_CURRENT_SOURCE_DIR}/jsmn.c") + +add_executable(fused_engine ${SRCS}) +target_include_directories(fused_engine PRIVATE ${CMAKE_CURRENT_SOURCE_DIR} ${OPENSSL_INCLUDE_DIR} ${YAML_INCLUDE_DIRS}) +target_link_libraries(fused_engine PRIVATE ${OPENSSL_LIBRARIES} ${YAML_LIBRARIES} pthread rt m) + +target_compile_options(fused_engine PRIVATE + -O3 -march=native -Wall -Wextra -Wpedantic + -Wno-unused-parameter +) diff --git a/src/book.c b/src/book.c new file mode 100644 index 0000000..be613e1 --- /dev/null +++ b/src/book.c @@ -0,0 +1,63 @@ +/* + * book.c - Global order book storage + * + * Maintains a flat array of order books indexed by symbol index. + * The ws_client parse_book_update directly writes to client->books[], + * bypassing this module. This file provides a legacy API for + * manual updates from string arrays. + */ + +#include "book.h" +#include +#include +#include + +static order_book_t g_books[MAX_SYMBOLS]; +static uint32_t g_book_count = 0; + +void book_init(void) { + memset(g_books, 0, sizeof(g_books)); + g_book_count = 0; +} + +order_book_t *book_get(uint16_t symbol_idx) { + if (symbol_idx >= g_book_count) return NULL; + return &g_books[symbol_idx]; +} + +uint32_t book_count(void) { + return g_book_count; +} + +/* + * Update book from string-encoded price/size arrays. + * bids/asks are flattened [price0, size0, price1, size1, ...] string arrays. + */ +order_book_t *book_update(uint16_t symbol_idx, int64_t ts_ms, int64_t sequence, + const char **bids, uint32_t bid_count, + const char **asks, uint32_t ask_count) { + if (symbol_idx >= MAX_SYMBOLS) return NULL; + + order_book_t *book = &g_books[symbol_idx]; + book->symbol_idx = symbol_idx; + book->ts_ms = ts_ms; + book->sequence = sequence; + + book->bid_count = bid_count > MAX_BOOK_LEVELS ? MAX_BOOK_LEVELS : bid_count; + for (uint32_t i = 0; i < book->bid_count; i++) { + book->bids[i][0] = atof(bids[i * 2]); + book->bids[i][1] = atof(bids[i * 2 + 1]); + } + + book->ask_count = ask_count > MAX_BOOK_LEVELS ? MAX_BOOK_LEVELS : ask_count; + for (uint32_t i = 0; i < book->ask_count; i++) { + book->asks[i][0] = atof(asks[i * 2]); + book->asks[i][1] = atof(asks[i * 2 + 1]); + } + + if (symbol_idx >= g_book_count) { + g_book_count = symbol_idx + 1; + } + + return book; +} diff --git a/src/book.h b/src/book.h new file mode 100644 index 0000000..a8c89b9 --- /dev/null +++ b/src/book.h @@ -0,0 +1,23 @@ +#ifndef FUSED_BOOK_H +#define FUSED_BOOK_H + +#include + +#define SYMBOL_NAME_LEN 16 +#define CURRENCY_NAME_LEN 8 +#define MAX_BOOK_LEVELS 5 +#define MAX_SYMBOLS 2048 + +/* In-memory order book snapshot for a single trading pair */ +typedef struct { + uint16_t symbol_idx; /* index into the symbol table */ + int64_t ts_ms; /* book timestamp (milliseconds) */ + int64_t sequence; /* exchange sequence number */ + double bids[MAX_BOOK_LEVELS][2]; /* bid levels [price, size] */ + double asks[MAX_BOOK_LEVELS][2]; /* ask levels [price, size] */ + uint8_t bid_count; /* number of valid bid levels */ + uint8_t ask_count; /* number of valid ask levels */ + char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol name */ +} order_book_t; + +#endif diff --git a/src/cJSON.c b/src/cJSON.c new file mode 100644 index 0000000..88c2d95 --- /dev/null +++ b/src/cJSON.c @@ -0,0 +1,3206 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +/* cJSON */ +/* JSON parser in C. */ + +/* disable warnings about old C89 functions in MSVC */ +#if !defined(_CRT_SECURE_NO_DEPRECATE) && defined(_MSC_VER) +#define _CRT_SECURE_NO_DEPRECATE +#endif + +#ifdef __GNUC__ +#pragma GCC visibility push(default) +#endif +#if defined(_MSC_VER) +#pragma warning (push) +/* disable warning about single line comments in system headers */ +#pragma warning (disable : 4001) +#endif + +#include +#include +#include +#include +#include +#include +#include + +#ifdef ENABLE_LOCALES +#include +#endif + +#if defined(_MSC_VER) +#pragma warning (pop) +#endif +#ifdef __GNUC__ +#pragma GCC visibility pop +#endif + +#include "cJSON.h" + +/* define our own boolean type */ +#ifdef true +#undef true +#endif +#define true ((cJSON_bool)1) + +#ifdef false +#undef false +#endif +#define false ((cJSON_bool)0) + +/* define isnan and isinf for ANSI C, if in C99 or above, isnan and isinf has been defined in math.h */ +#ifndef isinf +#define isinf(d) (isnan((d - d)) && !isnan(d)) +#endif +#ifndef isnan +#define isnan(d) (d != d) +#endif + +#ifndef NAN +#ifdef _WIN32 +#define NAN sqrt(-1.0) +#else +#define NAN 0.0/0.0 +#endif +#endif + +typedef struct { + const unsigned char *json; + size_t position; +} error; +static error global_error = { NULL, 0 }; + +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void) +{ + return (const char*) (global_error.json + global_error.position); +} + +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item) +{ + if (!cJSON_IsString(item)) + { + return NULL; + } + + return item->valuestring; +} + +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item) +{ + if (!cJSON_IsNumber(item)) + { + return (double) NAN; + } + + return item->valuedouble; +} + +/* This is a safeguard to prevent copy-pasters from using incompatible C and header files */ +#if (CJSON_VERSION_MAJOR != 1) || (CJSON_VERSION_MINOR != 7) || (CJSON_VERSION_PATCH != 19) + #error cJSON.h and cJSON.c have different versions. Make sure that both have the same. +#endif + +CJSON_PUBLIC(const char*) cJSON_Version(void) +{ + static char version[15]; + sprintf(version, "%i.%i.%i", CJSON_VERSION_MAJOR, CJSON_VERSION_MINOR, CJSON_VERSION_PATCH); + + return version; +} + +/* Case insensitive string comparison, doesn't consider two NULL pointers equal though */ +static int case_insensitive_strcmp(const unsigned char *string1, const unsigned char *string2) +{ + if ((string1 == NULL) || (string2 == NULL)) + { + return 1; + } + + if (string1 == string2) + { + return 0; + } + + for(; tolower(*string1) == tolower(*string2); (void)string1++, string2++) + { + if (*string1 == '\0') + { + return 0; + } + } + + return tolower(*string1) - tolower(*string2); +} + +typedef struct internal_hooks +{ + void *(CJSON_CDECL *allocate)(size_t size); + void (CJSON_CDECL *deallocate)(void *pointer); + void *(CJSON_CDECL *reallocate)(void *pointer, size_t size); +} internal_hooks; + +#if defined(_MSC_VER) +/* work around MSVC error C2322: '...' address of dllimport '...' is not static */ +static void * CJSON_CDECL internal_malloc(size_t size) +{ + return malloc(size); +} +static void CJSON_CDECL internal_free(void *pointer) +{ + free(pointer); +} +static void * CJSON_CDECL internal_realloc(void *pointer, size_t size) +{ + return realloc(pointer, size); +} +#else +#define internal_malloc malloc +#define internal_free free +#define internal_realloc realloc +#endif + +/* strlen of character literals resolved at compile time */ +#define static_strlen(string_literal) (sizeof(string_literal) - sizeof("")) + +static internal_hooks global_hooks = { internal_malloc, internal_free, internal_realloc }; + +static unsigned char* cJSON_strdup(const unsigned char* string, const internal_hooks * const hooks) +{ + size_t length = 0; + unsigned char *copy = NULL; + + if (string == NULL) + { + return NULL; + } + + length = strlen((const char*)string) + sizeof(""); + copy = (unsigned char*)hooks->allocate(length); + if (copy == NULL) + { + return NULL; + } + memcpy(copy, string, length); + + return copy; +} + +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks) +{ + if (hooks == NULL) + { + /* Reset hooks */ + global_hooks.allocate = malloc; + global_hooks.deallocate = free; + global_hooks.reallocate = realloc; + return; + } + + global_hooks.allocate = malloc; + if (hooks->malloc_fn != NULL) + { + global_hooks.allocate = hooks->malloc_fn; + } + + global_hooks.deallocate = free; + if (hooks->free_fn != NULL) + { + global_hooks.deallocate = hooks->free_fn; + } + + /* use realloc only if both free and malloc are used */ + global_hooks.reallocate = NULL; + if ((global_hooks.allocate == malloc) && (global_hooks.deallocate == free)) + { + global_hooks.reallocate = realloc; + } +} + +/* Internal constructor. */ +static cJSON *cJSON_New_Item(const internal_hooks * const hooks) +{ + cJSON* node = (cJSON*)hooks->allocate(sizeof(cJSON)); + if (node) + { + memset(node, '\0', sizeof(cJSON)); + } + + return node; +} + +/* Delete a cJSON structure. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item) +{ + cJSON *next = NULL; + while (item != NULL) + { + next = item->next; + if (!(item->type & cJSON_IsReference) && (item->child != NULL)) + { + cJSON_Delete(item->child); + } + if (!(item->type & cJSON_IsReference) && (item->valuestring != NULL)) + { + global_hooks.deallocate(item->valuestring); + item->valuestring = NULL; + } + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + global_hooks.deallocate(item->string); + item->string = NULL; + } + global_hooks.deallocate(item); + item = next; + } +} + +/* get the decimal point character of the current locale */ +static unsigned char get_decimal_point(void) +{ +#ifdef ENABLE_LOCALES + struct lconv *lconv = localeconv(); + return (unsigned char) lconv->decimal_point[0]; +#else + return '.'; +#endif +} + +typedef struct +{ + const unsigned char *content; + size_t length; + size_t offset; + size_t depth; /* How deeply nested (in arrays/objects) is the input at the current offset. */ + internal_hooks hooks; +} parse_buffer; + +/* check if the given size is left to read in a given parse buffer (starting with 1) */ +#define can_read(buffer, size) ((buffer != NULL) && (((buffer)->offset + size) <= (buffer)->length)) +/* check if the buffer can be accessed at the given index (starting with 0) */ +#define can_access_at_index(buffer, index) ((buffer != NULL) && (((buffer)->offset + index) < (buffer)->length)) +#define cannot_access_at_index(buffer, index) (!can_access_at_index(buffer, index)) +/* get a pointer to the buffer at the position */ +#define buffer_at_offset(buffer) ((buffer)->content + (buffer)->offset) + +/* Parse the input text to generate a number, and populate the result into item. */ +static cJSON_bool parse_number(cJSON * const item, parse_buffer * const input_buffer) +{ + double number = 0; + unsigned char *after_end = NULL; + unsigned char *number_c_string; + unsigned char decimal_point = get_decimal_point(); + size_t i = 0; + size_t number_string_length = 0; + cJSON_bool has_decimal_point = false; + + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; + } + + /* copy the number into a temporary buffer and replace '.' with the decimal point + * of the current locale (for strtod) + * This also takes care of '\0' not necessarily being available for marking the end of the input */ + for (i = 0; can_access_at_index(input_buffer, i); i++) + { + switch (buffer_at_offset(input_buffer)[i]) + { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case '+': + case '-': + case 'e': + case 'E': + number_string_length++; + break; + + case '.': + number_string_length++; + has_decimal_point = true; + break; + + default: + goto loop_end; + } + } +loop_end: + /* malloc for temporary buffer, add 1 for '\0' */ + number_c_string = (unsigned char *) input_buffer->hooks.allocate(number_string_length + 1); + if (number_c_string == NULL) + { + return false; /* allocation failure */ + } + + memcpy(number_c_string, buffer_at_offset(input_buffer), number_string_length); + number_c_string[number_string_length] = '\0'; + + if (has_decimal_point) + { + for (i = 0; i < number_string_length; i++) + { + if (number_c_string[i] == '.') + { + /* replace '.' with the decimal point of the current locale (for strtod) */ + number_c_string[i] = decimal_point; + } + } + } + + number = strtod((const char*)number_c_string, (char**)&after_end); + if (number_c_string == after_end) + { + /* free the temporary buffer */ + input_buffer->hooks.deallocate(number_c_string); + return false; /* parse_error */ + } + + item->valuedouble = number; + + /* use saturation in case of overflow */ + if (number >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)number; + } + + item->type = cJSON_Number; + + input_buffer->offset += (size_t)(after_end - number_c_string); + /* free the temporary buffer */ + input_buffer->hooks.deallocate(number_c_string); + return true; +} + +/* don't ask me, but the original cJSON_SetNumberValue returns an integer or double */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number) +{ + if (object == NULL) + { + return (double)NAN; + } + + if (number >= INT_MAX) + { + object->valueint = INT_MAX; + } + else if (number <= (double)INT_MIN) + { + object->valueint = INT_MIN; + } + else + { + object->valueint = (int)number; + } + + return object->valuedouble = number; +} + +/* Note: when passing a NULL valuestring, cJSON_SetValuestring treats this as an error and return NULL */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring) +{ + char *copy = NULL; + size_t v1_len; + size_t v2_len; + /* if object's type is not cJSON_String or is cJSON_IsReference, it should not set valuestring */ + if ((object == NULL) || !(object->type & cJSON_String) || (object->type & cJSON_IsReference)) + { + return NULL; + } + /* return NULL if the object is corrupted or valuestring is NULL */ + if (object->valuestring == NULL || valuestring == NULL) + { + return NULL; + } + + v1_len = strlen(valuestring); + v2_len = strlen(object->valuestring); + + if (v1_len <= v2_len) + { + /* strcpy does not handle overlapping string: [X1, X2] [Y1, Y2] => X2 < Y1 or Y2 < X1 */ + if (!( valuestring + v1_len < object->valuestring || object->valuestring + v2_len < valuestring )) + { + return NULL; + } + strcpy(object->valuestring, valuestring); + return object->valuestring; + } + copy = (char*) cJSON_strdup((const unsigned char*)valuestring, &global_hooks); + if (copy == NULL) + { + return NULL; + } + if (object->valuestring != NULL) + { + cJSON_free(object->valuestring); + } + object->valuestring = copy; + + return copy; +} + +typedef struct +{ + unsigned char *buffer; + size_t length; + size_t offset; + size_t depth; /* current nesting depth (for formatted printing) */ + cJSON_bool noalloc; + cJSON_bool format; /* is this print a formatted print */ + internal_hooks hooks; +} printbuffer; + +/* realloc printbuffer if necessary to have at least "needed" bytes more */ +static unsigned char* ensure(printbuffer * const p, size_t needed) +{ + unsigned char *newbuffer = NULL; + size_t newsize = 0; + + if ((p == NULL) || (p->buffer == NULL)) + { + return NULL; + } + + if ((p->length > 0) && (p->offset >= p->length)) + { + /* make sure that offset is valid */ + return NULL; + } + + if (needed > INT_MAX) + { + /* sizes bigger than INT_MAX are currently not supported */ + return NULL; + } + + needed += p->offset + 1; + if (needed <= p->length) + { + return p->buffer + p->offset; + } + + if (p->noalloc) { + return NULL; + } + + /* calculate new buffer size */ + if (needed > (INT_MAX / 2)) + { + /* overflow of int, use INT_MAX if possible */ + if (needed <= INT_MAX) + { + newsize = INT_MAX; + } + else + { + return NULL; + } + } + else + { + newsize = needed * 2; + } + + if (p->hooks.reallocate != NULL) + { + /* reallocate with realloc if available */ + newbuffer = (unsigned char*)p->hooks.reallocate(p->buffer, newsize); + if (newbuffer == NULL) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + } + else + { + /* otherwise reallocate manually */ + newbuffer = (unsigned char*)p->hooks.allocate(newsize); + if (!newbuffer) + { + p->hooks.deallocate(p->buffer); + p->length = 0; + p->buffer = NULL; + + return NULL; + } + + memcpy(newbuffer, p->buffer, p->offset + 1); + p->hooks.deallocate(p->buffer); + } + p->length = newsize; + p->buffer = newbuffer; + + return newbuffer + p->offset; +} + +/* calculate the new length of the string in a printbuffer and update the offset */ +static void update_offset(printbuffer * const buffer) +{ + const unsigned char *buffer_pointer = NULL; + if ((buffer == NULL) || (buffer->buffer == NULL)) + { + return; + } + buffer_pointer = buffer->buffer + buffer->offset; + + buffer->offset += strlen((const char*)buffer_pointer); +} + +/* securely comparison of floating-point variables */ +static cJSON_bool compare_double(double a, double b) +{ + double maxVal = fabs(a) > fabs(b) ? fabs(a) : fabs(b); + return (fabs(a - b) <= maxVal * DBL_EPSILON); +} + +/* Render the number nicely from the given item into a string. */ +static cJSON_bool print_number(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + double d = item->valuedouble; + int length = 0; + size_t i = 0; + unsigned char number_buffer[26] = {0}; /* temporary buffer to print the number into */ + unsigned char decimal_point = get_decimal_point(); + double test = 0.0; + + if (output_buffer == NULL) + { + return false; + } + + /* This checks for NaN and Infinity */ + if (isnan(d) || isinf(d)) + { + length = sprintf((char*)number_buffer, "null"); + } + else if(d == (double)item->valueint) + { + length = sprintf((char*)number_buffer, "%d", item->valueint); + } + else + { + /* Try 15 decimal places of precision to avoid nonsignificant nonzero digits */ + length = sprintf((char*)number_buffer, "%1.15g", d); + + /* Check whether the original double can be recovered */ + if ((sscanf((char*)number_buffer, "%lg", &test) != 1) || !compare_double((double)test, d)) + { + /* If not, print with 17 decimal places of precision */ + length = sprintf((char*)number_buffer, "%1.17g", d); + } + } + + /* sprintf failed or buffer overrun occurred */ + if ((length < 0) || (length > (int)(sizeof(number_buffer) - 1))) + { + return false; + } + + /* reserve appropriate space in the output */ + output_pointer = ensure(output_buffer, (size_t)length + sizeof("")); + if (output_pointer == NULL) + { + return false; + } + + /* copy the printed number to the output and replace locale + * dependent decimal point with '.' */ + for (i = 0; i < ((size_t)length); i++) + { + if (number_buffer[i] == decimal_point) + { + output_pointer[i] = '.'; + continue; + } + + output_pointer[i] = number_buffer[i]; + } + output_pointer[i] = '\0'; + + output_buffer->offset += (size_t)length; + + return true; +} + +/* parse 4 digit hexadecimal number */ +static unsigned parse_hex4(const unsigned char * const input) +{ + unsigned int h = 0; + size_t i = 0; + + for (i = 0; i < 4; i++) + { + /* parse digit */ + if ((input[i] >= '0') && (input[i] <= '9')) + { + h += (unsigned int) input[i] - '0'; + } + else if ((input[i] >= 'A') && (input[i] <= 'F')) + { + h += (unsigned int) 10 + input[i] - 'A'; + } + else if ((input[i] >= 'a') && (input[i] <= 'f')) + { + h += (unsigned int) 10 + input[i] - 'a'; + } + else /* invalid */ + { + return 0; + } + + if (i < 3) + { + /* shift left to make place for the next nibble */ + h = h << 4; + } + } + + return h; +} + +/* converts a UTF-16 literal to UTF-8 + * A literal can be one or two sequences of the form \uXXXX */ +static unsigned char utf16_literal_to_utf8(const unsigned char * const input_pointer, const unsigned char * const input_end, unsigned char **output_pointer) +{ + long unsigned int codepoint = 0; + unsigned int first_code = 0; + const unsigned char *first_sequence = input_pointer; + unsigned char utf8_length = 0; + unsigned char utf8_position = 0; + unsigned char sequence_length = 0; + unsigned char first_byte_mark = 0; + + if ((input_end - first_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + /* get the first utf16 sequence */ + first_code = parse_hex4(first_sequence + 2); + + /* check that the code is valid */ + if (((first_code >= 0xDC00) && (first_code <= 0xDFFF))) + { + goto fail; + } + + /* UTF16 surrogate pair */ + if ((first_code >= 0xD800) && (first_code <= 0xDBFF)) + { + const unsigned char *second_sequence = first_sequence + 6; + unsigned int second_code = 0; + sequence_length = 12; /* \uXXXX\uXXXX */ + + if ((input_end - second_sequence) < 6) + { + /* input ends unexpectedly */ + goto fail; + } + + if ((second_sequence[0] != '\\') || (second_sequence[1] != 'u')) + { + /* missing second half of the surrogate pair */ + goto fail; + } + + /* get the second utf16 sequence */ + second_code = parse_hex4(second_sequence + 2); + /* check that the code is valid */ + if ((second_code < 0xDC00) || (second_code > 0xDFFF)) + { + /* invalid second half of the surrogate pair */ + goto fail; + } + + + /* calculate the unicode codepoint from the surrogate pair */ + codepoint = 0x10000 + (((first_code & 0x3FF) << 10) | (second_code & 0x3FF)); + } + else + { + sequence_length = 6; /* \uXXXX */ + codepoint = first_code; + } + + /* encode as UTF-8 + * takes at maximum 4 bytes to encode: + * 11110xxx 10xxxxxx 10xxxxxx 10xxxxxx */ + if (codepoint < 0x80) + { + /* normal ascii, encoding 0xxxxxxx */ + utf8_length = 1; + } + else if (codepoint < 0x800) + { + /* two bytes, encoding 110xxxxx 10xxxxxx */ + utf8_length = 2; + first_byte_mark = 0xC0; /* 11000000 */ + } + else if (codepoint < 0x10000) + { + /* three bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx */ + utf8_length = 3; + first_byte_mark = 0xE0; /* 11100000 */ + } + else if (codepoint <= 0x10FFFF) + { + /* four bytes, encoding 1110xxxx 10xxxxxx 10xxxxxx 10xxxxxx */ + utf8_length = 4; + first_byte_mark = 0xF0; /* 11110000 */ + } + else + { + /* invalid unicode codepoint */ + goto fail; + } + + /* encode as utf8 */ + for (utf8_position = (unsigned char)(utf8_length - 1); utf8_position > 0; utf8_position--) + { + /* 10xxxxxx */ + (*output_pointer)[utf8_position] = (unsigned char)((codepoint | 0x80) & 0xBF); + codepoint >>= 6; + } + /* encode first byte */ + if (utf8_length > 1) + { + (*output_pointer)[0] = (unsigned char)((codepoint | first_byte_mark) & 0xFF); + } + else + { + (*output_pointer)[0] = (unsigned char)(codepoint & 0x7F); + } + + *output_pointer += utf8_length; + + return sequence_length; + +fail: + return 0; +} + +/* Parse the input text into an unescaped cinput, and populate item. */ +static cJSON_bool parse_string(cJSON * const item, parse_buffer * const input_buffer) +{ + const unsigned char *input_pointer = buffer_at_offset(input_buffer) + 1; + const unsigned char *input_end = buffer_at_offset(input_buffer) + 1; + unsigned char *output_pointer = NULL; + unsigned char *output = NULL; + + /* not a string */ + if (buffer_at_offset(input_buffer)[0] != '\"') + { + goto fail; + } + + { + /* calculate approximate size of the output (overestimate) */ + size_t allocation_length = 0; + size_t skipped_bytes = 0; + while (((size_t)(input_end - input_buffer->content) < input_buffer->length) && (*input_end != '\"')) + { + /* is escape sequence */ + if (input_end[0] == '\\') + { + if ((size_t)(input_end + 1 - input_buffer->content) >= input_buffer->length) + { + /* prevent buffer overflow when last input character is a backslash */ + goto fail; + } + skipped_bytes++; + input_end++; + } + input_end++; + } + if (((size_t)(input_end - input_buffer->content) >= input_buffer->length) || (*input_end != '\"')) + { + goto fail; /* string ended unexpectedly */ + } + + /* This is at most how much we need for the output */ + allocation_length = (size_t) (input_end - buffer_at_offset(input_buffer)) - skipped_bytes; + output = (unsigned char*)input_buffer->hooks.allocate(allocation_length + sizeof("")); + if (output == NULL) + { + goto fail; /* allocation failure */ + } + } + + output_pointer = output; + /* loop through the string literal */ + while (input_pointer < input_end) + { + if (*input_pointer != '\\') + { + *output_pointer++ = *input_pointer++; + } + /* escape sequence */ + else + { + unsigned char sequence_length = 2; + if ((input_end - input_pointer) < 1) + { + goto fail; + } + + switch (input_pointer[1]) + { + case 'b': + *output_pointer++ = '\b'; + break; + case 'f': + *output_pointer++ = '\f'; + break; + case 'n': + *output_pointer++ = '\n'; + break; + case 'r': + *output_pointer++ = '\r'; + break; + case 't': + *output_pointer++ = '\t'; + break; + case '\"': + case '\\': + case '/': + *output_pointer++ = input_pointer[1]; + break; + + /* UTF-16 literal */ + case 'u': + sequence_length = utf16_literal_to_utf8(input_pointer, input_end, &output_pointer); + if (sequence_length == 0) + { + /* failed to convert UTF16-literal to UTF-8 */ + goto fail; + } + break; + + default: + goto fail; + } + input_pointer += sequence_length; + } + } + + /* zero terminate the output */ + *output_pointer = '\0'; + + item->type = cJSON_String; + item->valuestring = (char*)output; + + input_buffer->offset = (size_t) (input_end - input_buffer->content); + input_buffer->offset++; + + return true; + +fail: + if (output != NULL) + { + input_buffer->hooks.deallocate(output); + output = NULL; + } + + if (input_pointer != NULL) + { + input_buffer->offset = (size_t)(input_pointer - input_buffer->content); + } + + return false; +} + +/* Render the cstring provided to an escaped version that can be printed. */ +static cJSON_bool print_string_ptr(const unsigned char * const input, printbuffer * const output_buffer) +{ + const unsigned char *input_pointer = NULL; + unsigned char *output = NULL; + unsigned char *output_pointer = NULL; + size_t output_length = 0; + /* numbers of additional characters needed for escaping */ + size_t escape_characters = 0; + + if (output_buffer == NULL) + { + return false; + } + + /* empty string */ + if (input == NULL) + { + output = ensure(output_buffer, sizeof("\"\"")); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "\"\""); + + return true; + } + + /* set "flag" to 1 if something needs to be escaped */ + for (input_pointer = input; *input_pointer; input_pointer++) + { + switch (*input_pointer) + { + case '\"': + case '\\': + case '\b': + case '\f': + case '\n': + case '\r': + case '\t': + /* one character escape sequence */ + escape_characters++; + break; + default: + if (*input_pointer < 32) + { + /* UTF-16 escape sequence uXXXX */ + escape_characters += 5; + } + break; + } + } + output_length = (size_t)(input_pointer - input) + escape_characters; + + output = ensure(output_buffer, output_length + sizeof("\"\"")); + if (output == NULL) + { + return false; + } + + /* no characters have to be escaped */ + if (escape_characters == 0) + { + output[0] = '\"'; + memcpy(output + 1, input, output_length); + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; + } + + output[0] = '\"'; + output_pointer = output + 1; + /* copy the string */ + for (input_pointer = input; *input_pointer != '\0'; (void)input_pointer++, output_pointer++) + { + if ((*input_pointer > 31) && (*input_pointer != '\"') && (*input_pointer != '\\')) + { + /* normal character, copy */ + *output_pointer = *input_pointer; + } + else + { + /* character needs to be escaped */ + *output_pointer++ = '\\'; + switch (*input_pointer) + { + case '\\': + *output_pointer = '\\'; + break; + case '\"': + *output_pointer = '\"'; + break; + case '\b': + *output_pointer = 'b'; + break; + case '\f': + *output_pointer = 'f'; + break; + case '\n': + *output_pointer = 'n'; + break; + case '\r': + *output_pointer = 'r'; + break; + case '\t': + *output_pointer = 't'; + break; + default: + /* escape and print as unicode codepoint */ + sprintf((char*)output_pointer, "u%04x", *input_pointer); + output_pointer += 4; + break; + } + } + } + output[output_length + 1] = '\"'; + output[output_length + 2] = '\0'; + + return true; +} + +/* Invoke print_string_ptr (which is useful) on an item. */ +static cJSON_bool print_string(const cJSON * const item, printbuffer * const p) +{ + return print_string_ptr((unsigned char*)item->valuestring, p); +} + +/* Predeclare these prototypes. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer); +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer); +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer); + +/* Utility to jump whitespace and cr/lf */ +static parse_buffer *buffer_skip_whitespace(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL)) + { + return NULL; + } + + if (cannot_access_at_index(buffer, 0)) + { + return buffer; + } + + while (can_access_at_index(buffer, 0) && (buffer_at_offset(buffer)[0] <= 32)) + { + buffer->offset++; + } + + if (buffer->offset == buffer->length) + { + buffer->offset--; + } + + return buffer; +} + +/* skip the UTF-8 BOM (byte order mark) if it is at the beginning of a buffer */ +static parse_buffer *skip_utf8_bom(parse_buffer * const buffer) +{ + if ((buffer == NULL) || (buffer->content == NULL) || (buffer->offset != 0)) + { + return NULL; + } + + if (can_access_at_index(buffer, 4) && (strncmp((const char*)buffer_at_offset(buffer), "\xEF\xBB\xBF", 3) == 0)) + { + buffer->offset += 3; + } + + return buffer; +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + size_t buffer_length; + + if (NULL == value) + { + return NULL; + } + + /* Adding null character size due to require_null_terminated. */ + buffer_length = strlen(value) + sizeof(""); + + return cJSON_ParseWithLengthOpts(value, buffer_length, return_parse_end, require_null_terminated); +} + +/* Parse an object - create a new root, and populate. */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated) +{ + parse_buffer buffer = { 0, 0, 0, 0, { 0, 0, 0 } }; + cJSON *item = NULL; + + /* reset error position */ + global_error.json = NULL; + global_error.position = 0; + + if (value == NULL || 0 == buffer_length) + { + goto fail; + } + + buffer.content = (const unsigned char*)value; + buffer.length = buffer_length; + buffer.offset = 0; + buffer.hooks = global_hooks; + + item = cJSON_New_Item(&global_hooks); + if (item == NULL) /* memory fail */ + { + goto fail; + } + + if (!parse_value(item, buffer_skip_whitespace(skip_utf8_bom(&buffer)))) + { + /* parse failure. ep is set. */ + goto fail; + } + + /* if we require null-terminated JSON without appended garbage, skip and then check for a null terminator */ + if (require_null_terminated) + { + buffer_skip_whitespace(&buffer); + if ((buffer.offset >= buffer.length) || buffer_at_offset(&buffer)[0] != '\0') + { + goto fail; + } + } + if (return_parse_end) + { + *return_parse_end = (const char*)buffer_at_offset(&buffer); + } + + return item; + +fail: + if (item != NULL) + { + cJSON_Delete(item); + } + + if (value != NULL) + { + error local_error; + local_error.json = (const unsigned char*)value; + local_error.position = 0; + + if (buffer.offset < buffer.length) + { + local_error.position = buffer.offset; + } + else if (buffer.length > 0) + { + local_error.position = buffer.length - 1; + } + + if (return_parse_end != NULL) + { + *return_parse_end = (const char*)local_error.json + local_error.position; + } + + global_error = local_error; + } + + return NULL; +} + +/* Default options for cJSON_Parse */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value) +{ + return cJSON_ParseWithOpts(value, 0, 0); +} + +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length) +{ + return cJSON_ParseWithLengthOpts(value, buffer_length, 0, 0); +} + +#define cjson_min(a, b) (((a) < (b)) ? (a) : (b)) + +static unsigned char *print(const cJSON * const item, cJSON_bool format, const internal_hooks * const hooks) +{ + static const size_t default_buffer_size = 256; + printbuffer buffer[1]; + unsigned char *printed = NULL; + + memset(buffer, 0, sizeof(buffer)); + + /* create buffer */ + buffer->buffer = (unsigned char*) hooks->allocate(default_buffer_size); + buffer->length = default_buffer_size; + buffer->format = format; + buffer->hooks = *hooks; + if (buffer->buffer == NULL) + { + goto fail; + } + + /* print the value */ + if (!print_value(item, buffer)) + { + goto fail; + } + update_offset(buffer); + + /* check if reallocate is available */ + if (hooks->reallocate != NULL) + { + printed = (unsigned char*) hooks->reallocate(buffer->buffer, buffer->offset + 1); + if (printed == NULL) { + goto fail; + } + buffer->buffer = NULL; + } + else /* otherwise copy the JSON over to a new buffer */ + { + printed = (unsigned char*) hooks->allocate(buffer->offset + 1); + if (printed == NULL) + { + goto fail; + } + memcpy(printed, buffer->buffer, cjson_min(buffer->length, buffer->offset + 1)); + printed[buffer->offset] = '\0'; /* just to be sure */ + + /* free the buffer */ + hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; + } + + return printed; + +fail: + if (buffer->buffer != NULL) + { + hooks->deallocate(buffer->buffer); + buffer->buffer = NULL; + } + + if (printed != NULL) + { + hooks->deallocate(printed); + printed = NULL; + } + + return NULL; +} + +/* Render a cJSON item/entity/structure to text. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item) +{ + return (char*)print(item, true, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item) +{ + return (char*)print(item, false, &global_hooks); +} + +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if (prebuffer < 0) + { + return NULL; + } + + p.buffer = (unsigned char*)global_hooks.allocate((size_t)prebuffer); + if (!p.buffer) + { + return NULL; + } + + p.length = (size_t)prebuffer; + p.offset = 0; + p.noalloc = false; + p.format = fmt; + p.hooks = global_hooks; + + if (!print_value(item, &p)) + { + global_hooks.deallocate(p.buffer); + p.buffer = NULL; + return NULL; + } + + return (char*)p.buffer; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format) +{ + printbuffer p = { 0, 0, 0, 0, 0, 0, { 0, 0, 0 } }; + + if ((length < 0) || (buffer == NULL)) + { + return false; + } + + p.buffer = (unsigned char*)buffer; + p.length = (size_t)length; + p.offset = 0; + p.noalloc = true; + p.format = format; + p.hooks = global_hooks; + + return print_value(item, &p); +} + +/* Parser core - when encountering text, process appropriately. */ +static cJSON_bool parse_value(cJSON * const item, parse_buffer * const input_buffer) +{ + if ((input_buffer == NULL) || (input_buffer->content == NULL)) + { + return false; /* no input */ + } + + /* parse the different types of values */ + /* null */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "null", 4) == 0)) + { + item->type = cJSON_NULL; + input_buffer->offset += 4; + return true; + } + /* false */ + if (can_read(input_buffer, 5) && (strncmp((const char*)buffer_at_offset(input_buffer), "false", 5) == 0)) + { + item->type = cJSON_False; + input_buffer->offset += 5; + return true; + } + /* true */ + if (can_read(input_buffer, 4) && (strncmp((const char*)buffer_at_offset(input_buffer), "true", 4) == 0)) + { + item->type = cJSON_True; + item->valueint = 1; + input_buffer->offset += 4; + return true; + } + /* string */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '\"')) + { + return parse_string(item, input_buffer); + } + /* number */ + if (can_access_at_index(input_buffer, 0) && ((buffer_at_offset(input_buffer)[0] == '-') || ((buffer_at_offset(input_buffer)[0] >= '0') && (buffer_at_offset(input_buffer)[0] <= '9')))) + { + return parse_number(item, input_buffer); + } + /* array */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '[')) + { + return parse_array(item, input_buffer); + } + /* object */ + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '{')) + { + return parse_object(item, input_buffer); + } + + return false; +} + +/* Render a value to text. */ +static cJSON_bool print_value(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output = NULL; + + if ((item == NULL) || (output_buffer == NULL)) + { + return false; + } + + switch ((item->type) & 0xFF) + { + case cJSON_NULL: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "null"); + return true; + + case cJSON_False: + output = ensure(output_buffer, 6); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "false"); + return true; + + case cJSON_True: + output = ensure(output_buffer, 5); + if (output == NULL) + { + return false; + } + strcpy((char*)output, "true"); + return true; + + case cJSON_Number: + return print_number(item, output_buffer); + + case cJSON_Raw: + { + size_t raw_length = 0; + if (item->valuestring == NULL) + { + return false; + } + + raw_length = strlen(item->valuestring) + sizeof(""); + output = ensure(output_buffer, raw_length); + if (output == NULL) + { + return false; + } + memcpy(output, item->valuestring, raw_length); + return true; + } + + case cJSON_String: + return print_string(item, output_buffer); + + case cJSON_Array: + return print_array(item, output_buffer); + + case cJSON_Object: + return print_object(item, output_buffer); + + default: + return false; + } +} + +/* Build an array from input text. */ +static cJSON_bool parse_array(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* head of the linked list */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (buffer_at_offset(input_buffer)[0] != '[') + { + /* not an array */ + goto fail; + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ']')) + { + /* empty array */ + goto success; + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + /* parse next value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || buffer_at_offset(input_buffer)[0] != ']') + { + goto fail; /* expected end of array */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Array; + item->child = head; + + input_buffer->offset++; + + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an array to text */ +static cJSON_bool print_array(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_element = item->child; + + if (output_buffer == NULL) + { + return false; + } + + if (output_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* nesting is too deep */ + } + + /* Compose the output array. */ + /* opening square bracket */ + output_pointer = ensure(output_buffer, 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer = '['; + output_buffer->offset++; + output_buffer->depth++; + + while (current_element != NULL) + { + if (!print_value(current_element, output_buffer)) + { + return false; + } + update_offset(output_buffer); + if (current_element->next) + { + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ','; + if(output_buffer->format) + { + *output_pointer++ = ' '; + } + *output_pointer = '\0'; + output_buffer->offset += length; + } + current_element = current_element->next; + } + + output_pointer = ensure(output_buffer, 2); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ']'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Build an object from the text. */ +static cJSON_bool parse_object(cJSON * const item, parse_buffer * const input_buffer) +{ + cJSON *head = NULL; /* linked list head */ + cJSON *current_item = NULL; + + if (input_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* to deeply nested */ + } + input_buffer->depth++; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '{')) + { + goto fail; /* not an object */ + } + + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == '}')) + { + goto success; /* empty object */ + } + + /* check if we skipped to the end of the buffer */ + if (cannot_access_at_index(input_buffer, 0)) + { + input_buffer->offset--; + goto fail; + } + + /* step back to character in front of the first element */ + input_buffer->offset--; + /* loop through the comma separated array elements */ + do + { + /* allocate next item */ + cJSON *new_item = cJSON_New_Item(&(input_buffer->hooks)); + if (new_item == NULL) + { + goto fail; /* allocation failure */ + } + + /* attach next item to list */ + if (head == NULL) + { + /* start the linked list */ + current_item = head = new_item; + } + else + { + /* add to the end and advance */ + current_item->next = new_item; + new_item->prev = current_item; + current_item = new_item; + } + + if (cannot_access_at_index(input_buffer, 1)) + { + goto fail; /* nothing comes after the comma */ + } + + /* parse the name of the child */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_string(current_item, input_buffer)) + { + goto fail; /* failed to parse name */ + } + buffer_skip_whitespace(input_buffer); + + /* swap valuestring and string, because we parsed the name */ + current_item->string = current_item->valuestring; + current_item->valuestring = NULL; + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != ':')) + { + goto fail; /* invalid object */ + } + + /* parse the value */ + input_buffer->offset++; + buffer_skip_whitespace(input_buffer); + if (!parse_value(current_item, input_buffer)) + { + goto fail; /* failed to parse value */ + } + buffer_skip_whitespace(input_buffer); + } + while (can_access_at_index(input_buffer, 0) && (buffer_at_offset(input_buffer)[0] == ',')); + + if (cannot_access_at_index(input_buffer, 0) || (buffer_at_offset(input_buffer)[0] != '}')) + { + goto fail; /* expected end of object */ + } + +success: + input_buffer->depth--; + + if (head != NULL) { + head->prev = current_item; + } + + item->type = cJSON_Object; + item->child = head; + + input_buffer->offset++; + return true; + +fail: + if (head != NULL) + { + cJSON_Delete(head); + } + + return false; +} + +/* Render an object to text. */ +static cJSON_bool print_object(const cJSON * const item, printbuffer * const output_buffer) +{ + unsigned char *output_pointer = NULL; + size_t length = 0; + cJSON *current_item = item->child; + + if (output_buffer == NULL) + { + return false; + } + + if (output_buffer->depth >= CJSON_NESTING_LIMIT) + { + return false; /* nesting is too deep */ + } + + /* Compose the output: */ + length = (size_t) (output_buffer->format ? 2 : 1); /* fmt: {\n */ + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + + *output_pointer++ = '{'; + output_buffer->depth++; + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + output_buffer->offset += length; + + while (current_item) + { + if (output_buffer->format) + { + size_t i; + output_pointer = ensure(output_buffer, output_buffer->depth); + if (output_pointer == NULL) + { + return false; + } + for (i = 0; i < output_buffer->depth; i++) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += output_buffer->depth; + } + + /* print key */ + if (!print_string_ptr((unsigned char*)current_item->string, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + length = (size_t) (output_buffer->format ? 2 : 1); + output_pointer = ensure(output_buffer, length); + if (output_pointer == NULL) + { + return false; + } + *output_pointer++ = ':'; + if (output_buffer->format) + { + *output_pointer++ = '\t'; + } + output_buffer->offset += length; + + /* print value */ + if (!print_value(current_item, output_buffer)) + { + return false; + } + update_offset(output_buffer); + + /* print comma if not last */ + length = ((size_t)(output_buffer->format ? 1 : 0) + (size_t)(current_item->next ? 1 : 0)); + output_pointer = ensure(output_buffer, length + 1); + if (output_pointer == NULL) + { + return false; + } + if (current_item->next) + { + *output_pointer++ = ','; + } + + if (output_buffer->format) + { + *output_pointer++ = '\n'; + } + *output_pointer = '\0'; + output_buffer->offset += length; + + current_item = current_item->next; + } + + output_pointer = ensure(output_buffer, output_buffer->format ? (output_buffer->depth + 1) : 2); + if (output_pointer == NULL) + { + return false; + } + if (output_buffer->format) + { + size_t i; + for (i = 0; i < (output_buffer->depth - 1); i++) + { + *output_pointer++ = '\t'; + } + } + *output_pointer++ = '}'; + *output_pointer = '\0'; + output_buffer->depth--; + + return true; +} + +/* Get Array size/item / object item. */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array) +{ + cJSON *child = NULL; + size_t size = 0; + + if (array == NULL) + { + return 0; + } + + child = array->child; + + while(child != NULL) + { + size++; + child = child->next; + } + + /* FIXME: Can overflow here. Cannot be fixed without breaking the API */ + + return (int)size; +} + +static cJSON* get_array_item(const cJSON *array, size_t index) +{ + cJSON *current_child = NULL; + + if (array == NULL) + { + return NULL; + } + + current_child = array->child; + while ((current_child != NULL) && (index > 0)) + { + index--; + current_child = current_child->next; + } + + return current_child; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index) +{ + if (index < 0) + { + return NULL; + } + + return get_array_item(array, (size_t)index); +} + +static cJSON *get_object_item(const cJSON * const object, const char * const name, const cJSON_bool case_sensitive) +{ + cJSON *current_element = NULL; + + if ((object == NULL) || (name == NULL)) + { + return NULL; + } + + current_element = object->child; + if (case_sensitive) + { + while ((current_element != NULL) && (current_element->string != NULL) && (strcmp(name, current_element->string) != 0)) + { + current_element = current_element->next; + } + } + else + { + while ((current_element != NULL) && (case_insensitive_strcmp((const unsigned char*)name, (const unsigned char*)(current_element->string)) != 0)) + { + current_element = current_element->next; + } + } + + if ((current_element == NULL) || (current_element->string == NULL)) { + return NULL; + } + + return current_element; +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, false); +} + +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string) +{ + return get_object_item(object, string, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string) +{ + return cJSON_GetObjectItem(object, string) ? 1 : 0; +} + +/* Utility for array list handling. */ +static void suffix_object(cJSON *prev, cJSON *item) +{ + prev->next = item; + item->prev = prev; +} + +/* Utility for handling references. */ +static cJSON *create_reference(const cJSON *item, const internal_hooks * const hooks) +{ + cJSON *reference = NULL; + if (item == NULL) + { + return NULL; + } + + reference = cJSON_New_Item(hooks); + if (reference == NULL) + { + return NULL; + } + + memcpy(reference, item, sizeof(cJSON)); + reference->string = NULL; + reference->type |= cJSON_IsReference; + reference->next = reference->prev = NULL; + return reference; +} + +static cJSON_bool add_item_to_array(cJSON *array, cJSON *item) +{ + cJSON *child = NULL; + + if ((item == NULL) || (array == NULL) || (array == item)) + { + return false; + } + + child = array->child; + /* + * To find the last item in array quickly, we use prev in array + */ + if (child == NULL) + { + /* list is empty, start new one */ + array->child = item; + item->prev = item; + item->next = NULL; + } + else + { + /* append to the end */ + if (child->prev) + { + suffix_object(child->prev, item); + array->child->prev = item; + } + } + + return true; +} + +/* Add item to array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item) +{ + return add_item_to_array(array, item); +} + +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic push +#endif +#ifdef __GNUC__ +#pragma GCC diagnostic ignored "-Wcast-qual" +#endif +/* helper function to cast away const */ +static void* cast_away_const(const void* string) +{ + return (void*)string; +} +#if defined(__clang__) || (defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && (__GNUC_MINOR__ > 5)))) + #pragma GCC diagnostic pop +#endif + + +static cJSON_bool add_item_to_object(cJSON * const object, const char * const string, cJSON * const item, const internal_hooks * const hooks, const cJSON_bool constant_key) +{ + char *new_key = NULL; + int new_type = cJSON_Invalid; + + if ((object == NULL) || (string == NULL) || (item == NULL) || (object == item)) + { + return false; + } + + if (constant_key) + { + new_key = (char*)cast_away_const(string); + new_type = item->type | cJSON_StringIsConst; + } + else + { + new_key = (char*)cJSON_strdup((const unsigned char*)string, hooks); + if (new_key == NULL) + { + return false; + } + + new_type = item->type & ~cJSON_StringIsConst; + } + + if (!(item->type & cJSON_StringIsConst) && (item->string != NULL)) + { + hooks->deallocate(item->string); + } + + item->string = new_key; + item->type = new_type; + + return add_item_to_array(object, item); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, false); +} + +/* Add an item to an object with constant string as key */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item) +{ + return add_item_to_object(object, string, item, &global_hooks, true); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item) +{ + if (array == NULL) + { + return false; + } + + return add_item_to_array(array, create_reference(item, &global_hooks)); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item) +{ + if ((object == NULL) || (string == NULL)) + { + return false; + } + + return add_item_to_object(object, string, create_reference(item, &global_hooks), &global_hooks, false); +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name) +{ + cJSON *null = cJSON_CreateNull(); + if (add_item_to_object(object, name, null, &global_hooks, false)) + { + return null; + } + + cJSON_Delete(null); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name) +{ + cJSON *true_item = cJSON_CreateTrue(); + if (add_item_to_object(object, name, true_item, &global_hooks, false)) + { + return true_item; + } + + cJSON_Delete(true_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name) +{ + cJSON *false_item = cJSON_CreateFalse(); + if (add_item_to_object(object, name, false_item, &global_hooks, false)) + { + return false_item; + } + + cJSON_Delete(false_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean) +{ + cJSON *bool_item = cJSON_CreateBool(boolean); + if (add_item_to_object(object, name, bool_item, &global_hooks, false)) + { + return bool_item; + } + + cJSON_Delete(bool_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number) +{ + cJSON *number_item = cJSON_CreateNumber(number); + if (add_item_to_object(object, name, number_item, &global_hooks, false)) + { + return number_item; + } + + cJSON_Delete(number_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string) +{ + cJSON *string_item = cJSON_CreateString(string); + if (add_item_to_object(object, name, string_item, &global_hooks, false)) + { + return string_item; + } + + cJSON_Delete(string_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw) +{ + cJSON *raw_item = cJSON_CreateRaw(raw); + if (add_item_to_object(object, name, raw_item, &global_hooks, false)) + { + return raw_item; + } + + cJSON_Delete(raw_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name) +{ + cJSON *object_item = cJSON_CreateObject(); + if (add_item_to_object(object, name, object_item, &global_hooks, false)) + { + return object_item; + } + + cJSON_Delete(object_item); + return NULL; +} + +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name) +{ + cJSON *array = cJSON_CreateArray(); + if (add_item_to_object(object, name, array, &global_hooks, false)) + { + return array; + } + + cJSON_Delete(array); + return NULL; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item) +{ + if ((parent == NULL) || (item == NULL) || (item != parent->child && item->prev == NULL)) + { + return NULL; + } + + if (item != parent->child) + { + /* not the first element */ + item->prev->next = item->next; + } + if (item->next != NULL) + { + /* not the last element */ + item->next->prev = item->prev; + } + + if (item == parent->child) + { + /* first element */ + parent->child = item->next; + } + else if (item->next == NULL) + { + /* last element */ + parent->child->prev = item->prev; + } + + /* make sure the detached item doesn't point anywhere anymore */ + item->prev = NULL; + item->next = NULL; + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which) +{ + if (which < 0) + { + return NULL; + } + + return cJSON_DetachItemViaPointer(array, get_array_item(array, (size_t)which)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which) +{ + cJSON_Delete(cJSON_DetachItemFromArray(array, which)); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItem(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON *to_detach = cJSON_GetObjectItemCaseSensitive(object, string); + + return cJSON_DetachItemViaPointer(object, to_detach); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObject(object, string)); +} + +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string) +{ + cJSON_Delete(cJSON_DetachItemFromObjectCaseSensitive(object, string)); +} + +/* Replace array/object items with new ones. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem) +{ + cJSON *after_inserted = NULL; + + if (which < 0 || newitem == NULL) + { + return false; + } + + after_inserted = get_array_item(array, (size_t)which); + if (after_inserted == NULL) + { + return add_item_to_array(array, newitem); + } + + if (after_inserted != array->child && after_inserted->prev == NULL) { + /* return false if after_inserted is a corrupted array item */ + return false; + } + + newitem->next = after_inserted; + newitem->prev = after_inserted->prev; + after_inserted->prev = newitem; + if (after_inserted == array->child) + { + array->child = newitem; + } + else + { + newitem->prev->next = newitem; + } + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement) +{ + if ((parent == NULL) || (parent->child == NULL) || (replacement == NULL) || (item == NULL)) + { + return false; + } + + if (replacement == item) + { + return true; + } + + replacement->next = item->next; + replacement->prev = item->prev; + + if (replacement->next != NULL) + { + replacement->next->prev = replacement; + } + if (parent->child == item) + { + if (parent->child->prev == parent->child) + { + replacement->prev = replacement; + } + parent->child = replacement; + } + else + { /* + * To find the last item in array quickly, we use prev in array. + * We can't modify the last item's next pointer where this item was the parent's child + */ + if (replacement->prev != NULL) + { + replacement->prev->next = replacement; + } + if (replacement->next == NULL) + { + parent->child->prev = replacement; + } + } + + item->next = NULL; + item->prev = NULL; + cJSON_Delete(item); + + return true; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem) +{ + if (which < 0) + { + return false; + } + + return cJSON_ReplaceItemViaPointer(array, get_array_item(array, (size_t)which), newitem); +} + +static cJSON_bool replace_item_in_object(cJSON *object, const char *string, cJSON *replacement, cJSON_bool case_sensitive) +{ + if ((replacement == NULL) || (string == NULL)) + { + return false; + } + + /* replace the name in the replacement */ + if (!(replacement->type & cJSON_StringIsConst) && (replacement->string != NULL)) + { + cJSON_free(replacement->string); + } + replacement->string = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if (replacement->string == NULL) + { + return false; + } + + replacement->type &= ~cJSON_StringIsConst; + + return cJSON_ReplaceItemViaPointer(object, get_object_item(object, string, case_sensitive), replacement); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, false); +} + +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object, const char *string, cJSON *newitem) +{ + return replace_item_in_object(object, string, newitem, true); +} + +/* Create basic types: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_NULL; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_True; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = boolean ? cJSON_True : cJSON_False; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Number; + item->valuedouble = num; + + /* use saturation in case of overflow */ + if (num >= INT_MAX) + { + item->valueint = INT_MAX; + } + else if (num <= (double)INT_MIN) + { + item->valueint = INT_MIN; + } + else + { + item->valueint = (int)num; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_String; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)string, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) + { + item->type = cJSON_String | cJSON_IsReference; + item->valuestring = (char*)cast_away_const(string); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Object | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child) { + cJSON *item = cJSON_New_Item(&global_hooks); + if (item != NULL) { + item->type = cJSON_Array | cJSON_IsReference; + item->child = (cJSON*)cast_away_const(child); + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type = cJSON_Raw; + item->valuestring = (char*)cJSON_strdup((const unsigned char*)raw, &global_hooks); + if(!item->valuestring) + { + cJSON_Delete(item); + return NULL; + } + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if(item) + { + item->type=cJSON_Array; + } + + return item; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void) +{ + cJSON *item = cJSON_New_Item(&global_hooks); + if (item) + { + item->type = cJSON_Object; + } + + return item; +} + +/* Create Arrays: */ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if (!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber((double)numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (numbers == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for(i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateNumber(numbers[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p, n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count) +{ + size_t i = 0; + cJSON *n = NULL; + cJSON *p = NULL; + cJSON *a = NULL; + + if ((count < 0) || (strings == NULL)) + { + return NULL; + } + + a = cJSON_CreateArray(); + + for (i = 0; a && (i < (size_t)count); i++) + { + n = cJSON_CreateString(strings[i]); + if(!n) + { + cJSON_Delete(a); + return NULL; + } + if(!i) + { + a->child = n; + } + else + { + suffix_object(p,n); + } + p = n; + } + + if (a && a->child) { + a->child->prev = n; + } + + return a; +} + +/* Duplication */ +cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse); + +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse) +{ + return cJSON_Duplicate_rec(item, 0, recurse ); +} + +cJSON * cJSON_Duplicate_rec(const cJSON *item, size_t depth, cJSON_bool recurse) +{ + cJSON *newitem = NULL; + cJSON *child = NULL; + cJSON *next = NULL; + cJSON *newchild = NULL; + + /* Bail on bad ptr */ + if (!item) + { + goto fail; + } + /* Create new item */ + newitem = cJSON_New_Item(&global_hooks); + if (!newitem) + { + goto fail; + } + /* Copy over all vars */ + newitem->type = item->type & (~cJSON_IsReference); + newitem->valueint = item->valueint; + newitem->valuedouble = item->valuedouble; + if (item->valuestring) + { + newitem->valuestring = (char*)cJSON_strdup((unsigned char*)item->valuestring, &global_hooks); + if (!newitem->valuestring) + { + goto fail; + } + } + if (item->string) + { + newitem->string = (item->type&cJSON_StringIsConst) ? item->string : (char*)cJSON_strdup((unsigned char*)item->string, &global_hooks); + if (!newitem->string) + { + goto fail; + } + } + /* If non-recursive, then we're done! */ + if (!recurse) + { + return newitem; + } + /* Walk the ->next chain for the child. */ + child = item->child; + while (child != NULL) + { + if(depth >= CJSON_CIRCULAR_LIMIT) { + goto fail; + } + newchild = cJSON_Duplicate_rec(child, depth + 1, true); /* Duplicate (with recurse) each item in the ->next chain */ + if (!newchild) + { + goto fail; + } + if (next != NULL) + { + /* If newitem->child already set, then crosswire ->prev and ->next and move on */ + next->next = newchild; + newchild->prev = next; + next = newchild; + } + else + { + /* Set newitem->child and move to it */ + newitem->child = newchild; + next = newchild; + } + child = child->next; + } + if (newitem && newitem->child) + { + newitem->child->prev = newchild; + } + + return newitem; + +fail: + if (newitem != NULL) + { + cJSON_Delete(newitem); + } + + return NULL; +} + +static void skip_oneline_comment(char **input) +{ + *input += static_strlen("//"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if ((*input)[0] == '\n') { + *input += static_strlen("\n"); + return; + } + } +} + +static void skip_multiline_comment(char **input) +{ + *input += static_strlen("/*"); + + for (; (*input)[0] != '\0'; ++(*input)) + { + if (((*input)[0] == '*') && ((*input)[1] == '/')) + { + *input += static_strlen("*/"); + return; + } + } +} + +static void minify_string(char **input, char **output) { + (*output)[0] = (*input)[0]; + *input += static_strlen("\""); + *output += static_strlen("\""); + + + for (; (*input)[0] != '\0'; (void)++(*input), ++(*output)) { + (*output)[0] = (*input)[0]; + + if ((*input)[0] == '\"') { + (*output)[0] = '\"'; + *input += static_strlen("\""); + *output += static_strlen("\""); + return; + } else if (((*input)[0] == '\\') && ((*input)[1] == '\"')) { + (*output)[1] = (*input)[1]; + *input += static_strlen("\""); + *output += static_strlen("\""); + } + } +} + +CJSON_PUBLIC(void) cJSON_Minify(char *json) +{ + char *into = json; + + if (json == NULL) + { + return; + } + + while (json[0] != '\0') + { + switch (json[0]) + { + case ' ': + case '\t': + case '\r': + case '\n': + json++; + break; + + case '/': + if (json[1] == '/') + { + skip_oneline_comment(&json); + } + else if (json[1] == '*') + { + skip_multiline_comment(&json); + } else { + json++; + } + break; + + case '\"': + minify_string(&json, (char**)&into); + break; + + default: + into[0] = json[0]; + json++; + into++; + } + } + + /* and null-terminate. */ + *into = '\0'; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Invalid; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_False; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xff) == cJSON_True; +} + + +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & (cJSON_True | cJSON_False)) != 0; +} +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_NULL; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Number; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_String; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Array; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Object; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item) +{ + if (item == NULL) + { + return false; + } + + return (item->type & 0xFF) == cJSON_Raw; +} + +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive) +{ + if ((a == NULL) || (b == NULL) || ((a->type & 0xFF) != (b->type & 0xFF))) + { + return false; + } + + /* check if type is valid */ + switch (a->type & 0xFF) + { + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + case cJSON_Number: + case cJSON_String: + case cJSON_Raw: + case cJSON_Array: + case cJSON_Object: + break; + + default: + return false; + } + + /* identical objects are equal */ + if (a == b) + { + return true; + } + + switch (a->type & 0xFF) + { + /* in these cases and equal type is enough */ + case cJSON_False: + case cJSON_True: + case cJSON_NULL: + return true; + + case cJSON_Number: + if (compare_double(a->valuedouble, b->valuedouble)) + { + return true; + } + return false; + + case cJSON_String: + case cJSON_Raw: + if ((a->valuestring == NULL) || (b->valuestring == NULL)) + { + return false; + } + if (strcmp(a->valuestring, b->valuestring) == 0) + { + return true; + } + + return false; + + case cJSON_Array: + { + cJSON *a_element = a->child; + cJSON *b_element = b->child; + + for (; (a_element != NULL) && (b_element != NULL);) + { + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + + a_element = a_element->next; + b_element = b_element->next; + } + + /* one of the arrays is longer than the other */ + if (a_element != b_element) { + return false; + } + + return true; + } + + case cJSON_Object: + { + cJSON *a_element = NULL; + cJSON *b_element = NULL; + cJSON_ArrayForEach(a_element, a) + { + /* TODO This has O(n^2) runtime, which is horrible! */ + b_element = get_object_item(b, a_element->string, case_sensitive); + if (b_element == NULL) + { + return false; + } + + if (!cJSON_Compare(a_element, b_element, case_sensitive)) + { + return false; + } + } + + /* doing this twice, once on a and b to prevent true comparison if a subset of b + * TODO: Do this the proper way, this is just a fix for now */ + cJSON_ArrayForEach(b_element, b) + { + a_element = get_object_item(a, b_element->string, case_sensitive); + if (a_element == NULL) + { + return false; + } + + if (!cJSON_Compare(b_element, a_element, case_sensitive)) + { + return false; + } + } + + return true; + } + + default: + return false; + } +} + +CJSON_PUBLIC(void *) cJSON_malloc(size_t size) +{ + return global_hooks.allocate(size); +} + +CJSON_PUBLIC(void) cJSON_free(void *object) +{ + global_hooks.deallocate(object); + object = NULL; +} diff --git a/src/cJSON.h b/src/cJSON.h new file mode 100644 index 0000000..cab5feb --- /dev/null +++ b/src/cJSON.h @@ -0,0 +1,306 @@ +/* + Copyright (c) 2009-2017 Dave Gamble and cJSON contributors + + Permission is hereby granted, free of charge, to any person obtaining a copy + of this software and associated documentation files (the "Software"), to deal + in the Software without restriction, including without limitation the rights + to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + copies of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + THE SOFTWARE. +*/ + +#ifndef cJSON__h +#define cJSON__h + +#ifdef __cplusplus +extern "C" +{ +#endif + +#if !defined(__WINDOWS__) && (defined(WIN32) || defined(WIN64) || defined(_MSC_VER) || defined(_WIN32)) +#define __WINDOWS__ +#endif + +#ifdef __WINDOWS__ + +/* When compiling for windows, we specify a specific calling convention to avoid issues where we are being called from a project with a different default calling convention. For windows you have 3 define options: + +CJSON_HIDE_SYMBOLS - Define this in the case where you don't want to ever dllexport symbols +CJSON_EXPORT_SYMBOLS - Define this on library build when you want to dllexport symbols (default) +CJSON_IMPORT_SYMBOLS - Define this if you want to dllimport symbol + +For *nix builds that support visibility attribute, you can define similar behavior by + +setting default visibility to hidden by adding +-fvisibility=hidden (for gcc) +or +-xldscope=hidden (for sun cc) +to CFLAGS + +then using the CJSON_API_VISIBILITY flag to "export" the same symbols the way CJSON_EXPORT_SYMBOLS does + +*/ + +#define CJSON_CDECL __cdecl +#define CJSON_STDCALL __stdcall + +/* export symbols by default, this is necessary for copy pasting the C and header file */ +#if !defined(CJSON_HIDE_SYMBOLS) && !defined(CJSON_IMPORT_SYMBOLS) && !defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_EXPORT_SYMBOLS +#endif + +#if defined(CJSON_HIDE_SYMBOLS) +#define CJSON_PUBLIC(type) type CJSON_STDCALL +#elif defined(CJSON_EXPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllexport) type CJSON_STDCALL +#elif defined(CJSON_IMPORT_SYMBOLS) +#define CJSON_PUBLIC(type) __declspec(dllimport) type CJSON_STDCALL +#endif +#else /* !__WINDOWS__ */ +#define CJSON_CDECL +#define CJSON_STDCALL + +#if (defined(__GNUC__) || defined(__SUNPRO_CC) || defined (__SUNPRO_C)) && defined(CJSON_API_VISIBILITY) +#define CJSON_PUBLIC(type) __attribute__((visibility("default"))) type +#else +#define CJSON_PUBLIC(type) type +#endif +#endif + +/* project version */ +#define CJSON_VERSION_MAJOR 1 +#define CJSON_VERSION_MINOR 7 +#define CJSON_VERSION_PATCH 19 + +#include + +/* cJSON Types: */ +#define cJSON_Invalid (0) +#define cJSON_False (1 << 0) +#define cJSON_True (1 << 1) +#define cJSON_NULL (1 << 2) +#define cJSON_Number (1 << 3) +#define cJSON_String (1 << 4) +#define cJSON_Array (1 << 5) +#define cJSON_Object (1 << 6) +#define cJSON_Raw (1 << 7) /* raw json */ + +#define cJSON_IsReference 256 +#define cJSON_StringIsConst 512 + +/* The cJSON structure: */ +typedef struct cJSON +{ + /* next/prev allow you to walk array/object chains. Alternatively, use GetArraySize/GetArrayItem/GetObjectItem */ + struct cJSON *next; + struct cJSON *prev; + /* An array or object item will have a child pointer pointing to a chain of the items in the array/object. */ + struct cJSON *child; + + /* The type of the item, as above. */ + int type; + + /* The item's string, if type==cJSON_String and type == cJSON_Raw */ + char *valuestring; + /* writing to valueint is DEPRECATED, use cJSON_SetNumberValue instead */ + int valueint; + /* The item's number, if type==cJSON_Number */ + double valuedouble; + + /* The item's name string, if this item is the child of, or is in the list of subitems of an object. */ + char *string; +} cJSON; + +typedef struct cJSON_Hooks +{ + /* malloc/free are CDECL on Windows regardless of the default calling convention of the compiler, so ensure the hooks allow passing those functions directly. */ + void *(CJSON_CDECL *malloc_fn)(size_t sz); + void (CJSON_CDECL *free_fn)(void *ptr); +} cJSON_Hooks; + +typedef int cJSON_bool; + +/* Limits how deeply nested arrays/objects can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_NESTING_LIMIT +#define CJSON_NESTING_LIMIT 1000 +#endif + +/* Limits the length of circular references can be before cJSON rejects to parse them. + * This is to prevent stack overflows. */ +#ifndef CJSON_CIRCULAR_LIMIT +#define CJSON_CIRCULAR_LIMIT 10000 +#endif + +/* returns the version of cJSON as a string */ +CJSON_PUBLIC(const char*) cJSON_Version(void); + +/* Supply malloc, realloc and free functions to cJSON */ +CJSON_PUBLIC(void) cJSON_InitHooks(cJSON_Hooks* hooks); + +/* Memory Management: the caller is always responsible to free the results from all variants of cJSON_Parse (with cJSON_Delete) and cJSON_Print (with stdlib free, cJSON_Hooks.free_fn, or cJSON_free as appropriate). The exception is cJSON_PrintPreallocated, where the caller has full responsibility of the buffer. */ +/* Supply a block of JSON, and this returns a cJSON object you can interrogate. */ +CJSON_PUBLIC(cJSON *) cJSON_Parse(const char *value); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLength(const char *value, size_t buffer_length); +/* ParseWithOpts allows you to require (and check) that the JSON is null terminated, and to retrieve the pointer to the final byte parsed. */ +/* If you supply a ptr in return_parse_end and parsing fails, then return_parse_end will contain a pointer to the error so will match cJSON_GetErrorPtr(). */ +CJSON_PUBLIC(cJSON *) cJSON_ParseWithOpts(const char *value, const char **return_parse_end, cJSON_bool require_null_terminated); +CJSON_PUBLIC(cJSON *) cJSON_ParseWithLengthOpts(const char *value, size_t buffer_length, const char **return_parse_end, cJSON_bool require_null_terminated); + +/* Render a cJSON entity to text for transfer/storage. */ +CJSON_PUBLIC(char *) cJSON_Print(const cJSON *item); +/* Render a cJSON entity to text for transfer/storage without any formatting. */ +CJSON_PUBLIC(char *) cJSON_PrintUnformatted(const cJSON *item); +/* Render a cJSON entity to text using a buffered strategy. prebuffer is a guess at the final size. guessing well reduces reallocation. fmt=0 gives unformatted, =1 gives formatted */ +CJSON_PUBLIC(char *) cJSON_PrintBuffered(const cJSON *item, int prebuffer, cJSON_bool fmt); +/* Render a cJSON entity to text using a buffer already allocated in memory with given length. Returns 1 on success and 0 on failure. */ +/* NOTE: cJSON is not always 100% accurate in estimating how much memory it will use, so to be safe allocate 5 bytes more than you actually need */ +CJSON_PUBLIC(cJSON_bool) cJSON_PrintPreallocated(cJSON *item, char *buffer, const int length, const cJSON_bool format); +/* Delete a cJSON entity and all subentities. */ +CJSON_PUBLIC(void) cJSON_Delete(cJSON *item); + +/* Returns the number of items in an array (or object). */ +CJSON_PUBLIC(int) cJSON_GetArraySize(const cJSON *array); +/* Retrieve item number "index" from array "array". Returns NULL if unsuccessful. */ +CJSON_PUBLIC(cJSON *) cJSON_GetArrayItem(const cJSON *array, int index); +/* Get item "string" from object. Case insensitive. */ +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItem(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON *) cJSON_GetObjectItemCaseSensitive(const cJSON * const object, const char * const string); +CJSON_PUBLIC(cJSON_bool) cJSON_HasObjectItem(const cJSON *object, const char *string); +/* For analysing failed parses. This returns a pointer to the parse error. You'll probably need to look a few chars back to make sense of it. Defined when cJSON_Parse() returns 0. 0 when cJSON_Parse() succeeds. */ +CJSON_PUBLIC(const char *) cJSON_GetErrorPtr(void); + +/* Check item type and return its value */ +CJSON_PUBLIC(char *) cJSON_GetStringValue(const cJSON * const item); +CJSON_PUBLIC(double) cJSON_GetNumberValue(const cJSON * const item); + +/* These functions check the type of an item */ +CJSON_PUBLIC(cJSON_bool) cJSON_IsInvalid(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsFalse(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsTrue(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsBool(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNull(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsNumber(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsString(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsArray(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsObject(const cJSON * const item); +CJSON_PUBLIC(cJSON_bool) cJSON_IsRaw(const cJSON * const item); + +/* These calls create a cJSON item of the appropriate type. */ +CJSON_PUBLIC(cJSON *) cJSON_CreateNull(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateTrue(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateFalse(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateBool(cJSON_bool boolean); +CJSON_PUBLIC(cJSON *) cJSON_CreateNumber(double num); +CJSON_PUBLIC(cJSON *) cJSON_CreateString(const char *string); +/* raw json */ +CJSON_PUBLIC(cJSON *) cJSON_CreateRaw(const char *raw); +CJSON_PUBLIC(cJSON *) cJSON_CreateArray(void); +CJSON_PUBLIC(cJSON *) cJSON_CreateObject(void); + +/* Create a string where valuestring references a string so + * it will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateStringReference(const char *string); +/* Create an object/array that only references it's elements so + * they will not be freed by cJSON_Delete */ +CJSON_PUBLIC(cJSON *) cJSON_CreateObjectReference(const cJSON *child); +CJSON_PUBLIC(cJSON *) cJSON_CreateArrayReference(const cJSON *child); + +/* These utilities create an Array of count items. + * The parameter count cannot be greater than the number of elements in the number array, otherwise array access will be out of bounds.*/ +CJSON_PUBLIC(cJSON *) cJSON_CreateIntArray(const int *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateFloatArray(const float *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateDoubleArray(const double *numbers, int count); +CJSON_PUBLIC(cJSON *) cJSON_CreateStringArray(const char *const *strings, int count); + +/* Append item to the specified array/object. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObject(cJSON *object, const char *string, cJSON *item); +/* Use this when string is definitely const (i.e. a literal, or as good as), and will definitely survive the cJSON object. + * WARNING: When this function was used, make sure to always check that (item->type & cJSON_StringIsConst) is zero before + * writing to `item->string` */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemToObjectCS(cJSON *object, const char *string, cJSON *item); +/* Append reference to item to the specified array/object. Use this when you want to add an existing cJSON to a new cJSON, but don't want to corrupt your existing cJSON. */ +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToArray(cJSON *array, cJSON *item); +CJSON_PUBLIC(cJSON_bool) cJSON_AddItemReferenceToObject(cJSON *object, const char *string, cJSON *item); + +/* Remove/Detach items from Arrays/Objects. */ +CJSON_PUBLIC(cJSON *) cJSON_DetachItemViaPointer(cJSON *parent, cJSON * const item); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(void) cJSON_DeleteItemFromArray(cJSON *array, int which); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(cJSON *) cJSON_DetachItemFromObjectCaseSensitive(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObject(cJSON *object, const char *string); +CJSON_PUBLIC(void) cJSON_DeleteItemFromObjectCaseSensitive(cJSON *object, const char *string); + +/* Update array items. */ +CJSON_PUBLIC(cJSON_bool) cJSON_InsertItemInArray(cJSON *array, int which, cJSON *newitem); /* Shifts pre-existing items to the right. */ +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemViaPointer(cJSON * const parent, cJSON * const item, cJSON * replacement); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInArray(cJSON *array, int which, cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObject(cJSON *object,const char *string,cJSON *newitem); +CJSON_PUBLIC(cJSON_bool) cJSON_ReplaceItemInObjectCaseSensitive(cJSON *object,const char *string,cJSON *newitem); + +/* Duplicate a cJSON item */ +CJSON_PUBLIC(cJSON *) cJSON_Duplicate(const cJSON *item, cJSON_bool recurse); +/* Duplicate will create a new, identical cJSON item to the one you pass, in new memory that will + * need to be released. With recurse!=0, it will duplicate any children connected to the item. + * The item->next and ->prev pointers are always zero on return from Duplicate. */ +/* Recursively compare two cJSON items for equality. If either a or b is NULL or invalid, they will be considered unequal. + * case_sensitive determines if object keys are treated case sensitive (1) or case insensitive (0) */ +CJSON_PUBLIC(cJSON_bool) cJSON_Compare(const cJSON * const a, const cJSON * const b, const cJSON_bool case_sensitive); + +/* Minify a strings, remove blank characters(such as ' ', '\t', '\r', '\n') from strings. + * The input pointer json cannot point to a read-only address area, such as a string constant, + * but should point to a readable and writable address area. */ +CJSON_PUBLIC(void) cJSON_Minify(char *json); + +/* Helper functions for creating and adding items to an object at the same time. + * They return the added item or NULL on failure. */ +CJSON_PUBLIC(cJSON*) cJSON_AddNullToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddTrueToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddFalseToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddBoolToObject(cJSON * const object, const char * const name, const cJSON_bool boolean); +CJSON_PUBLIC(cJSON*) cJSON_AddNumberToObject(cJSON * const object, const char * const name, const double number); +CJSON_PUBLIC(cJSON*) cJSON_AddStringToObject(cJSON * const object, const char * const name, const char * const string); +CJSON_PUBLIC(cJSON*) cJSON_AddRawToObject(cJSON * const object, const char * const name, const char * const raw); +CJSON_PUBLIC(cJSON*) cJSON_AddObjectToObject(cJSON * const object, const char * const name); +CJSON_PUBLIC(cJSON*) cJSON_AddArrayToObject(cJSON * const object, const char * const name); + +/* When assigning an integer value, it needs to be propagated to valuedouble too. */ +#define cJSON_SetIntValue(object, number) ((object) ? (object)->valueint = (object)->valuedouble = (number) : (number)) +/* helper for the cJSON_SetNumberValue macro */ +CJSON_PUBLIC(double) cJSON_SetNumberHelper(cJSON *object, double number); +#define cJSON_SetNumberValue(object, number) ((object != NULL) ? cJSON_SetNumberHelper(object, (double)number) : (number)) +/* Change the valuestring of a cJSON_String object, only takes effect when type of object is cJSON_String */ +CJSON_PUBLIC(char*) cJSON_SetValuestring(cJSON *object, const char *valuestring); + +/* If the object is not a boolean type this does nothing and returns cJSON_Invalid else it returns the new type*/ +#define cJSON_SetBoolValue(object, boolValue) ( \ + (object != NULL && ((object)->type & (cJSON_False|cJSON_True))) ? \ + (object)->type=((object)->type &(~(cJSON_False|cJSON_True)))|((boolValue)?cJSON_True:cJSON_False) : \ + cJSON_Invalid\ +) + +/* Macro for iterating over an array or object */ +#define cJSON_ArrayForEach(element, array) for(element = (array != NULL) ? (array)->child : NULL; element != NULL; element = element->next) + +/* malloc/free objects using the malloc/free functions that have been set with cJSON_InitHooks */ +CJSON_PUBLIC(void *) cJSON_malloc(size_t size); +CJSON_PUBLIC(void) cJSON_free(void *object); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/config.c b/src/config.c new file mode 100644 index 0000000..751199a --- /dev/null +++ b/src/config.c @@ -0,0 +1,257 @@ +/* + * config.c - libyaml-based config parser for fused_engine + * + * Parses config.yaml, supporting three levels: + * - Top level: api keys, live mode flag + * - fused_engine section: thresholds, symbols, hold currencies, connection params + * - executor section: ignored (consumed by separate executor binary) + * + * Uses a state machine (parse_state_t) tracking section, mapping depth, + * sequence membership (symbols/hold/excluded lists), and key/value alternation. + */ + +#include "log.h" +#include "config.h" +#include +#include +#include +#include +#include + +static void copy_string(const char *src, char *dst, size_t dst_len) { + if (!src) return; + strncpy(dst, src, dst_len - 1); + dst[dst_len - 1] = '\0'; +} + +typedef struct { + config_t *cfg; + char section[32]; // current YAML section name (e.g. "fused_engine") + char current_key[64]; // last seen scalar key + bool in_symbols; // inside fused_engine.symbols sequence + bool in_hold; // inside fused_engine.hold_currencies + bool in_excluded; // inside fused_engine.excluded_currencies + bool in_capital_map; // inside fused_engine.initial_capital mapping + char capital_currency[CURRENCY_NAME_LEN]; // current currency key in capital map + bool expect_key; // true = next scalar is a key, false = next is a value + int mapping_depth; // tracks nesting depth for section detection +} parse_state_t; + +/* + * Dispatch a parsed key-value pair to the appropriate config field. + * Section determines which field group to look up. + */ +static void handle_value(parse_state_t *st, const char *val) { + const char *key = st->current_key; + + if (strcmp(st->section, "fused_engine") == 0) { + if (st->in_symbols) { + if (st->cfg->symbol_count < MAX_SYMBOLS) { + copy_string(val, st->cfg->symbols[st->cfg->symbol_count], SYMBOL_NAME_LEN); + st->cfg->symbol_count++; + } + } else if (st->in_hold) { + if (st->cfg->hold_currency_count < MAX_HOLD_CURRENCIES) { + copy_string(val, st->cfg->hold_currencies[st->cfg->hold_currency_count], CURRENCY_NAME_LEN); + st->cfg->hold_currency_count++; + } + } else if (st->in_excluded) { + if (st->cfg->excluded_currency_count < MAX_EXCLUDED_CURRENCIES) { + copy_string(val, st->cfg->excluded_currencies[st->cfg->excluded_currency_count], CURRENCY_NAME_LEN); + st->cfg->excluded_currency_count++; + } + } else if (strcmp(key, "log_level") == 0) { + copy_string(val, st->cfg->log_level, sizeof(st->cfg->log_level)); + } else if (strcmp(key, "socket_path") == 0) { + copy_string(val, st->cfg->socket_path, sizeof(st->cfg->socket_path)); + } else if (strcmp(key, "rest_host") == 0) { + copy_string(val, st->cfg->rest_host, sizeof(st->cfg->rest_host)); + } else if (strcmp(key, "rest_port") == 0) { + st->cfg->rest_port = atoi(val); + } else if (strcmp(key, "ws_url") == 0) { + copy_string(val, st->cfg->ws_url, sizeof(st->cfg->ws_url)); + } else if (strcmp(key, "token_url") == 0) { + copy_string(val, st->cfg->token_url, sizeof(st->cfg->token_url)); + } else if (strcmp(key, "reconnect_base_delay") == 0) { + st->cfg->reconnect_base_delay = atof(val); + } else if (strcmp(key, "reconnect_max_delay") == 0) { + st->cfg->reconnect_max_delay = atof(val); + } else if (strcmp(key, "heartbeat_interval") == 0) { + st->cfg->heartbeat_interval = atof(val); + } else if (strcmp(key, "signal_threshold_bps") == 0) { + st->cfg->signal_threshold_bps = atof(val); + } else if (strcmp(key, "kcs_discount_active") == 0) { + st->cfg->kcs_discount_active = (strcmp(val, "true") == 0 || strcmp(val, "yes") == 0); + } else if (strcmp(key, "executor_socket_path") == 0) { + copy_string(val, st->cfg->executor_socket_path, sizeof(st->cfg->executor_socket_path)); + } else if (strcmp(key, "send_signals") == 0) { + st->cfg->send_signals = (strcmp(val, "true") == 0 || strcmp(val, "yes") == 0); + } else if (strcmp(key, "cooldown_seconds") == 0) { + st->cfg->cooldown_seconds = atof(val); + } else if (strcmp(key, "stats_interval_seconds") == 0) { + st->cfg->stats_interval_seconds = atof(val); + } + } else if (strcmp(st->section, "executor") == 0) { + return; + } else if (st->section[0] == '\0') { + // Top-level keys (outside any named section) + if (strcmp(key, "kucoin_api_key") == 0) { + copy_string(val, st->cfg->kucoin_api_key, sizeof(st->cfg->kucoin_api_key)); + } else if (strcmp(key, "kucoin_api_secret") == 0) { + copy_string(val, st->cfg->kucoin_api_secret, sizeof(st->cfg->kucoin_api_secret)); + } else if (strcmp(key, "kucoin_api_passphrase") == 0) { + copy_string(val, st->cfg->kucoin_api_passphrase, sizeof(st->cfg->kucoin_api_passphrase)); + } else if (strcmp(key, "live_mode") == 0) { + st->cfg->live_mode = (strcmp(val, "true") == 0 || strcmp(val, "yes") == 0); + } + } +} + +/* + * Load and parse a YAML config file into config_t. + * Uses the libyaml pull-parser API with a state machine to track: + * - Section nesting (mapping_depth) + * - Key/value alternation within mappings + * - Sequence membership for arrays (symbols, hold_currencies, excluded_currencies) + * + * Sets sensible defaults before parsing so the file only needs to override. + */ +int config_load(const char *path, config_t *cfg) { + if (!path || !cfg) return -1; + + memset(cfg, 0, sizeof(config_t)); + copy_string("INFO", cfg->log_level, sizeof(cfg->log_level)); + copy_string("/tmp/fh_ob.sock", cfg->socket_path, sizeof(cfg->socket_path)); + copy_string("0.0.0.0", cfg->rest_host, sizeof(cfg->rest_host)); + cfg->rest_port = 8000; + copy_string("wss://ws-api-spot.kucoin.com", cfg->ws_url, sizeof(cfg->ws_url)); + copy_string("https://api.kucoin.com/api/v1/bullet-public", cfg->token_url, sizeof(cfg->token_url)); + cfg->reconnect_base_delay = 1.0; + cfg->reconnect_max_delay = 60.0; + cfg->heartbeat_interval = 18.0; + + cfg->signal_threshold_bps = 0.2; + copy_string("USDT", cfg->hold_currencies[0], CURRENCY_NAME_LEN); + cfg->hold_currency_count = 1; + cfg->kcs_discount_active = false; + copy_string("/tmp/executor.sock", cfg->executor_socket_path, sizeof(cfg->executor_socket_path)); + cfg->send_signals = false; + cfg->cooldown_seconds = 0.0; + cfg->stats_interval_seconds = 60.0; + cfg->live_mode = false; + + FILE *f = fopen(path, "r"); + if (!f) { + log_write("config: cannot open '%s'\n", path); + return -1; + } + + yaml_parser_t parser; + if (!yaml_parser_initialize(&parser)) { + fclose(f); + return -1; + } + yaml_parser_set_input_file(&parser, f); + + parse_state_t st = {0}; + st.cfg = cfg; + st.expect_key = true; // YAML mapping starts with a key + + while (1) { + yaml_event_t event; + if (!yaml_parser_parse(&parser, &event)) break; + + switch (event.type) { + case YAML_STREAM_END_EVENT: + yaml_event_delete(&event); + goto done; + + case YAML_SCALAR_EVENT: { + char *s = (char *)event.data.scalar.value; + if (st.in_capital_map) { + if (st.expect_key) { + strncpy(st.capital_currency, s, CURRENCY_NAME_LEN - 1); + st.expect_key = false; + } else { + if (st.cfg->initial_capital_count < MAX_CAPITAL_ENTRIES) { + strncpy(st.cfg->initial_capital[st.cfg->initial_capital_count].currency, + st.capital_currency, CURRENCY_NAME_LEN - 1); + st.cfg->initial_capital[st.cfg->initial_capital_count].amount = atof(s); + st.cfg->initial_capital_count++; + } + st.expect_key = true; + } + } else if (st.expect_key) { + strncpy(st.current_key, s, sizeof(st.current_key) - 1); + st.expect_key = false; + } else { + handle_value(&st, s); + if (!st.in_symbols && !st.in_hold && !st.in_excluded) { + st.expect_key = true; + } + } + break; + } + + case YAML_MAPPING_START_EVENT: + // Root mapping is depth 0; depth 1 mappings are named sections + if (st.mapping_depth == 1 && + (strcmp(st.current_key, "fused_engine") == 0 || + strcmp(st.current_key, "executor") == 0)) { + strncpy(st.section, st.current_key, sizeof(st.section) - 1); + } + // Nested mapping inside fused_engine section (depth 2) + if (st.mapping_depth == 2 && strcmp(st.section, "fused_engine") == 0 && + strcmp(st.current_key, "initial_capital") == 0) { + st.in_capital_map = true; + st.cfg->initial_capital_count = 0; + st.expect_key = true; + } + st.mapping_depth++; + st.expect_key = true; + break; + + case YAML_MAPPING_END_EVENT: + st.mapping_depth--; + if (st.in_capital_map && st.mapping_depth <= 2) { + st.in_capital_map = false; + } + if (st.mapping_depth < 2) { + st.section[0] = '\0'; // exited a named section + } + st.current_key[0] = '\0'; + break; + + case YAML_SEQUENCE_START_EVENT: + if (strcmp(st.section, "fused_engine") == 0 && strcmp(st.current_key, "symbols") == 0) { + st.in_symbols = true; + } else if (strcmp(st.section, "fused_engine") == 0 && strcmp(st.current_key, "hold_currencies") == 0) { + st.in_hold = true; + st.cfg->hold_currency_count = 0; // override default + } else if (strcmp(st.section, "fused_engine") == 0 && strcmp(st.current_key, "excluded_currencies") == 0) { + st.in_excluded = true; + st.cfg->excluded_currency_count = 0; + } + st.expect_key = false; // sequence items are values + break; + + case YAML_SEQUENCE_END_EVENT: + st.in_symbols = false; + st.in_hold = false; + st.in_excluded = false; + st.expect_key = true; + break; + + default: + break; + } + + yaml_event_delete(&event); + } + +done: + yaml_parser_delete(&parser); + fclose(f); + + return 0; +} diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..d4e65c5 --- /dev/null +++ b/src/config.h @@ -0,0 +1,60 @@ +#ifndef FUSED_CONFIG_H +#define FUSED_CONFIG_H + +#include +#include +#include "book.h" + +#define MAX_SYMBOLS 2048 +#define MAX_HOLD_CURRENCIES 16 +#define MAX_EXCLUDED_CURRENCIES 64 +#define MAX_CAPITAL_ENTRIES 16 + +typedef struct { + char currency[CURRENCY_NAME_LEN]; /* currency ticker */ + double amount; /* max capital allocation */ +} capital_entry_t; + +/* Top-level application configuration parsed from config.yaml */ +typedef struct { + /* fh_ob section */ + char symbols[MAX_SYMBOLS][SYMBOL_NAME_LEN]; /* subscribed trading symbol names */ + uint32_t symbol_count; /* number of symbols in the list */ + char log_level[8]; /* log verbosity level string */ + char socket_path[256]; /* unix socket path for inter-process comm */ + char rest_host[64]; /* KuCoin REST API hostname */ + int rest_port; /* KuCoin REST API port */ + char ws_url[256]; /* KuCoin WebSocket base URL */ + char token_url[256]; /* KuCoin token endpoint URL */ + double reconnect_base_delay; /* initial WebSocket reconnect delay (seconds) */ + double reconnect_max_delay; /* max WebSocket reconnect delay (seconds) */ + double heartbeat_interval; /* WebSocket ping interval (seconds) */ + + /* oe_em section */ + double signal_threshold_bps; /* min predicted bps to fire a signal */ + char hold_currencies[MAX_HOLD_CURRENCIES][CURRENCY_NAME_LEN]; /* currencies to hold between legs */ + uint32_t hold_currency_count; /* number of hold currencies */ + char excluded_currencies[MAX_EXCLUDED_CURRENCIES][CURRENCY_NAME_LEN]; /* currencies to skip */ + uint32_t excluded_currency_count; /* number of excluded currencies */ + bool kcs_discount_active; /* whether KCS fee discount applies */ + char executor_socket_path[256]; /* unix socket path for signal executor */ + bool send_signals; /* whether to actually emit signals */ + double cooldown_seconds; /* min seconds between signals for same triangle */ + double stats_interval_seconds; /* period between stats log dumps */ + bool live_mode; /* live trading vs paper/simulation */ + + /* Capital allocation limits — each entry maps a currency ticker to a max + * quote amount the fused engine may deploy for any one triangle signal. */ + capital_entry_t initial_capital[MAX_CAPITAL_ENTRIES]; + uint32_t initial_capital_count; + + /* KuCoin API credentials (top-level keys in config.yaml) */ + char kucoin_api_key[64]; /* KuCoin API key */ + char kucoin_api_secret[128]; /* KuCoin API secret */ + char kucoin_api_passphrase[64]; /* KuCoin API passphrase */ +} config_t; + +/* Load and parse YAML config file into config_t */ +int config_load(const char *path, config_t *cfg); + +#endif diff --git a/src/evaluate.c b/src/evaluate.c new file mode 100644 index 0000000..2034339 --- /dev/null +++ b/src/evaluate.c @@ -0,0 +1,368 @@ +/* + * evaluate.c - Triangle arbitrage opportunity detection + * + * Given an updated order book, iterates all triangles that reference that symbol, + * computes the cumulative arbitrage return (bps), determines max tradeable volume + * constrained by liquidity, applies precision rounding per exchange increments, + * and pushes profitable signals to the SPSC queue for the executor. + * + * Core computation: cumulative = product of (rate * fee_factor) for all 3 legs. + * - Buy leg: rate = 1/ask_price (quote -> base) + * - Sell leg: rate = bid_price (base -> quote) + * - Fee factor = 1 - taker_fee_rate + */ + +#include "log.h" +#include "evaluate.h" +#include +#include +#include +#include + +static inline int64_t now_ms(void) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (int64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +void evaluator_init(evaluator_t *ev, const triangle_set_t *triangles, + const order_book_t *books, const config_t *cfg, + spsc_queue_t *queue, bool kcs_discount) { + ev->triangles = triangles; + ev->books = books; + ev->cfg = cfg; + ev->queue = queue; + ev->fee_mult = kcs_discount ? 0.8 : 1.0; + memset(&ev->stats, 0, sizeof(ev->stats)); + ev->stats.best_net_bps = -1e18; + ev->stats.worst_net_bps = 1e18; + ev->stats.best_triangle_key[0] = '\0'; + memset(ev->last_signal_ts_ms, 0, sizeof(ev->last_signal_ts_ms)); +} + +/* + * Evaluate all triangles involving symbol_idx after a book update. + * + * For each triangle: + * 1. Fetch the 3 order books (b0, b1, b2) + * 2. For each leg, compute rate and fee-adjusted multiplier: + * - use_bid = 1: sell base at bid -> rate = bid[0].price + * - use_bid = 0: buy base at ask -> rate = 1.0 / ask[0].price + * 3. cumulative = prod(rate * fee_factor) for all 3 legs + * 4. net_bps = (cumulative - 1) * 10000 + * 5. If net_bps > threshold, compute max_volume constrained by each leg's liquidity + * (converted back to starting quote via inverse cumulative product) + * 6. Apply exchange precision rounding: + * - floor() for quantities (base size) + * - ceil() for quote costs (must cover the order) + * - Adjust by 1e-12 epsilon to avoid floating-point boundary errors + * 7. Check base_min_size constraints in live mode + * 8. Push signal to queue with full leg/order params + * + * Returns true if at least one signal was fired. + */ +bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, int64_t t_arrive_ms) { + const triangle_set_t *tris = ev->triangles; + const order_book_t *books = ev->books; + const config_t *cfg = ev->cfg; + bool fired_any = false; + + uint32_t tri_count = tris->triangle_count; + if (tri_count == 0) return false; + + // Only evaluate triangles involving the updated symbol + uint32_t offset = tris->tri_index[symbol_idx].offset; + uint32_t count = tris->tri_index[symbol_idx].count; + + static uint64_t calls_no_tri = 0; + static uint64_t calls_with_tri = 0; + + if (count == 0) { + calls_no_tri++; + return false; + } + calls_with_tri++; + + uint32_t *tri_flat = tris->tri_flat; + if (!tri_flat) return false; + + static int64_t last_status_ms = 0; + + for (uint32_t j = 0; j < count; j++) { + uint32_t i = tri_flat[offset + j]; + const triangle_t *tri = &tris->triangles[i]; + + const order_book_t *b0 = &books[tri->symbol_idx[0]]; + const order_book_t *b1 = &books[tri->symbol_idx[1]]; + const order_book_t *b2 = &books[tri->symbol_idx[2]]; + + if (b0->ts_ms <= 0 || b1->ts_ms <= 0 || b2->ts_ms <= 0) { + ev->stats.triangles_evaluated++; + ev->stats.books_missing++; + continue; + } + + const order_book_t *books_arr[3] = {b0, b1, b2}; + double cumulative = 1.0; + double max_v0_list[3] = {0, 0, 0}; + double cumulative_mult = 1.0; + double rates[3]; + double fee_factors[3]; + bool valid = true; + + // Use the most recent book timestamp across all 3 legs + int64_t book_ts_ms = b0->ts_ms; + if (b1->ts_ms > book_ts_ms) book_ts_ms = b1->ts_ms; + if (b2->ts_ms > book_ts_ms) book_ts_ms = b2->ts_ms; + + for (int leg = 0; leg < 3; leg++) { + const order_book_t *bk = books_arr[leg]; + bool use_bid = tri->use_bid[leg]; + + double rate; + double max_input; + if (use_bid) { + // Sell: we receive base, sell at bid -> output = bid_price + if (bk->bid_count == 0) { valid = false; break; } + rate = bk->bids[0][0]; + max_input = bk->bids[0][1]; + } else { + // Buy: we input quote, buy at ask -> rate = 1/ask_price (quote-to-base conversion) + if (bk->ask_count == 0) { valid = false; break; } + double ask_price = bk->asks[0][0]; + if (ask_price <= 0.0) { valid = false; break; } + rate = 1.0 / ask_price; + max_input = bk->asks[0][1] * ask_price; + } + + rates[leg] = rate; + double ff = tri->fee_factor[leg]; + fee_factors[leg] = ff; + double leg_mult = rate * ff; + cumulative *= leg_mult; + + // max_v0_list[leg]: how much starting quote can pass through this leg + // Divide by cumulative_mult (product of prior leg multipliers) to + // convert this leg's max_input back to starting-quote-equivalent volume + if (cumulative_mult > 0) { + max_v0_list[leg] = max_input / cumulative_mult; + } + cumulative_mult *= leg_mult; + } + + if (!valid) { + ev->stats.triangles_evaluated++; + ev->stats.books_missing++; + continue; + } + + ev->stats.triangles_evaluated++; + + double net_bps = (cumulative - 1.0) * 10000.0; + + if (net_bps > ev->stats.best_net_bps) { + ev->stats.best_net_bps = net_bps; + snprintf(ev->stats.best_triangle_key, sizeof(ev->stats.best_triangle_key), + "%s/%s/%s", tri->base, tri->mid, tri->quote); + } + if (net_bps < ev->stats.worst_net_bps) ev->stats.worst_net_bps = net_bps; + + int64_t now = now_ms(); + if (now - last_status_ms >= 30000) { + last_status_ms = now; + log_write("[STATUS] evals=%lu signals=%lu " + "best=%.2f bps (%s) | %u triangles\n", + (unsigned long)ev->stats.triangles_evaluated, + (unsigned long)ev->stats.signals_fired, + ev->stats.best_net_bps, ev->stats.best_triangle_key, + tris->triangle_count); + } + + if (net_bps <= cfg->signal_threshold_bps) { + ev->stats.triangles_skipped++; + continue; + } + + // max_volume is the bottleneck leg: the smallest starting-quote-equivalent volume. + // Scale down by 0.5 so we never consume the entire top-of-book in one shot, + // leaving room for the subsequent legs and avoiding excessive slippage. + double max_volume = max_v0_list[0]; + for (int leg = 1; leg < 3; leg++) { + if (max_v0_list[leg] < max_volume) max_volume = max_v0_list[leg]; + } + max_volume *= 0.5; + + // Clamp by the configured capital allocation for this triangle's base currency. + for (uint32_t c = 0; c < cfg->initial_capital_count; c++) { + if (strcmp(tri->base, cfg->initial_capital[c].currency) == 0) { + double cap = cfg->initial_capital[c].amount; + if (cap > 0 && max_volume > cap) max_volume = cap; + break; + } + } + + int64_t cooldown_ms = (int64_t)(cfg->cooldown_seconds * 1000); + if (now - ev->last_signal_ts_ms[i] < cooldown_ms) continue; + ev->last_signal_ts_ms[i] = now; + + int64_t t_eval = now_ms(); + + signal_entry_t sig; + memset(&sig, 0, sizeof(sig)); + + /* + * Compute per-leg order parameters at max_volume scale with exchange precision. + * + * Precision rounding strategy: + * - Base size: floor(base_increment) — we cannot trade a fraction of a step + * - Quote cost: ceil(quote_increment) — must cover the full cost + * - 1e-12 epsilon guards against floating-point truncation at increment boundaries + * e.g. ceil(value / qi - 1e-12) ensures that 0.10000000000000001 doesn't + * round up to 0.10000001 when qi = 0.01 + * + * Buy leg: input = quote, output = base + * quote_cost = ceil(leg_input / qi - eps) * qi + * net = quote_cost * ff + * base = floor(net / price / bi + eps) * bi + * final_quote = ceil(base * price / qi - eps) * qi (re-check) + * + * Sell leg: input = base, output = quote + * base = floor(leg_input / bi + eps) * bi + * gross = ceil(base * price / qi - eps) * qi + * net = gross * ff + */ + double leg_input = max_volume; + double leg_quote_vol[3] = {0}; + double leg_base_size[3] = {0}; + for (int leg = 0; leg < 3; leg++) { + const order_book_t *bk = books_arr[leg]; + double bi = tri->base_increment[leg]; + double qi = tri->quote_increment[leg]; + double ff = tri->fee_factor[leg]; + bool is_buy = !tri->use_bid[leg]; + double price = is_buy ? bk->asks[0][0] : bk->bids[0][0]; + double leg_output; + + if (is_buy) { + double ceiling = (qi > 0) ? ceil(leg_input / qi - 1e-12) * qi : leg_input; + double net = ceiling * ff; + double base = (bi > 0) ? floor(net / price / bi + 1e-12) * bi : (net / price); + double quote_cost = (qi > 0) ? ceil(base * price / qi - 1e-12) * qi : (base * price); + leg_quote_vol[leg] = quote_cost; + sig.legs.legs[leg].quote_volume = quote_cost; + leg_base_size[leg] = base; + leg_output = base; + } else { + double base = (bi > 0) ? floor(leg_input / bi + 1e-12) * bi : leg_input; + double gross = (qi > 0) ? ceil(base * price / qi - 1e-12) * qi : (base * price); + leg_quote_vol[leg] = gross; + sig.legs.legs[leg].quote_volume = gross; + leg_base_size[leg] = base; + leg_output = gross * ff; + } + leg_input = leg_output; + } + sig.starting_volume = leg_quote_vol[0]; + sig.live = cfg->live_mode; + + if (sig.live) { + bool below_min = false; + for (int leg = 0; leg < 3; leg++) { + if (leg_base_size[leg] <= 0 || leg_base_size[leg] < tri->base_min_size[leg]) { + below_min = true; + break; + } + } + if (below_min) continue; + } + + snprintf(sig.triangle_key, sizeof(sig.triangle_key), "%s/%s/%s", + tri->base, tri->mid, tri->quote); + strncpy(sig.primary_quote, tri->base, CURRENCY_NAME_LEN); + sig.predicted_bps = net_bps; + snprintf(sig.max_volume, sizeof(sig.max_volume), "%.8g", max_volume); + sig.ts_ms = now; + sig.book_ts_ms = book_ts_ms; + sig.t_sock_arrive_ms = t_sock_arrive_ms; + sig.t_arrive_ms = t_arrive_ms; + sig.t_eval_ms = t_eval; + sig.book_count = 3; + sig.legs.leg_count = 3; + + for (int leg = 0; leg < 3; leg++) { + const order_book_t *bk = books_arr[leg]; + signal_book_t *sb = &sig.books[leg]; + strncpy(sb->symbol, bk->symbol, SYMBOL_NAME_LEN); + sb->ts_ms = bk->ts_ms; + sb->bid_count = bk->bid_count; + sb->ask_count = bk->ask_count; + for (uint8_t l = 0; l < bk->bid_count; l++) { + sb->bids[l].price = bk->bids[l][0]; + sb->bids[l].size = bk->bids[l][1]; + } + for (uint8_t l = 0; l < bk->ask_count; l++) { + sb->asks[l].price = bk->asks[l][0]; + sb->asks[l].size = bk->asks[l][1]; + } + + signal_leg_t *sl = &sig.legs.legs[leg]; + strncpy(sl->symbol, tri->symbol_names[leg], SYMBOL_NAME_LEN); + char base_cur[CURRENCY_NAME_LEN], quote_cur[CURRENCY_NAME_LEN]; + const char *dash = strchr(tri->symbol_names[leg], '-'); + if (dash) { + size_t blen = dash - tri->symbol_names[leg]; + if (blen >= CURRENCY_NAME_LEN) blen = CURRENCY_NAME_LEN - 1; + strncpy(base_cur, tri->symbol_names[leg], blen); + base_cur[blen] = '\0'; + strncpy(quote_cur, dash + 1, CURRENCY_NAME_LEN - 1); + quote_cur[CURRENCY_NAME_LEN - 1] = '\0'; + } else { + base_cur[0] = quote_cur[0] = '\0'; + } + + bool use_bid = tri->use_bid[leg]; + bool is_buy = !use_bid; + // order_param: for buys the param is quote volume, for sells it's base size + if (is_buy) { + snprintf(sl->order_param, sizeof(sl->order_param), "%.8g", + sig.legs.legs[leg].quote_volume); + } else { + snprintf(sl->order_param, sizeof(sl->order_param), "%.8g", leg_base_size[leg]); + } + sl->base_increment = tri->base_increment[leg]; + sl->quote_increment = tri->quote_increment[leg]; + sl->base_min_size = tri->base_min_size[leg]; + + if (use_bid) { + // Hit the bid: we sell base, receive quote + strncpy(sl->input_currency, base_cur, CURRENCY_NAME_LEN); + strncpy(sl->output_currency, quote_cur, CURRENCY_NAME_LEN); + strncpy(sl->side, "sell", 5); + } else { + // Hit the ask: we buy base, pay quote + strncpy(sl->input_currency, quote_cur, CURRENCY_NAME_LEN); + strncpy(sl->output_currency, base_cur, CURRENCY_NAME_LEN); + strncpy(sl->side, "buy", 5); + } + strncpy(sl->fee_currency, tri->fee_currency[leg], CURRENCY_NAME_LEN); + sl->fee_rate = 1.0 - fee_factors[leg]; + sl->exchange_rate = rates[leg]; + } + + if (spsc_push(ev->queue, &sig)) { + ev->stats.signals_fired++; + ev->stats.last_eval_ts_ms = now; + log_write("[SIGNAL] %.4f bps vol=%s | %s (%s, %s, %s)\n", + net_bps, sig.max_volume, sig.triangle_key, + sig.legs.legs[0].symbol, sig.legs.legs[1].symbol, sig.legs.legs[2].symbol); + fired_any = true; + } else { + static int drop_count = 0; + if (++drop_count <= 3) log_write("[SIGNAL] DROPPED (queue full) %.4f bps vol=%s | %s (%s, %s, %s)\n", + net_bps, sig.max_volume, sig.triangle_key, + sig.legs.legs[0].symbol, sig.legs.legs[1].symbol, sig.legs.legs[2].symbol); + } + } + + return fired_any; +} diff --git a/src/evaluate.h b/src/evaluate.h new file mode 100644 index 0000000..cfd8ee8 --- /dev/null +++ b/src/evaluate.h @@ -0,0 +1,42 @@ +#ifndef FUSED_EVALUATE_H +#define FUSED_EVALUATE_H + +#include +#include +#include "book.h" +#include "triangle.h" +#include "config.h" +#include "queue.h" + +/* Aggregated evaluation statistics for monitoring */ +typedef struct { + uint64_t triangles_evaluated; /* total triangles evaluated since start */ + uint64_t signals_fired; /* total signals generated since start */ + uint64_t books_missing; /* count of evaluations skipped due to missing books */ + uint64_t triangles_skipped; /* count of triangles skipped for other reasons */ + double best_net_bps; /* best net profit seen (basis points) */ + double worst_net_bps; /* worst net profit seen (basis points) */ + int64_t last_eval_ts_ms; /* timestamp of last evaluation (milliseconds) */ + char best_triangle_key[48]; /* triangle key that produced best_net_bps */ +} eval_stats_t; + +/* Runtime state for the triangular arbitrage evaluator */ +typedef struct { + const triangle_set_t *triangles; /* pre-enumerated triangle set (read-only) */ + const order_book_t *books; /* live order books array (read-only) */ + const config_t *cfg; /* application configuration (read-only) */ + spsc_queue_t *queue; /* signal queue for firing opportunities */ + eval_stats_t stats; /* cumulative evaluation statistics */ + double fee_mult; /* combined fee multiplier (includes KCS discount) */ + int64_t last_signal_ts_ms[MAX_TRIANGLES]; /* per-triangle cooldown timestamps */ +} evaluator_t; + +/* Initialise evaluator with triangle set, books, config, and signal queue */ +void evaluator_init(evaluator_t *ev, const triangle_set_t *triangles, + const order_book_t *books, const config_t *cfg, + spsc_queue_t *queue, bool kcs_discount); + +/* Evaluate all triangles involving the given symbol; returns true if a signal was fired */ +bool evaluate_symbol(evaluator_t *ev, uint16_t symbol_idx, int64_t t_sock_arrive_ms, int64_t t_arrive_ms); + +#endif diff --git a/src/events.c b/src/events.c new file mode 100644 index 0000000..22dccfe --- /dev/null +++ b/src/events.c @@ -0,0 +1,443 @@ +/* + * events.c - Epoll-based event loops for WebSocket I/O and signal dispatch + * + * Two-thread architecture: + * HOT thread: epoll_wait on WebSocket fds + timer fd for keep-alive pings + * COLD thread: polls SPSC signal queue + Unix domain socket to executor + * + * Signals flow: evaluate.c -> SPSC queue -> COLD thread -> executor via UDS + */ + +#include "log.h" +#include "events.h" +#include "evaluate.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int set_nonblocking(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) return -1; + return fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +int event_loops_add_fd(epoll_set_t *set, int fd, fd_type_t type, + uint32_t ws_idx, void *user_data, uint32_t events) { + if (set->fd_count >= MAX_EPOLL_FDS) { + log_write("[EVENTS] epoll set full\n"); + return -1; + } + + // If fd already tracked, modify instead of re-adding + for (uint32_t i = 0; i < set->fd_count; i++) { + if (set->fds[i].fd == fd) { + struct epoll_event ev = { + .events = events, + .data.ptr = &set->fds[i] + }; + return epoll_ctl(set->epoll_fd, EPOLL_CTL_MOD, fd, &ev); + } + } + + tracked_fd_t *tf = &set->fds[set->fd_count++]; + tf->fd = fd; + tf->type = type; + tf->ws_conn_idx = ws_idx; + tf->user_data = user_data; + + struct epoll_event ev = { + .events = events, + .data.ptr = tf + }; + return epoll_ctl(set->epoll_fd, EPOLL_CTL_ADD, fd, &ev); +} + +void event_loops_remove_fd(epoll_set_t *set, int fd) { + epoll_ctl(set->epoll_fd, EPOLL_CTL_DEL, fd, NULL); + for (uint32_t i = 0; i < set->fd_count; i++) { + if (set->fds[i].fd == fd) { + set->fds[i].fd = -1; + return; + } + } +} + +static void epoll_set_init(epoll_set_t *set) { + memset(set, 0, sizeof(*set)); + set->epoll_fd = epoll_create1(EPOLL_CLOEXEC); + if (set->epoll_fd < 0) { + perror("epoll_create1"); + exit(1); + } +} + +int event_loops_init(event_loops_t *loops, ws_client_t *ws_client, + spsc_queue_t *signal_queue, const config_t *cfg, int wakeup_fd) { + memset(loops, 0, sizeof(*loops)); + loops->ws_client = ws_client; + loops->signal_queue = signal_queue; + loops->running = true; + loops->unix_client_fd = -1; + loops->wakeup_fd = wakeup_fd; + + epoll_set_init(&loops->hot_epoll); + epoll_set_init(&loops->cold_epoll); + + loops->timer_fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC); + if (loops->timer_fd < 0) { + perror("timerfd_create"); + return -1; + } + + event_loops_add_fd(&loops->cold_epoll, loops->wakeup_fd, FD_TYPE_EVENT, + 0, NULL, EPOLLIN); + + return 0; +} + +void event_loops_destroy(event_loops_t *loops) { + loops->running = false; + if (loops->timer_fd >= 0) close(loops->timer_fd); + if (loops->wakeup_fd >= 0) close(loops->wakeup_fd); + if (loops->unix_client_fd >= 0) close(loops->unix_client_fd); + if (loops->http_server_fd >= 0) close(loops->http_server_fd); + if (loops->hot_epoll.epoll_fd >= 0) close(loops->hot_epoll.epoll_fd); + if (loops->cold_epoll.epoll_fd >= 0) close(loops->cold_epoll.epoll_fd); +} + +int unix_client_connect(const char *socket_path) { + int fd = socket(AF_UNIX, SOCK_STREAM | SOCK_NONBLOCK, 0); + if (fd < 0) return -1; + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + if (errno != EINPROGRESS) { + close(fd); + return -1; + } + struct pollfd pfd = { .fd = fd, .events = POLLOUT }; + if (poll(&pfd, 1, 100) <= 0) { // 100 ms timeout + close(fd); + return -1; + } + } + return fd; +} + +int unix_server_create(const char *socket_path) { + int fd = socket(AF_UNIX, SOCK_STREAM, 0); + if (fd < 0) return -1; + + struct sockaddr_un addr; + memset(&addr, 0, sizeof(addr)); + addr.sun_family = AF_UNIX; + strncpy(addr.sun_path, socket_path, sizeof(addr.sun_path) - 1); + + unlink(socket_path); + + if (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(fd); + return -1; + } + + if (listen(fd, 5) < 0) { + close(fd); + return -1; + } + + set_nonblocking(fd); + return fd; +} + +/* + * Build a JSON signal message and send it to the external executor over a Unix socket. + * + * JSON structure: + * { + * "type": "signal", + * "correlation_id": "", + * "triangle_key": ["base","mid","quote"], + * "primary_quote": "", + * "live": true/false, + * "starting_volume": "", + * "legs": [{...}, {...}, {...}], + * "predicted_bps": , + * "ts_ms", "book_ts_ms", "t_sock_arrive_ms", "t_arrive_ms", "t_eval_ms": , + * "books": [...] (snapshot, only when !live) + * } + * + * correlation_id is a mix of address/ts/bps values for best-effort uniqueness. + * Connects lazily on first signal; reconnects on write failure. + */ +static void send_signal_to_executor(event_loops_t *loops, signal_entry_t *sig) { + if (loops->unix_client_fd < 0) { + loops->unix_client_fd = unix_client_connect(loops->ws_client->cfg->executor_socket_path); + if (loops->unix_client_fd < 0) { + log_write("[EVENTS] Cannot connect to executor at %s\n", + loops->ws_client->cfg->executor_socket_path); + return; + } + event_loops_add_fd(&loops->cold_epoll, loops->unix_client_fd, + FD_TYPE_UNIX_CLIENT, 0, NULL, EPOLLIN); + } + + char json_buf[4096]; + char corr_id[37]; + snprintf(corr_id, sizeof(corr_id), + "%08x%08x%08x%08x", + (unsigned)(uintptr_t)&sig->legs.legs[0] ^ (unsigned)sig->ts_ms, + (unsigned)sig->ts_ms ^ (unsigned)sig->book_ts_ms, + (unsigned)sig->predicted_bps, + (unsigned)sig->t_arrive_ms); + + char legs_json[1024]; + legs_json[0] = '\0'; + for (uint8_t l = 0; l < 3; l++) { + const signal_leg_t *sl = &sig->legs.legs[l]; + char tmp[384]; + snprintf(tmp, sizeof(tmp), + "%s{\"pair\":\"%s\",\"side\":\"%s\"," + "\"order_param\":\"%s\"," + "\"fee_rate\":%.6f,\"fee_currency\":\"%s\"," + "\"base_increment\":\"%.10g\",\"quote_increment\":\"%.10g\",\"base_min_size\":\"%.10g\"}", + l ? "," : "", sl->symbol, sl->side, + sl->order_param, + sl->fee_rate, sl->fee_currency, + sl->base_increment, sl->quote_increment, sl->base_min_size); + strncat(legs_json, tmp, sizeof(legs_json) - 1); + } + + // triangle_key as JSON array ["base","mid","quote"] + char triangle_key_json[96]; + { + char parts[3][16] = {{0}}; + const char *tk = sig->triangle_key; + const char *s1 = strchr(tk, '/'); + const char *s2 = s1 ? strchr(s1 + 1, '/') : NULL; + if (s1 && s2) { + uint32_t l1 = s1 - tk; + if (l1 > 15) l1 = 15; + memcpy(parts[0], tk, l1); + uint32_t l2 = s2 - s1 - 1; + if (l2 > 15) l2 = 15; + memcpy(parts[1], s1 + 1, l2); + strncpy(parts[2], s2 + 1, 15); + snprintf(triangle_key_json, sizeof(triangle_key_json), + "[\"%s\",\"%s\",\"%s\"]", parts[0], parts[1], parts[2]); + } else { + snprintf(triangle_key_json, sizeof(triangle_key_json), "[\"%s\"]", tk); + } + } + + // Full book snapshot included when !live (paper trading mode) + char books_json_str[2048] = ""; + if (!sig->live && sig->book_count > 0) { + char *bp = books_json_str; + size_t rem = sizeof(books_json_str); + for (uint8_t b = 0; b < sig->book_count; b++) { + const signal_book_t *sb = &sig->books[b]; + char bid_arr[256] = {0}, ask_arr[256] = {0}; + for (uint8_t lev = 0; lev < sb->bid_count; lev++) { + char tmp[64]; + snprintf(tmp, sizeof(tmp), "%s{\"price\":\"%.6g\",\"size\":\"%.8g\"}", + lev ? "," : "", sb->bids[lev].price, sb->bids[lev].size); + strncat(bid_arr, tmp, sizeof(bid_arr) - 1); + } + for (uint8_t lev = 0; lev < sb->ask_count; lev++) { + char tmp[64]; + snprintf(tmp, sizeof(tmp), "%s{\"price\":\"%.6g\",\"size\":\"%.8g\"}", + lev ? "," : "", sb->asks[lev].price, sb->asks[lev].size); + strncat(ask_arr, tmp, sizeof(ask_arr) - 1); + } + int n = snprintf(bp, rem, + "%s{\"symbol\":\"%s\",\"bids\":[%s],\"asks\":[%s],\"ts_ms\":%lld}", + b ? "," : "", sb->symbol, bid_arr, ask_arr, (long long)sb->ts_ms); + if (n > 0 && (size_t)n < rem) { bp += n; rem -= (size_t)n; } + } + } + + snprintf(json_buf, sizeof(json_buf), + "{\"type\":\"signal\",\"correlation_id\":\"%s\"," + "\"triangle_key\":%s,\"primary_quote\":\"%s\"," + "\"live\":%s,\"starting_volume\":\"%.8g\"," + "\"legs\":[%s],\"predicted_bps\":%.4f," + "\"ts_ms\":%lld,\"book_ts_ms\":%lld,\"t_sock_arrive_ms\":%lld,\"t_arrive_ms\":%lld,\"t_eval_ms\":%lld" + "%s%s%s" + "}\n", + corr_id, triangle_key_json, sig->primary_quote, + sig->live ? "true" : "false", sig->starting_volume, + legs_json, sig->predicted_bps, + (long long)sig->ts_ms, (long long)sig->book_ts_ms, + (long long)sig->t_sock_arrive_ms, + (long long)sig->t_arrive_ms, (long long)sig->t_eval_ms, + (sig->live || sig->book_count == 0) ? "" : ",\"books\":[", + books_json_str[0] ? books_json_str : "", + (sig->live || sig->book_count == 0) ? "" : "]"); + + size_t to_send = strlen(json_buf); + size_t sent = 0; + while (sent < to_send) { + int r = (int)write(loops->unix_client_fd, json_buf + sent, to_send - sent); + if (r > 0) { + sent += (size_t)r; + continue; + } + if (r == 0 || (errno != EAGAIN && errno != EWOULDBLOCK)) { + log_write("[EVENTS] Write to executor failed, reconnecting\n"); + int old_fd = loops->unix_client_fd; + loops->unix_client_fd = -1; + close(old_fd); + event_loops_remove_fd(&loops->cold_epoll, old_fd); + break; + } + /* EAGAIN: executor buffer full, drop this signal and move on */ + break; + } +} + +static void arm_ping_timer(event_loops_t *loops, uint64_t interval_ms) { + if (interval_ms == 0) return; + struct itimerspec its = {0}; + its.it_value.tv_sec = interval_ms / 1000; + its.it_value.tv_nsec = (interval_ms % 1000) * 1000000; + timerfd_settime(loops->timer_fd, 0, &its, NULL); +} + +/* + * HOT thread: epoll-driven WebSocket I/O. + * Monitors WS connection fds for incoming data and ping timer for keep-alive. + * Sends ping frames to all connected WS connections on timer expiry. + */ +void *event_hot_thread(void *arg) { + event_loops_t *loops = (event_loops_t *)arg; + ws_client_t *ws = loops->ws_client; + + log_write("[HOT] Thread started\n"); + + for (uint32_t i = 0; i < ws->connection_count; i++) { + ws_connection_t *conn = &ws->connections[i]; + if (conn->fd >= 0) { + set_nonblocking(conn->fd); + event_loops_add_fd(&loops->hot_epoll, conn->fd, FD_TYPE_WS, i, NULL, EPOLLIN); + } + } + + if (ws->connections[0].ping_interval_ms > 0) { + event_loops_add_fd(&loops->hot_epoll, loops->timer_fd, FD_TYPE_TIMER, + 0, NULL, EPOLLIN); + arm_ping_timer(loops, ws->connections[0].ping_interval_ms); + } + + while (loops->running) { + int nfds = epoll_wait(loops->hot_epoll.epoll_fd, + loops->hot_epoll.events, MAX_EPOLL_FDS, 100); + if (nfds < 0) { + if (errno == EINTR) continue; + perror("epoll_wait hot"); + break; + } + + for (int i = 0; i < nfds; i++) { + tracked_fd_t *tf = (tracked_fd_t *)loops->hot_epoll.events[i].data.ptr; + if (!tf || tf->fd < 0) continue; + + if (tf->type == FD_TYPE_WS) { + ws_client_read(ws, tf->ws_conn_idx); + } else if (tf->type == FD_TYPE_TIMER) { + uint64_t expirations = 0; + read(loops->timer_fd, &expirations, sizeof(expirations)); + + for (uint32_t c = 0; c < ws->connection_count; c++) { + ws_connection_t *conn = &ws->connections[c]; + if (conn->state == WS_STATE_CONNECTED) { + ws_client_send_ping(conn); + } + } + + if (ws->connections[0].ping_interval_ms > 0) { + arm_ping_timer(loops, ws->connections[0].ping_interval_ms); + } + } + } + } + + log_write("[HOT] Thread exited\n"); + return NULL; +} + +/* + * COLD thread: drain SPSC signal queue and forward to executor. + * Uses epoll_wait on the Unix client fd to detect disconnection. + * Priority: drains queue before and after epoll to minimize latency. + */ +void *event_cold_thread(void *arg) { + event_loops_t *loops = (event_loops_t *)arg; + + log_write("[COLD] Thread started\n"); + + while (loops->running) { + while (!spsc_empty(loops->signal_queue)) { + signal_entry_t sig; + if (spsc_pop(loops->signal_queue, &sig)) { + send_signal_to_executor(loops, &sig); + } + } + + int nfds = epoll_wait(loops->cold_epoll.epoll_fd, + loops->cold_epoll.events, MAX_EPOLL_FDS, 200); + if (nfds < 0) { + if (errno == EINTR) continue; + perror("epoll_wait cold"); + break; + } + + for (int i = 0; i < nfds; i++) { + tracked_fd_t *tf = (tracked_fd_t *)loops->cold_epoll.events[i].data.ptr; + if (!tf || tf->fd < 0) continue; + + uint32_t ev = loops->cold_epoll.events[i].events; + + if (tf->type == FD_TYPE_EVENT) { + uint64_t val = 0; + read(loops->wakeup_fd, &val, sizeof(val)); + continue; + } + + if (tf->type == FD_TYPE_UNIX_CLIENT) { + if (ev & (EPOLLERR | EPOLLHUP)) { + log_write("[COLD] Executor disconnected\n"); + close(loops->unix_client_fd); + loops->unix_client_fd = -1; + event_loops_remove_fd(&loops->cold_epoll, tf->fd); + continue; + } + } + } + + // Drain again after epoll to catch any signals queued during processing + while (!spsc_empty(loops->signal_queue)) { + signal_entry_t sig; + if (spsc_pop(loops->signal_queue, &sig)) { + send_signal_to_executor(loops, &sig); + } + } + } + + log_write("[COLD] Thread exited\n"); + return NULL; +} diff --git a/src/events.h b/src/events.h new file mode 100644 index 0000000..cd0b34a --- /dev/null +++ b/src/events.h @@ -0,0 +1,72 @@ +#ifndef FUSED_EVENTS_H +#define FUSED_EVENTS_H + +#include +#include +#include +#include "ws_client.h" +#include "queue.h" + +#define MAX_EPOLL_FDS 64 + +/* Identifies the type of a tracked file descriptor */ +typedef enum { + FD_TYPE_WS, /* WebSocket connection */ + FD_TYPE_TIMER, /* timerfd */ + FD_TYPE_EVENT, /* eventfd for queue wakeup */ + FD_TYPE_UNIX_SERVER, /* unix domain socket server */ + FD_TYPE_HTTP_SERVER, /* HTTP server socket */ + FD_TYPE_UNIX_CLIENT /* unix domain socket client */ +} fd_type_t; + +/* A file descriptor tracked by the epoll event loop */ +typedef struct { + int fd; /* the file descriptor */ + fd_type_t type; /* type identifier for dispatch */ + uint32_t ws_conn_idx; /* WebSocket connection index (if type is FD_TYPE_WS) */ + void *user_data; /* optional user data pointer */ +} tracked_fd_t; + +/* Epoll-based event set for a group of file descriptors */ +typedef struct { + int epoll_fd; /* epoll instance fd */ + struct epoll_event events[MAX_EPOLL_FDS]; /* re-usable event array */ + tracked_fd_t fds[MAX_EPOLL_FDS]; /* tracked fd descriptors */ + uint32_t fd_count; /* number of tracked fds */ +} epoll_set_t; + +/* Top-level event loop state, split into hot (ws) and cold (timer/http) paths */ +typedef struct { + epoll_set_t hot_epoll; /* hot epoll set for latency-sensitive ws events */ + epoll_set_t cold_epoll; /* cold epoll set for timer/http events */ + ws_client_t *ws_client; /* WebSocket client instance */ + spsc_queue_t *signal_queue; /* signal queue for emitting opportunities */ + int unix_server_fd; /* unix domain server socket */ + int unix_client_fd; /* unix domain client socket */ + int http_server_fd; /* HTTP server socket */ + int timer_fd; /* timerfd for periodic tasks */ + int wakeup_fd; /* eventfd for waking the cold loop */ + uint64_t next_ping_ms; /* next scheduled WebSocket ping timestamp */ + bool running; /* false signals event loops to exit */ +} event_loops_t; + +/* Initialise both epoll sets, create sockets, and start event loops */ +int event_loops_init(event_loops_t *loops, ws_client_t *ws_client, + spsc_queue_t *signal_queue, const config_t *cfg, int wakeup_fd); +/* Tear down event loops, close all sockets */ +void event_loops_destroy(event_loops_t *loops); +/* Register a file descriptor with an epoll set */ +int event_loops_add_fd(epoll_set_t *set, int fd, fd_type_t type, + uint32_t ws_idx, void *user_data, uint32_t events); +/* Remove a file descriptor from an epoll set */ +void event_loops_remove_fd(epoll_set_t *set, int fd); +/* Hot event loop thread: handles WebSocket I/O */ +void *event_hot_thread(void *arg); +/* Cold event loop thread: handles timers, HTTP, and signal dispatch */ +void *event_cold_thread(void *arg); +/* Connect to a unix domain socket (non-blocking) */ +int unix_client_connect(const char *socket_path); +/* Create and listen on a unix domain socket */ +int unix_server_create(const char *socket_path); + +#endif diff --git a/src/hash.c b/src/hash.c new file mode 100644 index 0000000..1f25dc2 --- /dev/null +++ b/src/hash.c @@ -0,0 +1,78 @@ +/* + * hash.c - FNV-1a hash function and symbol table (sorted array with bsearch) + * + * The symbol table maps KuCoin trading pair names (e.g. "BTC-USDT") to + * dense 16-bit indices. Entries are sorted alphabetically for O(log n) + * lookup via bsearch(3). Used by ws_client to resolve symbol names in + * book update messages. + */ + +#include "hash.h" +#include +#include +#include + +static const uint32_t FNV_OFFSET = 2166136261u; +static const uint32_t FNV_PRIME = 16777619u; + +uint32_t fnv1a_hash(const char *str, uint32_t len) { + uint32_t hash = FNV_OFFSET; + for (uint32_t i = 0; i < len; i++) { + hash ^= (uint8_t)str[i]; + hash *= FNV_PRIME; + } + return hash; +} + +void symbol_table_init(symbol_table_t *table) { + table->capacity = SYMBOL_TABLE_INITIAL; + table->count = 0; + table->entries = calloc(table->capacity, sizeof(symbol_entry_t)); +} + +static int entry_cmp(const void *a, const void *b) { + const symbol_entry_t *ea = (const symbol_entry_t *)a; + const symbol_entry_t *eb = (const symbol_entry_t *)b; + return strcmp(ea->name, eb->name); +} + +static int entry_cmp_qsort(const void *a, const void *b) { + return entry_cmp(a, b); +} + +void symbol_table_sort(symbol_table_t *table) { + qsort(table->entries, table->count, sizeof(symbol_entry_t), entry_cmp_qsort); + for (uint32_t i = 0; i < table->count; i++) { + table->entries[i].index = (uint16_t)i; + } +} + +int symbol_table_add(symbol_table_t *table, const char *name) { + if (table->count >= table->capacity) { + uint32_t new_cap = table->capacity * 2; + symbol_entry_t *new_entries = realloc(table->entries, + new_cap * sizeof(symbol_entry_t)); + if (!new_entries) return -1; + table->entries = new_entries; + table->capacity = new_cap; + } + + symbol_entry_t *entry = &table->entries[table->count]; + strncpy(entry->name, name, SYMBOL_NAME_LEN - 1); + entry->name[SYMBOL_NAME_LEN - 1] = '\0'; + entry->index = (uint16_t)table->count; + table->count++; + + return (int)(table->count - 1); +} + +int16_t symbol_table_lookup(const symbol_table_t *table, const char *name) { + symbol_entry_t key; + strncpy(key.name, name, SYMBOL_NAME_LEN - 1); + key.name[SYMBOL_NAME_LEN - 1] = '\0'; + + symbol_entry_t *found = bsearch(&key, table->entries, table->count, + sizeof(symbol_entry_t), entry_cmp); + if (!found) return -1; + return (int16_t)found->index; +} diff --git a/src/hash.h b/src/hash.h new file mode 100644 index 0000000..16d1916 --- /dev/null +++ b/src/hash.h @@ -0,0 +1,34 @@ +#ifndef FUSED_HASH_H +#define FUSED_HASH_H + +#include +#include "book.h" + +#define SYMBOL_TABLE_INITIAL 1024 + +/* One entry in the symbol table mapping name -> numeric index */ +typedef struct { + char name[SYMBOL_NAME_LEN]; /* symbol name e.g. "BTC-USDT" */ + uint16_t index; /* assigned numeric index */ +} symbol_entry_t; + +/* Growable symbol table for mapping symbol names to dense indices */ +typedef struct { + symbol_entry_t *entries; /* dynamic array of entries */ + uint32_t count; /* number of entries currently stored */ + uint32_t capacity; /* allocated capacity of the array */ +} symbol_table_t; + +/* Initialise an empty symbol table */ +void symbol_table_init(symbol_table_t *table); +/* Add a symbol to the table; returns its index, or -1 on failure */ +int symbol_table_add(symbol_table_t *table, const char *name); +/* Look up a symbol by name; returns its index or -1 if not found */ +int16_t symbol_table_lookup(const symbol_table_t *table, const char *name); +/* Sort symbol table entries alphabetically by name */ +void symbol_table_sort(symbol_table_t *table); + +/* FNV-1a non-cryptographic hash for a byte string */ +uint32_t fnv1a_hash(const char *str, uint32_t len); + +#endif diff --git a/src/http_client.c b/src/http_client.c new file mode 100644 index 0000000..3018e11 --- /dev/null +++ b/src/http_client.c @@ -0,0 +1,431 @@ +/* + * http_client.c - Synchronous HTTP/HTTPS client with KuCoin API auth support + * + * Provides: TCP socket connection (IPv4), TLS via OpenSSL, HTTP request building, + * chunked transfer-encoding dechunking, and KuCoin HMAC-SHA256 signing. + * + * All calls are blocking with 10s socket timeouts. + * Response buffer is 1MB (KuCoin /api/v2/symbols response ~700KB). + */ + +#include "log.h" +#include "http_client.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define HTTP_BUFFER_SIZE 1048576 // 1MB for large responses (KuCoin symbols ~700KB) + +static int resolve_host(const char *host, struct sockaddr_in *addr) { + struct addrinfo hints = {0}, *res = NULL; + hints.ai_family = AF_INET; + hints.ai_socktype = SOCK_STREAM; + + int ret = getaddrinfo(host, "443", &hints, &res); + if (ret != 0 || !res) return -1; + + memcpy(addr, res->ai_addr, sizeof(struct sockaddr_in)); + freeaddrinfo(res); + return 0; +} + +static int create_tcp_socket(const char *host, int port) { + struct sockaddr_in addr = {0}; + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + + if (inet_pton(AF_INET, host, &addr.sin_addr) == 1) { + // IP address + } else { + if (resolve_host(host, &addr) != 0) return -1; + } + + int fd = socket(AF_INET, SOCK_STREAM, 0); + if (fd < 0) return -1; + + // Set connect/read/write timeouts to 10s + struct timeval tv = { .tv_sec = 10, .tv_usec = 0 }; + setsockopt(fd, SOL_SOCKET, SO_SNDTIMEO, &tv, sizeof(tv)); + setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv)); + + if (connect(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + close(fd); + return -1; + } + + return fd; +} + +static void build_request(char *buf, size_t buf_len, const char *method, + const char *host, const char *path, + const char *body, int body_len) { + snprintf(buf, buf_len, + "%s %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Accept: */*\r\n" + "User-Agent: fused-engine/1.0\r\n" + "Connection: close\r\n", + method, path, host); + + if (body && body_len > 0) { + snprintf(buf + strlen(buf), buf_len - strlen(buf), + "Content-Type: application/json\r\n" + "Content-Length: %d\r\n" + "\r\n%s", + body_len, body); + } else { + strcat(buf, "\r\n"); + } +} + +char *http_get(const char *host, int port, const char *path, int *out_len) { + return http_post(host, port, path, NULL, 0, out_len); +} + +char *http_post(const char *host, int port, const char *path, + const char *body, int body_len, int *out_len) { + int fd = create_tcp_socket(host, port); + if (fd < 0) return NULL; + + char req[4096]; + build_request(req, sizeof(req), body ? "POST" : "GET", host, path, body, body_len); + + if (send(fd, req, strlen(req), 0) < 0) { + close(fd); + return NULL; + } + + char *resp = malloc(HTTP_BUFFER_SIZE); + if (!resp) { + close(fd); + return NULL; + } + + int total = 0; + while (total < HTTP_BUFFER_SIZE - 1) { + int n = recv(fd, resp + total, HTTP_BUFFER_SIZE - 1 - total, 0); + if (n <= 0) break; + total += n; + } + resp[total] = '\0'; + + close(fd); + + // Extract body after headers + char *headers_end = strstr(resp, "\r\n\r\n"); + if (headers_end) { + memmove(resp, headers_end + 4, total - (headers_end - resp) - 4); + total = total - (headers_end - resp) - 4; + resp[total] = '\0'; + } + + if (out_len) *out_len = total; + return resp; +} + +char *https_get(const char *host, int port, const char *path, int *out_len) { + return https_post(host, port, path, NULL, 0, out_len); +} + +char *https_post(const char *host, int port, const char *path, + const char *body, int body_len, int *out_len) { + int fd = create_tcp_socket(host, port); + if (fd < 0) return NULL; + + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + if (!ctx) { + close(fd); + return NULL; + } + + SSL *ssl = SSL_new(ctx); + if (!ssl) { + SSL_CTX_free(ctx); + close(fd); + return NULL; + } + + SSL_set_fd(ssl, fd); + SSL_set_tlsext_host_name(ssl, host); + + if (SSL_connect(ssl) <= 0) { + SSL_free(ssl); + SSL_CTX_free(ctx); + close(fd); + return NULL; + } + + char req[4096]; + build_request(req, sizeof(req), body ? "POST" : "GET", host, path, body, body_len); + + if (SSL_write(ssl, req, strlen(req)) <= 0) { + SSL_free(ssl); + SSL_CTX_free(ctx); + close(fd); + return NULL; + } + + char *resp = malloc(HTTP_BUFFER_SIZE); + if (!resp) { + SSL_free(ssl); + SSL_CTX_free(ctx); + close(fd); + return NULL; + } + + int total = 0; + while (total < HTTP_BUFFER_SIZE - 1) { + int n = SSL_read(ssl, resp + total, HTTP_BUFFER_SIZE - 1 - total); + if (n <= 0) { + int err = SSL_get_error(ssl, n); + log_write("[HTTPS] SSL_read returned %d, SSL_error=%d\n", n, err); + break; + } + total += n; + } + resp[total] = '\0'; + log_write("[HTTPS] read %d bytes total, first 200: %.200s\n", total, resp); + log_write("[HTTPS] read %d bytes total\n", total); + + SSL_shutdown(ssl); + SSL_free(ssl); + SSL_CTX_free(ctx); + close(fd); + + // Strip HTTP headers + char *headers_end = strstr(resp, "\r\n\r\n"); + if (!headers_end) { + if (out_len) *out_len = 0; + return resp; + } + int header_len = (headers_end - resp) + 4; + bool is_chunked = (strcasestr(resp, "transfer-encoding") != NULL); + memmove(resp, headers_end + 4, total - header_len); + total -= header_len; + resp[total] = '\0'; + + // Dechunk if needed (parse hex chunk sizes, copy chunk data) + if (is_chunked) { + log_write("[HTTPS] dechunking %d bytes\n", total); + char *out = malloc(HTTP_BUFFER_SIZE); + if (out) { + int out_pos = 0; + char *p = resp; + int chunk_num = 0; + while (*p && !(*p == '0' && (p[1] == '\r' || p[1] == '\n'))) { + int chunk_len = 0; + while (*p && *p != '\r' && *p != '\n') { + char hex = *p; + chunk_len <<= 4; + chunk_len += (hex >= '0' && hex <= '9') ? (hex - '0') : ((hex & 0x1f) + 9); + p++; + } + if (*p == '\r') p++; + if (*p == '\n') p++; + if (chunk_len > 0 && out_pos + chunk_len < HTTP_BUFFER_SIZE - 1) { + memcpy(out + out_pos, p, chunk_len); + out_pos += chunk_len; + p += chunk_len; + } + if (*p == '\r') p++; + if (*p == '\n') p++; + chunk_num++; + if (chunk_num == 1) { + log_write("[HTTPS] first chunk: len=%d, data='%.100s'\n", chunk_len, p - chunk_len); + } + } + out[out_pos] = '\0'; + log_write("[HTTPS] dechunked: %d chunks, %d bytes, first 200: '%.200s'\n", chunk_num, out_pos, out); + free(resp); + resp = out; + total = out_pos; + } + } + + if (out_len) *out_len = total; + return resp; +} + +/* + * Compute HMAC-SHA256 digest of data using key, then base64-encode the result. + * Uses OpenSSL HMAC() + BIO_f_base64 filter chain. + */ +static int hmac_sha256_base64(const char *key, const char *data, char *out, size_t out_len) { + unsigned char digest[EVP_MAX_MD_SIZE]; + unsigned int digest_len = 0; + + if (HMAC(EVP_sha256(), key, (int)strlen(key), + (const unsigned char *)data, (int)strlen(data), + digest, &digest_len) == NULL) { + return -1; + } + + // Use BIO_s_mem as backend, BIO_f_base64 as filter + BIO *bmem = BIO_new(BIO_s_mem()); + BIO *b64 = BIO_new(BIO_f_base64()); + BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL); + BIO *chain = BIO_push(b64, bmem); + + BIO_write(chain, digest, digest_len); + BIO_flush(chain); + + // Get data from mem BIO before freeing + char *buf = NULL; + long len = BIO_get_mem_data(bmem, &buf); + if (len < 0 || (size_t)len >= out_len) { + BIO_free_all(chain); + return -1; + } + memcpy(out, buf, (size_t)len); + out[len] = '\0'; + + BIO_free_all(chain); + return (int)len; +} + +/* + * Authenticated GET request to KuCoin REST API. + * Builds signature from timestamp + "GET" + path using HMAC-SHA256. + * Passphrase is also HMAC'd. Sends as KC-API-* headers. + */ +char *https_get_auth(const char *host, int port, const char *path, + const char *api_key, const char *api_secret, + const char *api_passphrase, int *out_len) { + if (!api_key || !api_secret || !api_passphrase || !*api_key || !*api_secret || !*api_passphrase) { + return NULL; + } + + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + char timestamp[32]; + snprintf(timestamp, sizeof(timestamp), "%lld", (long long)(ts.tv_sec * 1000LL + ts.tv_nsec / 1000000LL)); + + char sign_input[512]; + snprintf(sign_input, sizeof(sign_input), "%sGET%s", timestamp, path); + log_write("[HTTP_AUTH] sign_input: '%s'\n", sign_input); + char sign_b64[256] = {0}; + if (hmac_sha256_base64(api_secret, sign_input, sign_b64, sizeof(sign_b64)) < 0) { + return NULL; + } + log_write("[HTTP_AUTH] sign_b64: '%s'\n", sign_b64); + + char passphrase_b64[256] = {0}; + if (hmac_sha256_base64(api_secret, api_passphrase, passphrase_b64, sizeof(passphrase_b64)) < 0) { + return NULL; + } + int fd = create_tcp_socket(host, port); + if (fd < 0) return NULL; + + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + if (!ctx) { close(fd); return NULL; } + + SSL *ssl = SSL_new(ctx); + if (!ssl) { SSL_CTX_free(ctx); close(fd); return NULL; } + + SSL_set_fd(ssl, fd); + SSL_set_tlsext_host_name(ssl, host); + + if (SSL_connect(ssl) <= 0) { + SSL_free(ssl); SSL_CTX_free(ctx); close(fd); return NULL; + } + + char req[4096]; + snprintf(req, sizeof(req), + "GET %s HTTP/1.1\r\n" + "Host: %s\r\n" + "Accept: */*\r\n" + "User-Agent: fused-engine/1.0\r\n" + "Connection: close\r\n" + "KC-API-KEY: %s\r\n" + "KC-API-SIGN: %s\r\n" + "KC-API-TIMESTAMP: %s\r\n" + "KC-API-PASSPHRASE: %s\r\n" + "KC-API-SIGN-TYPE: 2\r\n" + "KC-API-KEY-VERSION: 3\r\n" + "\r\n", + path, host, api_key, sign_b64, timestamp, passphrase_b64); + + if (SSL_write(ssl, req, (int)strlen(req)) <= 0) { + SSL_free(ssl); SSL_CTX_free(ctx); close(fd); return NULL; + } + + char *resp = malloc(HTTP_BUFFER_SIZE); + if (!resp) { SSL_free(ssl); SSL_CTX_free(ctx); close(fd); return NULL; } + + int total = 0; + while (total < HTTP_BUFFER_SIZE - 1) { + int n = SSL_read(ssl, resp + total, HTTP_BUFFER_SIZE - 1 - total); + if (n <= 0) { + int err = SSL_get_error(ssl, n); + log_write("[HTTPS_AUTH] SSL_read returned %d, SSL_error=%d\n", n, err); + break; + } + total += n; + } + resp[total] = '\0'; + log_write("[HTTPS_AUTH] read %d bytes total, first 200: %.200s\n", total, resp); + log_write("[HTTPS_AUTH] read %d bytes total\n", total); + + SSL_shutdown(ssl); + SSL_free(ssl); + SSL_CTX_free(ctx); + close(fd); + + // Strip headers and dechunk + char *headers_end = strstr(resp, "\r\n\r\n"); + if (headers_end) { + int hl = (headers_end - resp) + 4; + bool chunked = (strcasestr(resp, "transfer-encoding") != NULL); + memmove(resp, headers_end + 4, total - hl); + total -= hl; + resp[total] = '\0'; + if (chunked) { + char *out = malloc(HTTP_BUFFER_SIZE); + if (out) { + int op = 0; + char *p = resp; + while (*p && !(*p == '0' && (p[1] == '\r' || p[1] == '\n'))) { + int cl = 0; + while (*p && *p != '\r' && *p != '\n') { + char h = *p; + cl <<= 4; + cl += (h >= '0' && h <= '9') ? (h - '0') : ((h & 0x1f) + 9); + p++; + } + if (*p == '\r') p++; + if (*p == '\n') p++; + if (cl > 0 && op + cl < HTTP_BUFFER_SIZE - 1) { + memcpy(out + op, p, cl); + op += cl; + p += cl; + } + if (*p == '\r') p++; + if (*p == '\n') p++; + } + out[op] = '\0'; + free(resp); + resp = out; + total = op; + } + } + } + + log_write("[HTTP_AUTH] body (%d bytes): %.200s\n", total, resp); + + if (out_len) *out_len = total; + return resp; +} diff --git a/src/http_client.h b/src/http_client.h new file mode 100644 index 0000000..83c3f5c --- /dev/null +++ b/src/http_client.h @@ -0,0 +1,23 @@ +#ifndef FUSED_HTTP_CLIENT_H +#define FUSED_HTTP_CLIENT_H + +#include + +/* Plain TCP HTTP GET request; returns malloc'd body (caller frees) or NULL */ +char *http_get(const char *host, int port, const char *path, int *out_len); +/* Plain TCP HTTP POST request; returns malloc'd body (caller frees) or NULL */ +char *http_post(const char *host, int port, const char *path, + const char *body, int body_len, int *out_len); + +/* TLS HTTPS GET request via OpenSSL; returns malloc'd body (caller frees) or NULL */ +char *https_get(const char *host, int port, const char *path, int *out_len); +/* TLS HTTPS POST request via OpenSSL; returns malloc'd body (caller frees) or NULL */ +char *https_post(const char *host, int port, const char *path, + const char *body, int body_len, int *out_len); + +/* Authenticated HTTPS GET signed with KuCoin API HMAC-SHA256; returns malloc'd body */ +char *https_get_auth(const char *host, int port, const char *path, + const char *api_key, const char *api_secret, + const char *api_passphrase, int *out_len); + +#endif diff --git a/src/http_server.c b/src/http_server.c new file mode 100644 index 0000000..35487d0 --- /dev/null +++ b/src/http_server.c @@ -0,0 +1,360 @@ +/* + * http_server.c - Simple single-threaded HTTP server for health & book queries + * + * Provides REST endpoints: + * GET /health - connection status + * GET /book/{symbol} - single order book snapshot + * GET /books - all order books + * GET /symbols - list tracked symbols + * POST /symbols - dynamically add symbols (subscribe via WS) + * DELETE /symbols/{name} - remove symbol + */ + +#include "log.h" +#include "http_server.h" +#include "cJSON.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int set_nonblocking(int fd) { + int flags = fcntl(fd, F_GETFL, 0); + if (flags < 0) return -1; + return fcntl(fd, F_SETFL, flags | O_NONBLOCK); +} + +int http_server_init(http_server_t *srv, const char *host, int port, + order_book_t *books, symbol_table_t *symbols, + ws_client_t *ws_client, evaluator_t *evaluator, + config_t *cfg) { + memset(srv, 0, sizeof(*srv)); + srv->books = books; + srv->symbols = symbols; + srv->ws_client = ws_client; + srv->evaluator = evaluator; + srv->cfg = cfg; + srv->client_fd = -1; + srv->running = true; + + srv->listen_fd = socket(AF_INET, SOCK_STREAM, 0); + if (srv->listen_fd < 0) { + perror("socket"); + return -1; + } + + int opt = 1; + setsockopt(srv->listen_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt)); + + struct sockaddr_in addr; + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = htons(port); + if (strcmp(host, "0.0.0.0") == 0) { + addr.sin_addr.s_addr = INADDR_ANY; + } else { + inet_pton(AF_INET, host, &addr.sin_addr); + } + + if (bind(srv->listen_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) { + perror("bind"); + close(srv->listen_fd); + return -1; + } + + if (listen(srv->listen_fd, 16) < 0) { + perror("listen"); + close(srv->listen_fd); + return -1; + } + + set_nonblocking(srv->listen_fd); + log_write("[HTTP] Server listening on %s:%d\n", host, port); + return 0; +} + +void http_server_destroy(http_server_t *srv) { + srv->running = false; + if (srv->client_fd >= 0) close(srv->client_fd); + if (srv->listen_fd >= 0) close(srv->listen_fd); +} + +int http_server_accept(http_server_t *srv) { + if (srv->client_fd >= 0) { + close(srv->client_fd); + } + struct sockaddr_in client_addr; + socklen_t addr_len = sizeof(client_addr); + srv->client_fd = accept(srv->listen_fd, (struct sockaddr *)&client_addr, &addr_len); + if (srv->client_fd < 0) { + if (errno != EAGAIN && errno != EWOULDBLOCK) { + perror("accept"); + } + return -1; + } + set_nonblocking(srv->client_fd); + srv->recv_len = 0; + return srv->client_fd; +} + +static void http_send(http_server_t *srv, const char *status, + const char *content_type, const char *body) { + char header[512]; + int body_len = body ? (int)strlen(body) : 0; + int hdr_len = snprintf(header, sizeof(header), + "HTTP/1.1 %s\r\n" + "Content-Type: %s\r\n" + "Content-Length: %d\r\n" + "Connection: close\r\n" + "\r\n", + status, content_type, body_len); + write(srv->client_fd, header, (size_t)hdr_len); + if (body && body_len > 0) { + write(srv->client_fd, body, (size_t)body_len); + } +} + +static void http_send_json(http_server_t *srv, const char *body) { + http_send(srv, "200 OK", "application/json", body); +} + +static void http_send_error(http_server_t *srv, const char *status, const char *msg) { + http_send(srv, status, "text/plain", msg); +} + +static void handle_health(http_server_t *srv) { + char body[256]; + int connected = 0; + if (srv->ws_client) { + for (uint32_t i = 0; i < srv->ws_client->connection_count; i++) { + if (srv->ws_client->connections[i].state == WS_STATE_CONNECTED) connected++; + } + } + snprintf(body, sizeof(body), + "{\"status\":\"ok\",\"ws_connections\":%d,\"symbols\":%u}", + connected, srv->symbols ? srv->symbols->count : 0); + http_send_json(srv, body); +} + +static void handle_book(http_server_t *srv, const char *symbol) { + if (!srv->symbols || !srv->books) { + http_send_error(srv, "500 Internal Server Error", "not initialized\n"); + return; + } + + int16_t idx = symbol_table_lookup(srv->symbols, symbol); + if (idx < 0) { + char body[128]; + snprintf(body, sizeof(body), "{\"error\":\"symbol not found\",\"symbol\":\"%s\"}", symbol); + http_send(srv, "404 Not Found", "application/json", body); + return; + } + + order_book_t *book = &srv->books[idx]; + char body[2048]; + int off = 0; + off += snprintf(body + off, sizeof(body) - (size_t)off, + "{\"symbol\":\"%s\",\"ts_ms\":%lld,\"sequence\":%lld,\"bids\":[", + book->symbol, (long long)book->ts_ms, (long long)book->sequence); + for (uint8_t i = 0; i < book->bid_count; i++) { + off += snprintf(body + off, sizeof(body) - (size_t)off, + "%s[%.6g,%.8g]", i ? "," : "", book->bids[i][0], book->bids[i][1]); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "],\"asks\":["); + for (uint8_t i = 0; i < book->ask_count; i++) { + off += snprintf(body + off, sizeof(body) - (size_t)off, + "%s[%.6g,%.8g]", i ? "," : "", book->asks[i][0], book->asks[i][1]); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "]}"); + http_send_json(srv, body); +} + +static void handle_books(http_server_t *srv) { + if (!srv->symbols || !srv->books) { + http_send_error(srv, "500 Internal Server Error", "not initialized\n"); + return; + } + + char body[65536]; + int off = snprintf(body, sizeof(body), "["); + for (uint32_t i = 0; i < srv->symbols->count && (size_t)off < sizeof(body) - 512; i++) { + order_book_t *book = &srv->books[i]; + if (book->ts_ms <= 0) continue; + if (off > 1) off += snprintf(body + off, sizeof(body) - (size_t)off, ","); + off += snprintf(body + off, sizeof(body) - (size_t)off, + "{\"symbol\":\"%s\",\"ts\":%lld,\"bids\":[", + book->symbol, (long long)book->ts_ms); + for (uint8_t j = 0; j < book->bid_count; j++) { + off += snprintf(body + off, sizeof(body) - (size_t)off, + "%s[%.6g,%.8g]", j ? "," : "", book->bids[j][0], book->bids[j][1]); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "],\"asks\":["); + for (uint8_t j = 0; j < book->ask_count; j++) { + off += snprintf(body + off, sizeof(body) - (size_t)off, + "%s[%.6g,%.8g]", j ? "," : "", book->asks[j][0], book->asks[j][1]); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "]}"); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "]"); + http_send_json(srv, body); +} + +static void handle_symbols_list(http_server_t *srv) { + if (!srv->symbols) { + http_send_error(srv, "500 Internal Server Error", "not initialized\n"); + return; + } + + char body[65536]; + int off = snprintf(body, sizeof(body), "["); + for (uint32_t i = 0; i < srv->symbols->count && (size_t)off < sizeof(body) - 64; i++) { + off += snprintf(body + off, sizeof(body) - (size_t)off, + "%s\"%s\"", i ? "," : "", srv->symbols->entries[i].name); + } + off += snprintf(body + off, sizeof(body) - (size_t)off, "]"); + http_send_json(srv, body); +} + +static void handle_symbols_add(http_server_t *srv, const char *body) { + if (!srv->symbols || !srv->ws_client) { + http_send_error(srv, "500 Internal Server Error", "not initialized\n"); + return; + } + + cJSON *root = cJSON_Parse(body); + if (!root) { + http_send_error(srv, "400 Bad Request", "invalid JSON\n"); + return; + } + + char resp[1024] = "{\"added\":["; + int resp_len = (int)strlen(resp); + + cJSON *item; + cJSON_ArrayForEach(item, root) { + if (!cJSON_IsString(item)) continue; + const char *sym = item->valuestring; + if (!sym) continue; + + int16_t existing = symbol_table_lookup(srv->symbols, sym); + if (existing >= 0) continue; + + if (symbol_table_add(srv->symbols, sym) == 0) { + int16_t idx = symbol_table_lookup(srv->symbols, sym); + if (idx >= 0) { + if (resp_len > 11) resp_len += snprintf(resp + resp_len, + sizeof(resp) - (size_t)resp_len, ","); + resp_len += snprintf(resp + resp_len, + sizeof(resp) - (size_t)resp_len, "\"%s\"", sym); + + // Auto-subscribe to WS stream for the new symbol + uint16_t uidx = (uint16_t)idx; + if (srv->ws_client->connection_count > 0) { + ws_client_subscribe(srv->ws_client, 0, &uidx, 1); + } + } + } + } + resp_len += snprintf(resp + resp_len, sizeof(resp) - (size_t)resp_len, "]}"); + cJSON_Delete(root); + http_send_json(srv, resp); +} + +static void handle_symbols_remove(http_server_t *srv, const char *symbol) { + if (!srv->symbols || !srv->ws_client) { + http_send_error(srv, "500 Internal Server Error", "not initialized\n"); + return; + } + + int16_t idx = symbol_table_lookup(srv->symbols, symbol); + if (idx < 0) { + char body[128]; + snprintf(body, sizeof(body), "{\"error\":\"symbol not found\",\"symbol\":\"%s\"}", symbol); + http_send(srv, "404 Not Found", "application/json", body); + return; + } + + uint16_t uidx = (uint16_t)idx; + if (srv->ws_client->connection_count > 0) { + ws_client_unsubscribe(srv->ws_client, 0, &uidx, 1); + } + + // Compact the symbol table by shifting entries + for (uint32_t i = 0; i < srv->symbols->count; i++) { + if (strcmp(srv->symbols->entries[i].name, symbol) == 0) { + memmove(&srv->symbols->entries[i], &srv->symbols->entries[i + 1], + (srv->symbols->count - i - 1) * sizeof(symbol_entry_t)); + srv->symbols->count--; + for (uint32_t j = i; j < srv->symbols->count; j++) { + srv->symbols->entries[j].index = (uint16_t)j; + } + break; + } + } + + char resp[128]; + snprintf(resp, sizeof(resp), "{\"removed\":\"%s\"}", symbol); + http_send_json(srv, resp); +} + +int http_server_handle_request(http_server_t *srv) { + ssize_t n = read(srv->client_fd, srv->recv_buf + srv->recv_len, + sizeof(srv->recv_buf) - srv->recv_len - 1); + if (n <= 0) { + if (n < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + perror("read"); + } + close(srv->client_fd); + srv->client_fd = -1; + srv->recv_len = 0; + return -1; + } + srv->recv_len += (size_t)n; + srv->recv_buf[srv->recv_len] = '\0'; + + char *headers_end = strstr((char *)srv->recv_buf, "\r\n\r\n"); + if (!headers_end) return 0; + + char *request_line = (char *)srv->recv_buf; + char *rl_end = strchr(request_line, '\r'); + if (!rl_end) return 0; + *rl_end = '\0'; + + char method[16] = {0}, path[512] = {0}; + sscanf(request_line, "%15s %511s", method, path); + + char *body_start = headers_end + 4; + size_t body_len = srv->recv_len - (size_t)(body_start - (char *)srv->recv_buf); + + if (strcmp(path, "/health") == 0) { + handle_health(srv); + } else if (strncmp(path, "/book/", 6) == 0) { + handle_book(srv, path + 6); + } else if (strcmp(path, "/books") == 0) { + handle_books(srv); + } else if (strcmp(path, "/symbols") == 0) { + if (strcmp(method, "POST") == 0) { + handle_symbols_add(srv, body_start); + } else { + handle_symbols_list(srv); + } + } else if (strncmp(path, "/symbols/", 9) == 0) { + if (strcmp(method, "DELETE") == 0) { + handle_symbols_remove(srv, path + 9); + } else { + http_send_error(srv, "405 Method Not Allowed", "use DELETE\n"); + } + } else { + http_send_error(srv, "404 Not Found", "not found\n"); + } + + close(srv->client_fd); + srv->client_fd = -1; + srv->recv_len = 0; + return 0; +} diff --git a/src/http_server.h b/src/http_server.h new file mode 100644 index 0000000..7e3588c --- /dev/null +++ b/src/http_server.h @@ -0,0 +1,38 @@ +#ifndef FUSED_HTTP_SERVER_H +#define FUSED_HTTP_SERVER_H + +#include +#include +#include "book.h" +#include "hash.h" +#include "config.h" +#include "ws_client.h" +#include "evaluate.h" + +/* Embedded HTTP server for health/status endpoints */ +typedef struct { + int listen_fd; /* server listening socket */ + int client_fd; /* currently connected client socket */ + uint8_t recv_buf[8192]; /* request receive buffer */ + size_t recv_len; /* bytes received so far */ + order_book_t *books; /* pointer to shared order books */ + symbol_table_t *symbols; /* pointer to shared symbol table */ + ws_client_t *ws_client; /* pointer to WebSocket client state */ + evaluator_t *evaluator; /* pointer to evaluator state */ + config_t *cfg; /* pointer to configuration */ + bool running; /* false signals server to stop */ +} http_server_t; + +/* Initialise and bind the HTTP server */ +int http_server_init(http_server_t *srv, const char *host, int port, + order_book_t *books, symbol_table_t *symbols, + ws_client_t *ws_client, evaluator_t *evaluator, + config_t *cfg); +/* Destroy the HTTP server and close sockets */ +void http_server_destroy(http_server_t *srv); +/* Accept a new client connection (non-blocking) */ +int http_server_accept(http_server_t *srv); +/* Read, parse, and respond to the current client request */ +int http_server_handle_request(http_server_t *srv); + +#endif diff --git a/src/jsmn.h b/src/jsmn.h new file mode 100644 index 0000000..8ac14c1 --- /dev/null +++ b/src/jsmn.h @@ -0,0 +1,471 @@ +/* + * MIT License + * + * Copyright (c) 2010 Serge Zaitsev + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ +#ifndef JSMN_H +#define JSMN_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +#ifdef JSMN_STATIC +#define JSMN_API static +#else +#define JSMN_API extern +#endif + +/** + * JSON type identifier. Basic types are: + * o Object + * o Array + * o String + * o Other primitive: number, boolean (true/false) or null + */ +typedef enum { + JSMN_UNDEFINED = 0, + JSMN_OBJECT = 1 << 0, + JSMN_ARRAY = 1 << 1, + JSMN_STRING = 1 << 2, + JSMN_PRIMITIVE = 1 << 3 +} jsmntype_t; + +enum jsmnerr { + /* Not enough tokens were provided */ + JSMN_ERROR_NOMEM = -1, + /* Invalid character inside JSON string */ + JSMN_ERROR_INVAL = -2, + /* The string is not a full JSON packet, more bytes expected */ + JSMN_ERROR_PART = -3 +}; + +/** + * JSON token description. + * type type (object, array, string etc.) + * start start position in JSON data string + * end end position in JSON data string + */ +typedef struct jsmntok { + jsmntype_t type; + int start; + int end; + int size; +#ifdef JSMN_PARENT_LINKS + int parent; +#endif +} jsmntok_t; + +/** + * JSON parser. Contains an array of token blocks available. Also stores + * the string being parsed now and current position in that string. + */ +typedef struct jsmn_parser { + unsigned int pos; /* offset in the JSON string */ + unsigned int toknext; /* next token to allocate */ + int toksuper; /* superior token node, e.g. parent object or array */ +} jsmn_parser; + +/** + * Create JSON parser over an array of tokens + */ +JSMN_API void jsmn_init(jsmn_parser *parser); + +/** + * Run JSON parser. It parses a JSON data string into and array of tokens, each + * describing + * a single JSON object. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens); + +#ifndef JSMN_HEADER +/** + * Allocates a fresh unused token from the token pool. + */ +static jsmntok_t *jsmn_alloc_token(jsmn_parser *parser, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *tok; + if (parser->toknext >= num_tokens) { + return NULL; + } + tok = &tokens[parser->toknext++]; + tok->start = tok->end = -1; + tok->size = 0; +#ifdef JSMN_PARENT_LINKS + tok->parent = -1; +#endif + return tok; +} + +/** + * Fills token type and boundaries. + */ +static void jsmn_fill_token(jsmntok_t *token, const jsmntype_t type, + const int start, const int end) { + token->type = type; + token->start = start; + token->end = end; + token->size = 0; +} + +/** + * Fills next available token with JSON primitive. + */ +static int jsmn_parse_primitive(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + int start; + + start = parser->pos; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + switch (js[parser->pos]) { +#ifndef JSMN_STRICT + /* In strict mode primitive must be followed by "," or "}" or "]" */ + case ':': +#endif + case '\t': + case '\r': + case '\n': + case ' ': + case ',': + case ']': + case '}': + goto found; + default: + /* to quiet a warning from gcc*/ + break; + } + if (js[parser->pos] < 32 || js[parser->pos] >= 127) { + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } +#ifdef JSMN_STRICT + /* In strict mode primitive must be followed by a comma/object/array */ + parser->pos = start; + return JSMN_ERROR_PART; +#endif + +found: + if (tokens == NULL) { + parser->pos--; + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_PRIMITIVE, start, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + parser->pos--; + return 0; +} + +/** + * Fills next token with JSON string. + */ +static int jsmn_parse_string(jsmn_parser *parser, const char *js, + const size_t len, jsmntok_t *tokens, + const size_t num_tokens) { + jsmntok_t *token; + + int start = parser->pos; + + /* Skip starting quote */ + parser->pos++; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c = js[parser->pos]; + + /* Quote: end of string */ + if (c == '\"') { + if (tokens == NULL) { + return 0; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + parser->pos = start; + return JSMN_ERROR_NOMEM; + } + jsmn_fill_token(token, JSMN_STRING, start + 1, parser->pos); +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + return 0; + } + + /* Backslash: Quoted symbol expected */ + if (c == '\\' && parser->pos + 1 < len) { + int i; + parser->pos++; + switch (js[parser->pos]) { + /* Allowed escaped symbols */ + case '\"': + case '/': + case '\\': + case 'b': + case 'f': + case 'r': + case 'n': + case 't': + break; + /* Allows escaped symbol \uXXXX */ + case 'u': + parser->pos++; + for (i = 0; i < 4 && parser->pos < len && js[parser->pos] != '\0'; + i++) { + /* If it isn't a hex character we have an error */ + if (!((js[parser->pos] >= 48 && js[parser->pos] <= 57) || /* 0-9 */ + (js[parser->pos] >= 65 && js[parser->pos] <= 70) || /* A-F */ + (js[parser->pos] >= 97 && js[parser->pos] <= 102))) { /* a-f */ + parser->pos = start; + return JSMN_ERROR_INVAL; + } + parser->pos++; + } + parser->pos--; + break; + /* Unexpected symbol */ + default: + parser->pos = start; + return JSMN_ERROR_INVAL; + } + } + } + parser->pos = start; + return JSMN_ERROR_PART; +} + +/** + * Parse JSON string and fill tokens. + */ +JSMN_API int jsmn_parse(jsmn_parser *parser, const char *js, const size_t len, + jsmntok_t *tokens, const unsigned int num_tokens) { + int r; + int i; + jsmntok_t *token; + int count = parser->toknext; + + for (; parser->pos < len && js[parser->pos] != '\0'; parser->pos++) { + char c; + jsmntype_t type; + + c = js[parser->pos]; + switch (c) { + case '{': + case '[': + count++; + if (tokens == NULL) { + break; + } + token = jsmn_alloc_token(parser, tokens, num_tokens); + if (token == NULL) { + return JSMN_ERROR_NOMEM; + } + if (parser->toksuper != -1) { + jsmntok_t *t = &tokens[parser->toksuper]; +#ifdef JSMN_STRICT + /* In strict mode an object or array can't become a key */ + if (t->type == JSMN_OBJECT) { + return JSMN_ERROR_INVAL; + } +#endif + t->size++; +#ifdef JSMN_PARENT_LINKS + token->parent = parser->toksuper; +#endif + } + token->type = (c == '{' ? JSMN_OBJECT : JSMN_ARRAY); + token->start = parser->pos; + parser->toksuper = parser->toknext - 1; + break; + case '}': + case ']': + if (tokens == NULL) { + break; + } + type = (c == '}' ? JSMN_OBJECT : JSMN_ARRAY); +#ifdef JSMN_PARENT_LINKS + if (parser->toknext < 1) { + return JSMN_ERROR_INVAL; + } + token = &tokens[parser->toknext - 1]; + for (;;) { + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + token->end = parser->pos + 1; + parser->toksuper = token->parent; + break; + } + if (token->parent == -1) { + if (token->type != type || parser->toksuper == -1) { + return JSMN_ERROR_INVAL; + } + break; + } + token = &tokens[token->parent]; + } +#else + for (i = parser->toknext - 1; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + if (token->type != type) { + return JSMN_ERROR_INVAL; + } + parser->toksuper = -1; + token->end = parser->pos + 1; + break; + } + } + /* Error if unmatched closing bracket */ + if (i == -1) { + return JSMN_ERROR_INVAL; + } + for (; i >= 0; i--) { + token = &tokens[i]; + if (token->start != -1 && token->end == -1) { + parser->toksuper = i; + break; + } + } +#endif + break; + case '\"': + r = jsmn_parse_string(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + case '\t': + case '\r': + case '\n': + case ' ': + break; + case ':': + parser->toksuper = parser->toknext - 1; + break; + case ',': + if (tokens != NULL && parser->toksuper != -1 && + tokens[parser->toksuper].type != JSMN_ARRAY && + tokens[parser->toksuper].type != JSMN_OBJECT) { +#ifdef JSMN_PARENT_LINKS + parser->toksuper = tokens[parser->toksuper].parent; +#else + for (i = parser->toknext - 1; i >= 0; i--) { + if (tokens[i].type == JSMN_ARRAY || tokens[i].type == JSMN_OBJECT) { + if (tokens[i].start != -1 && tokens[i].end == -1) { + parser->toksuper = i; + break; + } + } + } +#endif + } + break; +#ifdef JSMN_STRICT + /* In strict mode primitives are: numbers and booleans */ + case '-': + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 't': + case 'f': + case 'n': + /* And they must not be keys of the object */ + if (tokens != NULL && parser->toksuper != -1) { + const jsmntok_t *t = &tokens[parser->toksuper]; + if (t->type == JSMN_OBJECT || + (t->type == JSMN_STRING && t->size != 0)) { + return JSMN_ERROR_INVAL; + } + } +#else + /* In non-strict mode every unquoted value is a primitive */ + default: +#endif + r = jsmn_parse_primitive(parser, js, len, tokens, num_tokens); + if (r < 0) { + return r; + } + count++; + if (parser->toksuper != -1 && tokens != NULL) { + tokens[parser->toksuper].size++; + } + break; + +#ifdef JSMN_STRICT + /* Unexpected char in strict mode */ + default: + return JSMN_ERROR_INVAL; +#endif + } + } + + if (tokens != NULL) { + for (i = parser->toknext - 1; i >= 0; i--) { + /* Unmatched opened object or array */ + if (tokens[i].start != -1 && tokens[i].end == -1) { + return JSMN_ERROR_PART; + } + } + } + + return count; +} + +/** + * Creates a new parser based over a given buffer with an array of tokens + * available. + */ +JSMN_API void jsmn_init(jsmn_parser *parser) { + parser->pos = 0; + parser->toknext = 0; + parser->toksuper = -1; +} + +#endif /* JSMN_HEADER */ + +#ifdef __cplusplus +} +#endif + +#endif /* JSMN_H */ diff --git a/src/log.c b/src/log.c new file mode 100644 index 0000000..60ca794 --- /dev/null +++ b/src/log.c @@ -0,0 +1,93 @@ +/* + * log.c - Non-blocking timestamped stderr logger + * + * Formats messages into a pipe with O_NONBLOCK so the hot path never + * blocks on I/O. A background thread drains the pipe and writes to + * stderr. When the pipe buffer is full messages are silently dropped. + */ + +#define _GNU_SOURCE +#include "log.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static int log_pipe[2] = {-1, -1}; +static pthread_t log_thread; +static atomic_bool log_running = false; + +static void *log_worker(void *arg) { + (void)arg; + char buf[4096]; + while (atomic_load(&log_running)) { + ssize_t n = read(log_pipe[0], buf, sizeof(buf)); + if (n > 0) { + write(STDERR_FILENO, buf, (size_t)n); + } else if (n < 0) { + if (errno == EAGAIN || errno == EWOULDBLOCK) { + usleep(100); + } else { + break; + } + } else { + break; + } + } + return NULL; +} + +void log_init(void) { + if (pipe2(log_pipe, O_NONBLOCK) != 0) { + log_pipe[0] = log_pipe[1] = -1; + return; + } + atomic_store(&log_running, true); + pthread_create(&log_thread, NULL, log_worker, NULL); +} + +void log_shutdown(void) { + atomic_store(&log_running, false); + if (log_thread) { + pthread_join(log_thread, NULL); + } + if (log_pipe[0] >= 0) { close(log_pipe[0]); log_pipe[0] = -1; } + if (log_pipe[1] >= 0) { close(log_pipe[1]); log_pipe[1] = -1; } +} + +void log_write(const char *fmt, ...) { + if (log_pipe[1] < 0) { + /* fallback: sync write to stderr */ + va_list ap; + va_start(ap, fmt); + vfprintf(stderr, fmt, ap); + va_end(ap); + return; + } + + char ts[32]; + time_t t = time(NULL); + struct tm tm; + localtime_r(&t, &tm); + strftime(ts, sizeof(ts), "[%Y/%m/%d %H:%M:%S] ", &tm); + + char buf[1536]; + int ts_len = (int)strlen(ts); + memcpy(buf, ts, (size_t)ts_len); + + va_list ap; + va_start(ap, fmt); + int msg_len = vsnprintf(buf + ts_len, sizeof(buf) - (size_t)ts_len, fmt, ap); + va_end(ap); + + int total = ts_len + (msg_len > 0 ? msg_len : 0); + if (total > 0) { + write(log_pipe[1], buf, (size_t)total); + } +} diff --git a/src/log.h b/src/log.h new file mode 100644 index 0000000..637e35f --- /dev/null +++ b/src/log.h @@ -0,0 +1,16 @@ +#ifndef FUSED_LOG_H +#define FUSED_LOG_H + +#include + +/* Initialise the non-blocking log subsystem (pipe + writer thread). */ +void log_init(void); + +/* Shut down the writer thread and close the pipe. */ +void log_shutdown(void); + +/* Write a formatted log line to stderr with timestamp and newline. + * Non-blocking after log_init(); falls back to synchronous fprintf. */ +void log_write(const char *fmt, ...) __attribute__((format(printf, 1, 2))); + +#endif diff --git a/src/main.c b/src/main.c new file mode 100644 index 0000000..ccaaf19 --- /dev/null +++ b/src/main.c @@ -0,0 +1,266 @@ +/* + * main.c - Fused triangular arbitrage engine entry point + * + * Orchestrates: config loading -> fee table fetch -> symbol discovery -> + * WebSocket connections -> epoll event loops (hot/cold threads) -> HTTP status server. + * Signal delivery to external executor via Unix domain socket. + */ + +#include "log.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "config.h" +#include "hash.h" +#include "book.h" +#include "triangle.h" +#include "http_client.h" +#include "symbols_api.h" +#include "ws_client.h" +#include "evaluate.h" +#include "queue.h" +#include "events.h" +#include "http_server.h" + +static volatile sig_atomic_t g_running = 1; + +static void signal_handler(int sig) { + (void)sig; + g_running = 0; +} + +int main(int argc, char *argv[]) { + const char *config_path = "config.yaml"; + if (argc > 1) config_path = argv[1]; + + struct sigaction sa = {0}; + sa.sa_handler = signal_handler; + sa.sa_flags = 0; + sigaction(SIGINT, &sa, NULL); + sigaction(SIGTERM, &sa, NULL); + + sigset_t block_mask; + sigemptyset(&block_mask); + sigaddset(&block_mask, SIGINT); + sigaddset(&block_mask, SIGTERM); + sigaddset(&block_mask, SIGPIPE); + pthread_sigmask(SIG_BLOCK, &block_mask, NULL); + + /* Early OpenSSL init to avoid provider thread issues */ + SSL_library_init(); + OpenSSL_add_all_algorithms(); + SSL_load_error_strings(); + + log_init(); + + log_write("[MAIN] Loading config from '%s'...\n", config_path); + config_t cfg; + if (config_load(config_path, &cfg) != 0) { + log_write("[MAIN] Failed to load config\n"); + return 1; + } + log_write("[MAIN] Config: threshold=%.1f bps, cooldown=%.0fs, hold=%u currencies\n", + cfg.signal_threshold_bps, cfg.cooldown_seconds, cfg.hold_currency_count); + + // Fetch fee table with auth (KuCoin /api/v1/base-fee) + fee_entry_t *fees = NULL; + uint32_t fee_count = 0; + + log_write("[MAIN] API key present: %s\n", cfg.kucoin_api_key[0] ? "yes" : "no"); + if (cfg.kucoin_api_key[0] && cfg.kucoin_api_secret[0] && cfg.kucoin_api_passphrase[0]) { + log_write("[MAIN] >>> Calling https_get_auth for /api/v1/base-fee\n"); + int out_len = 0; + char *fee_json = https_get_auth("api.kucoin.com", 443, "/api/v1/base-fee", + cfg.kucoin_api_key, cfg.kucoin_api_secret, + cfg.kucoin_api_passphrase, &out_len); + log_write("[MAIN] <<< https_get_auth returned: %p, len=%d\n", fee_json, out_len); + if (fee_json && out_len > 0) { + if (load_fee_table(fee_json, &fees, &fee_count) == 0) { + log_write("[MAIN] Fee table: %u currencies loaded\n", fee_count); + } else { + log_write("[MAIN] Fee table parse failed, using default 0.1%% fees\n"); + } + free(fee_json); + } else { + log_write("[MAIN] Could not fetch fee table, using default 0.1%% fees\n"); + } + } else { + log_write("[MAIN] No API credentials in config, using default 0.1%% fees\n"); + } + + // Discover symbols from KuCoin: fetch pairs, enumerate triangles, populate table + log_write("[MAIN] >>> Initializing symbol table\n"); + symbol_table_t symbols; + symbol_table_init(&symbols); + + for (uint32_t i = 0; i < cfg.symbol_count; i++) { + symbol_table_add(&symbols, cfg.symbols[i]); + } + + log_write("[MAIN] >>> Calling discover_symbols\n"); + triangle_set_t triangles; + if (discover_symbols(&symbols, &triangles, &cfg, fees, fee_count) != 0) { + log_write("[MAIN] Symbol discovery failed\n"); + free_fee_table(fees); + return 1; + } + log_write("[MAIN] <<< discover_symbols done: %u symbols, %u triangles\n", symbols.count, triangles.triangle_count); + + log_write("[MAIN] >>> Allocating books array\n"); + order_book_t *books = calloc(MAX_SYMBOLS, sizeof(order_book_t)); + log_write("[MAIN] books=%p, size=%zu\n", (void*)books, sizeof(order_book_t)); + + log_write("[MAIN] >>> Init SPSC queue\n"); + if (!books) { + log_write("[MAIN] Failed to allocate books\n"); + free_fee_table(fees); + return 1; + } + + spsc_queue_t signal_queue; + log_write("[MAIN] >>> Calling spsc_init\n"); + int wakeup_fd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); + if (wakeup_fd < 0 || spsc_init(&signal_queue, wakeup_fd) != 0) { + log_write("[MAIN] Failed to init signal queue\n"); + triangle_set_free(&triangles); + free_fee_table(fees); + return 1; + } + + evaluator_t evaluator; + evaluator_init(&evaluator, &triangles, books, &cfg, &signal_queue, + cfg.kcs_discount_active); + + ws_client_t ws_client; + if (ws_client_init(&ws_client, &cfg, &symbols, books, &evaluator) != 0) { + log_write("[MAIN] Failed to init WS client\n"); + spsc_destroy(&signal_queue); + triangle_set_free(&triangles); + free_fee_table(fees); + return 1; + } + + event_loops_t events; + if (event_loops_init(&events, &ws_client, &signal_queue, &cfg, wakeup_fd) != 0) { + log_write("[MAIN] Failed to init event loops\n"); + ws_client_destroy(&ws_client); + spsc_destroy(&signal_queue); + triangle_set_free(&triangles); + free_fee_table(fees); + return 1; + } + + http_server_t http_srv; + if (http_server_init(&http_srv, cfg.rest_host, cfg.rest_port, + books, &symbols, &ws_client, &evaluator, &cfg) != 0) { + log_write("[MAIN] HTTP server init failed (non-fatal)\n"); + } + + if (symbols.count > 0) { + uint16_t all_indices[MAX_SYMBOLS]; + uint32_t n = symbols.count > MAX_SYMBOLS ? MAX_SYMBOLS : symbols.count; + for (uint32_t i = 0; i < n; i++) { + all_indices[i] = (uint16_t)i; + } + + uint32_t conns_needed = (n + 399) / 400; + if (conns_needed < 1) conns_needed = 1; + if (conns_needed > WS_MAX_CONNECTIONS) conns_needed = WS_MAX_CONNECTIONS; + ws_client.connection_count = conns_needed; + + log_write("[MAIN] Connecting %u WS connections...\n", conns_needed); + for (uint32_t i = 0; i < conns_needed; i++) { + if (ws_client_connect(&ws_client, i) != 0) { + log_write("[MAIN] WS connection %u failed\n", i); + } + } + + // Batch-subscribe up to 400 symbols per WS connection + uint32_t batch_start = 0; + for (uint32_t conn_idx = 0; conn_idx < conns_needed; conn_idx++) { + uint32_t batch_end = batch_start + 400; + if (batch_end > n) batch_end = n; + uint32_t batch_count = batch_end - batch_start; + if (batch_count > 0) { + ws_client_subscribe(&ws_client, conn_idx, + all_indices + batch_start, batch_count); + } + batch_start = batch_end; + } + log_write("[MAIN] Subscribed to %u symbols across %u WS connections\n", + n, ws_client.connection_count); + } + + log_write("[MAIN] Spawning threads...\n"); + pthread_t hot_thread, cold_thread; + pthread_create(&hot_thread, NULL, event_hot_thread, &events); + pthread_create(&cold_thread, NULL, event_cold_thread, &events); + + // Unblock signals in main thread only; worker threads inherit blocked mask + sigset_t unblock_mask; + sigemptyset(&unblock_mask); + sigaddset(&unblock_mask, SIGINT); + sigaddset(&unblock_mask, SIGTERM); + pthread_sigmask(SIG_UNBLOCK, &unblock_mask, NULL); + + log_write("[MAIN] Fused engine running. Press Ctrl+C to stop.\n"); + + // Main loop: accept HTTP connections and reconnect disconnected WS + while (g_running) { + if (http_srv.listen_fd >= 0 && http_srv.client_fd < 0) { + http_server_accept(&http_srv); + } + if (http_srv.client_fd >= 0) { + http_server_handle_request(&http_srv); + } + + struct timespec ts = {0, 100000000}; + nanosleep(&ts, NULL); + + for (uint32_t i = 0; i < ws_client.connection_count; i++) { + ws_connection_t *conn = &ws_client.connections[i]; + if (conn->state == WS_STATE_DISCONNECTED && g_running) { + uint64_t now = ws_client_now_ms(); + if (now - conn->last_activity_ms > 5000) { + log_write("[MAIN] Reconnecting WS %u...\n", i); + if (ws_client_connect(&ws_client, i) == 0) { + if (conn->symbol_count > 0) { + ws_client_subscribe(&ws_client, i, + conn->symbol_indices, conn->symbol_count); + } + } + conn->last_activity_ms = now; + } + } + } + } + + log_write("[MAIN] Shutting down...\n"); + events.running = false; + ws_client.running = false; + + uint64_t val = 1; + ssize_t wr = write(events.wakeup_fd, &val, sizeof(val)); + (void)wr; + + pthread_join(hot_thread, NULL); + pthread_join(cold_thread, NULL); + + http_server_destroy(&http_srv); + event_loops_destroy(&events); + ws_client_destroy(&ws_client); + spsc_destroy(&signal_queue); + triangle_set_free(&triangles); + free(books); + free_fee_table(fees); + + log_write("[MAIN] Shutdown complete.\n"); + log_shutdown(); + return 0; +} diff --git a/src/queue.c b/src/queue.c new file mode 100644 index 0000000..d9a22d6 --- /dev/null +++ b/src/queue.c @@ -0,0 +1,90 @@ +/* + * queue.c - Lock-free single-producer single-consumer (SPSC) bounded queue + * + * Uses C11 atomics with acquire/release ordering for correct head/tail + * synchronization without locks. The eventfd notify on push wakes the + * consumer's epoll loop (cold thread) for immediate dispatch. + */ + +#include "queue.h" +#include +#include +#include +#include +#include +#include + +int spsc_init(spsc_queue_t *q, int wakeup_fd) { + memset(q, 0, sizeof(*q)); + q->buffer = calloc(Spsc_QUEUE_DEPTH, sizeof(signal_entry_t)); + if (!q->buffer) return -1; + q->head = 0; + q->tail = 0; + q->depth = Spsc_QUEUE_DEPTH; + q->dropped = 0; + q->eventfd = wakeup_fd; + return 0; +} + +void spsc_destroy(spsc_queue_t *q) { + /* eventfd is owned by caller (event_loops), don't close */ + q->eventfd = -1; + free(q->buffer); + q->buffer = NULL; +} + +static inline void eventfd_notify(int fd) { + uint64_t val = 1; + ssize_t ret; + do { + ret = write(fd, &val, sizeof(val)); + } while (ret < 0 && errno == EINTR); + (void)ret; +} + +bool spsc_push(spsc_queue_t *q, const signal_entry_t *entry) { + uint32_t head = atomic_load_explicit(&q->head, memory_order_relaxed); + uint32_t tail = atomic_load_explicit(&q->tail, memory_order_acquire); + + uint32_t next_head = head + 1; + if (next_head >= q->depth) next_head = 0; + + if (next_head == tail) { + q->dropped++; + return false; + } + + q->buffer[head] = *entry; + + atomic_store_explicit(&q->head, next_head, memory_order_release); + eventfd_notify(q->eventfd); + return true; +} + +bool spsc_pop(spsc_queue_t *q, signal_entry_t *entry) { + uint32_t tail = atomic_load_explicit(&q->tail, memory_order_relaxed); + uint32_t head = atomic_load_explicit(&q->head, memory_order_acquire); + + if (tail == head) return false; + + *entry = q->buffer[tail]; + + uint32_t next_tail = tail + 1; + if (next_tail >= q->depth) next_tail = 0; + + atomic_store_explicit(&q->tail, next_tail, memory_order_release); + return true; +} + +bool spsc_empty(const spsc_queue_t *q) { + uint32_t head = atomic_load_explicit(&q->head, memory_order_acquire); + uint32_t tail = atomic_load_explicit(&q->tail, memory_order_acquire); + return head == tail; +} + +uint32_t spsc_count(const spsc_queue_t *q) { + uint32_t head = atomic_load_explicit(&q->head, memory_order_acquire); + uint32_t tail = atomic_load_explicit(&q->tail, memory_order_acquire); + if (head >= tail) return head - tail; + return q->depth - tail + head; +} diff --git a/src/queue.h b/src/queue.h new file mode 100644 index 0000000..4f40740 --- /dev/null +++ b/src/queue.h @@ -0,0 +1,92 @@ +#ifndef FUSED_QUEUE_H +#define FUSED_QUEUE_H + +#include +#include +#include +#include "book.h" +#include "triangle.h" + +#define MAX_SIGNAL_LEN 4096 +#define Spsc_QUEUE_DEPTH 1024 + +/* Single price+size level in an order book snapshot */ +typedef struct { + double price; /* price at this level */ + double size; /* available size at this level */ +} book_level_t; + +/* Snapshot of one leg's order book included in a signal */ +typedef struct { + char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol name */ + int64_t ts_ms; /* book timestamp (milliseconds) */ + book_level_t bids[MAX_BOOK_LEVELS]; /* bid levels (top of book) */ + book_level_t asks[MAX_BOOK_LEVELS]; /* ask levels (top of book) */ + uint8_t bid_count; /* number of valid bid levels */ + uint8_t ask_count; /* number of valid ask levels */ +} signal_book_t; + +/* One leg of a triangular arbitrage signal */ +typedef struct { + char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol */ + char input_currency[CURRENCY_NAME_LEN]; /* currency being traded in */ + char output_currency[CURRENCY_NAME_LEN]; /* currency being traded out */ + char fee_currency[CURRENCY_NAME_LEN]; /* currency used to pay fees */ + double fee_rate; /* fee rate for this leg */ + double exchange_rate; /* computed exchange rate for the leg */ + char side[5]; /* trade side: "buy" or "sell" */ + char order_param[32]; /* order parameter string for the executor */ + double quote_volume; /* notional quote volume for the leg */ + double base_increment; /* base asset lot size step */ + double quote_increment; /* quote asset lot size step */ + double base_min_size; /* minimum base asset order size */ +} signal_leg_t; + +/* Collection of up to 3 legs comprising a triangular signal */ +typedef struct { + uint8_t leg_count; /* number of legs (typically 3) */ + signal_leg_t legs[3]; /* the individual leg descriptors */ +} signal_legs_t; + +/* Entry describing one triangular arbitrage opportunity */ +typedef struct { + char triangle_key[CURRENCY_NAME_LEN * 3 + 4]; /* unique triangle identifier e.g. "BTC-ETH-USDT" */ + char primary_quote[CURRENCY_NAME_LEN]; /* primary quote currency of the triangle */ + double predicted_bps; /* predicted profit in basis points */ + char max_volume[32]; /* max trade volume as string */ + double starting_volume; /* recommended starting volume */ + bool live; /* whether this entry is from live (vs simulated) data */ + int64_t ts_ms; /* signal generation timestamp */ + int64_t book_ts_ms; /* reference order book timestamp */ + int64_t t_sock_arrive_ms; /* timestamp when bytes arrived at SSL_read */ + int64_t t_arrive_ms; /* arrival timestamp at evaluator (post-parse) */ + int64_t t_eval_ms; /* evaluation completion timestamp */ + uint8_t book_count; /* number of books used (typically 3) */ + signal_book_t books[3]; /* order book snapshots for each leg */ + signal_legs_t legs; /* leg descriptors for execution */ +} signal_entry_t; + +/* Lock-free single-producer single-consumer queue for signal entries */ +typedef struct { + signal_entry_t *buffer; /* ring buffer of entries */ + _Atomic uint32_t head; /* consumer read index (atomic) */ + _Atomic uint32_t tail; /* producer write index (atomic) */ + int eventfd; /* eventfd for waking consumer */ + uint32_t depth; /* capacity of the ring buffer */ + uint32_t dropped; /* count of dropped entries due to full queue */ +} spsc_queue_t; + +/* Initialise an SPSC queue backed by a wakeup eventfd */ +int spsc_init(spsc_queue_t *q, int wakeup_fd); +/* Destroy an SPSC queue and free its buffer */ +void spsc_destroy(spsc_queue_t *q); +/* Push an entry into the queue (non-blocking); returns false if full */ +bool spsc_push(spsc_queue_t *q, const signal_entry_t *entry); +/* Pop an entry from the queue (non-blocking); returns false if empty */ +bool spsc_pop(spsc_queue_t *q, signal_entry_t *entry); +/* Returns true if the queue is empty */ +bool spsc_empty(const spsc_queue_t *q); +/* Returns the number of entries currently in the queue */ +uint32_t spsc_count(const spsc_queue_t *q); + +#endif diff --git a/src/symbols_api.c b/src/symbols_api.c new file mode 100644 index 0000000..55a2957 --- /dev/null +++ b/src/symbols_api.c @@ -0,0 +1,426 @@ +/* + * symbols_api.c - KuCoin symbol discovery and triangle enumeration + * + * Fetches all trading pairs from KuCoin /api/v2/symbols, filters by exclusion list, + * enumerates all triangular arbitrage paths over the hold currencies. + * + * Triangle enumeration: for each hold currency H, find all pairs (H, A) and (H, B), + * then for each unordered pair {A, B} check if pair (A, B) exists, forming triangle + * H -> A -> B -> H in both directional orders. + */ + +#include "log.h" +#include "symbols_api.h" +#include "http_client.h" +#include "cJSON.h" +#include +#include +#include +#include + +#define MAX_PAIRS 4096 +#define MAX_SYMBOLS 2048 +#define SYMBOL_NAME_LEN 16 +#define CURRENCY_NAME_LEN 8 +#define PAIR_HASH_SIZE 4096 +#define MAX_NEIGHBORS 2048 + +/* --- Pair hash table: unordered currency pair -> pair index --- */ + +typedef struct { + char a[CURRENCY_NAME_LEN]; + char b[CURRENCY_NAME_LEN]; + uint32_t pair_idx; + bool used; +} ph_entry_t; + +typedef struct { + ph_entry_t entries[PAIR_HASH_SIZE]; +} pair_hash_t; + +static uint32_t ph_hash(const char *a, const char *b) { + uint32_t h = 5381; + const uint8_t *s = (const uint8_t *)a; + while (*s) { h = (h << 5) + h + *s; s++; } + s = (const uint8_t *)b; + while (*s) { h = (h << 5) + h + *s; s++; } + return h % PAIR_HASH_SIZE; +} + +static void ph_init(pair_hash_t *ph) { + memset(ph, 0, sizeof(*ph)); +} + +static void ph_insert(pair_hash_t *ph, const char *c1, const char *c2, uint32_t idx) { + // Normalize: store lexicographically smaller first for unordered lookup + const char *a = c1, *b = c2; + if (strcmp(a, b) > 0) { a = c2; b = c1; } + uint32_t h = ph_hash(a, b); + while (ph->entries[h].used) { + if (strcmp(ph->entries[h].a, a) == 0 && strcmp(ph->entries[h].b, b) == 0) + return; /* already inserted, keep first */ + h = (h + 1) % PAIR_HASH_SIZE; + } + strncpy(ph->entries[h].a, a, CURRENCY_NAME_LEN - 1); + strncpy(ph->entries[h].b, b, CURRENCY_NAME_LEN - 1); + ph->entries[h].pair_idx = idx; + ph->entries[h].used = true; +} + +static bool ph_find(const pair_hash_t *ph, const char *c1, const char *c2, uint32_t *idx) { + const char *a = c1, *b = c2; + if (strcmp(a, b) > 0) { a = c2; b = c1; } + uint32_t h = ph_hash(a, b); + while (ph->entries[h].used) { + if (strcmp(ph->entries[h].a, a) == 0 && strcmp(ph->entries[h].b, b) == 0) { + *idx = ph->entries[h].pair_idx; + return true; + } + h = (h + 1) % PAIR_HASH_SIZE; + } + return false; +} + +/* --- Fee lookup helper --- */ + +/* Fee rate per category: cat1=0.1%, cat2=0.2%, cat3=0.3% */ +static double fee_rate_for_pair(const trading_pair_t *pair, bool kcs_discount) { + double base = pair->fee_category * 0.001; + double rate = base * pair->taker_fee_coeff; + return kcs_discount ? rate * 0.8 : rate; +} + +int fetch_trading_pairs(pair_list_t *out) { + memset(out, 0, sizeof(*out)); + out->capacity = MAX_PAIRS; + out->pairs = calloc(out->capacity, sizeof(trading_pair_t)); + if (!out->pairs) return -1; + + int out_len = 0; + char *json = https_get("api.kucoin.com", 443, "/api/v2/symbols", &out_len); + if (!json || out_len <= 0) { + log_write("[SYMBOLS] Failed to fetch trading pairs\n"); + free(out->pairs); + out->pairs = NULL; + return -1; + } + + cJSON *root = cJSON_Parse(json); + free(json); + if (!root) { + log_write("[SYMBOLS] Failed to parse symbols JSON\n"); + free(out->pairs); + out->pairs = NULL; + return -1; + } + + cJSON *code = cJSON_GetObjectItem(root, "code"); + if (!cJSON_IsString(code) || strcmp(code->valuestring, "200000") != 0) { + log_write("[SYMBOLS] API error: %s\n", cJSON_PrintUnformatted(root)); + cJSON_Delete(root); + free(out->pairs); + out->pairs = NULL; + return -1; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!cJSON_IsArray(data)) { + log_write("[SYMBOLS] 'data' is not an array\n"); + cJSON_Delete(root); + free(out->pairs); + out->pairs = NULL; + return -1; + } + + uint32_t count = 0; + cJSON *item; + cJSON_ArrayForEach(item, data) { + if (count >= out->capacity) break; + if (!cJSON_IsObject(item)) continue; + + cJSON *sym = cJSON_GetObjectItem(item, "symbol"); + cJSON *base = cJSON_GetObjectItem(item, "baseCurrency"); + cJSON *quote = cJSON_GetObjectItem(item, "quoteCurrency"); + cJSON *fee_cur = cJSON_GetObjectItem(item, "feeCurrency"); + cJSON *enable = cJSON_GetObjectItem(item, "enableTrading"); + cJSON *fee_cat = cJSON_GetObjectItem(item, "feeCategory"); + cJSON *taker_coeff = cJSON_GetObjectItem(item, "takerFeeCoefficient"); + cJSON *base_inc = cJSON_GetObjectItem(item, "baseIncrement"); + cJSON *quote_inc = cJSON_GetObjectItem(item, "quoteIncrement"); + cJSON *base_min = cJSON_GetObjectItem(item, "baseMinSize"); + + if (!cJSON_IsString(sym) || !cJSON_IsString(base) || !cJSON_IsString(quote)) continue; + if (!cJSON_IsBool(enable) || !cJSON_IsTrue(enable)) continue; + + trading_pair_t *pair = &out->pairs[count++]; + strncpy(pair->symbol, sym->valuestring, SYMBOL_NAME_LEN - 1); + strncpy(pair->base, base->valuestring, CURRENCY_NAME_LEN - 1); + strncpy(pair->quote, quote->valuestring, CURRENCY_NAME_LEN - 1); + if (cJSON_IsString(fee_cur)) { + strncpy(pair->fee_currency, fee_cur->valuestring, CURRENCY_NAME_LEN - 1); + } + pair->fee_category = cJSON_IsNumber(fee_cat) ? (uint8_t)fee_cat->valueint : 1; + pair->taker_fee_coeff = cJSON_IsNumber(taker_coeff) ? taker_coeff->valuedouble : 1.0; + pair->maker_fee_coeff = 1.0; + pair->base_increment = cJSON_IsString(base_inc) ? atof(base_inc->valuestring) : 0.0; + pair->quote_increment = cJSON_IsString(quote_inc) ? atof(quote_inc->valuestring) : 0.0; + pair->base_min_size = cJSON_IsString(base_min) ? atof(base_min->valuestring) : 0.0; + } + + cJSON_Delete(root); + out->count = count; + log_write("[SYMBOLS] Fetched %u trading pairs\n", count); + return 0; +} + +/* + * Discover triangles from trading pairs. + * + * For each configured hold currency H: + * 1. Find all neighbor currencies A such that pair(H, A) exists + * 2. For each unordered pair (A, B) of neighbors, check if pair(A, B) exists + * 3. If yes, two directed triangles are formed: + * dir0: H -> A -> B -> H (H->A, A->B, B->H) + * dir1: H -> B -> A -> H (H->B, B->A, A->H) + * + * use_bid logic (per leg): + * For a leg trading pair X-Y: + * We want output_currency = Y (the next currency in the cycle). + * If Y equals pair.quote, we can buy Y (pay X) at ask (use_bid=0). + * BUT the code uses use_bid=1 when output_currency == pair.quote + * because selling X gets us quote currency (Y). + * Actually: use_bid=1 means hit bid = sell base = receive quote. + * use_bid=0 means hit ask = buy base = pay quote. + * + * t->use_bid[leg] = 1 when the output currency matches pair.quote: + * We reach this leg with "next currency = quote" -> to get from base to quote, + * we sell base at bid (use_bid=1). + * t->use_bid[leg] = 0 when the output currency matches pair.base: + * We need to go from quote to base -> buy base at ask (use_bid=0). + * + * After enumeration, converts pair indices to symbol table indices and builds + * tri_index (symbol -> flat triangle list) for fast symbol-based lookup. + */ +int discover_symbols(symbol_table_t *symbols, triangle_set_t *triangles, + const config_t *cfg, const fee_entry_t *fees, uint32_t fee_count) { + pair_list_t pairs; + if (fetch_trading_pairs(&pairs) != 0) { + log_write("[SYMBOLS] Failed to fetch pairs\n"); + return -1; + } + + /* Filter out excluded currencies */ + if (cfg->excluded_currency_count > 0) { + uint32_t w = 0; + for (uint32_t i = 0; i < pairs.count; i++) { + const trading_pair_t *p = &pairs.pairs[i]; + bool skip = false; + for (uint32_t j = 0; j < cfg->excluded_currency_count; j++) { + if (strcmp(p->base, cfg->excluded_currencies[j]) == 0 || + strcmp(p->quote, cfg->excluded_currencies[j]) == 0) { skip = true; break; } + } + if (!skip) { if (w != i) pairs.pairs[w] = pairs.pairs[i]; w++; } + } + log_write("[SYMBOLS] excluded %u/%u pairs (excluded_currencies=%u)\n", + pairs.count - w, pairs.count, cfg->excluded_currency_count); + pairs.count = w; + } + log_write("[SYMBOLS] %u pairs after filtering\n", pairs.count); + + /* Build pair hash table: unordered {c1,c2} -> pair index */ + pair_hash_t ph; + ph_init(&ph); + for (uint32_t i = 0; i < pairs.count; i++) { + ph_insert(&ph, pairs.pairs[i].base, pairs.pairs[i].quote, i); + } + + /* Collect unique symbols */ + uint32_t sym_count = 0; + char discovered_symbols[MAX_SYMBOLS][SYMBOL_NAME_LEN]; + for (uint32_t i = 0; i < pairs.count; i++) { + const char *sym = pairs.pairs[i].symbol; + bool dup = false; + for (uint32_t j = 0; j < sym_count; j++) { + if (strcmp(discovered_symbols[j], sym) == 0) { dup = true; break; } + } + if (!dup && sym_count < MAX_SYMBOLS) { + strncpy(discovered_symbols[sym_count++], sym, SYMBOL_NAME_LEN - 1); + } + } + + /* Enumerate triangles for each hold currency */ + uint32_t tri_count = 0; + triangle_t *tris = calloc(MAX_TRIANGLES, sizeof(triangle_t)); + if (!tris) { free(pairs.pairs); return -1; } + bool kcs = cfg->kcs_discount_active; + + for (uint32_t hi = 0; hi < cfg->hold_currency_count; hi++) { + const char *hold = cfg->hold_currencies[hi]; + + /* Collect neighbors: all currencies c where pair(hold, c) exists, + excluding the hold itself and other hold currencies. */ + char neighbors[MAX_NEIGHBORS][CURRENCY_NAME_LEN]; + uint32_t nb_count = 0; + for (uint32_t i = 0; i < pairs.count; i++) { + const trading_pair_t *p = &pairs.pairs[i]; + const char *other = NULL; + if (strcmp(p->base, hold) == 0) other = p->quote; + else if (strcmp(p->quote, hold) == 0) other = p->base; + else continue; + bool dup = false; + for (uint32_t j = 0; j < nb_count; j++) { + if (strcmp(neighbors[j], other) == 0) { dup = true; break; } + } + if (!dup && nb_count < MAX_NEIGHBORS) { + strncpy(neighbors[nb_count++], other, CURRENCY_NAME_LEN - 1); + } + } + + /* Sort neighbors for deterministic ordering */ + for (uint32_t i = 0; i < nb_count; i++) { + for (uint32_t j = 0; j < nb_count - 1 - i; j++) { + if (strcmp(neighbors[j], neighbors[j+1]) > 0) { + char t[CURRENCY_NAME_LEN]; + strcpy(t, neighbors[j]); + strcpy(neighbors[j], neighbors[j+1]); + strcpy(neighbors[j+1], t); + } + } + } + + /* For each unique unordered pair {a,b} of neighbors, check if pair(a,b) exists */ + for (uint32_t a = 0; a < nb_count; a++) { + for (uint32_t b = a + 1; b < nb_count; b++) { + uint32_t ab_idx; + if (!ph_find(&ph, neighbors[a], neighbors[b], &ab_idx)) continue; + /* pair(a,b) exists -> triangle (hold, neighbors[a], neighbors[b]) */ + + /* + * Two directions: + * dir0: hold -> a -> b -> hold (via pairs hold-a, a-b, b-hold) + * dir1: hold -> b -> a -> hold (via pairs hold-b, b-a, a-hold) + */ + for (int dir = 0; dir < 2; dir++) { + const char *x = (dir == 0) ? neighbors[a] : neighbors[b]; + const char *y = (dir == 0) ? neighbors[b] : neighbors[a]; + + uint32_t i1, i2, i3; + if (!ph_find(&ph, hold, x, &i1)) continue; + if (!ph_find(&ph, x, y, &i2)) continue; + if (!ph_find(&ph, y, hold, &i3)) continue; + + if (tri_count >= MAX_TRIANGLES) goto done; + + triangle_t *t = &tris[tri_count]; + t->symbol_idx[0] = (uint16_t)i1; + t->symbol_idx[1] = (uint16_t)i2; + t->symbol_idx[2] = (uint16_t)i3; + + /* + * use_bid[leg] = 1 if we want to receive pair.quote (sell base at bid), + * = 0 if we want to receive pair.base (buy base at ask). + * + * For leg 0 (hold -> x): we hold 'hold' and want to end up with 'x'. + * If pair.quote == x: we can sell 'hold' to get 'x' at bid -> use_bid=1 + * If pair.base == x: we need to buy 'x' paying 'hold' at ask -> use_bid=0 + */ + t->use_bid[0] = (strcmp(pairs.pairs[i1].quote, x) == 0) ? 1 : 0; + t->use_bid[1] = (strcmp(pairs.pairs[i2].quote, y) == 0) ? 1 : 0; + t->use_bid[2] = (strcmp(pairs.pairs[i3].quote, hold) == 0) ? 1 : 0; + t->id = (uint16_t)tri_count; + strncpy(t->symbol_names[0], pairs.pairs[i1].symbol, SYMBOL_NAME_LEN - 1); + strncpy(t->symbol_names[1], pairs.pairs[i2].symbol, SYMBOL_NAME_LEN - 1); + strncpy(t->symbol_names[2], pairs.pairs[i3].symbol, SYMBOL_NAME_LEN - 1); + strncpy(t->fee_currency[0], pairs.pairs[i1].fee_currency, CURRENCY_NAME_LEN - 1); + strncpy(t->fee_currency[1], pairs.pairs[i2].fee_currency, CURRENCY_NAME_LEN - 1); + strncpy(t->fee_currency[2], pairs.pairs[i3].fee_currency, CURRENCY_NAME_LEN - 1); + strncpy(t->base, hold, CURRENCY_NAME_LEN - 1); + strncpy(t->mid, x, CURRENCY_NAME_LEN - 1); + strncpy(t->quote, y, CURRENCY_NAME_LEN - 1); + t->fee_factor[0] = 1.0 - fee_rate_for_pair(&pairs.pairs[i1], kcs); + t->fee_factor[1] = 1.0 - fee_rate_for_pair(&pairs.pairs[i2], kcs); + t->fee_factor[2] = 1.0 - fee_rate_for_pair(&pairs.pairs[i3], kcs); + t->base_increment[0] = pairs.pairs[i1].base_increment; + t->base_increment[1] = pairs.pairs[i2].base_increment; + t->base_increment[2] = pairs.pairs[i3].base_increment; + t->quote_increment[0] = pairs.pairs[i1].quote_increment; + t->quote_increment[1] = pairs.pairs[i2].quote_increment; + t->quote_increment[2] = pairs.pairs[i3].quote_increment; + t->base_min_size[0] = pairs.pairs[i1].base_min_size; + t->base_min_size[1] = pairs.pairs[i2].base_min_size; + t->base_min_size[2] = pairs.pairs[i3].base_min_size; + + tri_count++; + } + } + } + } + +done: + triangles->triangles = tris; + triangles->triangle_count = tri_count; + + /* Populate symbol table first (so symbols->count is final) */ + for (uint32_t i = 0; i < sym_count; i++) { + symbol_table_add(symbols, discovered_symbols[i]); + } + symbol_table_sort(symbols); + + /* Convert triangle symbol_idx from pair index to symbol table index */ + uint32_t convert_miss = 0; + for (uint32_t i = 0; i < tri_count; i++) { + for (int leg = 0; leg < 3; leg++) { + uint32_t pair_idx = tris[i].symbol_idx[leg]; + int16_t sym_idx = symbol_table_lookup(symbols, pairs.pairs[pair_idx].symbol); + tris[i].symbol_idx[leg] = (uint16_t)(sym_idx >= 0 ? sym_idx : 0); + if (sym_idx < 0) convert_miss++; + } + } + log_write("[SYMBOLS] converted %u triangle legs, %u lookup failures\n", + 3 * tri_count, convert_miss); + + /* Allocate tri_index based on final symbol count */ + triangles->tri_index = calloc(symbols->count, sizeof(tri_index_entry_t)); + + /* + * Build triangle flat index by symbol. + * Phase 1: count triangles per symbol (all 3 legs) + * Phase 2: compute offsets (prefix sum) + * Phase 3: fill flat index array (tri_flat) + */ + for (uint32_t i = 0; i < tri_count; i++) { + for (int leg = 0; leg < 3; leg++) { + uint16_t si = tris[i].symbol_idx[leg]; + if (si < symbols->count) triangles->tri_index[si].count++; + } + } + + uint32_t syms_with_tri = 0; + for (uint32_t s = 0; s < symbols->count; s++) { + if (triangles->tri_index[s].count > 0) syms_with_tri++; + } + log_write("[SYMBOLS] %u/%u symbols have triangles (total_refs=%u)\n", + syms_with_tri, symbols->count, 3 * tri_count); + uint32_t off = 0; + uint32_t total_refs = 0; + for (uint32_t s = 0; s < symbols->count; s++) { + triangles->tri_index[s].offset = off; + off += triangles->tri_index[s].count; + total_refs += triangles->tri_index[s].count; + triangles->tri_index[s].count = 0; // reset for phase 3 + } + uint32_t *tri_flat = calloc(total_refs, sizeof(uint32_t)); + triangles->tri_flat = tri_flat; + for (uint32_t i = 0; i < tri_count; i++) { + for (int leg = 0; leg < 3; leg++) { + uint16_t si = tris[i].symbol_idx[leg]; + if (si < symbols->count) { + tri_flat[triangles->tri_index[si].offset + triangles->tri_index[si].count++] = i; + } + } + } + + log_write("[SYMBOLS] %u symbols, %u triangles\n", symbols->count, tri_count); + free(pairs.pairs); + return 0; +} diff --git a/src/symbols_api.h b/src/symbols_api.h new file mode 100644 index 0000000..dff8908 --- /dev/null +++ b/src/symbols_api.h @@ -0,0 +1,38 @@ +#ifndef FUSED_SYMBOLS_API_H +#define FUSED_SYMBOLS_API_H + +#include +#include +#include "hash.h" +#include "config.h" +#include "triangle.h" + +/* Describes one trading pair as returned by the KuCoin REST API */ +typedef struct { + char symbol[SYMBOL_NAME_LEN]; /* trading pair symbol e.g. "BTC-USDT" */ + char base[CURRENCY_NAME_LEN]; /* base currency code */ + char quote[CURRENCY_NAME_LEN]; /* quote currency code */ + char fee_currency[CURRENCY_NAME_LEN]; /* currency used for trading fee */ + uint8_t fee_category; /* fee category identifier */ + double taker_fee_coeff; /* taker fee coefficient */ + double maker_fee_coeff; /* maker fee coefficient */ + double base_increment; /* base lot size step */ + double quote_increment; /* quote lot size step */ + double base_min_size; /* minimum base order size */ +} trading_pair_t; + +/* Growable list of trading pairs */ +typedef struct { + trading_pair_t *pairs; /* dynamic array of trading pairs */ + uint32_t count; /* number of pairs currently stored */ + uint32_t capacity; /* allocated capacity */ +} pair_list_t; + +/* Fetch all trading pairs from the KuCoin REST API */ +int fetch_trading_pairs(pair_list_t *out); + +/* Full symbol discovery: fetch pairs, enumerate triangles, populate tables */ +int discover_symbols(symbol_table_t *symbols, triangle_set_t *triangles, + const config_t *cfg, const fee_entry_t *fees, uint32_t fee_count); + +#endif diff --git a/src/triangle.c b/src/triangle.c new file mode 100644 index 0000000..071c8fb --- /dev/null +++ b/src/triangle.c @@ -0,0 +1,96 @@ +/* + * triangle.c - Triangle data structure management and fee table parsing + * + * triangle_set_init is a stub; actual triangle enumeration happens in + * symbols_api.c:discover_symbols. This file provides fee parsing from + * KuCoin's /api/v1/base-fee response (both object and array formats). + */ + +#include "triangle.h" +#include +#include +#include +#include "cJSON.h" + +int triangle_set_init(triangle_set_t *set, const symbol_table_t *symbols, + const config_t *cfg, const fee_entry_t *fees, + uint32_t fee_count) { + /* Triangle enumeration is now done in discover_symbols (symbols_api.c) */ + (void)set; (void)symbols; (void)cfg; (void)fees; (void)fee_count; + return 0; +} + +void triangle_set_free(triangle_set_t *set) { + free(set->triangles); + free(set->tri_index); + free(set->tri_flat); + set->triangles = NULL; + set->tri_index = NULL; + set->tri_flat = NULL; + set->triangle_count = 0; +} + +/* + * Parse KuCoin /api/v1/base-fee JSON response. + * Supports two formats: + * - Object: {"takerFeeRate": 0.001, ...} + * - Array: [{"currency": "BTC", "takerFeeRate": 0.001}, ...] + * Stores result as fee_entry_t array (single "ALL" entry for object format). + */ +int load_fee_table(const char *json, fee_entry_t **out_fees, uint32_t *out_count) { + cJSON *root = cJSON_Parse(json); + if (!root) return -1; + + cJSON *code = cJSON_GetObjectItem(root, "code"); + if (!cJSON_IsString(code) || strcmp(code->valuestring, "200000") != 0) { + cJSON_Delete(root); + return -1; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!data) { + cJSON_Delete(root); + return -1; + } + + *out_count = 0; + + if (cJSON_IsObject(data)) { + // Single global fee rate + *out_fees = calloc(1, sizeof(fee_entry_t)); + if (!*out_fees) { cJSON_Delete(root); return -1; } + fee_entry_t *fee = *out_fees; + strncpy(fee->currency, "ALL", CURRENCY_NAME_LEN - 1); + cJSON *taker = cJSON_GetObjectItem(data, "takerFeeRate"); + cJSON *maker = cJSON_GetObjectItem(data, "makerFeeRate"); + if (cJSON_IsNumber(taker)) fee->taker_fee = taker->valuedouble; + if (cJSON_IsNumber(maker)) fee->maker_fee = maker->valuedouble; + *out_count = 1; + } else if (cJSON_IsArray(data)) { + // Per-currency fee rates array + int arr_size = cJSON_GetArraySize(data); + *out_fees = calloc(arr_size, sizeof(fee_entry_t)); + if (!*out_fees) { cJSON_Delete(root); return -1; } + cJSON *item; + int idx = 0; + cJSON_ArrayForEach(item, data) { + if (!cJSON_IsObject(item)) continue; + fee_entry_t *fee = &((*out_fees)[idx]); + cJSON *cur = cJSON_GetObjectItem(item, "currency"); + cJSON *taker = cJSON_GetObjectItem(item, "takerFeeRate"); + cJSON *maker = cJSON_GetObjectItem(item, "makerFeeRate"); + if (cJSON_IsString(cur)) strncpy(fee->currency, cur->valuestring, CURRENCY_NAME_LEN - 1); + if (cJSON_IsNumber(taker)) fee->taker_fee = taker->valuedouble; + if (cJSON_IsNumber(maker)) fee->maker_fee = maker->valuedouble; + idx++; + } + *out_count = idx; + } + + cJSON_Delete(root); + return 0; +} + +void free_fee_table(fee_entry_t *fees) { + free(fees); +} diff --git a/src/triangle.h b/src/triangle.h new file mode 100644 index 0000000..61b6cde --- /dev/null +++ b/src/triangle.h @@ -0,0 +1,62 @@ +#ifndef FUSED_TRIANGLE_H +#define FUSED_TRIANGLE_H + +#include +#include +#include "book.h" +#include "hash.h" +#include "config.h" + +#define MAX_TRIANGLES 16384 +#define MAX_CURRENCIES 512 + +/* Describes one triangular arbitrage path of three trading pairs */ +typedef struct { + uint16_t symbol_idx[3]; /* indices into the symbol table for each leg */ + uint8_t use_bid[3]; /* 1=use bid price, 0=use ask price for this leg */ + double fee_factor[3]; /* fee multiplier (1 - fee_rate) for each leg */ + double base_increment[3]; /* base asset lot step for each leg */ + double quote_increment[3]; /* quote asset lot step for each leg */ + double base_min_size[3]; /* min base order size for each leg */ + uint16_t id; /* unique triangle ID */ + char symbol_names[3][SYMBOL_NAME_LEN]; /* trading pair names for each leg */ + char fee_currency[3][CURRENCY_NAME_LEN]; /* fee currency per leg */ + char base[CURRENCY_NAME_LEN]; /* base currency of the triangle */ + char mid[CURRENCY_NAME_LEN]; /* intermediate currency */ + char quote[CURRENCY_NAME_LEN]; /* quote currency of the triangle */ +} triangle_t; + +/* Index entry into the per-currency triangle lookup table */ +typedef struct { + uint32_t offset; /* start index in the flat triangle array */ + uint32_t count; /* number of triangles for this currency */ +} tri_index_entry_t; + +/* Complete set of enumerated triangles with fast per-currency indexing */ +typedef struct { + triangle_t *triangles; /* contiguous array of all triangles */ + uint32_t triangle_count; /* total number of triangles */ + tri_index_entry_t *tri_index; /* per-currency index into tri_flat */ + uint32_t *tri_flat; /* flat array mapping currency->triangle indices */ +} triangle_set_t; + +/* Fee rate entry for a specific currency (from fee table) */ +typedef struct { + char currency[CURRENCY_NAME_LEN]; /* currency name */ + double taker_fee; /* taker fee rate for this currency */ + double maker_fee; /* maker fee rate for this currency */ +} fee_entry_t; + +/* Initialise triangle set: enumerate all triangles from the symbol table */ +int triangle_set_init(triangle_set_t *set, const symbol_table_t *symbols, + const config_t *cfg, const fee_entry_t *fees, + uint32_t fee_count); +/* Free all memory owned by a triangle set */ +void triangle_set_free(triangle_set_t *set); + +/* Parse fee table JSON into an array of fee_entry_t */ +int load_fee_table(const char *json, fee_entry_t **out_fees, uint32_t *out_count); +/* Free a fee table array */ +void free_fee_table(fee_entry_t *fees); + +#endif diff --git a/src/ws_client.c b/src/ws_client.c new file mode 100644 index 0000000..2a93197 --- /dev/null +++ b/src/ws_client.c @@ -0,0 +1,785 @@ +/* + * ws_client.c - KuCoin WebSocket client for level2 depth (top 5) book updates + * + * Handles: token fetch via REST /api/v1/bullet-public, TLS connections, + * RFC 6455 frame read/write/mask, subscription management, + * book update JSON parsing, and per-connection epoll-driven reads. + * Each WS connection handles up to 400 symbol subscriptions. + */ + +#include "log.h" +#include "ws_client.h" +#include "http_client.h" +#include "cJSON.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +static uint64_t now_ms_impl(void) { + struct timespec ts; + clock_gettime(CLOCK_MONOTONIC, &ts); + return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +uint64_t ws_client_now_ms(void) { + return now_ms_impl(); +} + +static uint64_t now_realtime_ms(void) { + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + return (uint64_t)ts.tv_sec * 1000 + ts.tv_nsec / 1000000; +} + +static void ws_connection_reset(ws_connection_t *conn) { + conn->state = WS_STATE_DISCONNECTED; + conn->read_pos = 0; + conn->read_len = 0; + conn->frame_payload_len = 0; + conn->frame_finished = false; + conn->frame_opcode = 0; + if (conn->ssl) { + SSL_free(conn->ssl); + conn->ssl = NULL; + } + if (conn->bio_mem) { + BIO_free(conn->bio_mem); + conn->bio_mem = NULL; + } + if (conn->bio_ssl) { + BIO_free(conn->bio_ssl); + conn->bio_ssl = NULL; + } + if (conn->bio_socket) { + BIO_free(conn->bio_socket); + conn->bio_socket = NULL; + } + if (conn->fd >= 0) { + close(conn->fd); + conn->fd = -1; + } +} + +static SSL_CTX *create_ssl_ctx(void) { + SSL_CTX *ctx = SSL_CTX_new(TLS_client_method()); + if (!ctx) { + log_write("[WS] SSL_CTX_new failed: %s\n", + ERR_error_string(ERR_get_error(), NULL)); + return NULL; + } + SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL); + return ctx; +} + +static int resolve_and_connect(const char *host, int port) { + struct addrinfo hints = {0}, *res = NULL; + hints.ai_family = AF_UNSPEC; + hints.ai_socktype = SOCK_STREAM; + + char port_str[8]; + snprintf(port_str, sizeof(port_str), "%d", port); + + int ret = getaddrinfo(host, port_str, &hints, &res); + if (ret != 0) { + log_write("[WS] getaddrinfo failed for %s:%d: %s\n", host, port, gai_strerror(ret)); + return -1; + } + + int fd = -1; + for (struct addrinfo *rp = res; rp; rp = rp->ai_next) { + fd = socket(rp->ai_family, rp->ai_socktype, rp->ai_protocol); + if (fd < 0) continue; + + if (connect(fd, rp->ai_addr, rp->ai_addrlen) == 0) break; + close(fd); + fd = -1; + } + freeaddrinfo(res); + return fd; +} + +static int setup_tls(ws_connection_t *conn) { + conn->ssl = SSL_new(conn->ctx); + if (!conn->ssl) { + log_write("[WS] SSL_new failed\n"); + return -1; + } + + if (SSL_set_tlsext_host_name(conn->ssl, conn->host) != 1) { + log_write("[WS] SSL_set_tlsext_host_name failed\n"); + return -1; + } + + SSL_set_fd(conn->ssl, conn->fd); + log_write("[WS] Connecting SSL to %s:%d (fd=%d)\n", conn->host, conn->port, conn->fd); + + int r = SSL_connect(conn->ssl); + if (r != 1) { + int err = SSL_get_error(conn->ssl, r); + unsigned long err2 = ERR_peek_last_error(); + log_write("[WS] TLS handshake failed: SSL_error=%d errno=%d r=%d err2=%lu\n", err, errno, r, err2); + if (err2) { + char err_str[256]; + ERR_error_string_n(err2, err_str, sizeof(err_str)); + log_write("[WS] OpenSSL error: %s\n", err_str); + } + return -1; + } + log_write("[WS] TLS handshake OK, cipher=%s\n", SSL_get_cipher(conn->ssl)); + return 0; +} + +int ws_client_init(ws_client_t *client, const config_t *cfg, + symbol_table_t *symbols, order_book_t *books, + evaluator_t *evaluator) { + memset(client, 0, sizeof(*client)); + client->cfg = cfg; + client->symbols = symbols; + client->books = books; + client->evaluator = evaluator; + client->running = true; + + SSL_CTX *shared_ctx = create_ssl_ctx(); + if (!shared_ctx) { + log_write("[WS] Failed to create SSL context\n"); + return -1; + } + + for (uint32_t i = 0; i < WS_MAX_CONNECTIONS; i++) { + ws_connection_t *conn = &client->connections[i]; + conn->fd = -1; + conn->ctx = shared_ctx; + conn->reconnect_base_delay = cfg->reconnect_base_delay; + conn->reconnect_max_delay = cfg->reconnect_max_delay; + conn->reconnect_delay = cfg->reconnect_base_delay; + strncpy(conn->host, "ws-api-spot.kucoin.com", sizeof(conn->host)); + conn->port = 443; + } + client->connection_count = 1; + return 0; +} + +void ws_client_destroy(ws_client_t *client) { + client->running = false; + SSL_CTX *ctx = NULL; + for (uint32_t i = 0; i < client->connection_count; i++) { + ws_connection_t *conn = &client->connections[i]; + if (i == 0 && conn->ctx) ctx = conn->ctx; + ws_connection_reset(conn); + conn->ctx = NULL; + } + if (ctx) SSL_CTX_free(ctx); +} + +/* + * Fetch a WebSocket token and server endpoint from KuCoin's /api/v1/bullet-public. + * Stores token, host, ping_interval_ms, ping_timeout_ms in the connection struct. + */ +int ws_client_fetch_token(ws_connection_t *conn) { + const char *body = ""; + + int out_len = 0; + char *response = https_post("api.kucoin.com", 443, "/api/v1/bullet-public", + body, strlen(body), &out_len); + if (!response || out_len <= 0) { + log_write("[WS] Failed to fetch token\n"); + free(response); + return -1; + } + + cJSON *root = cJSON_Parse(response); + free(response); + if (!root) { + log_write("[WS] Failed to parse token response\n"); + return -1; + } + + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!cJSON_IsObject(data)) { + log_write("[WS] No 'data' in token response\n"); + cJSON_Delete(root); + return -1; + } + + cJSON *token = cJSON_GetObjectItem(data, "token"); + if (cJSON_IsString(token)) { + strncpy(conn->token, token->valuestring, sizeof(conn->token) - 1); + } + + cJSON *servers = cJSON_GetObjectItem(data, "instanceServers"); + if (cJSON_IsArray(servers) && cJSON_GetArraySize(servers) > 0) { + cJSON *inst = cJSON_GetArrayItem(servers, 0); + cJSON *endpoint = cJSON_GetObjectItem(inst, "endpoint"); + cJSON *pingInterval = cJSON_GetObjectItem(inst, "pingInterval"); + cJSON *pingTimeout = cJSON_GetObjectItem(inst, "pingTimeout"); + + if (cJSON_IsString(endpoint)) { + const char *ep = endpoint->valuestring; + const char *slash_pair = strstr(ep, "//"); + char host_start[256] = {0}; + if (slash_pair) { + strncpy(host_start, slash_pair + 2, sizeof(host_start) - 1); + } else { + strncpy(host_start, ep, sizeof(host_start) - 1); + } + char *slash = strchr(host_start, '/'); + if (slash) *slash = '\0'; + strncpy(conn->host, host_start, sizeof(conn->host) - 1); + } + + if (cJSON_IsNumber(pingInterval)) conn->ping_interval_ms = (uint32_t)pingInterval->valuedouble; + if (cJSON_IsNumber(pingTimeout)) conn->ping_timeout_ms = (uint32_t)pingTimeout->valuedouble; + } + + if (!conn->token[0]) { + log_write("[WS] Empty token received\n"); + cJSON_Delete(root); + return -1; + } + + if (!conn->ping_interval_ms) conn->ping_interval_ms = 18000; + if (!conn->ping_timeout_ms) conn->ping_timeout_ms = 10000; + + log_write("[WS] Token fetched, ping_interval=%u ms, host='%s'\n", conn->ping_interval_ms, conn->host); + cJSON_Delete(root); + return 0; +} + +int ws_client_connect(ws_client_t *client, uint32_t conn_idx) { + if (conn_idx >= WS_MAX_CONNECTIONS) return -1; + ws_connection_t *conn = &client->connections[conn_idx]; + + if (conn->state == WS_STATE_CONNECTED) return 0; + + ws_connection_reset(conn); + + if (!conn->ctx) { + conn->ctx = create_ssl_ctx(); + if (!conn->ctx) return -1; + } + + if (!conn->token[0]) { + conn->state = WS_STATE_GETTING_TOKEN; + if (ws_client_fetch_token(conn) != 0) return -1; + } + + snprintf(conn->connect_id, sizeof(conn->connect_id), "fused-%" PRIu32, conn_idx + 1); + + conn->fd = resolve_and_connect(conn->host, conn->port); + if (conn->fd < 0) { + log_write("[WS] Connection failed for %s:%d\n", conn->host, conn->port); + return -1; + } + + { + int opt = 1; + setsockopt(conn->fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof(opt)); + int rcvbuf = 256 * 1024; + setsockopt(conn->fd, SOL_SOCKET, SO_RCVBUF, &rcvbuf, sizeof(rcvbuf)); + } + + if (setup_tls(conn) != 0) { + log_write("[WS] TLS setup failed\n"); + close(conn->fd); + conn->fd = -1; + return -1; + } + + char url[512]; + snprintf(url, sizeof(url), + "GET /?token=%s&connectId=%s HTTP/1.1\r\n" + "Host: %s\r\n" + "Upgrade: websocket\r\n" + "Connection: Upgrade\r\n" + "Sec-WebSocket-Key: dGhlIHNhbXBsZSBub25jZQ==\r\n" + "Sec-WebSocket-Version: 13\r\n" + "\r\n", + conn->token, conn->connect_id, conn->host); + + int r = ws_client_write(conn, url, strlen(url)); + if (r < 0) { + log_write("[WS] Failed to send upgrade request\n"); + return -1; + } + + conn->state = WS_STATE_CONNECTING; + conn->last_activity_ms = now_ms_impl(); + + // Read HTTP 101 Switching Protocols response + char resp_buf[1024]; + int resp_len = SSL_read(conn->ssl, resp_buf, sizeof(resp_buf) - 1); + if (resp_len <= 0) { + int err = SSL_get_error(conn->ssl, resp_len); + log_write("[WS] No response to upgrade request: SSL_error=%d\n", err); + return -1; + } + resp_buf[resp_len] = '\0'; + + if (strstr(resp_buf, "101 Switching Protocols") == NULL) { + log_write("[WS] Upgrade failed:\n%s\n", resp_buf); + return -1; + } + + conn->state = WS_STATE_CONNECTED; + log_write("[WS] Connected to %s:%d\n", conn->host, conn->port); + + if (conn->symbol_count > 0) { + ws_client_subscribe(client, conn_idx, conn->symbol_indices, conn->symbol_count); + } + + return 0; +} + +void ws_client_disconnect(ws_client_t *client, uint32_t conn_idx) { + if (conn_idx >= WS_MAX_CONNECTIONS) return; + ws_connection_t *conn = &client->connections[conn_idx]; + ws_connection_reset(conn); +} + +int ws_client_write(ws_connection_t *conn, const void *data, size_t len) { + if (conn->ssl == NULL) return -1; + int written = 0; + while ((size_t)written < len) { + int r = SSL_write(conn->ssl, (const char *)data + written, len - written); + if (r <= 0) { + int err = SSL_get_error(conn->ssl, r); + log_write("[WS] SSL_write error: %d\n", err); + return -1; + } + written += r; + } + return written; +} + +/* + * Build and send an RFC 6455 WebSocket frame with masking. + * Client frames MUST be masked (bit 0x80 in byte 1). + * Supports payload lengths < 126 (inline), < 65536 (16-bit ext), and >= 65536 (64-bit ext). + * Masking key derived from monotonic clock to avoid predictable patterns. + */ +static int ws_send_frame(ws_connection_t *conn, uint8_t opcode, + const uint8_t *payload, size_t payload_len) { + uint8_t header[14]; + int hdr_len = 2; + + header[0] = 0x80 | opcode; + if (payload_len < 126) { + header[1] = 0x80 | (uint8_t)payload_len; + } else if (payload_len < 65536) { + header[1] = 0x80 | 126; + header[2] = (uint8_t)(payload_len >> 8); + header[3] = (uint8_t)(payload_len & 0xFF); + hdr_len = 4; + } else { + header[1] = 0x80 | 127; + uint64_t len64 = (uint64_t)payload_len; + for (int i = 0; i < 8; i++) { + header[2 + i] = (uint8_t)(len64 >> ((7 - i) * 8)); + } + hdr_len = 10; + } + + uint8_t mask[4]; + mask[0] = (uint8_t)(now_ms_impl() & 0xFF); + mask[1] = (uint8_t)((now_ms_impl() >> 8) & 0xFF); + mask[2] = (uint8_t)((now_ms_impl() >> 16) & 0xFF); + mask[3] = (uint8_t)((now_ms_impl() >> 24) & 0xFF); + memcpy(header + hdr_len, mask, 4); + hdr_len += 4; + + int total = 0; + int r = ws_client_write(conn, header, (size_t)hdr_len); + if (r < 0) return r; + total += r; + + if (payload_len > 0) { + // XOR payload with mask before sending (RFC 6455 §5.3) + uint8_t buf[4096]; + size_t off = 0; + while (off < payload_len) { + size_t chunk = payload_len - off; + if (chunk > sizeof(buf)) chunk = sizeof(buf); + for (size_t i = 0; i < chunk; i++) { + buf[i] = payload[off + i] ^ mask[(off + i) % 4]; + } + r = ws_client_write(conn, buf, chunk); + if (r < 0) return r; + total += r; + off += chunk; + } + } + + conn->last_activity_ms = now_ms_impl(); + return total; +} + +static int ws_send_text(ws_connection_t *conn, const char *text) { + return ws_send_frame(conn, 0x1, (const uint8_t *)text, strlen(text)); +} + +int ws_client_send_ping(ws_connection_t *conn) { + return ws_send_frame(conn, 0x9, NULL, 0); +} + +int ws_client_subscribe(ws_client_t *client, uint32_t conn_idx, + const uint16_t *symbol_indices, uint32_t count) { + if (conn_idx >= WS_MAX_CONNECTIONS) return -1; + ws_connection_t *conn = &client->connections[conn_idx]; + + // Batch subscriptions: KuCoin accepts up to ~100 symbols per subscribe message + for (uint32_t batch = 0; batch < count; batch += 100) { + uint32_t batch_end = batch + 100; + if (batch_end > count) batch_end = count; + uint32_t batch_count = batch_end - batch; + + // Build topic: /spotMarket/level2Depth5:S1,S2,... + char sym_list[4096] = {0}; + for (uint32_t i = batch; i < batch_end; i++) { + char sep = (i == batch) ? ':' : ','; + char part[SYMBOL_NAME_LEN + 1]; + strncpy(part, client->symbols->entries[symbol_indices[i]].name, SYMBOL_NAME_LEN); + part[SYMBOL_NAME_LEN] = '\0'; + char tmp[SYMBOL_NAME_LEN + 2]; + snprintf(tmp, sizeof(tmp), "%c%s", sep, part); + strncat(sym_list, tmp, sizeof(sym_list) - 1); + } + + char msg[4600]; + snprintf(msg, sizeof(msg), + "{\"type\":\"subscribe\",\"topic\":\"/spotMarket/level2Depth5%s\",\"response\":true}", + sym_list); + + int r = ws_send_text(conn, msg); + if (r < 0) { + log_write("[WS] Subscribe failed for batch %u\n", batch); + return -1; + } + log_write("[WS] Subscribed to %u symbols (batch %u-%u)\n", + batch_count, batch, batch_end - 1); + } + + conn->symbol_count = count; + for (uint32_t i = 0; i < count && i < MAX_SYMBOLS; i++) { + conn->symbol_indices[i] = symbol_indices[i]; + } + conn->state = WS_STATE_CONNECTED; + return 0; +} + +int ws_client_unsubscribe(ws_client_t *client, uint32_t conn_idx, + const uint16_t *symbol_indices, uint32_t count) { + if (conn_idx >= WS_MAX_CONNECTIONS) return -1; + ws_connection_t *conn = &client->connections[conn_idx]; + + char topic[4096]; + topic[0] = '\0'; + for (uint32_t i = 0; i < count; i++) { + char sep = (i == 0) ? ':' : ','; + char part[SYMBOL_NAME_LEN + 1]; + strncpy(part, client->symbols->entries[symbol_indices[i]].name, SYMBOL_NAME_LEN); + part[SYMBOL_NAME_LEN] = '\0'; + char tmp[SYMBOL_NAME_LEN + 2]; + snprintf(tmp, sizeof(tmp), "%c%s", sep, part); + strncat(topic, tmp, sizeof(topic) - 1); + } + char full_topic[4096]; + snprintf(full_topic, sizeof(full_topic), "/spotMarket/level2Depth5:%s", topic); + + char msg[4600]; + snprintf(msg, sizeof(msg), + "{\"type\":\"unsubscribe\",\"topic\":\"%s\",\"response\":true}", full_topic); + + return ws_send_text(conn, msg); +} + +/* + * Parse a KuCoin level2Depth5 book update JSON and update the in-memory order book. + * Topic format: /spotMarket/level2Depth5:{symbol} + * Extracts timestamp, sequence, bids array, asks array (each [price, size]). + * Falls back through timestamp fields: timestamp -> sequence -> time. + * Converts both numeric and string-encoded price/size values. + * After updating the book, triggers evaluate_symbol for the updated symbol. + */ +static void parse_book_update(ws_connection_t *conn, cJSON *root, + ws_client_t *client, uint32_t conn_idx) { + cJSON *type = cJSON_GetObjectItem(root, "type"); + if (type && cJSON_IsString(type) && strcmp(type->valuestring, "message") == 0) { + cJSON *topic = cJSON_GetObjectItem(root, "topic"); + cJSON *data = cJSON_GetObjectItem(root, "data"); + if (!cJSON_IsString(topic) || !cJSON_IsObject(data)) { + return; + } + + // Extract symbol from topic: /spotMarket/level2Depth5:{symbol} + const char *topic_str = topic->valuestring; + const char *sym_start = strstr(topic_str, "level2Depth5:"); + if (!sym_start) { return; } + sym_start += 13; + char symbol[SYMBOL_NAME_LEN] = {0}; + strncpy(symbol, sym_start, SYMBOL_NAME_LEN - 1); + char *comma = strchr(symbol, ','); + if (comma) *comma = '\0'; + + int16_t sym_idx = symbol_table_lookup(client->symbols, symbol); + if (sym_idx < 0) { return; } + + order_book_t *book = &client->books[sym_idx]; + + // Try multiple timestamp fields (KuCoin version-dependent) + cJSON *ts_val = cJSON_GetObjectItem(data, "timestamp"); + cJSON *seq_val = cJSON_GetObjectItem(data, "sequence"); + cJSON *seqNum_val = cJSON_GetObjectItem(data, "sequenceNum"); + if (cJSON_IsNumber(ts_val)) book->ts_ms = (int64_t)ts_val->valuedouble; + if (!book->ts_ms && cJSON_IsNumber(seq_val)) book->ts_ms = (int64_t)seq_val->valuedouble; + if (!book->ts_ms) { + cJSON *time_val = cJSON_GetObjectItem(data, "time"); + if (cJSON_IsNumber(time_val)) book->ts_ms = (int64_t)time_val->valuedouble; + } + if (cJSON_IsNumber(seq_val)) book->sequence = (int64_t)seq_val->valuedouble; + else if (cJSON_IsNumber(seqNum_val)) book->sequence = (int64_t)seqNum_val->valuedouble; + + cJSON *bids = cJSON_GetObjectItem(data, "bids"); + cJSON *asks = cJSON_GetObjectItem(data, "asks"); + + if (cJSON_IsArray(bids)) { + int count = 0; + cJSON *bid; + cJSON_ArrayForEach(bid, bids) { + if (count >= MAX_BOOK_LEVELS) break; + if (cJSON_IsArray(bid) && cJSON_GetArraySize(bid) >= 2) { + cJSON *price = cJSON_GetArrayItem(bid, 0); + cJSON *size = cJSON_GetArrayItem(bid, 1); + double p = cJSON_IsNumber(price) ? price->valuedouble : + cJSON_IsString(price) ? atof(price->valuestring) : 0.0; + double s = cJSON_IsNumber(size) ? size->valuedouble : + cJSON_IsString(size) ? atof(size->valuestring) : 0.0; + if (p > 0 && s > 0) { + book->bids[count][0] = p; + book->bids[count][1] = s; + count++; + } + } + } + book->bid_count = (uint8_t)count; + } + + if (cJSON_IsArray(asks)) { + int count = 0; + cJSON *ask; + cJSON_ArrayForEach(ask, asks) { + if (count >= MAX_BOOK_LEVELS) break; + if (cJSON_IsArray(ask) && cJSON_GetArraySize(ask) >= 2) { + cJSON *price = cJSON_GetArrayItem(ask, 0); + cJSON *size = cJSON_GetArrayItem(ask, 1); + double p = cJSON_IsNumber(price) ? price->valuedouble : + cJSON_IsString(price) ? atof(price->valuestring) : 0.0; + double s = cJSON_IsNumber(size) ? size->valuedouble : + cJSON_IsString(size) ? atof(size->valuestring) : 0.0; + if (p > 0 && s > 0) { + book->asks[count][0] = p; + book->asks[count][1] = s; + count++; + } + } + } + book->ask_count = (uint8_t)count; + } + + book->symbol_idx = (uint16_t)sym_idx; + strncpy(book->symbol, symbol, SYMBOL_NAME_LEN - 1); + + static uint64_t book_count = 0; + book_count++; + + int64_t t_arrive = (int64_t)now_realtime_ms(); + evaluate_symbol(client->evaluator, (uint16_t)sym_idx, conn->t_sock_arrive_ms, t_arrive); + } +} + +/* + * Process a single complete WebSocket frame after it has been fully read. + * Handles: ping (0x9) -> pong (0xA), close (0x8), text (0x1). + * Text frames are JSON-parsed and dispatched: welcome, ack, message (-> book update), error. + */ +void ws_client_process_frame(ws_client_t *client, uint32_t conn_idx) { + if (conn_idx >= WS_MAX_CONNECTIONS) return; + ws_connection_t *conn = &client->connections[conn_idx]; + + uint8_t *payload = conn->frame_buf; + size_t payload_len = conn->frame_payload_len; + uint8_t opcode = conn->frame_opcode; + if (payload_len == 0 && opcode != 0x8 && opcode != 0xA) return; + + if (opcode == 0x9) { + ws_send_frame(conn, 0xA, payload, payload_len); + conn->last_activity_ms = now_ms_impl(); + conn->frame_payload_len = 0; + conn->frame_finished = false; + return; + } + + if (opcode == 0x8) { + if (payload_len >= 2) { + uint16_t code = ((uint16_t)payload[0] << 8) | payload[1]; + char reason[128] = {0}; + if (payload_len > 2) { + uint32_t rlen = payload_len - 2; + if (rlen > sizeof(reason) - 1) rlen = sizeof(reason) - 1; + memcpy(reason, payload + 2, rlen); + } + log_write("[WS] Close frame on conn %u: code=%u reason='%s'\n", conn_idx, code, reason); + } else { + log_write("[WS] Close frame received on conn %u\n", conn_idx); + } + conn->state = WS_STATE_DISCONNECTED; + conn->frame_payload_len = 0; + conn->frame_finished = false; + return; + } + + if (opcode == 0xA) { + conn->frame_payload_len = 0; + conn->frame_finished = false; + return; + } + + if (opcode == 0x1) { + cJSON *msg_root = cJSON_ParseWithLength((const char *)payload, payload_len); + if (!msg_root) { + static int parse_fails = 0; + if (++parse_fails <= 3) log_write("[WS] JSON parse fail: %.*s\n", (int)(payload_len > 100 ? 100 : payload_len), (const char *)payload); + conn->frame_payload_len = 0; + conn->frame_finished = false; + return; + } + + cJSON *msg_type = cJSON_GetObjectItem(msg_root, "type"); + if (cJSON_IsString(msg_type)) { + if (strcmp(msg_type->valuestring, "welcome") == 0) { + log_write("[WS] Welcome message received\n"); + } else if (strcmp(msg_type->valuestring, "ack") == 0) { + static int ack_count = 0; + if (++ack_count <= 5) log_write("[WS] Ack #%d: %.*s\n", ack_count, + (int)(payload_len > 200 ? 200 : payload_len), (const char *)payload); + } else if (strcmp(msg_type->valuestring, "message") == 0) { + parse_book_update(conn, msg_root, client, conn_idx); + } else if (strcmp(msg_type->valuestring, "error") == 0) { + log_write("[WS] Error message: %.*s\n", + (int)(payload_len > 200 ? 200 : payload_len), (const char *)payload); + } + } + + cJSON_Delete(msg_root); + } + + conn->frame_payload_len = 0; + conn->frame_finished = false; +} + +/* + * Read raw bytes from SSL socket and reassemble WebSocket frames. + * Handles mask unmasking (RFC 6455: server frames are unmasked) and + * the extended payload length encoding (16-bit and 64-bit extended fields). + * Accumulates partial frames across multiple read() calls. + * Dispatches complete frames via ws_client_process_frame. + */ +int ws_client_read(ws_client_t *client, uint32_t conn_idx) { + if (conn_idx >= WS_MAX_CONNECTIONS) return -1; + ws_connection_t *conn = &client->connections[conn_idx]; + if (conn->state != WS_STATE_CONNECTED) return -1; + + int r = SSL_read(conn->ssl, conn->read_buf + conn->read_len, + WS_READ_BUF_SIZE - conn->read_len); + if (r < 0) { + int err = SSL_get_error(conn->ssl, r); + if (err == SSL_ERROR_WANT_READ || err == SSL_ERROR_WANT_WRITE) return 0; + log_write("[WS] SSL_read error: %d\n", err); + return -1; + } + if (r == 0) { + log_write("[WS] Connection closed on conn %u\n", conn_idx); + conn->state = WS_STATE_DISCONNECTED; + return -1; + } + conn->read_len += (size_t)r; + conn->t_sock_arrive_ms = (int64_t)now_realtime_ms(); + + // Process all complete frames in the read buffer + while (conn->read_len >= 2) { + if (!conn->frame_finished && conn->frame_payload_len == 0) { + uint8_t fin = conn->read_buf[0] & 0x80; + bool masked = (conn->read_buf[1] & 0x80) != 0; + uint64_t payload_len_raw = conn->read_buf[1] & 0x7F; + + size_t hdr_len = 2; + if (payload_len_raw == 126) { + if (conn->read_len < 4) break; + payload_len_raw = ((uint64_t)conn->read_buf[2] << 8) | conn->read_buf[3]; + hdr_len = 4; + } else if (payload_len_raw == 127) { + if (conn->read_len < 10) break; + payload_len_raw = 0; + for (int i = 0; i < 8; i++) { + payload_len_raw = (payload_len_raw << 8) | conn->read_buf[2 + i]; + } + hdr_len = 10; + } + + if (masked) hdr_len += 4; + + if (conn->read_len < hdr_len) break; + + if (payload_len_raw > WS_MAX_FRAME_SIZE) { + log_write("[WS] Frame too large: %lu\n", (unsigned long)payload_len_raw); + conn->state = WS_STATE_DISCONNECTED; + return -1; + } + + // Unmask payload in-place (server frames from KuCoin are unmasked, + // but handle masking per spec just in case) + if (masked) { + uint8_t mask[4]; + memcpy(mask, conn->read_buf + hdr_len - 4, 4); + for (uint64_t i = 0; i < payload_len_raw; i++) { + conn->read_buf[hdr_len + i] ^= mask[i % 4]; + } + } + + size_t frame_size = hdr_len + (size_t)payload_len_raw; + if (conn->read_len < frame_size) break; + conn->frame_payload_len = (size_t)payload_len_raw; + conn->frame_opcode = conn->read_buf[0] & 0x0F; + memcpy(conn->frame_buf, conn->read_buf + hdr_len, payload_len_raw); + conn->frame_finished = (fin != 0); + + // Consume the frame data from the read buffer + memmove(conn->read_buf, conn->read_buf + frame_size, conn->read_len - frame_size); + conn->read_len -= frame_size; + } + + if (conn->frame_finished && conn->frame_payload_len > 0) { + ws_client_process_frame(client, conn_idx); + } + if (conn->frame_finished && conn->frame_payload_len == 0) { + conn->frame_finished = false; + } + + if (conn->read_len == 0) break; + } + + return 0; +} diff --git a/src/ws_client.h b/src/ws_client.h new file mode 100644 index 0000000..b0784f4 --- /dev/null +++ b/src/ws_client.h @@ -0,0 +1,105 @@ +#ifndef FUSED_WS_CLIENT_H +#define FUSED_WS_CLIENT_H + +#include +#include +#include +#include +#include "book.h" +#include "config.h" +#include "hash.h" +#include "evaluate.h" + +#define WS_MAX_FRAME_SIZE (128 * 1024) +#define WS_MAX_CONNECTIONS 8 +#define WS_READ_BUF_SIZE (64 * 1024) + +/* WebSocket connection state machine */ +typedef enum { + WS_STATE_DISCONNECTED, /* not connected */ + WS_STATE_CONNECTING, /* TCP/TLS handshake in progress */ + WS_STATE_GETTING_TOKEN, /* awaiting KuCoin WebSocket token */ + WS_STATE_SUBSCRIBING, /* sending subscription messages */ + WS_STATE_CONNECTED, /* fully connected and subscribed */ + WS_STATE_CLOSING /* graceful close in progress */ +} ws_state_t; + +/* State for a single WebSocket connection */ +typedef struct { + int fd; /* TCP socket fd */ + SSL *ssl; /* OpenSSL SSL object */ + SSL_CTX *ctx; /* OpenSSL SSL context */ + BIO *bio_mem; /* memory BIO for SSL read buffering */ + BIO *bio_ssl; /* SSL BIO */ + BIO *bio_socket; /* socket BIO */ + + char host[256]; /* WebSocket server hostname */ + int port; /* WebSocket server port */ + char token[256]; /* KuCoin connection token */ + char connect_id[64]; /* KuCoin connection ID */ + uint32_t ping_interval_ms; /* negotiated ping interval (ms) */ + uint32_t ping_timeout_ms; /* ping response timeout (ms) */ + + ws_state_t state; /* current connection state */ + uint64_t last_ping_ms; /* timestamp of last sent ping */ + uint64_t last_activity_ms; /* timestamp of last rx/tx activity */ + uint32_t reconnect_count; /* consecutive reconnection count */ + double reconnect_delay; /* current reconnect backoff delay */ + double reconnect_base_delay; /* initial reconnect delay */ + double reconnect_max_delay; /* max reconnect delay */ + + uint8_t read_buf[WS_READ_BUF_SIZE]; /* raw socket read buffer */ + size_t read_pos; /* current read position */ + size_t read_len; /* bytes available in read_buf */ + + uint8_t frame_buf[WS_MAX_FRAME_SIZE]; /* reassembled WebSocket frame */ + size_t frame_payload_len; /* payload length of current frame */ + bool frame_finished; /* true when full frame received */ + uint8_t frame_opcode; /* opcode of current frame */ + int64_t t_sock_arrive_ms; /* wall-clock when last SSL_read returned */ + + uint16_t symbol_indices[MAX_SYMBOLS]; /* subscribed symbol indices */ + uint32_t symbol_count; /* number of subscribed symbols */ +} ws_connection_t; + +/* Top-level WebSocket client managing multiple connections */ +typedef struct { + ws_connection_t connections[WS_MAX_CONNECTIONS]; /* fixed-size connection pool */ + uint32_t connection_count; /* number of active connections */ + const config_t *cfg; /* pointer to configuration */ + symbol_table_t *symbols; /* pointer to symbol table */ + order_book_t *books; /* pointer to shared order books */ + evaluator_t *evaluator; /* pointer to evaluator */ + bool running; /* false signals client to stop */ +} ws_client_t; + +/* Initialise a WebSocket client with config, symbol table, books, and evaluator */ +int ws_client_init(ws_client_t *client, const config_t *cfg, + symbol_table_t *symbols, order_book_t *books, + evaluator_t *evaluator); +/* Destroy WebSocket client and close all connections */ +void ws_client_destroy(ws_client_t *client); +/* Initiate a WebSocket connection (non-blocking) */ +int ws_client_connect(ws_client_t *client, uint32_t conn_idx); +/* Disconnect a WebSocket connection */ +void ws_client_disconnect(ws_client_t *client, uint32_t conn_idx); +/* Read and process data from a WebSocket connection */ +int ws_client_read(ws_client_t *client, uint32_t conn_idx); +/* Write raw data to a WebSocket connection */ +int ws_client_write(ws_connection_t *conn, const void *data, size_t len); +/* Subscribe to a set of symbols on a connection */ +int ws_client_subscribe(ws_client_t *client, uint32_t conn_idx, + const uint16_t *symbol_indices, uint32_t count); +/* Unsubscribe from a set of symbols on a connection */ +int ws_client_unsubscribe(ws_client_t *client, uint32_t conn_idx, + const uint16_t *symbol_indices, uint32_t count); +/* Fetch a WebSocket token from the KuCoin API */ +int ws_client_fetch_token(ws_connection_t *conn); +/* Process a received WebSocket frame (dispatch to book updates, etc.) */ +void ws_client_process_frame(ws_client_t *client, uint32_t conn_idx); +/* Send a WebSocket ping frame */ +int ws_client_send_ping(ws_connection_t *conn); +/* Get current monotonic timestamp in milliseconds */ +uint64_t ws_client_now_ms(void); + +#endif diff --git a/test_fused.py b/test_fused.py new file mode 100644 index 0000000..a52ea80 --- /dev/null +++ b/test_fused.py @@ -0,0 +1,238 @@ +#!/usr/bin/env python3 +"""Test harness for fused_engine binary. + +Starts the binary, adds symbols via REST API, listens for signals +on the executor Unix socket, and reports results. +""" +import asyncio +import json +import os +import signal +import socket +import subprocess +import sys +import time +from pathlib import Path + +BINARY = Path(__file__).parent / "build" / "fused_engine" +CONFIG = Path(__file__).parent / "config.yaml" +REST_URL = "http://127.0.0.1:8000" +SOCKET_PATH = "/tmp/executor.sock" +SIGNAL_FILE = Path(__file__).parent / "test_signals.jsonl" +LOG_FILE = Path(__file__).parent / "test_stderr.log" +TEST_DURATION = 120 # seconds +SYMBOLS_TO_ADD = [ + "BTC-USDT", "ETH-USDT", "ETH-BTC", + "BNB-USDT", "BNB-BTC", "BNB-ETH", + "XRP-USDT", "XRP-BTC", "XRP-ETH", + "SOL-USDT", "SOL-BTC", "SOL-ETH", + "ADA-USDT", "ADA-BTC", "ADA-ETH", + "DOGE-USDT", "DOGE-BTC", "DOGE-ETH", + "MATIC-USDT", "MATIC-BTC", "MATIC-ETH", + "DOT-USDT", "DOT-BTC", "DOT-ETH", +] + + +async def wait_for_rest(timeout=15): + """Wait until the REST API is reachable.""" + import urllib.request + deadline = time.time() + timeout + while time.time() < deadline: + try: + req = urllib.request.urlopen(f"{REST_URL}/health", timeout=2) + if req.status == 200: + return True + except Exception: + pass + await asyncio.sleep(0.5) + return False + + +async def add_symbols(): + """Add symbols via POST /symbols.""" + import urllib.request + try: + data = json.dumps(SYMBOLS_TO_ADD).encode() + req = urllib.request.Request( + f"{REST_URL}/symbols", + data=data, + headers={"Content-Type": "application/json"}, + method="POST", + ) + resp = urllib.request.urlopen(req, timeout=5) + body = json.loads(resp.read()) + print(f" Added symbols: {body.get('added', [])}") + except Exception as e: + print(f" Symbol add failed: {e}") + + +async def check_health(): + """Print health status.""" + import urllib.request + try: + req = urllib.request.urlopen(f"{REST_URL}/health", timeout=2) + body = json.loads(req.read()) + return body + except Exception as e: + return {"error": str(e)} + + +async def listen_for_signals(duration): + """Listen on the executor Unix socket for signal JSON lines.""" + signals = [] + errors = [] + deadline = time.time() + duration + + while time.time() < deadline: + try: + sock = socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) + sock.settimeout(2.0) + sock.connect(SOCKET_PATH) + buf = b"" + while time.time() < deadline: + try: + chunk = sock.recv(4096) + if not chunk: + break + buf += chunk + while b"\n" in buf: + line, buf = buf.split(b"\n", 1) + line = line.strip() + if not line: + continue + try: + sig = json.loads(line) + signals.append(sig) + bps = sig.get("predicted_bps", "?") + key = sig.get("triangle_key", "?") + t_arrive = sig.get("t_arrive_ms", "?") + t_eval = sig.get("t_eval_ms", "?") + print(f" [SIGNAL] {bps} bps | {key} | arrive={t_arrive} eval={t_eval}") + except json.JSONDecodeError: + errors.append(f"Bad JSON: {line[:80]}") + except socket.timeout: + continue + except Exception as e: + errors.append(f"Read error: {e}") + break + sock.close() + except Exception as e: + await asyncio.sleep(1) + + return signals, errors + + +async def main(): + print(f"=== Fused Engine Test ===") + print(f"Binary: {BINARY}") + print(f"Config: {CONFIG}") + print(f"Duration: {TEST_DURATION}s") + print(f"Symbols to add: {len(SYMBOLS_TO_ADD)}") + print() + + if not BINARY.exists(): + print(f"ERROR: Binary not found at {BINARY}") + sys.exit(1) + + # Clean up old socket + try: + os.unlink(SOCKET_PATH) + except OSError: + pass + + # Start the binary + print("[1] Starting fused_engine...") + with LOG_FILE.open("w") as log_f: + proc = subprocess.Popen( + [str(BINARY), str(CONFIG)], + stdout=subprocess.PIPE, + stderr=log_f, + text=True, + ) + print(f" PID: {proc.pid}") + + # Wait for REST API + print("[2] Waiting for REST API...") + if not await wait_for_rest(20): + print(" ERROR: REST API did not come up") + proc.terminate() + proc.wait() + print(" stderr output:") + print(LOG_FILE.read_text()[-2000:]) + sys.exit(1) + print(" REST API is up") + + # Check health + health = await check_health() + print(f" Health: {health}") + + # Add symbols + print("[3] Adding symbols...") + await add_symbols() + + # Wait a moment for subscriptions to take effect + await asyncio.sleep(3) + + # Check health again + health = await check_health() + print(f" Health after add: {health}") + + # Listen for signals + print(f"[4] Listening for signals for {TEST_DURATION}s...") + signals, errors = await listen_for_signals(TEST_DURATION) + + # Stop the binary + print("[5] Stopping fused_engine...") + proc.terminate() + try: + proc.wait(timeout=5) + except subprocess.TimeoutExpired: + proc.kill() + proc.wait() + + # Report results + print() + print(f"=== Results ===") + print(f"Signals received: {len(signals)}") + print(f"Socket errors: {len(errors)}") + + if signals: + SIGNAL_FILE.write_text(json.dumps(signals, indent=2) + "\n") + print(f"Signals saved to: {SIGNAL_FILE}") + + bps_values = [s.get("predicted_bps", 0) for s in signals] + print(f"BPS range: {min(bps_values):.4f} - {max(bps_values):.4f}") + + triangles = set(s.get("triangle_key", "?") for s in signals) + print(f"Unique triangles: {triangles}") + + for s in signals[:5]: + print(f" {s.get('triangle_key', '?')} | {s.get('predicted_bps', '?')} bps | " + f"t_arrive={s.get('t_arrive_ms', '?')} t_eval={s.get('t_eval_ms', '?')}") + else: + print("No signals received during test period.") + + if errors: + print(f"Errors: {errors[:5]}") + + # Print last lines of stderr log + print() + print("=== Last 40 lines of stderr ===") + log_text = LOG_FILE.read_text() + lines = log_text.strip().split("\n") + for line in lines[-40:]: + print(f" {line}") + + print(f"\nFull log: {LOG_FILE}") + print(f"Signals: {SIGNAL_FILE if signals else '(none)'}") + print() + + if len(signals) > 0: + print("PASS: Signals were received.") + else: + print("INFO: No signals. This may be normal if no arbitrage opportunities arose.") + print(" Check stderr above for connection/subscription issues.") + + +if __name__ == "__main__": + asyncio.run(main())