build 044: establish canonical candles feed foundation
This commit is contained in:
1299
docs/migrations/build_044.md
Normal file
1299
docs/migrations/build_044.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -1,246 +0,0 @@
|
||||
((.venv) ) segeba@mbpbsg dzentra_bot % >....
|
||||
elif isinstance(data.get("payload"), dict):
|
||||
payload = data["payload"]
|
||||
if isinstance(payload.get("symbols"), list):
|
||||
symbols = payload["symbols"]
|
||||
|
||||
print("Количество symbols:", len(symbols) if symbols is not None else None)
|
||||
|
||||
if symbols:
|
||||
dict_items = [item for item in symbols if isinstance(item, dict)]
|
||||
|
||||
all_keys = sorted(
|
||||
{
|
||||
key
|
||||
for item in dict_items
|
||||
for key in item
|
||||
}
|
||||
)
|
||||
|
||||
print("Все ключи symbol items:")
|
||||
for key in all_keys:
|
||||
print(f" {key}")
|
||||
|
||||
print("\nПервый symbol item:")
|
||||
print(json.dumps(dict_items[0], ensure_ascii=False, indent=2))
|
||||
PY
|
||||
Корневой тип: dict
|
||||
Корневые ключи: ['exchangeFilters', 'rateLimits', 'serverTime', 'symbols', 'timezone']
|
||||
Количество symbols: 51
|
||||
Все ключи symbol items:
|
||||
assetType
|
||||
baseAsset
|
||||
baseAssetPrecision
|
||||
country
|
||||
filters
|
||||
industry
|
||||
longRate
|
||||
marketModes
|
||||
marketType
|
||||
maxSLGap
|
||||
maxTPGap
|
||||
minSLGap
|
||||
minTPGap
|
||||
name
|
||||
orderTypes
|
||||
quoteAsset
|
||||
quoteAssetId
|
||||
quotePrecision
|
||||
sector
|
||||
shortRate
|
||||
status
|
||||
swapChargeInterval
|
||||
symbol
|
||||
tickSize
|
||||
tickValue
|
||||
tradingFee
|
||||
tradingHours
|
||||
|
||||
Первый symbol item:
|
||||
{
|
||||
"assetType": "CRYPTOCURRENCY",
|
||||
"baseAsset": "ETH",
|
||||
"baseAssetPrecision": 3,
|
||||
"country": "",
|
||||
"filters": [
|
||||
{
|
||||
"filterType": "LOT_SIZE",
|
||||
"maxQty": "1000",
|
||||
"minQty": "0.001",
|
||||
"stepSize": "0.001"
|
||||
},
|
||||
{
|
||||
"filterType": "MIN_NOTIONAL",
|
||||
"minNotional": "2"
|
||||
}
|
||||
],
|
||||
"industry": "",
|
||||
"longRate": -0.01,
|
||||
"marketModes": [
|
||||
"REGULAR"
|
||||
],
|
||||
"marketType": "LEVERAGE",
|
||||
"maxSLGap": 50.0,
|
||||
"maxTPGap": 50.0,
|
||||
"minSLGap": 0,
|
||||
"minTPGap": 0,
|
||||
"name": "ETH/EUR",
|
||||
"orderTypes": [
|
||||
"LIMIT",
|
||||
"MARKET",
|
||||
"STOP"
|
||||
],
|
||||
"quoteAsset": "EUR",
|
||||
"quoteAssetId": "EUR_LEVERAGE",
|
||||
"quotePrecision": 3,
|
||||
"sector": "",
|
||||
"shortRate": 0.01,
|
||||
"status": "TRADING",
|
||||
"swapChargeInterval": 480,
|
||||
"symbol": "ETH/EUR_LEVERAGE",
|
||||
"tickSize": 0.01,
|
||||
"tickValue": 18.3415,
|
||||
"tradingFee": 0.06,
|
||||
"tradingHours": "UTC; Mon - 21:00, 21:05 -; Tue - 21:00, 21:05 -; Wed - 21:00, 21:05 -; Thu - 21:00, 21:05 -; Fri - 21:00, 22:01 -; Sat - 05:00, 07:00 - 21:00, 21:05 -; Sun - 21:00, 21:05 -"
|
||||
}
|
||||
|
||||
|
||||
((.venv) ) segeba@mbpbsg dzentra_bot % >....
|
||||
filter_keys: dict[str, set[str]] = {}
|
||||
|
||||
for item in symbols:
|
||||
if not isinstance(item, dict):
|
||||
continue
|
||||
|
||||
filters = item.get("filters")
|
||||
if not isinstance(filters, list):
|
||||
continue
|
||||
|
||||
for entry in filters:
|
||||
if not isinstance(entry, dict):
|
||||
continue
|
||||
|
||||
filter_type = str(entry.get("filterType") or "<missing>")
|
||||
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 (
|
||||
File diff suppressed because one or more lines are too long
Reference in New Issue
Block a user