assetai / app.py
aiqtech's picture
Update app.py
6d2d53b verified
raw
history blame
4.08 kB
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
def plot_cum_returns(data, title, initial_capital=1000):
# ์ผ์ผ ๋ˆ„์  ์ˆ˜์ต๋ฅ  ๊ณ„์‚ฐ ๋ฐ ์‹œ๊ฐํ™”
daily_cum_returns = (1 + data.dropna().pct_change()).cumprod() * initial_capital
fig = px.line(daily_cum_returns, title=title)
return fig
def plot_efficient_frontier_and_max_sharpe(mu, S):
# ์ตœ๋Œ€ ์ƒคํ”„ ๋น„์œจ๋กœ ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์ ํ™” ๋ฐ ํšจ์œจ์  ํˆฌ์ž์„  ๊ทธ๋ฆฌ๊ธฐ
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)
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")
ax.legend()
return fig
def plot_weights(weights):
# ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์  ํˆฌ์ž ๋น„์œจ ๊ทธ๋ž˜ํ”„ ์ถœ๋ ฅ
labels = weights.keys()
sizes = weights.values()
fig, ax = plt.subplots()
ax.pie(sizes, labels=labels, autopct='%1.1f%%')
ax.axis('equal')
return fig
def output_results(start_date, end_date, tickers_string):
tickers = tickers_string.split(',')
stocks_df = yf.download(tickers, start=start_date, end=end_date)['Adj Close']
fig_indiv_prices = px.line(stocks_df, title='๊ฐœ๋ณ„ ์ฃผ์‹ ๊ฐ€๊ฒฉ')
fig_cum_returns = plot_cum_returns(stocks_df, '๊ฐœ๋ณ„ ์ฃผ์‹์˜ ๋ˆ„์  ์ˆ˜์ต๋ฅ  ($1,000 ์‹œ์ž‘)')
corr_df = stocks_df.corr().round(2)
fig_corr = px.imshow(corr_df, text_auto=True, title='์ฃผ์‹ ๊ฐ„ ์ƒ๊ด€ ๊ด€๊ณ„')
mu = expected_returns.mean_historical_return(stocks_df)
S = risk_models.sample_cov(stocks_df)
ef = EfficientFrontier(mu, S)
weights = ef.max_sharpe(risk_free_rate=0.02)
cleaned_weights = ef.clean_weights()
fig_weights = plot_weights(cleaned_weights)
expected_annual_return, annual_volatility, sharpe_ratio = ef.portfolio_performance()
fig_efficient_frontier = plot_efficient_frontier_and_max_sharpe(mu, S)
return fig_cum_returns, fig_efficient_frontier, fig_corr, fig_indiv_prices, fig_weights, \
f"{expected_annual_return*100:.2f}%", f"{annual_volatility*100:.2f}%", f"{sharpe_ratio:.2f}"
css = """
footer {
visibility: hidden;
}
"""
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ๊ตฌ์„ฑ
with gr.Blocks(css=css) as app:
gr.Markdown("<h1>๊ธ€๋กœ๋ฒŒ ์ž์‚ฐ(์ฃผ์‹,์ง€์ˆ˜,BTC,์ƒํ’ˆ ๋“ฑ) ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์ ํ™” ๋„๊ตฌ</h1>")
with gr.Row():
start_date = gr.Textbox("2013-01-01", label="์‹œ์ž‘ ์ผ์ž")
end_date = gr.Textbox(datetime.now().date(), label="์ข…๋ฃŒ ์ผ์ž")
tickers_string = gr.Textbox("NVDA,^GSPC,GC=F,MSFT,BTC-USD", label="์ฃผ์‹ ํ‹ฐ์ปค๋ฅผ ์‰ผํ‘œ๋กœ ๊ตฌ๋ถ„ํ•˜์—ฌ ์ž…๋ ฅํ•˜์„ธ์š”")
btn = gr.Button("ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์ ํ™” ๊ฒฐ๊ณผ ๋ณด๊ธฐ")
with gr.Row():
expected_annual_return = gr.Text(label="์˜ˆ์ƒ ์—ฐ๊ฐ„ ์ˆ˜์ต๋ฅ ")
annual_volatility = gr.Text(label="์—ฐ๊ฐ„ ๋ณ€๋™์„ฑ")
sharpe_ratio = gr.Text(label="์ƒคํ”„ ๋น„์œจ")
with gr.Column():
fig_cum_returns = gr.Plot(label="์ตœ์ ํ™”๋œ ํฌํŠธํด๋ฆฌ์˜ค์˜ ๋ˆ„์  ์ˆ˜์ต๋ฅ  (์‹œ์ž‘ ๊ฐ€๊ฒฉ $1,000)")
fig_efficient_frontier = gr.Plot(label="ํšจ์œจ์  ํˆฌ์ž์„ ")
fig_corr = gr.Plot(label="์ฃผ์‹ ๊ฐ„ ์ƒ๊ด€ ๊ด€๊ณ„")
fig_indiv_prices = gr.Plot(label="๊ฐœ๋ณ„ ์ฃผ์‹ ๊ฐ€๊ฒฉ")
fig_weights = gr.Plot(label="ํฌํŠธํด๋ฆฌ์˜ค ์ตœ์  ํˆฌ์ž ๋น„์œจ")
btn.click(fn=output_results, inputs=[start_date, end_date, tickers_string],
outputs=[fig_cum_returns, fig_efficient_frontier, fig_corr, fig_indiv_prices, fig_weights, expected_annual_return, annual_volatility, sharpe_ratio])
app.launch()