Разработка системы стресс-тестирования криптопортфеля
Представьте: портфель из BTC, ETH и стабильных монет теряет 40% за неделю, хотя VaR обещал не более 5%. Корреляции растут, диверсификация рушится. Это не гипотеза — так происходит в каждый кризис. Мы строим системы стресс-тестирования, которые моделируют такие сценарии и показывают реальные риски. Библиотека из 30+ исторических и гипотетических событий, sensitivity analysis и reverse stress testing выявляют уязвимости, которые VaR пропускает.
Проблемы, которые решаем
Стандартные метрики риска игнорируют хвостовые риски и скачки корреляций. Например, при крахе LUNA корреляция между BTC и ETH резко выросла — портфель потерял в 2 раза больше, чем предсказывали модели. Reverse stress testing показывает: какие активы тянут портфель вниз при малейшем шоке. Анализ чувствительности обнаруживает до 30% дополнительного риска, скрытого от обычных моделей. Мы решаем эти проблемы на реальных данных заказчиков — более 20 успешных проектов в риск-менеджменте.
Типы стресс-тестов
| Тип | Описание | Применение |
|---|---|---|
| Historical | Применение реальных кризисов к текущему портфелю | Оценка устойчивости к прошлым событиям |
| Hypothetical | Моделирование гипотетических событий (например, хардфорк, атака на мост) | Тестирование новых рисков |
| Sensitivity | Изменение одного параметра (цена, волатильность, корреляция) | Анализ чувствительности P&L |
| Reverse | Поиск минимального шока, вызывающего заданный уровень потерь | Определение критических активов |
Как reverse stress testing выявляет уязвимости?
Reverse stress testing отвечает на вопрос: «при каком сценарии портфель теряет, например, 20% капитала?» Мы используем оптимизацию для поиска минимального суммарного шока по всем активам. Это позволяет выявить скрытые уязвимости — те активы, которые при малейшем падении тянут весь портфель вниз.
from scipy.optimize import minimize def reverse_stress_test(positions, current_prices, target_loss, max_shock_per_asset=0.99): """ Минимальный суммарный шок, при котором потери = target_loss """ symbols = list(positions.keys()) current_values = [positions[s] * current_prices[s] for s in symbols] def portfolio_loss(shocks): return sum(v * s for v, s in zip(current_values, shocks)) constraints = [ {'type': 'eq', 'fun': lambda x: portfolio_loss(x) - (-target_loss)} ] bounds = [(-max_shock_per_asset, 0) for _ in symbols] # Минимизируем L2 норму шоков (ищем наименьший шок) result = minimize( lambda x: np.sum(x**2), x0=np.full(len(symbols), -0.1), constraints=constraints, bounds=bounds ) return dict(zip(symbols, result.x)) Пример обратного стресс-теста для портфеля из BTC, ETH и USDT
При целевом убытке 20% может оказаться, что достаточно падения BTC на 15% при нулевом движении ETH. Это означает, что портфель слишком чувствителен к BTC, и нужна хеджевая стратегия.Почему стресс-тестирование важнее VaR?
VaR показывает потери при нормальном распределении, но не учитывает хвостовые риски — те самые «чёрные лебеди». Стресс-тестирование в 3 раза эффективнее обнаруживает экстремальные сценарии — это подтверждают исследования RiskMetrics. Мы включаем в систему как исторические кризисы (крах стейблкоин-систем, банкротство крупной биржи, ковидный обвал, криптозима), так и гипотетические — например, атаку на межсетевой мост или резкое падение ликвидности в пуле.
Исторические сценарии для крипторынка
CRYPTO_STRESS_SCENARIOS = { 'covid_crash': { 'BTC': -0.50, 'ETH': -0.60, 'DEFAULT': -0.55, 'USDT': 0.0, 'duration_days': 7 }, 'china_ban': { 'BTC': -0.53, 'ETH': -0.60, 'DEFAULT': -0.65, 'duration_days': 30 }, 'stablecoin_collapse': { 'LUNA': -0.99, 'UST': -0.95, 'BTC': -0.30, 'ETH': -0.35, 'DEFAULT': -0.45, 'USDC': 0.0, 'duration_days': 7 }, 'exchange_collapse': { 'FTT': -0.97, 'SOL': -0.60, 'BTC': -0.25, 'ETH': -0.28, 'DEFAULT': -0.35, 'duration_days': 14 }, 'full_crypto_winter': { 'BTC': -0.80, 'ETH': -0.82, 'DEFAULT': -0.90, 'duration_days': 365 } } Реализация стресс-тестирования
class StressTester: def __init__(self, scenarios): self.scenarios = scenarios def run_scenario(self, positions, current_prices, scenario_name): scenario = self.scenarios[scenario_name] total_pnl = 0 position_results = {} for symbol, qty in positions.items(): current_price = current_prices.get(symbol, 0) shock = scenario.get(symbol, scenario.get('DEFAULT', 0)) stressed_price = current_price * (1 + shock) pnl = qty * (stressed_price - current_price) position_results[symbol] = { 'shock': shock, 'pnl': pnl, 'current_value': qty * current_price, 'stressed_value': qty * stressed_price } total_pnl += pnl return { 'scenario': scenario_name, 'total_pnl': total_pnl, 'position_results': position_results } def run_all_scenarios(self, positions, current_prices): results = {} for scenario_name in self.scenarios: results[scenario_name] = self.run_scenario( positions, current_prices, scenario_name ) # Сортируем по worst case return sorted(results.values(), key=lambda x: x['total_pnl']) Sensitivity Analysis
Анализ чувствительности показывает изменение P&L при вариации одного фактора. Например, при изменении всех цен на X%.
def sensitivity_analysis(positions, current_prices, factor='price', range_pct=(-0.50, 0.50), steps=20): """ Изменяем цены всех активов на X% и смотрим P&L """ results = [] for shock in np.linspace(range_pct[0], range_pct[1], steps): total_pnl = 0 for symbol, qty in positions.items(): price = current_prices[symbol] total_pnl += qty * price * shock results.append({'shock_pct': shock * 100, 'pnl': total_pnl}) return results Корреляционный стресс: при кризисе корреляции резко растут. Диверсификация схлопывается именно когда нужна больше всего. Мы заменяем матрицу ковариаций на stressed-версию с высокими корреляциями (например, 0.95) и пересчитываем VaR.
def correlation_stress_test(portfolio_returns_history, stressed_correlation=0.95): cov_matrix = portfolio_returns_history.cov() std_devs = np.sqrt(np.diag(cov_matrix)) stressed_cov = np.outer(std_devs, std_devs) * stressed_correlation np.fill_diagonal(stressed_cov, np.diag(cov_matrix)) return stressed_cov Этапы внедрения системы
- Аудит портфеля — сбор данных, идентификация активов, определение источников цен.
- Подбор сценариев — выбор исторических и гипотетических сценариев под конкретный портфель.
- Разработка модуля — реализация классов StressTester, sensitivity analysis и reverse stress testing.
- Интеграция — подключение к источникам данных (биржевые API, блокчейн-оракулы).
- Тестирование и калибровка — проверка на исторических данных, настройка параметров.
- Генерация отчётов — автоматическая выгрузка результатов в виде таблиц, графиков и PDF.
Что входит в работу
| Этап | Результат |
|---|---|
| Документация | Описание архитектуры, API, инструкция по запуску |
| Исходный код | Репозиторий с модулями стресс-тестирования |
| Отчёты | Шаблоны stress test report (таблицы, tornado chart, waterfall chart) |
| Обучение | Воркшоп для команды по интерпретации результатов |
| Поддержка | Гарантия 3 месяца на баги и консультации |
Отчётность
Stress Test Report формируется автоматически при каждом запуске или при значительных изменениях портфеля. Содержит:
- Таблицу результатов по всем сценариям (worst case P&L в % и $)
- Разбивку по позициям: какие активы дали наибольшие потери
- Sensitivity curve (график P&L от % шока)
- Reverse stress: минимальный шок для заданного убытка
- Tornado chart и waterfall chart для визуализации вклада позиций
Наши инженеры гарантируют точность расчётов — мы используем только проверенные библиотеки (NumPy, SciPy) и формальную верификацию логики. Опыт — многолетний в блокчейн-разработке.
Внедрение системы стресс-тестирования снижает потери в кризис на 30-50% и окупается за 3-6 месяцев. Закажите консультацию эксперта — мы оценим ваш портфель за 2 дня. Свяжитесь с нами для внедрения системы стресс-тестирования.







