← Makalelere geri dön
September 25, 2025
5 dakikalık okuma

Kripto için Markowitz Portföy Teorisi: Sıfırdan Zirveye

Kripto için Markowitz Portföy Teorisi: Sıfırdan Zirveye
#portföy optimizasyonu
#Markowitz
#kripto
#Python
#kantitatif finans
#risk yönetimi
#çeşitlendirme
#etkin sınır
#Sharpe oranı
#algoritmik ticaret

Python ile optimal kripto portföyleri oluşturma - çünkü YOLO bir strateji değildir

Markowitz Portföy Teorisi 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 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 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ı Portföy Optimizasyonu Ç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()

![Portföy Stratejisi Geriye Dönük Testleri](/images/blog/markowitz-backtest.webp)
*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:

  1. Temel hesaplamalar risk ve getiri için
  2. Etkin sınır görselleştirmesi
  3. Matematiksel optimizasyon farklı hedefler için
  4. Gelişmiş stratejiler risk paritesi gibi
  5. Geriye dönük test çerçevesi stratejilerinizi doğrulamak için
  6. 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! 📈

Sorumluluk Reddi: Bu makalede sağlanan bilgiler yalnızca eğitim ve bilgilendirme amaçlıdır ve finansal, yatırım veya ticaret tavsiyesi niteliği taşımaz. Kripto para ticareti önemli bir kayıp riski içerir.

Yazarlar

Eugen Soloviov
Eugen Soloviov

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.

Newsletter

Piyasanın Önünde Olun

Özel yapay zeka ticaret içgörüleri, piyasa analizi ve platform güncellemeleri için bültenimize abone olun.

Gizliliğinize saygı duyuyoruz. İstediğiniz zaman abonelikten çıkabilirsiniz.