Kripto uchun Markowitz portfel nazariyasi: noldan qahramongacha
Python yordamida optimal kripto portfellar qurish - chunki YOLO strategiya emas
Markowitz portfel nazariyasi: berilgan xavf darajasi uchun daromadni maksimal darajaga yetkazish maqsadida raqamli aktivlarga qo'llaniladigan matematik optimallashtirish.
Kirish: nega sizning kripto portfelingizga faqat hissiyot emas, matematika kerak
Salom, kripto-degenlar! 👋
Elon tvit yozgani uchun butun stackingizni DOGE'ga tashlab yuborgan paytingizni eslaysizmi? Yoki oxirgi qulash paytida hamma narsani vahima ichida sotib yuborgan paytingizni? Ha, hammamiz bu yerdan o'tganmiz. Bugun biz portfelingizni (va aql-hushingizni) saqlab qolishi mumkin bo'lgan narsa haqida gaplashamiz: Markowitz portfel nazariyasi.
Harri Markowitz buning uchun 1990 yilda rostdan ham Nobel mukofotiga sazovor bo'lgan. Asosiy g'oya nima? Siz istalgan xavf darajasi uchun eng yaxshi mumkin bo'lgan daromadga erishish maqsadida portfelingizni matematik jihatdan optimallashtira olasiz. Bu ko'zingizni yumib mashina haydashning o'rniga investitsiyalaringiz uchun GPS bo'lishga o'xshaydi.
Asosiy tushuncha: xavf va daromad (abadiy raqs)
Kodga o'tishdan oldin, nima bilan shug'ullanayotganimizni tushunib olaylik:
- Kutilayotgan daromad: qancha pul topishni kutayapsiz
- Xavf (o'zgaruvchanlik): portfelingiz qiymati qanchalik tebranadi
- Korrelyatsiya: turli aktivlar bir-biriga qanchalik o'xshash harakat qiladi
Sehr o'zaro mukammal sinxron harakat qilmaydigan aktivlarni birlashtirganingizda sodir bo'ladi. Bitcoin qulaganda, ba'zi DeFi tokenlar yaxshiroq chidashi mumkin. Bu sizning foydangizga ishlayotgan diversifikatsiya.
Xavf va daromad: optimal geometrik o'rtacha daromadga erishish uchun yuqori daromadli, o'zgaruvchan aktivlarni barqaror asos bilan muvozanatlash.
Python muhitimizni sozlash
Avvalo eng muhimi - asboblarimizni tayyorlaymiz:
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import seaborn as sns
from scipy.optimize import minimize
import yfinance as yf
import warnings
warnings.filterwarnings('ignore')
plt.style.use('dark_background')
sns.set_palette("husl")
1-daraja: dastlabki qadamlar - oddiy portfel matematikasi
Asoslardan boshlaylik. Oddiy 2 aktivli portfel uchun daromad va xavfni hisoblaymiz.
def get_crypto_data(symbols, period="1y"):
"""
Fetch crypto data from Yahoo Finance
symbols: list of crypto symbols (e.g., ['BTC-USD', 'ETH-USD'])
period: time period for data
"""
data = yf.download(symbols, period=period)['Adj Close']
return data
crypto_symbols = ['BTC-USD', 'ETH-USD']
prices = get_crypto_data(crypto_symbols)
returns = prices.pct_change().dropna()
print("Daily Returns Preview:")
print(returns.head())
Endi bir nechta asosiy portfel ko'rsatkichlarini hisoblaymiz:
def portfolio_performance(weights, returns):
"""
Calculate portfolio return and volatility
weights: array of portfolio weights
returns: dataframe of asset returns
"""
portfolio_return = np.sum(returns.mean() * weights) * 252
portfolio_vol = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))
return portfolio_return, portfolio_vol
weights_5050 = np.array([0.5, 0.5])
ret_5050, vol_5050 = portfolio_performance(weights_5050, returns)
print(f"50/50 Portfolio:")
print(f"Expected Annual Return: {ret_5050:.2%}")
print(f"Annual Volatility: {vol_5050:.2%}")
print(f"Sharpe Ratio: {ret_5050/vol_5050:.3f}")
2-daraja: jiddiyroq harakat - samarali chegara (efficient frontier)
Endi haqiqiy ish boshlanadi! Samarali chegara bizga barcha mumkin bo'lgan optimal portfellarni ko'rsatadi. Har bir nuqta berilgan xavf darajasi uchun eng yaxshi mumkin bo'lgan daromadni bildiradi.
def generate_random_portfolios(returns, num_portfolios=10000):
"""
Generate random portfolio combinations
"""
num_assets = len(returns.columns)
results = np.zeros((4, num_portfolios))
for i in range(num_portfolios):
weights = np.random.random(num_assets)
weights /= np.sum(weights) # Normalize to sum to 1
portfolio_return, portfolio_vol = portfolio_performance(weights, returns)
sharpe_ratio = portfolio_return / portfolio_vol
results[0,i] = portfolio_return
results[1,i] = portfolio_vol
results[2,i] = sharpe_ratio
results[3,i:] = weights
return results
results = generate_random_portfolios(returns)
portfolio_results = pd.DataFrame({
'Returns': results[0],
'Volatility': results[1],
'Sharpe_Ratio': results[2]
})
plt.figure(figsize=(12, 8))
scatter = plt.scatter(portfolio_results['Volatility'],
portfolio_results['Returns'],
c=portfolio_results['Sharpe_Ratio'],
cmap='viridis', alpha=0.6)
plt.colorbar(scatter, label='Sharpe Ratio')
plt.xlabel('Volatility (Risk)')
plt.ylabel('Expected Return')
plt.title('Efficient Frontier - Random Portfolios')
plt.show()
Samarali chegara: berilgan xavf darajasi uchun maksimal mumkin bo'lgan kutilayotgan daromadni ifodalovchi egri chiziq.
3-daraja: optimallashtirish ustasi - mukammal portfelni topish
Tasodifiy tanlash qiziqarli, lekin bizga matematik jihatdan optimal yechim kerak. Og'ir artilleriyani ishga solish vaqti keldi - scipy optimallashtirishi!
def negative_sharpe_ratio(weights, returns, risk_free_rate=0.02):
"""
Calculate negative Sharpe ratio (we minimize this)
"""
portfolio_return, portfolio_vol = portfolio_performance(weights, returns)
sharpe = (portfolio_return - risk_free_rate) / portfolio_vol
return -sharpe
def minimize_volatility(weights, returns):
"""
Calculate portfolio volatility (we minimize this)
"""
_, portfolio_vol = portfolio_performance(weights, returns)
return portfolio_vol
def portfolio_return_objective(weights, returns):
"""
Calculate portfolio return (we maximize this)
"""
portfolio_return, _ = portfolio_performance(weights, returns)
return -portfolio_return # Negative because we minimize
def optimize_portfolio(returns, objective='sharpe', target_return=None):
"""
Optimize portfolio based on different objectives
"""
num_assets = len(returns.columns)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1}) # Weights sum to 1
bounds = tuple((0, 1) for _ in range(num_assets)) # No short selling
initial_guess = num_assets * [1. / num_assets]
if objective == 'sharpe':
result = minimize(negative_sharpe_ratio, initial_guess,
args=(returns,), method='SLSQP',
bounds=bounds, constraints=constraints)
elif objective == 'min_vol':
result = minimize(minimize_volatility, initial_guess,
args=(returns,), method='SLSQP',
bounds=bounds, constraints=constraints)
elif objective == 'target_return':
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1},
{'type': 'eq', 'fun': lambda x: portfolio_performance(x, returns)[0] - target_return})
result = minimize(minimize_volatility, initial_guess,
args=(returns,), method='SLSQP',
bounds=bounds, constraints=constraints)
return result
max_sharpe = optimize_portfolio(returns, 'sharpe')
min_vol = optimize_portfolio(returns, 'min_vol')
print("🎯 Maximum Sharpe Ratio Portfolio:")
for i, symbol in enumerate(crypto_symbols):
print(f"{symbol}: {max_sharpe.x[i]:.3f}")
ret_sharpe, vol_sharpe = portfolio_performance(max_sharpe.x, returns)
print(f"Return: {ret_sharpe:.2%}, Volatility: {vol_sharpe:.2%}")
print(f"Sharpe Ratio: {ret_sharpe/vol_sharpe:.3f}\n")
print("🛡️ Minimum Volatility Portfolio:")
for i, symbol in enumerate(crypto_symbols):
print(f"{symbol}: {min_vol.x[i]:.3f}")
ret_minvol, vol_minvol = portfolio_performance(min_vol.x, returns)
print(f"Return: {ret_minvol:.2%}, Volatility: {vol_minvol:.2%}")
4-daraja: ko'p aktivli aljashuv - haqiqiy kripto portfel
Buni bir nechta aktivdan iborat to'liq huquqli kripto portfeliga kengaytiramiz:
crypto_portfolio = ['BTC-USD', 'ETH-USD', 'BNB-USD', 'ADA-USD', 'SOL-USD', 'DOT-USD']
prices_multi = get_crypto_data(crypto_portfolio, period="2y")
returns_multi = prices_multi.pct_change().dropna()
correlation_matrix = returns_multi.corr()
plt.figure(figsize=(10, 8))
sns.heatmap(correlation_matrix, annot=True, cmap='RdYlBu_r', center=0)
plt.title('Crypto Asset Correlation Matrix')
plt.show()
def efficient_frontier(returns, num_portfolios=50):
"""
Calculate the efficient frontier
"""
ret_range = np.linspace(returns.mean().min()*252, returns.mean().max()*252, num_portfolios)
efficient_portfolios = []
for target_ret in ret_range:
try:
result = optimize_portfolio(returns, 'target_return', target_ret)
if result.success:
ret, vol = portfolio_performance(result.x, returns)
efficient_portfolios.append([ret, vol, result.x])
except:
continue
return np.array(efficient_portfolios)
efficient_port = efficient_frontier(returns_multi)
plt.figure(figsize=(14, 10))
random_results = generate_random_portfolios(returns_multi, 5000)
plt.scatter(random_results[1], random_results[0],
c=random_results[2], cmap='viridis', alpha=0.3, s=10)
if len(efficient_port) > 0:
plt.plot(efficient_port[:,1], efficient_port[:,0], 'r-', linewidth=3, label='Efficient Frontier')
max_sharpe_multi = optimize_portfolio(returns_multi, 'sharpe')
min_vol_multi = optimize_portfolio(returns_multi, 'min_vol')
ret_sharpe_multi, vol_sharpe_multi = portfolio_performance(max_sharpe_multi.x, returns_multi)
ret_minvol_multi, vol_minvol_multi = portfolio_performance(min_vol_multi.x, returns_multi)
plt.scatter(vol_sharpe_multi, ret_sharpe_multi, marker='*', color='gold', s=500, label='Max Sharpe')
plt.scatter(vol_minvol_multi, ret_minvol_multi, marker='*', color='red', s=500, label='Min Volatility')
plt.colorbar(label='Sharpe Ratio')
plt.xlabel('Volatility (Risk)')
plt.ylabel('Expected Return')
plt.title('Multi-Asset Crypto Portfolio Optimization')
plt.legend()
plt.show()
print("🚀 Optimal Multi-Asset Allocations:")
print("\nMaximum Sharpe Ratio Portfolio:")
sharpe_weights = pd.Series(max_sharpe_multi.x, index=crypto_portfolio).sort_values(ascending=False)
for asset, weight in sharpe_weights.items():
if weight > 0.01: # Only show significant allocations
print(f"{asset}: {weight:.1%}")
print(f"\nPortfolio Metrics:")
print(f"Expected Return: {ret_sharpe_multi:.1%}")
print(f"Volatility: {vol_sharpe_multi:.1%}")
print(f"Sharpe Ratio: {ret_sharpe_multi/vol_sharpe_multi:.2f}")
Ko'p aktivli diversifikatsiya: bir-biriga bog'liq bo'lmagan kripto aktivlarni barqaror geometrik tuzilmaga birlashtirish orqali mustahkam portfel qurish.
5-daraja: ilg'or texnikalar - Black-Litterman va xavf paritetlari
Portfelni optimallashtirishning haqiqiy ninjalari uchun bir nechta ilg'or texnikani amalga oshiramiz:
def risk_parity_portfolio(returns):
"""
Risk Parity Portfolio - each asset contributes equally to portfolio risk
"""
def risk_contribution(weights, cov_matrix):
portfolio_vol = np.sqrt(np.dot(weights.T, np.dot(cov_matrix, weights)))
marginal_contrib = np.dot(cov_matrix, weights) / portfolio_vol
contrib = weights * marginal_contrib
return contrib
def risk_parity_objective(weights, cov_matrix):
contrib = risk_contribution(weights, cov_matrix)
target_contrib = np.ones(len(weights)) / len(weights)
return np.sum((contrib - target_contrib)**2)
num_assets = len(returns.columns)
cov_matrix = returns.cov() * 252
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1})
bounds = tuple((0.001, 1) for _ in range(num_assets))
initial_guess = num_assets * [1. / num_assets]
result = minimize(risk_parity_objective, initial_guess,
args=(cov_matrix,), method='SLSQP',
bounds=bounds, constraints=constraints)
return result
risk_parity_result = risk_parity_portfolio(returns_multi)
print("⚖️ Risk Parity Portfolio:")
rp_weights = pd.Series(risk_parity_result.x, index=crypto_portfolio).sort_values(ascending=False)
for asset, weight in rp_weights.items():
print(f"{asset}: {weight:.1%}")
ret_rp, vol_rp = portfolio_performance(risk_parity_result.x, returns_multi)
print(f"\nRisk Parity Metrics:")
print(f"Expected Return: {ret_rp:.1%}")
print(f"Volatility: {vol_rp:.1%}")
print(f"Sharpe Ratio: {ret_rp/vol_rp:.2f}")
def backtest_portfolio(weights, prices):
"""
Simple backtest of portfolio performance
"""
returns = prices.pct_change().dropna()
portfolio_returns = (returns * weights).sum(axis=1)
cumulative_returns = (1 + portfolio_returns).cumprod()
total_return = cumulative_returns.iloc[-1] - 1
annualized_return = (1 + total_return) ** (252 / len(portfolio_returns)) - 1
annualized_vol = portfolio_returns.std() * np.sqrt(252)
sharpe_ratio = annualized_return / annualized_vol
max_dd = (cumulative_returns / cumulative_returns.expanding().max() - 1).min()
return {
'total_return': total_return,
'annualized_return': annualized_return,
'annualized_volatility': annualized_vol,
'sharpe_ratio': sharpe_ratio,
'max_drawdown': max_dd,
'cumulative_returns': cumulative_returns
}
strategies = {
'Max Sharpe': max_sharpe_multi.x,
'Min Volatility': min_vol_multi.x,
'Risk Parity': risk_parity_result.x,
'Equal Weight': np.ones(len(crypto_portfolio)) / len(crypto_portfolio)
}
plt.figure(figsize=(14, 8))
for name, weights in strategies.items():
backtest_results = backtest_portfolio(weights, prices_multi)
plt.plot(backtest_results['cumulative_returns'], label=f"{name} (Sharpe: {backtest_results['sharpe_ratio']:.2f})")
plt.title('Portfolio Strategy Backtests')
plt.xlabel('Date')
plt.ylabel('Cumulative Returns')
plt.legend()
plt.yscale('log')
plt.grid(True, alpha=0.3)
plt.show()

*Algoritmik bektesting: nazariy optimallashtirish modellarini tasdiqlash uchun tarixiy natijalarni simulyatsiya qilish.*
performance_summary = pd.DataFrame()
for name, weights in strategies.items():
results = backtest_portfolio(weights, prices_multi)
performance_summary[name] = [
f"{results['annualized_return']:.1%}",
f"{results['annualized_volatility']:.1%}",
f"{results['sharpe_ratio']:.2f}",
f"{results['max_drawdown']:.1%}"
]
performance_summary.index = ['Annual Return', 'Annual Volatility', 'Sharpe Ratio', 'Max Drawdown']
print("\n📊 Strategy Performance Summary:")
print(performance_summary)
Haqiqatga qaytish: Markowitz sizga aytmaydigan narsalar
Matematik optimallashtirishga to'liq bel bog'lashdan oldin, kripto haqida bir nechta qattiq haqiqatlar:
1. O'tmishdagi natijalar kelajakdagi natijalarga teng emas Kripto bozori yosh va tartibsiz. Siz hisoblagan korrelyatsiyalar-chi? Ular tartibga solish qoidalari o'zgarganda yoki keyingi katta xakerlik hujumi sodir bo'lganda bir kechada teskarisiga aylanishi mumkin.
2. Tranzaksiya xarajatlari muhim Portfelingizni qayta muvozanatlash pul talab qiladi. DeFi'da gaz to'lovlari foydangizni yeyishi mumkin. Buni strategiyangizda hisobga oling.
3. Likvidlik muammolari Barcha kriptovalyutalar bir xil darajada likvid emas. O'sha kichik kapitalli altkoin optimallashtiruvingizda ajoyib ko'rinishi mumkin, lekin uni qulash paytida sotib ko'ring.
4. Rejim o'zgarishlari Kripto bozorlarida turli "rejimlar" mavjud - ko'tarilish bozorlari, tushish bozorlari, yon tomonga siljish bozorlari. Bittasida ishlaydigan narsa boshqasida ishlamasligi mumkin.
Amaliy joriy etish bo'yicha maslahatlar
def practical_portfolio_rebalancing(target_weights, current_weights, threshold=0.05):
"""
Only rebalance when weights drift beyond threshold
"""
weight_diff = np.abs(target_weights - current_weights)
needs_rebalancing = np.any(weight_diff > threshold)
if needs_rebalancing:
print("🔄 Rebalancing needed!")
for i, (target, current) in enumerate(zip(target_weights, current_weights)):
if abs(target - current) > threshold:
print(f"Asset {i}: {current:.1%} → {target:.1%}")
else:
print("✅ Portfolio within tolerance, no rebalancing needed")
return needs_rebalancing
current_allocation = np.array([0.35, 0.25, 0.15, 0.10, 0.10, 0.05])
target_allocation = max_sharpe_multi.x
practical_portfolio_rebalancing(target_allocation, current_allocation)
Xulosa: portfelni optimallashtirish uchun asboblar to'plamingiz
Endi sizda kripto portfelini optimallashtirish uchun to'liq asboblar to'plami bor:
- Xavf va daromad uchun asosiy hisob-kitoblar
- Samarali chegarani vizualizatsiya qilish
- Turli maqsadlar uchun matematik optimallashtirish
- Xavf pariteti kabi ilg'or strategiyalar
- Strategiyalaringizni tasdiqlash uchun bektesting freymvorki
- Real dunyoda joriy etish uchun amaliy mulohazalar
Asosiy xulosalar
- Diversifikatsiya - bu bepul tushlik - investitsiyalardagi yagona bepul narsa
- Xavfga bardoshliligingizga qarab optimallashtiring - maksimal Sharpe koeffitsienti har doim ham siz uchun eng yaxshisi bo'lavermaydi
- Tizimli ravishda qayta muvozanatlang, lekin ortiqcha savdo qilmang
- Kamtar bo'ling - modellar asbob, sehrli sharlar emas
- Oddiydan boshlang va o'rganib borgan sari murakkablikni qo'shing
Esda tuting: kriptoda hatto eng yaxshi matematik modellar ham Elon Dogecoin haqida qachon tvit yozishini yoki keyingi birja qachon xakerlik hujumiga uchrashini bashorat qila olmaydi. Portfel nazariyasini asos sifatida ishlating, lekin har doim biroz zaxira saqlang va yo'qotishga tayyor bo'lmagan miqdordan ko'proq hech qachon investitsiya qilmang.
Endi boring va mas'uliyat bilan optimallashtiring! 🚀
Qo'shimcha o'qish
Kod repozitoriysi
Ushbu qo'llanmadagi barcha kod GitHub'da mavjud: https://github.com/suenot/markowitz
Muvaffaqiyatli optimallashtirish! 📈
Authors
Trading-systems engineer
Trading-systems engineer building bots since 2017: cross-exchange arbitrage (connected up to 30 venues), cointegration-based pairs arbitrage across spot and futures, scalping, news and sentiment-driven strategies, trend algorithms, and portfolio management and balancing algorithms. Also builds sub-millisecond order execution, big-data warehouses, backtesting engines, AI agents, and trading interfaces (incl. open-source profitmaker.cc). Stack: JS/TS, Python, Rust/Zig/Go, DevOps, backend, frontend, architecture.