Розробка системи стрес-тестування портфелю

Проєктуємо та розробляємо блокчейн-рішення повного циклу: від архітектури смарт-контрактів до запуску DeFi-протоколів, NFT-маркетплейсів та криптобірж. Аудит безпеки, токеноміка, інтеграція з наявною інфраструктурою.
Показано 1 з 1Усі 1306 послуг
Розробка системи стрес-тестування портфелю
Складний
~5 днів
Часті запитання

Напрямки блокчейн-розробки

Етапи блокчейн-розробки

Останні роботи

  • image_website-b2b-advance_0.webp
    Розробка сайту компанії B2B ADVANCE
    1288
  • image_web-applications_feedme_466_0.webp
    Розробка веб-додатків для компанії FEEDME
    1198
  • image_websites_belfingroup_462_0.webp
    Розробка веб-сайту для компанії БЕЛФІНГРУП
    902
  • image_ecommerce_furnoro_435_0.webp
    Розробка інтернет магазину для компанії FURNORO
    1122
  • image_logo-advance_0.webp
    Розробка логотипу компанії B2B Advance
    589
  • image_crm_enviok_479_0.webp
    Розробка веб-додатків для компанії Enviok
    859

Розробка системи стрес-тестування портфеля

Стрес-тестування — перевірка портфеля в умовах екстремальних сценаріїв, що виходять за межи звичайного статистичного ризику. VaR показує «нормальний» ризик. Стрес-тест показує, що відбувається під час справжніх катастроф.

Типи стрес-тестів

Історичні сценарії стресу: застосовуємо історично сталі кризи до поточного портфеля.

Гіпотетичні сценарії: моделюємо можливі, але не сталі події.

Аналіз чутливості: змінюємо один параметр (ціну, волатильність, кореляцію) і спостерігаємо P&L.

Зворотне стрес-тестування: шукаємо сценарії, при яких портфель втрачає критичну суму.

Історичні сценарії для крипторинку

CRYPTO_STRESS_SCENARIOS = {
    'covid_march_2020': {
        'BTC': -0.50,  # -50% за тиждень
        'ETH': -0.60,
        'DEFAULT': -0.55,
        'USDT': 0.0,
        'duration_days': 7
    },
    'china_ban_may_2021': {
        'BTC': -0.53,
        'ETH': -0.60,
        'DEFAULT': -0.65,
        'duration_days': 30
    },
    'luna_terra_collapse_2022': {
        'LUNA': -0.99,
        'UST': -0.95,
        'BTC': -0.30,
        'ETH': -0.35,
        'DEFAULT': -0.45,
        'USDC': 0.0,
        'duration_days': 7
    },
    'ftx_collapse_2022': {
        'FTT': -0.97,
        'SOL': -0.60,
        'BTC': -0.25,
        'ETH': -0.28,
        'DEFAULT': -0.35,
        'duration_days': 14
    },
    'full_crypto_winter': {
        'BTC': -0.80,  # 2022
        '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
            )
        
        # Сортуємо за гіршим випадком
        return sorted(results.values(), key=lambda x: x['total_pnl'])

Аналіз чутливості

Аналіз чутливості: як змінюється P&L при зміні одного фактора?

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

Стрес кореляцій: під час кризи всі активи корелюють сильніше. Що якщо кореляція всіх активів = 0.95?

def correlation_stress_test(portfolio_returns_history, stressed_correlation=0.95):
    cov_matrix = portfolio_returns_history.cov()
    # Замінюємо всі позадіагональні елементи на stressed_correlation
    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

Зворотне стрес-тестування

Зворотна задача: знайти сценарій, при якому втрати досягають критичного рівня (наприклад, 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))

Кореляції під час кризи

Одне з ключових спостережень: під час кризи кореляції між активами різко зростають. Диверсифікація «схлопується» саме тоді, коли вона потрібна найбільше.

Стрес-тест «correlation crisis»: замінюємо матрицю коваріацій на «stressed» версію з високими кореляціями та перерахуємо VaR.

Звітність

Звіт стрес-тесту — щомісячно або при значних змінах портфеля:

  • Таблиця результатів для всіх сценаріїв
  • Гірший випадок P&L в абсолютних значеннях і % від капіталу
  • Розбір: які позиції привели до найбільших втрат
  • Крива чутливості (графік P&L від % шоку)
  • Зворотний стрес: при якому шоці досягається критичний убиток

Візуалізація: діаграма tornado (вклад кожної позиції в стрес-убиток), водоспад графік (накопичення втрат за позиціями), графік кривої чутливості.

Розробляємо систему стрес-тестування з бібліотекою історичних сценаріїв, аналізом чутливості, зворотним стрес-тестуванням та автоматичною генерацією звітів.