Розробка системи risk-reporting крипто-фонду
Крипто-фонди працюють в умовах, які традиційний риск-менеджмент просто не передбачав: 24/7 ринок без circuit breakers, позиції одночасно в on-chain протоколах та на централізованих біржах, liquidation ризики з нелінійною залежністю від ціни, контрагентний ризик кастодіана та смарт-контракту одночасно. Стандартні інструменти (Bloomberg, Advent) не розуміють DeFi. Будувати систему потрібно з нуля — або адаптувати існуючі риск-фреймворки до крипто-реальності.
Джерела даних: де живуть позиції фонду
Перша та головна складність — агрегація. Позиції фонду можуть знаходитися в:
CeFi: Binance, OKX, Bybit, Kraken — у кожної біржі свій API. REST для снапшотів позицій, WebSocket для real-time PnL. Проблема: API rate limits, нестандартні формати маржинальних рахунків, різні моделі ризику для cross/isolated margin.
DeFi on-chain:
- Lending: Aave v3, Compound v3, Morpho — позиції через смарт-контракт view functions або subgraph
- Perps: GMX, dYdX v4, Hyperliquid — у кожного своя модель рахунку
- LP позиції: Uniswap v3 (concentrated liquidity = нелінійний payoff), Curve, Balancer
- Yield: EigenLayer, Pendle (токенізований yield), Convex
- Структуровані продукти: Ribbon, Lyra — опційні стратегії on-chain
Custody: Fireblocks, Copper, Anchorage — зазвичай REST API для балансів. MPC-гаманці видні як звичайні on-chain адреси.
Итого: агрегатор даних — це 5-15 різних інтеграцій з різною якістю API та надійністю джерел.
Архітектура системи
Data layer
[CeFi APIs] [On-chain nodes] [Price feeds]
↓ ↓ ↓
[Kafka / message queue]
↓
[Normalizer Service] ← єдина модель Position, Balance, Trade
↓
[Time-series DB] ← TimescaleDB або ClickHouse
↓
[Risk Engine] ← розрахунок метрик
↓
[Reporting API + UI]
Нормалізована модель позиції:
interface Position {
id: string;
fund_id: string;
venue: 'binance' | 'aave_v3' | 'gmx' | string;
venue_type: 'cex' | 'dex_perp' | 'lending' | 'lp' | 'spot';
asset: string; // базовий актив (ETH, BTC, SOL)
quote_asset: string; // USDT, USDC, USD
size: Decimal; // в базовому активі
size_usd: Decimal; // USD-еквівалент
side: 'long' | 'short' | 'neutral';
entry_price?: Decimal;
mark_price: Decimal;
unrealized_pnl_usd: Decimal;
// для lending
health_factor?: Decimal;
liquidation_price?: Decimal;
// для LP
tick_lower?: number;
tick_upper?: number;
in_range?: boolean;
snapshot_ts: Date;
}
Risk Engine: ключові метрики
Net Delta. Сумарна експозиція по кожному базовому активу з урахуванням всіх позицій:
delta_ETH = Σ(position.size × sign × delta_multiplier)
Для лінійних позицій delta = 1, для опцій — greeks, для LP в Uniswap v3 — похідна від функції ліквідності (нелінійно залежить від поточної ціни в діапазоні).
Portfolio VaR (Value at Risk). Кілька підходів для крипто:
- Historical simulation — на основі фактичної P&L історії за 1-2 роки. Проблема: історія біткоїна коротка, крипто-кореляції нестабільні (особливо в кризи).
- Parametric VaR — модель нормального розподілу доходностей. Для крипто погано працює: важкі хвости, skew. Використовується тільки як grounding estimate.
- Monte Carlo — симуляція ціновых путей з заданими параметрами волатильності та кореляцій. Найбільш гнучкий, але обчислювально важкий.
import numpy as np
from scipy import stats
def historical_var(returns: np.ndarray, confidence: float = 0.99) -> float:
"""
returns: дневные доходности портфеля в USD
confidence: 0.99 → 1% worst case
"""
return -np.percentile(returns, (1 - confidence) * 100)
def conditional_var(returns: np.ndarray, confidence: float = 0.99) -> float:
"""Expected Shortfall / CVaR — середнє втрат гірше ніж VaR"""
var = historical_var(returns, confidence)
tail_returns = returns[returns <= -var]
return -tail_returns.mean() if len(tail_returns) > 0 else var
Stress testing. Сценарії специфічні для крипто:
| Сценарій | Параметри |
|---|---|
| BTC -30% за 24 години | Історичний прецедент: май 2021, ноябрь 2022 |
| Stablecoin depeg | USDC -5%, USDT -10% (аналог SVB-события) |
| DeFi exploit | Миттєва втрата позицій у конкретному протоколі |
| CEX withdrawal halt | FTX-сценарій: втрата доступу до CeFi активів |
| Gas spike на Ethereum | > 500 gwei — неможливість закрити позиції |
| Liquidation cascade | Ціновой шок → ланцюгові ліквідації → flash crash |
Liquidation distance. Для кожної lending позиції:
def liquidation_distance(
health_factor: Decimal,
liquidation_threshold: Decimal,
collateral_price: Decimal,
) -> dict:
"""
Aave v3 liquidation: health_factor < 1
health_factor = Σ(collateral_i × LT_i) / total_debt
"""
# При якому падінні ціни коллатера наступає ліквідація
price_drop_to_liquidation = 1 - (1 / health_factor)
return {
'current_hf': health_factor,
'price_drop_pct': price_drop_to_liquidation * 100,
'liquidation_price': collateral_price * (1 - price_drop_to_liquidation),
}
Concentration risk. Доля кожного активу/протоколу/контрагента в портфелі. Herfindahl-Hirschman Index для концентрації:
HHI = Σ(s_i²) де s_i — доля i-го активу
HHI = 1 — повна концентрація, HHI → 0 — повна диверсифікація.
Counterparty risk score. Суб'єктивна але необхідна метрика:
| Контрагент | Фактори |
|---|---|
| CeFi біржа | Обсяг резервів (PoR), регуляторний статус, історія |
| DeFi протокол | TVL, audit історія, upgrade механізм (multisig? timelock?), вік |
| Custodian | Insurance покриття, MPC vs multisig, SLA |
Алерти та триггери
Real-time моніторинг з порогами:
alerts:
- name: health_factor_critical
condition: health_factor < 1.2
severity: critical
channels: [telegram, pagerduty]
- name: net_delta_breach
condition: abs(net_delta_usd) > max_allowed_delta
severity: high
- name: var_limit_breach
condition: daily_var > var_limit * portfolio_nav
severity: high
- name: concentration_limit
condition: single_asset_pct > 0.4
severity: medium
- name: exchange_withdrawal_anomaly
condition: cex_balance_change > 0.1 * cex_total
severity: medium
Доставка алертів: Telegram Bot API для оперативних повідомлень, PagerDuty для критичних, email для дневних звітів.
Отчётність
Дневний risk-звіт
Структура (автоматично генерується в PDF або відправляється в Telegram/email):
- Snapshot NAV — загальна вартість портфеля з розбивкою по venues
- Delta exposure — нетто експозиція по кожному активу
- VaR metrics — 1-day VaR at 95%/99%, CVaR
- Liquidation watchlist — позиції з HF < 1.5, відстань до ліквідації
- Concentration — топ-5 активів та протоколів по доле
- Realized PnL — за день/тиждень/місяць з attribution по стратегіях
- Stress scenarios — результати стандартних сценаріїв
Compliance reporting
Для інституціональних інвесторів (LP) часто потрібні:
- ILPA-совместимі звіти — стандартні формати для приватних фондів
- Risk disclosure — описання ризиків на зрозумілій мові для non-technical LP
- Exposure limits compliance — підтвердження дотримання інвестиційної декларації
Якщо фонд регулюється (наприклад, через MiCA в EU або як VASP), звітність повинна відповідати вимогам регулятора.
Технологічний стек
| Компонент | Технологія |
|---|---|
| Data ingestion | Python (ccxt для CeFi, web3.py + viem для on-chain) |
| Message queue | Kafka / Redpanda |
| Time-series DB | TimescaleDB (позиції) + ClickHouse (trade historya) |
| Risk engine | Python (numpy, scipy, pandas) |
| API backend | FastAPI + PostgreSQL |
| Frontend | React + Recharts/TradingView widgets |
| Алерти | Prometheus Alertmanager → Telegram/PagerDuty |
| Звіти | WeasyPrint (PDF) / custom HTML templates |
Етапи реалізації
Етап 1 — Інтеграції (3-5 тижнів). Підключення до CeFi API та on-chain sources для конкретних venues фонду. Нормалізація в єдину модель позиції. Історичний бэкфіл.
Етап 2 — Risk engine (2-3 тижні). Розрахунок delta, VaR, liquidation distance, concentration metrics. Стрес-тесты. Валідація на історичних даних.
Етап 3 — Алерти (1-2 тижні). Real-time моніторинг, конфігурованані пороги, інтеграція з Telegram/PagerDuty.
Етап 4 — Reporting UI (2-3 тижні). Дашборд для портфельного менеджера, автоматична генерація звітів, експорт для LP.
Итого: 8-13 тижнів для фонду зі стандартним набором venues (2-3 CeFi + 3-5 DeFi протоколів). Кожна нова нестандартна інтеграція додає 3-7 днів.







