Криптопортфель із десяти токенів з рівними вагами — 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.xRisk 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.







