spb/crypto-trade-bot
Public
Python 54.7%
TypeScript 42.5%
SQL 1.9%
1"""Pair metadata discovery (AssetPairs) → `pairs` table. Capabilities are read from the exchange, never assumed."""23from __future__ import annotations45import asyncpg67from ktrade.kraken.models import PairMeta8from ktrade.kraken.rest import KrakenREST9from ktrade.logging import get_logger1011log = get_logger("ingest.pairs")121314async def refresh_pairs(rest: KrakenREST, pool: asyncpg.Pool, universe: list[str]) -> dict[str, PairMeta]:15 pairs = await rest.asset_pairs()16 uni = set(universe)17 async with pool.acquire() as conn, conn.transaction():18 for k, p in pairs.items():19 await conn.execute(20 """INSERT INTO pairs (pair_id, altname, wsname, base, quote, status, ordermin, costmin, tick_size, pair_decimals, lot_decimals, cost_decimals,21 leverage_buy, leverage_sell, in_universe, raw, updated_at)22 VALUES ($1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14,$15,$16, now())23 ON CONFLICT (pair_id) DO UPDATE SET altname=EXCLUDED.altname, wsname=EXCLUDED.wsname, base=EXCLUDED.base, quote=EXCLUDED.quote,24 status=EXCLUDED.status, ordermin=EXCLUDED.ordermin, costmin=EXCLUDED.costmin, tick_size=EXCLUDED.tick_size,25 pair_decimals=EXCLUDED.pair_decimals, lot_decimals=EXCLUDED.lot_decimals, cost_decimals=EXCLUDED.cost_decimals,26 leverage_buy=EXCLUDED.leverage_buy, leverage_sell=EXCLUDED.leverage_sell, in_universe=EXCLUDED.in_universe, raw=EXCLUDED.raw, updated_at=now()""",27 k, p.altname, p.wsname, p.base, p.quote, p.status, p.ordermin, p.costmin, p.tick_size, p.pair_decimals, p.lot_decimals, p.cost_decimals,28 p.leverage_buy, p.leverage_sell, p.wsname in uni, p.model_dump(mode="json"),29 )30 missing = uni - {p.wsname for p in pairs.values()}31 if missing:32 log.warning("ingest.pairs.universe_missing", symbols=sorted(missing))33 log.info("ingest.pairs.refreshed", count=len(pairs), universe=len(uni - missing))34 return {p.wsname: p for p in pairs.values() if p.wsname in uni}35