Last active
November 26, 2024 02:32
-
-
Save architectureman/fd60160f77c4b20543f11df5382e1853 to your computer and use it in GitHub Desktop.
Draft Portfolio Optimize Basic
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import yfinance as yf | |
| import pandas as pd | |
| import numpy as np | |
| from pypfopt import EfficientFrontier | |
| from pypfopt import risk_models | |
| from pypfopt import expected_returns | |
| from datetime import datetime, timedelta | |
| # Định nghĩa danh sách cổ phiếu | |
| tickers = ['AAPL', 'GOOGL', 'MSFT', 'AMZN', 'META', 'TSLA', 'NVDA', 'JPM'] | |
| # Lấy dữ liệu giá từ Yahoo Finance | |
| end_date = datetime.now() | |
| start_date = end_date - timedelta(days=365) | |
| df = pd.DataFrame() | |
| for ticker in tickers: | |
| data = yf.download(ticker, start=start_date, end=end_date)['Adj Close'] | |
| df[ticker] = data | |
| # Tính toán returns | |
| # returns = df.pct_change() | |
| # 1. Portfolio với phân bổ đều | |
| equal_weights = np.array([1/len(tickers)] * len(tickers)) | |
| # Tính các metrics cho portfolio phân bổ đều trước khi optimize | |
| mu = expected_returns.mean_historical_return(df) | |
| S = risk_models.sample_cov(df) | |
| equal_ret = mu.dot(equal_weights) | |
| equal_std = np.sqrt(equal_weights.T.dot(S).dot(equal_weights)) | |
| equal_sharpe = equal_ret / equal_std | |
| print("\nPortfolio phân bổ đều trước khi optimize:") | |
| print(f"Expected Return: {equal_ret:.4f}") | |
| print(f"Standard Deviation: {equal_std:.4f}") | |
| print(f"Sharpe Ratio: {equal_sharpe:.4f}") | |
| # Optimize portfolio phân bổ đều | |
| ef_equal = EfficientFrontier(mu, S) | |
| ef_equal.add_constraint(lambda x: x >= 0.1) # Mỗi cổ phiếu ít nhất 10% | |
| ef_equal.add_constraint(lambda x: x <= 0.2) # Mỗi cổ phiếu không quá 20% | |
| equal_weights_opt = ef_equal.max_sharpe() | |
| equal_ret_opt = mu.dot(pd.Series(equal_weights_opt)) | |
| equal_std_opt = np.sqrt(pd.Series(equal_weights_opt).T.dot(S).dot(pd.Series(equal_weights_opt))) | |
| equal_sharpe_opt = equal_ret_opt / equal_std_opt | |
| print("\nPortfolio phân bổ đều sau khi optimize:") | |
| print(f"Expected Return: {equal_ret_opt:.4f}") | |
| print(f"Standard Deviation: {equal_std_opt:.4f}") | |
| print(f"Sharpe Ratio: {equal_sharpe_opt:.4f}") | |
| # 2. Portfolio với phân bổ không đều | |
| unequal_weights = np.array([0.25, 0.15, 0.15, 0.1, 0.1, 0.1, 0.1, 0.05]) | |
| # Tính các metrics cho portfolio phân bổ không đều trước khi optimize | |
| unequal_ret = mu.dot(unequal_weights) | |
| unequal_std = np.sqrt(unequal_weights.T.dot(S).dot(unequal_weights)) | |
| unequal_sharpe = unequal_ret / unequal_std | |
| print("\nPortfolio phân bổ không đều trước khi optimize:") | |
| print(f"Expected Return: {unequal_ret:.4f}") | |
| print(f"Standard Deviation: {unequal_std:.4f}") | |
| print(f"Sharpe Ratio: {unequal_sharpe:.4f}") | |
| # Optimize portfolio phân bổ không đều | |
| ef_unequal = EfficientFrontier(mu, S) | |
| ef_unequal.add_constraint(lambda x: x >= 0.05) # Mỗi cổ phiếu ít nhất 5% | |
| ef_unequal.add_constraint(lambda x: x <= 0.3) # Mỗi cổ phiếu không quá 30% | |
| unequal_weights_opt = ef_unequal.max_sharpe() | |
| unequal_ret_opt = mu.dot(pd.Series(unequal_weights_opt)) | |
| unequal_std_opt = np.sqrt(pd.Series(unequal_weights_opt).T.dot(S).dot(pd.Series(unequal_weights_opt))) | |
| unequal_sharpe_opt = unequal_ret_opt / unequal_std_opt | |
| print("\nPortfolio phân bổ không đều sau khi optimize:") | |
| print(f"Expected Return: {unequal_ret_opt:.4f}") | |
| print(f"Standard Deviation: {unequal_std_opt:.4f}") | |
| print(f"Sharpe Ratio: {unequal_sharpe_opt:.4f}") | |
| # In ra phân bổ tối ưu cho cả hai portfolio | |
| print("\nPhân bổ tối ưu cho portfolio đều:") | |
| for ticker, weight in zip(tickers, equal_weights_opt.values()): | |
| print(f"{ticker}: {weight:.4f}") | |
| print("\nPhân bổ tối ưu cho portfolio không đều:") | |
| for ticker, weight in zip(tickers, unequal_weights_opt.values()): | |
| print(f"{ticker}: {weight:.4f}") |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment