מערכת אופטימיזציה לתיק מטבעות קריפטו (תורת התיקים המודרנית)
תיק של עשרה נכסים במשקל שווה—BTC, ETH, SOL, MATIC, ARB, OP, ATOM, DOT, LINK, UNI—מאבד 60% מערכו בשבוע אחד בעוד ביטקוין צונח ב-40%. המתאמים מזנקים ל-0.95, והפיזור מפסיק לעבוד. אם אתם משקיעים במטבעות קריפטו באופן מקצועי, אתם זקוקים למערכת שלא רק ממצעת נתונים היסטוריים אלא מתאימה עצמה לאי-סטציונריות של השוק. אנו בונים מערכות כאלה: מבניית הגבול היעיל ועד לאיזון מחדש אוטומטי שמתחשב בהחלקה ובעמלות.
העבודה המקורית (MPT) של הארי מרקוביץ היא המסגרת הקלאסית שממטבת תיק לפי יחס תשואה/סיכון, כפי שתואר לראשונה על ידי מרקוביץ. עם זאת, בשוק הקריפטו, ההנחות הקלאסיות קורסות: להתפלגויות התשואות יש זנבות עבים, מטריצות השונות אינן יציבות, ועלויות העסקה אוכלות את הרווחים. לכן, אנו משלבים את MPT עם שיטות חזקות: אופטימיזציית CVaR, Black-Litterman, ו-Risk Parity. המטרה שלנו היא תיק ששורד גם סופת שלגים וגם מחזור שוק שורי. למהנדסים שלנו יש ניסיון של למעלה מ-7 שנים ב-DLT/בלוקצ'יין והם יישמו למעלה מ-15 פרויקטים. החיסכון בעלויות עסקה במהלך איזון מחדש יכול להגיע ל-0.5% מהיקף התיק—על תיק של מיליון דולר, זה 5,000 דולר בשנה.
כיצד MPT מתאימה עצמה למטבעות קריפטו
בסיס מתמטי
תשואת תיק: E[Rp] = Σ(wi × E[Ri]) שונות תיק: σ²p = Σi Σj wi × wj × σij
כאשר σij הוא השונות המשותפת בין נכסים i ו-j. תובנה מרכזית: אם הנכסים אינם מתואמים באופן מושלם (ρ < 1), הסיכון המשולב של התיק נמוך מהסיכון הממוצע המשוקלל של הנכסים הבודדים.
גבול יעיל לתיק קריפטו
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
הצדקה מתמטית של הגבול היעיל
תשואת תיק: E[Rp] = Σ(wi × E[Ri]) שונות תיק: σ²p = Σi Σj wi × wj × σij
כאשר σij הוא השונות המשותפת בין נכסים i ו-j. תובנה מרכזית: אם הנכסים אינם מתואמים באופן מושלם (ρ < 1), הסיכון המשולב של התיק נמוך מהסיכון הממוצע המשוקלל של הנכסים הבודדים.
מדוע פיזור נכשל במשבר
בעיה 1: מתאמים לא-סטציונריים
בקריפטו, המתאמים אינם יציבים. בשוק שורי, BTC ואלטקוינס נעים יחד (ρ > 0.8); בשוק דובי, הם גם עושים זאת. הפיזור "נעלם" בדיוק כשצריך אותו. פתרון: חלון מתאם נע (30–90 יום), מטריצת שונות משוכללת במבחני לחץ.
בעיה 2: זנבות עבים
MPT מניחה התפלגות נורמלית. לתשואות קריפטו יש זנבות משמעותיים. פתרון: אופטימיזציית CVaR במקום מזעור שונות. אופטימיזציית CVaR חזקה פי 1.25 לזנבות עבים מאשר MPT ומניבה משקלים קיצוניים פחותים.
בעיה 3: שגיאת הערכה
מטריצת השונות מוערכת מנתונים היסטוריים—שגיאות בהערכות מובילות למשקלים קיצוניים. פתרון:
- רגולריזציה: מעריך הצמצום של Ledoit-Wolf
- מודל Black-Litterman: משלב "קדימות" שוקית עם דעות אישיות משלכם
אילו שיטות אופטימיזציה אנו משתמשים
| שיטה | מתמטיקה | חוסן לזנבות עבים | התאמה לקריפטו |
|---|---|---|---|
| MPT | שונות | נמוך | בינוני |
| Risk Parity | תרומת סיכון שווה | בינוני | גבוה |
| CVaR | הפסד צפוי ב-5% | גבוה | גבוה מאוד |
| Black-Litterman | הסקה בייסיאנית | בינוני | גבוה |
אופטימיזציית CVaR חזקה פי 1.25 לזנבות עבים מאשר MPT קלאסית ומניבה משקלים קיצוניים פחותים.
| שיטה | עליית Sharpe (לעומת משקלים שווים) | גרירה מקסימלית | עלויות איזון מחדש |
|---|---|---|---|
| MPT | +18% | -55% | 0.8% |
| Risk Parity | +22% | -48% | 0.6% |
| CVaR | +25% | -45% | 0.7% |
| Black-Litterman | +20% | -50% | 0.7% |
יחס Sharpe של המערכת שלנו גבוה פי 1.3 מתיק פשוט במשקלים שווים, ו-Risk Parity מפחית את הגרירה המקסימלית פי 1.1 לעומת משקלים שווים.
מודל Black-Litterman
שיפור ל-MPT: במקום להשתמש בתשואות היסטוריות כתשואות צפויות, שלבו שיווי משקל שוקי עם דעות אנליסטים סובייקטיביות.
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
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
חלופה ל-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 יש את התנודתיות הנמוכה ביותר מבין נכסי הקריפטו המרכזיים → הוא מקבל את המשקל הגבוה ביותר. אלטקוינס עם תנודתיות גבוהה → משקל נמוך. פרקטי וחזק.
איך אנחנו עושים את זה: תהליך ושלבים
- ניתוח: איסוף נתונים היסטוריים ל-2+ שנים (מינימום 700 יום), הערכת מתאמים, בדיקת שברים מבניים.
- עיצוב: בחירת מודל (MPT, Risk Parity, CVaR, Black-Litterman או שילוב). חישוב אילוצים: משקל מקסימלי לנכס בודד 40%, נזילות, עמלות 0.1-0.5%.
- יישום: Python + NumPy/SciPy + PyPortfolioOpt. ממשק web ב-React להמחשת הגבול היעיל ולהורדת משקלים.
- בדיקות: Backtesting עם אימות walk-forward (חלון אימון 500 יום, בדיקה 100 יום), בדיקות לחץ על משברים היסטוריים.
- פריסה: API של FastAPI, איזון מחדש אוטומטי עם ספים של 5%, אינטגרציה עם בורסות דרך CCXT.
לוח זמנים משוער: 4 עד 8 שבועות תלוי במורכבות. העלות מחושבת באופן אישי. קבלו ייעוץ ממהנדס אופטימיזציית תיקים.
מה כלול
- מערך נתונים ומודל מוכנים.
- יישום אלגוריתם האופטימיזציה הנבחר (קוד Python).
- API לקבלת משקלים עדכניים ואותות איזון מחדש.
- תיעוד והוראות התקנה.
- הדרכת צוות (שעתיים מקוונות).
- אחריות על קוד — 3 חודשים.
צרו קשר כדי לדון בתיק שלכם. הזמינו פיתוח מערכת מפתח. אנו מבטיחים איכות ואבטחה—כל חוזה נבדק באמצעות Slither.







