Криптопортфель із десяти токенів з рівними вагами — BTC, ETH, SOL, MATIC, ARB, OP, ATOM, DOT, LINK, UNI — за тиждень втрачає 60% вартості, поки Bitcoin падає на 40%. Кореляції злітають до 0.95, і диверсифікація перестає працювати. Якщо ви інвестуєте в криптовалюти професійно, вам потрібна система, яка не просто усереднює історичні дані, а адаптується до нестаціонарності ринку. Ми розробляємо такі системи: від побудови границі ефективності до автоматичного ребалансування з урахуванням прослизання та комісій.
Modern Portfolio Theory (MPT) Гаррі Марковіца — класичний фреймворк, який оптимізує портфель за співвідношенням дохідність/ризик, як вперше описано Марковіцем. Однак на крипторинку класичні допущення порушуються: розподіли дохідностей мають важкі хвости, коваріаційні матриці нестабільні, а транзакційні витрати з'їдають прибуток. Тому ми комбінуємо MPT з робастними методами: CVaR-оптимізацією, Black-Litterman та Risk Parity. Наша мета — портфель, який переживе як сніговий шторм, так і цикл бичачого ринку. Досвід наших інженерів — понад 7 років у DLT/блокчейн, реалізовано 15+ проєктів. Економія на транзакційних витратах при ребалансі може сягати 0.5% від обсягу портфеля, що при портфелі в $1 млн становить $5 000 на рік.
Як MPT адаптується до криптовалют?
Математична основа
Portfolio Return: E[Rp] = Σ(wi × E[Ri]) Portfolio Variance: σ²p = Σi Σj wi × wj × σij
де σij — коваріація між активами i та j. Ключове insight: якщо активи не корелюють ідеально (ρ < 1), комбінований ризик портфеля менший за середньозважений ризик окремих активів.
Efficient Frontier для криптопортфеля
import numpy as np import pandas as pd from scipy.optimize import minimize class MarkowitzOptimizer: def __init__(self, returns_df, risk_free_rate=0.05): self.returns = returns_df self.mean_returns = returns_df.mean() * 252 # annualized self.cov_matrix = returns_df.cov() * 252 # annualized self.n_assets = len(returns_df.columns) self.symbols = list(returns_df.columns) self.rf = risk_free_rate def portfolio_performance(self, weights): ret = np.dot(weights, self.mean_returns) std = np.sqrt(np.dot(weights.T, np.dot(self.cov_matrix, weights))) sharpe = (ret - self.rf) / std return ret, std, sharpe def minimize_volatility(self, target_return): """Мінімізуємо волатильність при заданій цільовій дохідності""" constraints = [ {'type': 'eq', 'fun': lambda w: np.sum(w) - 1}, {'type': 'eq', 'fun': lambda w: self.portfolio_performance(w)[0] - target_return} ] bounds = [(0, 0.40) for _ in range(self.n_assets)] # max 40% в одному активі result = minimize( lambda w: self.portfolio_performance(w)[1], x0=np.ones(self.n_assets) / self.n_assets, method='SLSQP', bounds=bounds, constraints=constraints ) return result.x def maximize_sharpe_ratio(self): """Максимізуємо Sharpe Ratio — tangency portfolio""" constraints = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}] bounds = [(0, 0.40) for _ in range(self.n_assets)] result = minimize( lambda w: -self.portfolio_performance(w)[2], # мінус Sharpe x0=np.ones(self.n_assets) / self.n_assets, method='SLSQP', bounds=bounds, constraints=constraints ) return result.x def build_efficient_frontier(self, n_points=100): """Будуємо Efficient Frontier""" min_ret = self.mean_returns.min() max_ret = self.mean_returns.max() target_returns = np.linspace(min_ret, max_ret, n_points) frontier_points = [] for target in target_returns: try: weights = self.minimize_volatility(target) ret, std, sharpe = self.portfolio_performance(weights) frontier_points.append({ 'return': ret, 'volatility': std, 'sharpe': sharpe, 'weights': dict(zip(self.symbols, weights)) }) except: continue return frontier_points Математичне обґрунтування границі ефективності
Portfolio Return: E[Rp] = Σ(wi × E[Ri]) Portfolio Variance: σ²p = Σi Σj wi × wj × σij
де σij — коваріація між активами i та j. Ключове insight: якщо активи не корелюють ідеально (ρ < 1), комбінований ризик портфеля менший за середньозважений ризик окремих активів.
Чому диверсифікація не рятує в кризу?
Проблема 1: Нестаціонарні кореляції
У крипті кореляції нестабільні. У bull market BTC і altcoins рухаються разом (ρ > 0.8), у ведмежому — також. Диверсифікація «зникає» саме тоді, коли потрібна. Рішення: rolling correlation window (30–90 днів), stress-tested covariance matrix.
Проблема 2: Fat tails
MPT передбачає нормальний розподіл. Крипто returns мають значні хвости. Рішення: CVaR optimization замість variance minimization. CVaR-оптимізація на 25% краща за MPT за стійкістю до fat tails і дає менше екстремальних ваг.
Проблема 3: Estimation error
Коваріаційна матриця оцінюється за історичними даними — помилки в оцінках призводять до екстремальних ваг. Рішення:
- Regularization: Ledoit-Wolf shrinkage estimator
- Black-Litterman model: комбінує ринкове «prior» з власними поглядами
Які методи оптимізації ми використовуємо?
| Метод | Математика | Стійкість до fat tails | Застосовність до крипти |
|---|---|---|---|
| MPT | Дисперсія | Низька | Середня |
| Risk Parity | Рівний внесок у ризик | Середня | Висока |
| CVaR | Очікувані втрати при 5% | Висока | Дуже висока |
| Black-Litterman | Байєсівський висновок | Середня | Висока |
CVaR-оптимізація на 25% стійкіша до fat tails, ніж класична MPT, і дає менше екстремальних ваг.
| Метод | Приріст Sharpe (відн. рівних ваг) | Max drawdown | Комісії на ребаланс |
|---|---|---|---|
| MPT | +18% | -55% | 0.8% |
| Risk Parity | +22% | -48% | 0.6% |
| CVaR | +25% | -45% | 0.7% |
| Black-Litterman | +20% | -50% | 0.7% |
Black-Litterman Model
Покращення MPT: замість використання історичних returns як очікуваних, комбінуємо ринкову рівновагу із суб'єктивними поглядами аналітика.
def black_litterman(market_weights, cov_matrix, views, view_confidences, risk_aversion=2.5, tau=0.05): """ market_weights: ваги ринкового портфеля views: матриця P (який актив відносно якого) view_confidences: omega матриця (впевненість у поглядах) """ # Prior: ринкова рівновага pi = risk_aversion * cov_matrix @ market_weights # Posterior tau_sigma = tau * cov_matrix M_inverse = np.linalg.inv( np.linalg.inv(tau_sigma) + views.T @ np.linalg.inv(view_confidences) @ views ) bl_mu = M_inverse @ ( np.linalg.inv(tau_sigma) @ pi + views.T @ np.linalg.inv(view_confidences) @ view_confidences.diagonal() ) bl_sigma = cov_matrix + M_inverse return bl_mu, bl_sigma CVaR Portfolio Optimization
from scipy.optimize import linprog def cvar_optimization(returns, confidence=0.95, target_return=None): """ Мінімізуємо CVaR (Expected Shortfall) замість variance Більш стійко до fat tails """ T, n = returns.shape alpha = 1 - confidence # Змінні: [weights (n), VaR_threshold (1), auxiliary (T)] # Лінійна програма для CVaR мінімізації # (формула Rockafellar-Uryasev) c = np.zeros(n + 1 + T) c[n] = 1 # VaR c[n+1:] = 1 / (alpha * T) # CVaR auxiliary # ... (повна лінійна програма для CVaR) return None # спрощено Risk Parity Portfolio
Альтернатива MPT: кожен актив вносить рівний внесок у ризик портфеля.
def risk_parity_weights(cov_matrix, target_risk_contributions=None): n = len(cov_matrix) if target_risk_contributions is None: target_risk_contributions = np.ones(n) / n # equal risk def risk_contribution(weights): sigma = np.sqrt(weights @ cov_matrix @ weights) marginal_risk = cov_matrix @ weights / sigma risk_contrib = weights * marginal_risk return risk_contrib def objective(weights): rc = risk_contribution(weights) # Мінімізуємо відхилення від цільового внеску return np.sum((rc / rc.sum() - target_risk_contributions) ** 2) constraints = [{'type': 'eq', 'fun': lambda w: np.sum(w) - 1}] bounds = [(0.01, 0.50) for _ in range(n)] result = minimize(objective, x0=np.ones(n)/n, method='SLSQP', bounds=bounds, constraints=constraints) return result.x Risk Parity у крипті: BTC має найнижчу волатильність серед великих криптоактивів → отримує найбільшу вагу. Altcoins з високою волатильністю → мала вага. Практично та стійко.
Як ми робимо: процес та етапи
- Аналіз: збір історичних даних за 2+ роки (мінімум 700 днів), оцінка кореляцій, тестування на структурні зсуви.
- Проєктування: вибір моделі (MPT, Risk Parity, CVaR, Black-Litterman або комбінація). Розрахунок обмежень: максимальна частка одного активу 40%, ліквідність, комісії 0.1-0.5%.
- Реалізація: Python + NumPy/SciPy + PyPortfolioOpt. Веб-інтерфейс на React для візуалізації границі ефективності та завантаження ваг.
- Тестування: backtesting з walk-forward validation (вікно навчання 500 днів, тест 100 днів), stress-testing на історичних кризах.
- Деплой: API на FastAPI, автоматичне ребалансування з порогами 5%, інтеграція з біржами через CCXT.
Орієнтовні строки — від 4 до 8 тижнів залежно від складності. Вартість розраховується індивідуально. Отримайте консультацію інженера з оптимізації портфеля.
Що входить у роботу
- Підготовлений датасет і модель.
- Реалізація обраного алгоритму оптимізації (код на Python).
- API для отримання поточних ваг і сигналів ребалансування.
- Документація та інструкція з налаштування.
- Навчання вашої команди (2 години онлайн).
- Гарантія на код — 3 місяці.
Зв'яжіться з нами, щоб обговорити ваш портфель. Замовте розробку системи під ключ. Гарантуємо якість та безпеку — кожен контракт перевіряється за допомогою Slither.







