((.venv) ) segeba@mbpbsg dzentra_bot % >.... elif isinstance(data.get("payload"), dict): payload = data["payload"] if isinstance(payload.get("symbols"), list): symbols = payload["symbols"] print("Количество symbols:", len(symbols) if symbols is not None else None) if symbols: dict_items = [item for item in symbols if isinstance(item, dict)] all_keys = sorted( { key for item in dict_items for key in item } ) print("Все ключи symbol items:") for key in all_keys: print(f" {key}") print("\nПервый symbol item:") print(json.dumps(dict_items[0], ensure_ascii=False, indent=2)) PY Корневой тип: dict Корневые ключи: ['exchangeFilters', 'rateLimits', 'serverTime', 'symbols', 'timezone'] Количество symbols: 51 Все ключи symbol items: assetType baseAsset baseAssetPrecision country filters industry longRate marketModes marketType maxSLGap maxTPGap minSLGap minTPGap name orderTypes quoteAsset quoteAssetId quotePrecision sector shortRate status swapChargeInterval symbol tickSize tickValue tradingFee tradingHours Первый symbol item: { "assetType": "CRYPTOCURRENCY", "baseAsset": "ETH", "baseAssetPrecision": 3, "country": "", "filters": [ { "filterType": "LOT_SIZE", "maxQty": "1000", "minQty": "0.001", "stepSize": "0.001" }, { "filterType": "MIN_NOTIONAL", "minNotional": "2" } ], "industry": "", "longRate": -0.01, "marketModes": [ "REGULAR" ], "marketType": "LEVERAGE", "maxSLGap": 50.0, "maxTPGap": 50.0, "minSLGap": 0, "minTPGap": 0, "name": "ETH/EUR", "orderTypes": [ "LIMIT", "MARKET", "STOP" ], "quoteAsset": "EUR", "quoteAssetId": "EUR_LEVERAGE", "quotePrecision": 3, "sector": "", "shortRate": 0.01, "status": "TRADING", "swapChargeInterval": 480, "symbol": "ETH/EUR_LEVERAGE", "tickSize": 0.01, "tickValue": 18.3415, "tradingFee": 0.06, "tradingHours": "UTC; Mon - 21:00, 21:05 -; Tue - 21:00, 21:05 -; Wed - 21:00, 21:05 -; Thu - 21:00, 21:05 -; Fri - 21:00, 22:01 -; Sat - 05:00, 07:00 - 21:00, 21:05 -; Sun - 21:00, 21:05 -" } ((.venv) ) segeba@mbpbsg dzentra_bot % >.... filter_keys: dict[str, set[str]] = {} for item in symbols: if not isinstance(item, dict): continue filters = item.get("filters") if not isinstance(filters, list): continue for entry in filters: if not isinstance(entry, dict): continue filter_type = str(entry.get("filterType") or "") filter_types[filter_type] += 1 filter_keys.setdefault(filter_type, set()).update( str(key) for key in entry ) print("Типы filters:") for filter_type, count in sorted(filter_types.items()): print(f"{filter_type}: {count}") print(" keys:", sorted(filter_keys[filter_type])) PY Типы filters: LOT_SIZE: 51 keys: ['filterType', 'maxQty', 'minQty', 'stepSize'] MIN_NOTIONAL: 39 keys: ['filterType', 'minNotional'] python - <<'PY' import json from collections import Counter from pathlib import Path path = Path( "app/tools/dzengi_probe/runtime_samples/rest/exchangeInfo/all.json" ) data = json.loads(path.read_text(encoding="utf-8")) if isinstance(data, dict) and isinstance(data.get("symbols"), list): symbols = data["symbols"] elif ( isinstance(data, dict) and isinstance(data.get("payload"), dict) and isinstance(data["payload"].get("symbols"), list) ): symbols = data["payload"]["symbols"] else: raise SystemExit("symbols не найдены") fields = [ "symbol", "name", "status", "baseAsset", "quoteAsset", "marketModes", "marketType", "tickSize", "stepSize", "minQty", "minNotional", "filters", ] for field in fields: present = 0 non_empty = 0 types = Counter() for item in symbols: if not isinstance(item, dict): continue if field in item: present += 1 value = item[field] types[type(value).__name__] += 1 if value not in (None, "", [], {}): non_empty += 1 print( f"{field}: present={present}, " f"non_empty={non_empty}, " f"types={dict(types)}" ) PY symbol: present=51, non_empty=51, types={'str': 51} name: present=51, non_empty=51, types={'str': 51} status: present=51, non_empty=51, types={'str': 51} baseAsset: present=51, non_empty=51, types={'str': 51} quoteAsset: present=51, non_empty=51, types={'str': 51} marketModes: present=51, non_empty=51, types={'list': 51} marketType: present=51, non_empty=51, types={'str': 51} tickSize: present=51, non_empty=51, types={'float': 48, 'int': 3} stepSize: present=0, non_empty=0, types={} minQty: present=0, non_empty=0, types={} minNotional: present=0, non_empty=0, types={} filters: present=51, non_empty=51, types={'list': 51} ((.venv) ) segeba@mbpbsg dzentra_bot % ;2B ((.venv) ) segeba@mbpbsg dzentra_bot % ;2Bgrep -RIn \ --exclude-dir="__pycache__" \ --exclude="*.pyc" \ -E "from src\.telegram\.handlers\.market import|import src\.telegram\.handlers\.market|include_router\(.*market|market\.router|handlers\.market" \ app/src app/tests tests 2>/dev/null ((.venv) ) segeba@mbpbsg dzentra_bot % grep -RIn \ --exclude-dir="__pycache__" \ --exclude="*.pyc" \ -E "include_router|include_routers" \ app/src \ | grep -Ei "market|router" app/src/telegram/routers.py:16: dispatcher.include_router(start_router) app/src/telegram/routers.py:17: dispatcher.include_router(home_router) app/src/telegram/routers.py:18: dispatcher.include_router(portfolio_router) app/src/telegram/routers.py:19: dispatcher.include_router(auto_router) app/src/telegram/routers.py:20: dispatcher.include_router(journal_router) app/src/telegram/routers.py:21: dispatcher.include_router(debug_auto_router) app/src/telegram/routers.py:22: dispatcher.include_router(debug_router) app/src/telegram/routers.py:23: dispatcher.include_router(system_router) app/src/telegram/handlers/auto/__init__.py:8:router.include_router(main_router) app/src/telegram/handlers/auto/__init__.py:9:router.include_router(risk_router) ((.venv) ) segeba@mbpbsg dzentra_bot % ((.venv) ) segeba@mbpbsg dzentra_bot % grep -RIn \ --exclude-dir="__pycache__" \ --exclude="*.pyc" \ -E "from src\.telegram\.ui\.currency_ui import|import src\.telegram\.ui\.currency_ui" \ app/src app/tests tests 2>/dev/null app/src/telegram/handlers/market.py:28:from src.telegram.ui.currency_ui import format_usd_amount app/src/telegram/handlers/portfolio.py:26:from src.telegram.ui.currency_ui import (