क्रिप्टो के लिए मार्कोविट्ज़ पोर्टफोलियो थ्योरी: शून्य से हीरो तक

Python के साथ आदर्श क्रिप्टो पोर्टफोलियो बनाना - क्योंकि YOLO कोई रणनीति नहीं है। जानें कि व्यावहारिक Python कोड उदाहरणों के साथ नोबेल पुरस्कार विजेता पोर्टफोलियो थ्योरी को क्रिप्टो निवेश पर कैसे लागू करें।

Python के साथ आदर्श क्रिप्टो पोर्टफोलियो बनाना - क्योंकि YOLO कोई रणनीति नहीं है

Markowitz Portfolio Theory मार्कोविट्ज़ पोर्टफोलियो थ्योरी: किसी दिए गए जोखिम स्तर के लिए रिटर्न को अधिकतम करने हेतु डिजिटल एसेट्स पर लागू गणितीय अनुकूलन।


परिचय: आपके क्रिप्टो पोर्टफोलियो को गणित की जरूरत क्यों है (सिर्फ इंट्यूशन की नहीं)

नमस्ते क्रिप्टो डिजेन्स! 👋

याद है वो वक्त जब एलन के ट्वीट करने पर आपने अपना पूरा स्टैक DOGE में झोंक दिया था? या जब पिछले क्रैश के दौरान आपने घबराकर सब कुछ बेच दिया था? हां, हम सब वहां से गुजरे हैं। आज हम बात करेंगे उस चीज़ की जो आपके पोर्टफोलियो (और आपके दिमागी सुकून) को बचा सकती है: मार्कोविट्ज़ पोर्टफोलियो थ्योरी।

हैरी मार्कोविट्ज़ को इसके लिए 1990 में सचमुच नोबेल पुरस्कार मिला था। मूल विचार क्या है? आप गणितीय रूप से अपने पोर्टफोलियो को इस तरह ऑप्टिमाइज़ कर सकते हैं कि किसी भी दिए गए जोखिम स्तर पर सबसे अच्छा संभव रिटर्न मिले। यह आंखों पर पट्टी बांधकर गाड़ी चलाने की बजाय अपने निवेश के लिए GPS रखने जैसा है।

मूल अवधारणा: जोखिम बनाम रिटर्न (शाश्वत नृत्य)

कोड में उतरने से पहले, समझते हैं कि हम किससे निपट रहे हैं:

  • अपेक्षित रिटर्न: आप कितना पैसा कमाने की उम्मीद करते हैं
  • जोखिम (वोलैटिलिटी): आपके पोर्टफोलियो का मूल्य कितना उतार-चढ़ाव करता है
  • सहसंबंध (correlation): अलग-अलग एसेट्स एक-दूसरे के साथ कितनी समानता से चलते हैं

जादू तब होता है जब आप ऐसे एसेट्स को मिलाते हैं जो एकदम एक साथ नहीं चलते। जब Bitcoin क्रैश होता है, तो शायद कुछ DeFi टोकन बेहतर टिके रहें। यही डाइवर्सिफिकेशन आपके लिए काम कर रहा होता है।

Risk vs Return जोखिम बनाम रिटर्न: इष्टतम ज्यामितीय औसत रिटर्न प्राप्त करने के लिए उच्च-उपज वाले अस्थिर एसेट्स को एक स्थिर आधार के साथ संतुलित करना।

हमारा Python एनवायरनमेंट सेट करना

सबसे पहली चीज़ - अपने टूल्स तैयार करते हैं:

# Essential libraries for our crypto portfolio optimization
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')

# Set up plotting style
plt.style.use('dark_background')
sns.set_palette("husl")

लेवल 1: शुरुआती कदम - सरल पोर्टफोलियो गणित

बुनियादी बातों से शुरू करते हैं। हम एक साधारण 2-एसेट पोर्टफोलियो के लिए रिटर्न और जोखिम की गणना करेंगे।

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

# Get data for Bitcoin and Ethereum
crypto_symbols = ['BTC-USD', 'ETH-USD']
prices = get_crypto_data(crypto_symbols)

# Calculate daily returns
returns = prices.pct_change().dropna()
print("Daily Returns Preview:")
print(returns.head())

अब कुछ बुनियादी पोर्टफोलियो मेट्रिक्स की गणना करते हैं:

def portfolio_performance(weights, returns):
    """
    Calculate portfolio return and volatility
    weights: array of portfolio weights
    returns: dataframe of asset returns
    """
    # Portfolio return (annualized)
    portfolio_return = np.sum(returns.mean() * weights) * 252

    # Portfolio volatility (annualized)
    portfolio_vol = np.sqrt(np.dot(weights.T, np.dot(returns.cov() * 252, weights)))

    return portfolio_return, portfolio_vol

# Example: 50% BTC, 50% ETH
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: अब गंभीर मामला - एफिशिएंट फ्रंटियर

अब असली खेल शुरू होता है! एफिशिएंट फ्रंटियर हमें सभी संभावित इष्टतम पोर्टफोलियो दिखाता है। हर बिंदु किसी दिए गए जोखिम स्तर के लिए सर्वश्रेष्ठ संभव रिटर्न दर्शाता है।

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):
        # Generate random weights
        weights = np.random.random(num_assets)
        weights /= np.sum(weights)  # Normalize to sum to 1

        # Calculate portfolio metrics
        portfolio_return, portfolio_vol = portfolio_performance(weights, returns)
        sharpe_ratio = portfolio_return / portfolio_vol

        # Store results
        results[0,i] = portfolio_return
        results[1,i] = portfolio_vol
        results[2,i] = sharpe_ratio
        results[3,i:] = weights

    return results

# Generate 10,000 random portfolios
results = generate_random_portfolios(returns)

# Create a dataframe for easier handling
portfolio_results = pd.DataFrame({
    'Returns': results[0],
    'Volatility': results[1],
    'Sharpe_Ratio': results[2]
})

# Plot the efficient frontier
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()

Efficient Frontier एफिशिएंट फ्रंटियर: वह वक्र जो किसी दिए गए जोखिम स्तर के लिए अधिकतम संभव अपेक्षित रिटर्न को दर्शाता है।

लेवल 3: ऑप्टिमाइज़ेशन मास्टर - सही पोर्टफोलियो ढूंढना

रैंडम सैंपलिंग मज़ेदार है, लेकिन हमें गणितीय रूप से इष्टतम समाधान चाहिए। बड़ी तोपें निकालने का समय - scipy ऑप्टिमाइज़ेशन!

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 and bounds
    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
    initial_guess = num_assets * [1. / num_assets]

    if objective == 'sharpe':
        # Maximize Sharpe ratio
        result = minimize(negative_sharpe_ratio, initial_guess,
                         args=(returns,), method='SLSQP',
                         bounds=bounds, constraints=constraints)

    elif objective == 'min_vol':
        # Minimize volatility
        result = minimize(minimize_volatility, initial_guess,
                         args=(returns,), method='SLSQP',
                         bounds=bounds, constraints=constraints)

    elif objective == 'target_return':
        # Minimize volatility for 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

# Find optimal portfolios
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: मल्टी-एसेट मायाजाल - असली क्रिप्टो पोर्टफोलियो

चलिए इसे कई एसेट्स वाले एक असली क्रिप्टो पोर्टफोलियो तक बड़ा करते हैं:

# Expand to more cryptocurrencies
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()

# Check correlations
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
    """
    # Calculate range of target returns
    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)

# Calculate efficient frontier
efficient_port = efficient_frontier(returns_multi)

# Plot everything together
plt.figure(figsize=(14, 10))

# Random portfolios
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)

# Efficient frontier
if len(efficient_port) > 0:
    plt.plot(efficient_port[:,1], efficient_port[:,0], 'r-', linewidth=3, label='Efficient Frontier')

# Optimal portfolios
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()

# Display optimal allocations
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}")

Multi-Asset Portfolio Optimization मल्टी-एसेट डाइवर्सिफिकेशन: असंबद्ध क्रिप्टो एसेट्स को मिलाकर एक स्थिर ज्यामितीय संरचना में एक मज़बूत पोर्टफोलियो बनाना।

लेवल 5: एडवांस्ड तकनीकें - ब्लैक-लिटरमैन और रिस्क पैरिटी

पोर्टफोलियो ऑप्टिमाइज़ेशन के असली निंजाओं के लिए, चलिए कुछ एडवांस्ड तकनीकें लागू करते हैं:

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

# Calculate Risk Parity portfolio
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)

    # Calculate cumulative returns
    cumulative_returns = (1 + portfolio_returns).cumprod()

    # Performance metrics
    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
    }

# Backtest our strategies
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()

![Portfolio Strategy Backtests](/images/blog/markowitz-backtest.webp)
*एल्गोरिदमिक बैकटेस्टिंग: सैद्धांतिक ऑप्टिमाइज़ेशन मॉडलों को मान्य करने के लिए ऐतिहासिक प्रदर्शन का अनुकरण।*


# Performance summary table
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)

रियलिटी चेक: जो मार्कोविट्ज़ आपको नहीं बताता

गणितीय ऑप्टिमाइज़ेशन में पूरी तरह उतरने से पहले, यहां क्रिप्टो के बारे में कुछ कठोर सच्चाइयां हैं:

1. पिछला प्रदर्शन ≠ भविष्य के परिणाम क्रिप्टो बाज़ार युवा और अराजक है। जो सहसंबंध आपने गणना किए हैं? रेगुलेशन बदलने पर या अगला बड़ा हैक होने पर वे रातोंरात पलट सकते हैं।

2. ट्रांजैक्शन लागत मायने रखती है अपने पोर्टफोलियो को रीबैलेंस करना पैसे खर्च करता है। DeFi में, गैस फीस आपका मुनाफा खा सकती है। इसे अपनी रणनीति में शामिल करें।

3. लिक्विडिटी की समस्याएं सभी क्रिप्टो समान रूप से लिक्विड नहीं होतीं। वह स्मॉल-कैप ऑल्टकॉइन आपके ऑप्टिमाइज़ेशन में शानदार लग सकता है, लेकिन क्रैश के दौरान उसे बेचकर देखिए।

4. रेजीम में बदलाव क्रिप्टो बाज़ारों में अलग-अलग "रेजीम" होते हैं - बुल मार्केट, बियर मार्केट, क्रैब मार्केट। जो एक में काम करता है, वह दूसरे में काम नहीं भी कर सकता।

व्यावहारिक कार्यान्वयन के सुझाव

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

# Example usage
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)

निष्कर्ष: आपकी पोर्टफोलियो ऑप्टिमाइज़ेशन टूलकिट

अब आपके पास क्रिप्टो पोर्टफोलियो ऑप्टिमाइज़ेशन के लिए एक पूरी टूलकिट है:

  1. जोखिम और रिटर्न के लिए बुनियादी गणनाएं
  2. एफिशिएंट फ्रंटियर विज़ुअलाइज़ेशन
  3. अलग-अलग उद्देश्यों के लिए गणितीय ऑप्टिमाइज़ेशन
  4. रिस्क पैरिटी जैसी एडवांस्ड रणनीतियां
  5. अपनी रणनीतियों को मान्य करने के लिए बैकटेस्टिंग फ्रेमवर्क
  6. असल दुनिया के कार्यान्वयन के लिए व्यावहारिक बातें

मुख्य बातें

  • डाइवर्सिफिकेशन एक मुफ्त दोपहर का भोजन है - निवेश में एकमात्र मुफ्त चीज़
  • अपनी जोखिम सहनशीलता के आधार पर ऑप्टिमाइज़ करें - अधिकतम शार्प हमेशा आपके लिए सबसे अच्छा नहीं होता
  • व्यवस्थित रूप से रीबैलेंस करें लेकिन ओवरट्रेड न करें
  • विनम्र बने रहें - मॉडल टूल्स हैं, क्रिस्टल बॉल नहीं
  • सरलता से शुरू करें और जैसे-जैसे सीखें, जटिलता जोड़ें

याद रखें: क्रिप्टो में, बेहतरीन गणितीय मॉडल भी यह भविष्यवाणी नहीं कर सकते कि एलन डॉगकॉइन के बारे में कब ट्वीट करेंगे या अगला एक्सचेंज कब हैक होगा। पोर्टफोलियो थ्योरी को अपनी नींव के रूप में इस्तेमाल करें, लेकिन हमेशा कुछ बारूद सूखा रखें और कभी भी उतना निवेश न करें जितना आप गंवाने का जोखिम नहीं उठा सकते।

अब जाइए और जिम्मेदारी से ऑप्टिमाइज़ कीजिए! 🚀

आगे पढ़ें

कोड रिपॉज़िटरी

इस ट्यूटोरियल का पूरा कोड GitHub पर उपलब्ध है: https://github.com/suenot/markowitz

हैप्पी ऑप्टिमाइज़िंग! 📈