क्रिप्टो के लिए मार्कोविट्ज़ पोर्टफोलियो थ्योरी: शून्य से हीरो तक
Python के साथ आदर्श क्रिप्टो पोर्टफोलियो बनाना - क्योंकि YOLO कोई रणनीति नहीं है
मार्कोविट्ज़ पोर्टफोलियो थ्योरी: किसी दिए गए जोखिम स्तर के लिए रिटर्न को अधिकतम करने हेतु डिजिटल एसेट्स पर लागू गणितीय अनुकूलन।
परिचय: आपके क्रिप्टो पोर्टफोलियो को गणित की जरूरत क्यों है (सिर्फ इंट्यूशन की नहीं)
नमस्ते क्रिप्टो डिजेन्स! 👋
याद है वो वक्त जब एलन के ट्वीट करने पर आपने अपना पूरा स्टैक DOGE में झोंक दिया था? या जब पिछले क्रैश के दौरान आपने घबराकर सब कुछ बेच दिया था? हां, हम सब वहां से गुजरे हैं। आज हम बात करेंगे उस चीज़ की जो आपके पोर्टफोलियो (और आपके दिमागी सुकून) को बचा सकती है: मार्कोविट्ज़ पोर्टफोलियो थ्योरी।
हैरी मार्कोविट्ज़ को इसके लिए 1990 में सचमुच नोबेल पुरस्कार मिला था। मूल विचार क्या है? आप गणितीय रूप से अपने पोर्टफोलियो को इस तरह ऑप्टिमाइज़ कर सकते हैं कि किसी भी दिए गए जोखिम स्तर पर सबसे अच्छा संभव रिटर्न मिले। यह आंखों पर पट्टी बांधकर गाड़ी चलाने की बजाय अपने निवेश के लिए GPS रखने जैसा है।
मूल अवधारणा: जोखिम बनाम रिटर्न (शाश्वत नृत्य)
कोड में उतरने से पहले, समझते हैं कि हम किससे निपट रहे हैं:
- अपेक्षित रिटर्न: आप कितना पैसा कमाने की उम्मीद करते हैं
- जोखिम (वोलैटिलिटी): आपके पोर्टफोलियो का मूल्य कितना उतार-चढ़ाव करता है
- सहसंबंध (correlation): अलग-अलग एसेट्स एक-दूसरे के साथ कितनी समानता से चलते हैं
जादू तब होता है जब आप ऐसे एसेट्स को मिलाते हैं जो एकदम एक साथ नहीं चलते। जब Bitcoin क्रैश होता है, तो शायद कुछ DeFi टोकन बेहतर टिके रहें। यही डाइवर्सिफिकेशन आपके लिए काम कर रहा होता है।
जोखिम बनाम रिटर्न: इष्टतम ज्यामितीय औसत रिटर्न प्राप्त करने के लिए उच्च-उपज वाले अस्थिर एसेट्स को एक स्थिर आधार के साथ संतुलित करना।
हमारा Python एनवायरनमेंट सेट करना
सबसे पहली चीज़ - अपने टूल्स तैयार करते हैं:
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: शुरुआती कदम - सरल पोर्टफोलियो गणित
बुनियादी बातों से शुरू करते हैं। हम एक साधारण 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
crypto_symbols = ['BTC-USD', 'ETH-USD']
prices = get_crypto_data(crypto_symbols)
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 = 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: अब गंभीर मामला - एफिशिएंट फ्रंटियर
अब असली खेल शुरू होता है! एफिशिएंट फ्रंटियर हमें सभी संभावित इष्टतम पोर्टफोलियो दिखाता है। हर बिंदु किसी दिए गए जोखिम स्तर के लिए सर्वश्रेष्ठ संभव रिटर्न दर्शाता है।
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()
एफिशिएंट फ्रंटियर: वह वक्र जो किसी दिए गए जोखिम स्तर के लिए अधिकतम संभव अपेक्षित रिटर्न को दर्शाता है।
लेवल 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 = ({'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: मल्टी-एसेट मायाजाल - असली क्रिप्टो पोर्टफोलियो
चलिए इसे कई एसेट्स वाले एक असली क्रिप्टो पोर्टफोलियो तक बड़ा करते हैं:
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}")
मल्टी-एसेट डाइवर्सिफिकेशन: असंबद्ध क्रिप्टो एसेट्स को मिलाकर एक स्थिर ज्यामितीय संरचना में एक मज़बूत पोर्टफोलियो बनाना।
लेवल 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
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()

*एल्गोरिदमिक बैकटेस्टिंग: सैद्धांतिक ऑप्टिमाइज़ेशन मॉडलों को मान्य करने के लिए ऐतिहासिक प्रदर्शन का अनुकरण।*
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
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)
निष्कर्ष: आपकी पोर्टफोलियो ऑप्टिमाइज़ेशन टूलकिट
अब आपके पास क्रिप्टो पोर्टफोलियो ऑप्टिमाइज़ेशन के लिए एक पूरी टूलकिट है:
- जोखिम और रिटर्न के लिए बुनियादी गणनाएं
- एफिशिएंट फ्रंटियर विज़ुअलाइज़ेशन
- अलग-अलग उद्देश्यों के लिए गणितीय ऑप्टिमाइज़ेशन
- रिस्क पैरिटी जैसी एडवांस्ड रणनीतियां
- अपनी रणनीतियों को मान्य करने के लिए बैकटेस्टिंग फ्रेमवर्क
- असल दुनिया के कार्यान्वयन के लिए व्यावहारिक बातें
मुख्य बातें
- डाइवर्सिफिकेशन एक मुफ्त दोपहर का भोजन है - निवेश में एकमात्र मुफ्त चीज़
- अपनी जोखिम सहनशीलता के आधार पर ऑप्टिमाइज़ करें - अधिकतम शार्प हमेशा आपके लिए सबसे अच्छा नहीं होता
- व्यवस्थित रूप से रीबैलेंस करें लेकिन ओवरट्रेड न करें
- विनम्र बने रहें - मॉडल टूल्स हैं, क्रिस्टल बॉल नहीं
- सरलता से शुरू करें और जैसे-जैसे सीखें, जटिलता जोड़ें
याद रखें: क्रिप्टो में, बेहतरीन गणितीय मॉडल भी यह भविष्यवाणी नहीं कर सकते कि एलन डॉगकॉइन के बारे में कब ट्वीट करेंगे या अगला एक्सचेंज कब हैक होगा। पोर्टफोलियो थ्योरी को अपनी नींव के रूप में इस्तेमाल करें, लेकिन हमेशा कुछ बारूद सूखा रखें और कभी भी उतना निवेश न करें जितना आप गंवाने का जोखिम नहीं उठा सकते।
अब जाइए और जिम्मेदारी से ऑप्टिमाइज़ कीजिए! 🚀
आगे पढ़ें
कोड रिपॉज़िटरी
इस ट्यूटोरियल का पूरा कोड GitHub पर उपलब्ध है: https://github.com/suenot/markowitz
हैप्पी ऑप्टिमाइज़िंग! 📈
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.