Kripto için Markowitz Portföy Teorisi: Sıfırdan Zirveye
Python ile optimal kripto portföyleri oluşturma - çünkü YOLO bir strateji değildir
Markowitz Portföy Teorisi: Belirli bir risk düzeyi için getirileri maksimize etmek amacıyla dijital varlıklara uygulanan matematiksel optimizasyon.
Giriş: Kripto Portföyünüz Neden Matematiğe İhtiyaç Duyar (Sezgiye Değil)
Hey kripto tutkunları! 👋
Elon tweet attığı için tüm birikimini DOGE'a yatırdığın o anı hatırlıyor musun? Ya da son çöküşte paniğe kapılıp her şeyi sattığın zamanı? Evet, hepimiz orada bulunduk. Bugün portföyünü (ve aklını) kurtarabilecek bir şeyden bahsedeceğiz: Markowitz Portföy Teorisi.
Harry Markowitz bu konu için 1990 yılında gerçekten Nobel Ödülü kazandı. Temel fikir? Herhangi bir risk düzeyi için mümkün olan en iyi getirileri elde etmek amacıyla portföyünü matematiksel olarak optimize edebilirsin. Yatırımların için gözleri kapalı sürmek yerine GPS kullanmak gibi.
Temel Kavram: Risk ve Getiri (Sonsuz Dans)
Koda dalmadan önce ne ile uğraştığımızı anlayalım:
- Beklenen Getiri: Ne kadar para kazanmayı beklediğin
- Risk (Oynaklık): Portföy değerinin ne kadar dalgalandığı
- Korelasyon: Farklı varlıkların birlikte nasıl hareket ettiği
Sihir, tam olarak eş zamanlı hareket etmeyen varlıkları birleştirdiğinde ortaya çıkar. Bitcoin çöktüğünde, bazı DeFi tokenleri daha iyi dayanıklılık gösterebilir. İşte bu sizin için çalışan çeşitlendirmedir.
Risk ve Getiri: Optimal geometrik ortalama getiriyi elde etmek için oynak yüksek verimli varlıkları istikrarlı bir temel ile dengeleme.
Python Ortamını Kurma
Her şeyden önce - araçlarımızı hazırlayalım:
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")
Seviye 1: Küçük Adımlar - Basit Portföy Matematiği
Temel bilgilerle başlayalım. Basit 2 varlıklı bir portföy için getiri ve riski hesaplayacağız.
def get_crypto_data(symbols, period="1y"):
"""
Yahoo Finance'den kripto verisi çek
symbols: kripto sembollerinin listesi (örn. ['BTC-USD', 'ETH-USD'])
period: veri için zaman dilimi
"""
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("Günlük Getiri Önizlemesi:")
print(returns.head())
Şimdi bazı temel portföy metriklerini hesaplayalım:
def portfolio_performance(weights, returns):
"""
Portföy getirisi ve oynaklığını hesapla
weights: portföy ağırlıklarının dizisi
returns: varlık getirilerinin veri çerçevesi
"""
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 Portföy:")
print(f"Beklenen Yıllık Getiri: {ret_5050:.2%}")
print(f"Yıllık Oynaklık: {vol_5050:.2%}")
print(f"Sharpe Oranı: {ret_5050/vol_5050:.3f}")
Seviye 2: Ciddiye Alma - Etkin Sınır
Artık pişiriyoruz! Etkin sınır, mümkün olan tüm optimal portföyleri gösterir. Her nokta, belirli bir risk düzeyi için mümkün olan en iyi getiriyi temsil eder.
def generate_random_portfolios(returns, num_portfolios=10000):
"""
Rastgele portföy kombinasyonları oluştur
"""
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) # Toplamı 1'e normalize et
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 Oranı')
plt.xlabel('Oynaklık (Risk)')
plt.ylabel('Beklenen Getiri')
plt.title('Etkin Sınır - Rastgele Portföyler')
plt.show()
Etkin Sınır: Belirli bir risk düzeyi için mümkün olan maksimum beklenen getiriyi temsil eden eğri.
Seviye 3: Optimizasyon Ustası - Mükemmel Portföyü Bulmak
Rastgele örnekleme eğlenceli, ancak matematiksel olarak optimal çözümü istiyoruz. Büyük silahları çıkarma zamanı - scipy optimizasyonu!
def negative_sharpe_ratio(weights, returns, risk_free_rate=0.02):
"""
Negatif Sharpe oranını hesapla (bunu minimize ediyoruz)
"""
portfolio_return, portfolio_vol = portfolio_performance(weights, returns)
sharpe = (portfolio_return - risk_free_rate) / portfolio_vol
return -sharpe
def minimize_volatility(weights, returns):
"""
Portföy oynaklığını hesapla (bunu minimize ediyoruz)
"""
_, portfolio_vol = portfolio_performance(weights, returns)
return portfolio_vol
def portfolio_return_objective(weights, returns):
"""
Portföy getirisini hesapla (bunu maksimize ediyoruz)
"""
portfolio_return, _ = portfolio_performance(weights, returns)
return -portfolio_return # Minimize ettiğimiz için negatif
def optimize_portfolio(returns, objective='sharpe', target_return=None):
"""
Farklı hedeflere göre portföyü optimize et
"""
num_assets = len(returns.columns)
constraints = ({'type': 'eq', 'fun': lambda x: np.sum(x) - 1}) # Ağırlıklar 1'e toplar
bounds = tuple((0, 1) for _ in range(num_assets)) # Açığa satış yok
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("🎯 Maksimum Sharpe Oranlı Portföy:")
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"Getiri: {ret_sharpe:.2%}, Oynaklık: {vol_sharpe:.2%}")
print(f"Sharpe Oranı: {ret_sharpe/vol_sharpe:.3f}\n")
print("🛡️ Minimum Oynaklık Portföyü:")
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"Getiri: {ret_minvol:.2%}, Oynaklık: {vol_minvol:.2%}")
Seviye 4: Çok Varlıklı Çılgınlık - Gerçek Kripto Portföyü
Bunu birden fazla varlıklı gerçek bir kripto portföyüne ölçekleyelim:
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('Kripto Varlık Korelasyon Matrisi')
plt.show()
def efficient_frontier(returns, num_portfolios=50):
"""
Etkin sınırı hesapla
"""
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='Etkin Sınır')
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='Maks. Sharpe')
plt.scatter(vol_minvol_multi, ret_minvol_multi, marker='*', color='red', s=500, label='Min. Oynaklık')
plt.colorbar(label='Sharpe Oranı')
plt.xlabel('Oynaklık (Risk)')
plt.ylabel('Beklenen Getiri')
plt.title('Çok Varlıklı Kripto Portföy Optimizasyonu')
plt.legend()
plt.show()
print("🚀 Optimal Çok Varlıklı Dağılımlar:")
print("\nMaksimum Sharpe Oranlı Portföy:")
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: # Yalnızca önemli tahsisleri göster
print(f"{asset}: {weight:.1%}")
print(f"\nPortföy Metrikleri:")
print(f"Beklenen Getiri: {ret_sharpe_multi:.1%}")
print(f"Oynaklık: {vol_sharpe_multi:.1%}")
print(f"Sharpe Oranı: {ret_sharpe_multi/vol_sharpe_multi:.2f}")
Çok Varlıklı Çeşitlendirme: Korelasyonsuz kripto varlıkları stabil bir geometrik yapıda birleştirerek güçlü bir portföy oluşturma.
Seviye 5: Gelişmiş Teknikler - Black-Litterman ve Risk Paritesi
Gerçek portföy optimizasyon ninja'ları için bazı gelişmiş teknikler uygulayalım:
def risk_parity_portfolio(returns):
"""
Risk Paritesi Portföyü - her varlık portföy riskine eşit katkıda bulunur
"""
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 Paritesi Portföyü:")
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 Paritesi Metrikleri:")
print(f"Beklenen Getiri: {ret_rp:.1%}")
print(f"Oynaklık: {vol_rp:.1%}")
print(f"Sharpe Oranı: {ret_rp/vol_rp:.2f}")
def backtest_portfolio(weights, prices):
"""
Portföy performansının basit geriye dönük testi
"""
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 = {
'Maks. Sharpe': max_sharpe_multi.x,
'Min. Oynaklık': min_vol_multi.x,
'Risk Paritesi': risk_parity_result.x,
'Eşit Ağırlık': 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('Portföy Stratejisi Geriye Dönük Testleri')
plt.xlabel('Tarih')
plt.ylabel('Kümülatif Getiriler')
plt.legend()
plt.yscale('log')
plt.grid(True, alpha=0.3)
plt.show()

*Algoritmik Geriye Dönük Test: Teorik optimizasyon modellerini doğrulamak için tarihsel performansı simüle etme.*
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 = ['Yıllık Getiri', 'Yıllık Oynaklık', 'Sharpe Oranı', 'Maksimum Düşüş']
print("\n📊 Strateji Performans Özeti:")
print(performance_summary)
Gerçeklik Kontrolü: Markowitz'in Sana Söylemediği Şeyler
Matematiksel optimizasyona tamamen dalmadan önce, kripto hakkında bazı acı gerçekler:
1. Geçmiş Performans ≠ Gelecekteki Sonuçlar Kripto piyasası genç ve kaotik. Hesapladığın korelasyonlar mı? Düzenlemeler değiştiğinde ya da bir sonraki büyük hack gerçekleştiğinde bir gecede tersine dönebilirler.
2. İşlem Maliyetleri Önemlidir Portföyünü yeniden dengelemek para harcar. DeFi'de gas ücretleri seni mahvedebilir. Bunu stratejine dahil et.
3. Likidite Sorunları Tüm kriptolar eşit derecede likit değildir. O düşük piyasa değerli altcoin optimizasyonunda harika görünebilir, ancak bir çöküş sırasında satmayı dene.
4. Rejim Değişiklikleri Kripto piyasalarının farklı "rejimleri" vardır - boğa piyasaları, ayı piyasaları, yatay piyasalar. Birinde işe yarayan diğerinde çalışmayabilir.
Pratik Uygulama İpuçları
def practical_portfolio_rebalancing(target_weights, current_weights, threshold=0.05):
"""
Yalnızca ağırlıklar eşiği aştığında yeniden dengele
"""
weight_diff = np.abs(target_weights - current_weights)
needs_rebalancing = np.any(weight_diff > threshold)
if needs_rebalancing:
print("🔄 Yeniden dengeleme gerekiyor!")
for i, (target, current) in enumerate(zip(target_weights, current_weights)):
if abs(target - current) > threshold:
print(f"Varlık {i}: {current:.1%} → {target:.1%}")
else:
print("✅ Portföy tolerans dahilinde, yeniden dengeleme gerekmiyor")
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)
Sonuç: Portföy Optimizasyon Araç Setiniz
Artık kripto portföy optimizasyonu için eksiksiz bir araç setiniz var:
- Temel hesaplamalar risk ve getiri için
- Etkin sınır görselleştirmesi
- Matematiksel optimizasyon farklı hedefler için
- Gelişmiş stratejiler risk paritesi gibi
- Geriye dönük test çerçevesi stratejilerinizi doğrulamak için
- Pratik değerlendirmeler gerçek dünya uygulaması için
Temel Çıkarımlar
- Çeşitlendirme bedava öğle yemeğidir - yatırımda tek bedava öğle yemeği
- Risk toleransına göre optimize et - maksimum Sharpe her zaman senin için en iyisi değildir
- Sistematik olarak yeniden dengele ama aşırı işlem yapma
- Alçakgönüllü kal - modeller araçtır, kristal küre değil
- Basit başla ve öğrendikçe karmaşıklık ekle
Unutma: Kriptoda, en iyi matematiksel modeller bile Elon'un ne zaman Dogecoin hakkında tweet atacağını ya da bir sonraki borsanın ne zaman hacklenebileceğini tahmin edemez. Portföy teorisini temel olarak kullan, ancak her zaman biraz nakit yedekte tut ve asla kaybetmeyi göze alamayacağından fazlasını yatırma.
Artık sorumlu bir şekilde optimize et! 🚀
Daha Fazla Okuma
Kod Deposu
Bu eğitimdeki tüm kodlar GitHub'da mevcuttur: https://github.com/suenot/markowitz
İyi optimizasyonlar! 📈
Yazarlar
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.