malkhut: three-layer identifier architecture for cross-system asset identification

Layer 1 (canonical identity): symbol, base_asset, name, unified_symbol
  (CCXT format), quote_currency
Layer 2 (cross-system): coingecko_id, cmc_id, blockchain, contract_address
Layer 3 (exchange mapping): exchanges tuple

All 13 pre-defined assets migrated with accurate CoinGecko IDs, CMC IDs,
blockchains, and contract addresses (ERC-20 tokens).

7 new query functions: get_asset_by_coingecko_id, get_asset_by_cmc_id,
get_assets_by_base_asset, get_assets_by_blockchain,
get_assets_by_unified_symbol.

33 new tests covering: Layer 1 identity, Layer 2 cross-system identifiers,
identifier query functions, identifier consistency (uniqueness, derivation),
exchange registry.

Total: 1189 tests, 47 files, all green.

Based on research: CCXT BASE/QUOTE is de facto standard, CoinGecko ID
most widely used in crypto-native, ISO 24165 DTI emerging, FIGI for
institutional.
This commit is contained in:
Codex
2026-07-12 00:40:14 +02:00
parent da61c8f6c2
commit 1f709af6d1
4 changed files with 341 additions and 13 deletions

View File

@@ -69,8 +69,18 @@ EXCHANGE_PROFILES["okx"] = ExchangeProfile(
```python
@dataclass(frozen=True, slots=True)
class AssetProfile:
# Identity
symbol: str # "BTCUSDT"
# --- Layer 1: Canonical identity (venue-independent) ---
symbol: str # "BTCUSDT" — internal canonical ID
base_asset: str # "BTC" — asset without quote
name: str # "Bitcoin" — human-readable
unified_symbol: str # "BTC/USDT" — CCXT format
quote_currency: str # "USDT" — settlement currency
# --- Layer 2: Cross-system identifiers ---
coingecko_id: str # "bitcoin" — CoinGecko slug
cmc_id: int # 1 — CoinMarketCap numeric ID
blockchain: str # "bitcoin" — native chain
contract_address: str # "0x..." for ERC-20, "" for native coins
# Fundamental (intrinsic, never change)
sectors: tuple[Sector, ...] # ("CURRENCY",)
@@ -101,7 +111,7 @@ class AssetProfile:
has_funding: bool = False
has_options: bool = False
# Exchange membership
# --- Layer 3: Exchange membership ---
exchanges: tuple[str, ...] = ("binance",) # which venues trade this
```
@@ -118,6 +128,11 @@ class AssetProfile:
|----------|---------|
| `get_asset_profile(symbol)` | Single profile or None |
| `list_assets()` | All symbols |
| `get_asset_by_coingecko_id(id)` | Profile by CoinGecko slug |
| `get_asset_by_cmc_id(id)` | Profile by CMC numeric ID |
| `get_assets_by_base_asset(base)` | All profiles for a base asset |
| `get_assets_by_blockchain(chain)` | Assets on a given chain |
| `get_assets_by_unified_symbol(sym)` | Profile by CCXT unified symbol |
| `get_assets_by_sector(sector)` | Assets in ANY of the queried sector |
| `get_assets_by_token_role(role)` | Assets with ANY of the queried role |
| `get_assets_by_supply(model)` | Assets with given supply model |