Spaces:
Runtime error
Runtime error
| import gradio as gr | |
| import yfinance as yf | |
| from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices | |
| from pypfopt import EfficientFrontier | |
| from pypfopt import risk_models | |
| from pypfopt import expected_returns | |
| from pypfopt import plotting | |
| import copy | |
| import numpy as np | |
| import pandas as pd | |
| import plotly.express as px | |
| import matplotlib.pyplot as plt | |
| from datetime import datetime | |
| import datetime | |
| def plot_cum_returns(data, title): | |
| daily_cum_returns = 1 + data.dropna().pct_change() | |
| daily_cum_returns = daily_cum_returns.cumprod()*100 | |
| fig = px.line(daily_cum_returns, title=title) | |
| return fig | |
| def plot_efficient_frontier_and_max_sharpe(mu, S): | |
| # Optimize portfolio for max Sharpe ratio and plot it out with efficient frontier curve | |
| ef = EfficientFrontier(mu, S) | |
| fig, ax = plt.subplots(figsize=(6,4)) | |
| ef_max_sharpe = copy.deepcopy(ef) | |
| plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False) | |
| # Find the max sharpe portfolio | |
| ef_max_sharpe.max_sharpe(risk_free_rate=0.02) | |
| ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance() | |
| ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="Max Sharpe") | |
| # Generate random portfolios with random weights | |
| n_samples = 1000 | |
| w = np.random.dirichlet(np.ones(ef.n_assets), n_samples) | |
| rets = w.dot(ef.expected_returns) | |
| stds = np.sqrt(np.diag(w @ ef.cov_matrix @ w.T)) | |
| sharpes = rets / stds | |
| ax.scatter(stds, rets, marker=".", c=sharpes, cmap="viridis_r") | |
| # Output | |
| ax.legend() | |
| return fig | |
| def output_results(start_date, end_date, tickers_string): | |
| tickers = tickers_string.split(',') | |
| # Get Stock Prices | |
| stocks_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close'] | |
| # Plot Individual Stock Prices | |
| fig_indiv_prices = px.line(stocks_df, title='Giá cổ phiếu riêng lẻ') | |
| # Plot Individual Cumulative Returns | |
| fig_cum_returns = plot_cum_returns(stocks_df, 'Lợi nhuận tích lũy của từng cổ phiếu bắt đầu từ 100 USD') | |
| # Calculatge and Plot Correlation Matrix between Stocks | |
| corr_df = stocks_df.corr().round(2) | |
| fig_corr = px.imshow(corr_df, text_auto=True, title = 'Tương quan giữa các cổ phiếu') | |
| # Calculate expected returns and sample covariance matrix for portfolio optimization later | |
| mu = expected_returns.mean_historical_return(stocks_df) | |
| S = risk_models.sample_cov(stocks_df) | |
| # Plot efficient frontier curve | |
| fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S) | |
| # Get optimized weights | |
| ef = EfficientFrontier(mu, S) | |
| ef.max_sharpe(risk_free_rate=0.04) | |
| weights = ef.clean_weights() | |
| expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance() | |
| expected_annual_return, annual_volatility, sharpe_ratio = '{}%'.format((expected_annual_return*100).round(2)), \ | |
| '{}%'.format((annual_volatility*100).round(2)), \ | |
| '{}%'.format((sharpe_ratio*100).round(2)) | |
| weights_df = pd.DataFrame.from_dict(weights, orient = 'index') | |
| weights_df = weights_df.reset_index() | |
| weights_df.columns = ['Mã chứng khoán', 'Trọng số'] | |
| # Calculate returns of portfolio with optimized weights | |
| stocks_df['Danh mục đầu tư được tối ưu hóa'] = 0 | |
| for ticker, weight in weights.items(): | |
| stocks_df['Danh mục đầu tư được tối ưu hóa'] += stocks_df[ticker]*weight | |
| # Plot Cumulative Returns of Optimized Portfolio | |
| fig_cum_returns_optimized = plot_cum_returns(stocks_df['Danh mục đầu tư được tối ưu hóa'], 'Lợi nhuận tích lũy của từng cổ phiếu bắt đầu từ 100 USD') | |
| return fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \ | |
| expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns | |
| with gr.Blocks(theme=gr.themes.Soft()) as app: | |
| with gr.Row(): | |
| gr.HTML("<h1>Trình tối ưu hóa danh mục đầu tư chứng khoán</h1>") | |
| with gr.Row(): | |
| start_date = gr.Textbox("2013-01-01", label="Ngày bắt đầu") | |
| end_date = gr.Textbox(datetime.datetime.now().date(), label="Ngày kết thúc") | |
| with gr.Row(): | |
| tickers_string = gr.Textbox("MA,V,JPM,BA", | |
| label='Nhập tất cả các mã cổ phiếu sẽ được đưa vào danh mục đầu tư tách biệt \ | |
| bằng dấu phẩy KHÔNG có dấu cách, ví dụ: "MA,V,JPM,BA"') | |
| btn = gr.Button("Tối ưu hóa danh mục đầu tư") | |
| with gr.Row(): | |
| gr.HTML("<h3>Số liệu danh mục đầu tư được tối ưu hóa</h3>") | |
| with gr.Row(): | |
| expected_annual_return = gr.Text(label="Lợi nhuận dự kiến hàng năm") | |
| annual_volatility = gr.Text(label="Biến động hàng năm") | |
| sharpe_ratio = gr.Text(label="Tỷ lệ Sharpe") | |
| with gr.Row(): | |
| fig_cum_returns_optimized = gr.Plot(label="Lợi nhuận tích lũy của danh mục đầu tư được tối ưu hóa (Giá khởi điểm là 100 USD)") | |
| weights_df = gr.DataFrame(label="Trọng số được tối ưu hóa của mỗi mã") | |
| with gr.Row(): | |
| fig_efficient_frontier = gr.Plot(label="Biên giới hiệu quả") | |
| fig_corr = gr.Plot(label="Tương quan giữa các cổ phiếu") | |
| with gr.Row(): | |
| fig_indiv_prices = gr.Plot(label="Giá cổ phiếu riêng lẻ") | |
| fig_cum_returns = gr.Plot(label="Lợi nhuận tích lũy của từng cổ phiếu bắt đầu từ 100 USD") | |
| btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string], | |
| outputs=[fig_cum_returns_optimized, weights_df, fig_efficient_frontier, fig_corr, \ | |
| expected_annual_return, annual_volatility, sharpe_ratio, fig_indiv_prices, fig_cum_returns]) | |
| app.launch() |