Create app.py
Browse files
app.py
ADDED
@@ -0,0 +1,88 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import gradio as gr
|
2 |
+
import yfinance as yf
|
3 |
+
from pypfopt.discrete_allocation import DiscreteAllocation, get_latest_prices
|
4 |
+
from pypfopt import EfficientFrontier
|
5 |
+
from pypfopt import risk_models
|
6 |
+
from pypfopt import expected_returns
|
7 |
+
from pypfopt import plotting
|
8 |
+
import copy
|
9 |
+
import numpy as np
|
10 |
+
import pandas as pd
|
11 |
+
import plotly.express as px
|
12 |
+
import matplotlib.pyplot as plt
|
13 |
+
from datetime import datetime
|
14 |
+
|
15 |
+
def plot_cum_returns(data, title):
|
16 |
+
# ์ผ์ผ ๋์ ์์ต๋ฅ ๊ณ์ฐ ๋ฐ ์๊ฐํ
|
17 |
+
daily_cum_returns = 1 + data.dropna().pct_change()
|
18 |
+
daily_cum_returns = daily_cum_returns.cumprod() * 100
|
19 |
+
fig = px.line(daily_cum_returns, title=title)
|
20 |
+
return fig
|
21 |
+
|
22 |
+
def plot_efficient_frontier_and_max_sharpe(mu, S):
|
23 |
+
# ์ต๋ ์คํ ๋น์จ๋ก ํฌํธํด๋ฆฌ์ค ์ต์ ํ ๋ฐ ํจ์จ์ ํฌ์์ ๊ทธ๋ฆฌ๊ธฐ
|
24 |
+
ef = EfficientFrontier(mu, S)
|
25 |
+
fig, ax = plt.subplots(figsize=(6, 4))
|
26 |
+
ef_max_sharpe = copy.deepcopy(ef)
|
27 |
+
plotting.plot_efficient_frontier(ef, ax=ax, show_assets=False)
|
28 |
+
# ์ต๋ ์คํ ๋น์จ ํฌํธํด๋ฆฌ์ค ์ฐพ๊ธฐ
|
29 |
+
ef_max_sharpe.max_sharpe(risk_free_rate=0.02)
|
30 |
+
ret_tangent, std_tangent, _ = ef_max_sharpe.portfolio_performance()
|
31 |
+
ax.scatter(std_tangent, ret_tangent, marker="*", s=100, c="r", label="์ต๋ ์คํ")
|
32 |
+
ax.legend()
|
33 |
+
return fig
|
34 |
+
|
35 |
+
def output_results(start_date, end_date, tickers_string):
|
36 |
+
# ์
๋ ฅ๋ฐ์ ๋ฐ์ดํฐ๋ฅผ ๋ฐํ์ผ๋ก ์ต์ ํ ๊ฒฐ๊ณผ ์ถ๋ ฅ
|
37 |
+
tickers = tickers_string.split(',')
|
38 |
+
|
39 |
+
# ์ฃผ์ ๊ฐ๊ฒฉ ๋ฐ์ดํฐ ๊ฐ์ ธ์ค๊ธฐ
|
40 |
+
stocks_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
|
41 |
+
|
42 |
+
# ๊ฐ๋ณ ์ฃผ์ ๊ฐ๊ฒฉ ์๊ฐํ
|
43 |
+
fig_indiv_prices = px.line(stocks_df, title='๊ฐ๋ณ ์ฃผ์ ๊ฐ๊ฒฉ')
|
44 |
+
|
45 |
+
# ๊ฐ๋ณ ์ฃผ์ ๋์ ์์ต๋ฅ ์๊ฐํ
|
46 |
+
fig_cum_returns = plot_cum_returns(stocks_df, '๊ฐ๋ณ ์ฃผ์์ ๋์ ์์ต๋ฅ ($100 ์์)')
|
47 |
+
|
48 |
+
# ์ฃผ์ ๊ฐ ์๊ด ๊ด๊ณ ๊ณ์ฐ ๋ฐ ์๊ฐํ
|
49 |
+
corr_df = stocks_df.corr().round(2)
|
50 |
+
fig_corr = px.imshow(corr_df, text_auto=True, title='์ฃผ์ ๊ฐ ์๊ด ๊ด๊ณ')
|
51 |
+
|
52 |
+
# ํฌํธํด๋ฆฌ์ค ์ต์ ํ๋ฅผ ์ํ ๊ธฐ๋ ์์ต๋ฅ ๊ณผ ์ํ ๊ณต๋ถ์ฐ ํ๋ ฌ ๊ณ์ฐ
|
53 |
+
mu = expected_returns.mean_historical_return(stocks_df)
|
54 |
+
S = risk_models.sample_cov(stocks_df)
|
55 |
+
|
56 |
+
# ํจ์จ์ ํฌ์์ ์๊ฐํ
|
57 |
+
fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
|
58 |
+
|
59 |
+
return fig_cum_returns, fig_efficient_frontier, fig_corr, fig_indiv_prices
|
60 |
+
|
61 |
+
# Gradio ์ธํฐํ์ด์ค ๊ตฌ์ฑ
|
62 |
+
with gr.Blocks() as app:
|
63 |
+
with gr.Row():
|
64 |
+
gr.HTML("<h1>๊ธ๋ก๋ฒ ์ฃผ์ ํฌํธํด๋ฆฌ์ค ์ต์ ํ ๋๊ตฌ</h1>")
|
65 |
+
|
66 |
+
with gr.Row():
|
67 |
+
start_date = gr.Textbox("2013-01-01", label="์์ ์ผ์")
|
68 |
+
end_date = gr.Textbox(datetime.now().date(), label="์ข
๋ฃ ์ผ์")
|
69 |
+
|
70 |
+
with gr.Row():
|
71 |
+
tickers_string = gr.Textbox("TSLA,META,AMZN,MSFT,BTC-USD", label="ํฌํธํด๋ฆฌ์ค์ ํฌํจ๋ ์ฃผ์ ํฐ์ปค๋ฅผ ์ผํ๋ก ๊ตฌ๋ถํ์ฌ ์
๋ ฅํ์ธ์ (์: 'TSLA,META,AMZN,MSFT,BTC-USD')")
|
72 |
+
btn = gr.Button("ํฌํธํด๋ฆฌ์ค ์ต์ ํ ๊ฒฐ๊ณผ ๋ณด๊ธฐ")
|
73 |
+
|
74 |
+
with gr.Row():
|
75 |
+
expected_annual_return = gr.Text(label="์์ ์ฐ๊ฐ ์์ต๋ฅ ")
|
76 |
+
annual_volatility = gr.Text(label="์ฐ๊ฐ ๋ณ๋์ฑ")
|
77 |
+
sharpe_ratio = gr.Text(label="์คํ ๋น์จ")
|
78 |
+
|
79 |
+
with gr.Row():
|
80 |
+
fig_cum_returns = gr.Plot(label="์ต์ ํ๋ ํฌํธํด๋ฆฌ์ค์ ๋์ ์์ต๋ฅ (์์ ๊ฐ๊ฒฉ $100)")
|
81 |
+
fig_efficient_frontier = gr.Plot(label="ํจ์จ์ ํฌ์์ ")
|
82 |
+
fig_corr = gr.Plot(label="์ฃผ์ ๊ฐ ์๊ด ๊ด๊ณ")
|
83 |
+
fig_indiv_prices = gr.Plot(label="๊ฐ๋ณ ์ฃผ์ ๊ฐ๊ฒฉ")
|
84 |
+
|
85 |
+
btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string],
|
86 |
+
outputs=[fig_cum_returns, fig_efficient_frontier, fig_corr, fig_indiv_prices])
|
87 |
+
|
88 |
+
app.launch()
|