File size: 6,922 Bytes
23c88d4
 
0d01ec2
ae75bb8
 
 
 
a8444e5
f05802f
ae75bb8
a7925b2
7185b69
ae75bb8
 
7185b69
696277a
baea38f
 
 
696277a
 
 
 
 
a7925b2
696277a
 
 
 
1238274
9c77d88
f05802f
baea38f
a7925b2
2af2718
 
baea38f
2af2718
 
 
baea38f
2af2718
 
45bf426
2af2718
45bf426
baea38f
a7925b2
45bf426
 
 
 
baea38f
ae75bb8
 
 
 
 
 
fd97ee3
ae75bb8
 
 
 
 
 
 
 
 
fd97ee3
ae75bb8
 
 
 
 
 
fd97ee3
 
 
 
 
 
 
 
 
 
cc4bd74
ae75bb8
a8444e5
 
 
 
ae75bb8
0880176
 
 
 
ae75bb8
0880176
 
 
 
ae75bb8
e266db4
a7925b2
2af2718
a8076e2
2af2718
 
ae75bb8
 
a8444e5
0880176
 
a7925b2
baea38f
ae75bb8
2af2718
e266db4
e64a138
 
4db4956
f05802f
 
 
e64a138
 
 
 
ae75bb8
 
a8444e5
0880176
 
e64a138
0d01ec2
 
f05802f
a8444e5
0d01ec2
a5272ad
e64a138
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import gradio as gr
import yfinance as yf
from prophet import Prophet
from sklearn.linear_model import LinearRegression, BayesianRidge
from sklearn.svm import SVR
from sklearn.preprocessing import MinMaxScaler
from statsmodels.tsa.arima.model import ARIMA
#from xgboost import XGBRegressor
import pandas as pd
import numpy as np
from datetime import datetime
import plotly.graph_objects as go
from tensorflow.keras.models import Sequential
from tensorflow.keras.layers import LSTM, Dense

def download_data(ticker, start_date='2010-01-01'):
    """
    ์ฃผ์‹ ๋ฐ์ดํ„ฐ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜๊ณ  ํฌ๋งท์„ ์กฐ์ •ํ•˜๋Š” ํ•จ์ˆ˜
    """
    data = yf.download(ticker, start=start_date)
    if data.empty:
        raise ValueError(f"No data returned for {ticker}")
    data.reset_index(inplace=True)
    if 'Adj Close' in data.columns:
        data = data[['Date', 'Adj Close']]
        data.rename(columns={'Date': 'ds', 'Adj Close': 'y'}, inplace=True)
    else:
        raise ValueError("Expected 'Adj Close' in columns")
    return data

def predict_future_prices(ticker, periods=1825):
    data = download_data(ticker)
    
    # Prophet ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
    model_prophet = Prophet(daily_seasonality=False, weekly_seasonality=False, yearly_seasonality=True)
    model_prophet.fit(data)
    
    # ๋ฏธ๋ž˜ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ ๋ฐ ์˜ˆ์ธก
    future = model_prophet.make_future_dataframe(periods=periods, freq='D')
    forecast_prophet = model_prophet.predict(future)
    
    # Linear Regression ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
    model_lr = LinearRegression()
    X = pd.Series(range(len(data))).values.reshape(-1, 1)
    y = data['y'].values
    model_lr.fit(X, y)
    
    # ๋ฏธ๋ž˜ ๋ฐ์ดํ„ฐ ํ”„๋ ˆ์ž„ ์ƒ์„ฑ ๋ฐ ์˜ˆ์ธก
    future_dates = pd.date_range(start=data['ds'].iloc[-1], periods=periods+1, freq='D')[1:].strftime('%Y-%m-%d')
    X_future = pd.Series(range(len(data), len(data) + len(future_dates))).values.reshape(-1, 1)
    future_lr = pd.DataFrame({'ds': future_dates, 'yhat': model_lr.predict(X_future)})
    
    
    # ARIMA ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
    model_arima = ARIMA(data['y'], order=(1, 1, 1))
    model_arima_fit = model_arima.fit()
    forecast_arima = model_arima_fit.forecast(steps=periods)
    future_arima = pd.DataFrame({'ds': future_dates, 'yhat': forecast_arima})
    

    # LSTM ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
    scaler = MinMaxScaler(feature_range=(0, 1))
    scaled_data = scaler.fit_transform(data['y'].values.reshape(-1, 1))
    X_train, y_train = [], []
    for i in range(60, len(scaled_data)):
        X_train.append(scaled_data[i-60:i, 0])
        y_train.append(scaled_data[i, 0])
    X_train, y_train = np.array(X_train), np.array(y_train)
    X_train = np.reshape(X_train, (X_train.shape[0], X_train.shape[1], 1))

    model_lstm = Sequential()
    model_lstm.add(LSTM(units=50, return_sequences=True, input_shape=(X_train.shape[1], 1)))
    model_lstm.add(LSTM(units=50))
    model_lstm.add(Dense(1))
    model_lstm.compile(loss='mean_squared_error', optimizer='adam')
    model_lstm.fit(X_train, y_train, epochs=10, batch_size=32)

    pred_lstm = []
    last_60_days = scaled_data[-60:]
    for i in range(periods):
        X_test = last_60_days.reshape(1, 60, 1)
        pred = model_lstm.predict(X_test)
        last_60_days = np.append(last_60_days[1:], pred)
        pred_lstm.append(pred[0, 0])

    pred_lstm = scaler.inverse_transform(np.array(pred_lstm).reshape(-1, 1))
    future_lstm = pd.DataFrame({'ds': future_dates[:len(pred_lstm)], 'yhat': pred_lstm.flatten()})
    
#  # XGBoost ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
#   model_xgb = XGBRegressor(n_estimators=100, learning_rate=0.1)
#   model_xgb.fit(X.reshape(-1, 1), y)
#   future_xgb = pd.DataFrame({'ds': future_dates, 'yhat': model_xgb.predict(X_future)})
    
#    # SVR ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
#   model_svr = SVR(kernel='rbf', C=1e3, gamma=0.1)
#   model_svr.fit(X.reshape(-1, 1), y)
#   future_svr = pd.DataFrame({'ds': future_dates, 'yhat': model_svr.predict(X_future)})
    
#    # Bayesian Regression ๋ชจ๋ธ ์ƒ์„ฑ ๋ฐ ํ•™์Šต
#   model_bayes = BayesianRidge()
#   model_bayes.fit(X.reshape(-1, 1), y)
#   future_bayes = pd.DataFrame({'ds': future_dates, 'yhat': model_bayes.predict(X_future)})
    

    # ์˜ˆ์ธก ๊ฒฐ๊ณผ ๊ทธ๋ž˜ํ”„ ์ƒ์„ฑ
    forecast_prophet['ds'] = forecast_prophet['ds'].dt.strftime('%Y-%m-%d')
    fig = go.Figure()
    fig.add_trace(go.Scatter(x=forecast_prophet['ds'], y=forecast_prophet['yhat'], mode='lines', name='Prophet Forecast (Blue)'))
    fig.add_trace(go.Scatter(x=future_lr['ds'], y=future_lr['yhat'], mode='lines', name='Linear Regression Forecast (Red)', line=dict(color='red')))
    fig.add_trace(go.Scatter(x=future_arima['ds'], y=future_arima['yhat'], mode='lines', name='ARIMA Forecast (Green)', line=dict(color='green')))
    fig.add_trace(go.Scatter(x=future_lstm['ds'], y=future_lstm['yhat'], mode='lines', name='LSTM Forecast (Orange)', line=dict(color='orange')))
#   fig.add_trace(go.Scatter(x=future_xgb['ds'], y=future_xgb['yhat'], mode='lines', name='XGBoost Forecast (Purple)', line=dict(color='purple')))
#   fig.add_trace(go.Scatter(x=future_svr['ds'], y=future_svr['yhat'], mode='lines', name='SVR Forecast (Brown)', line=dict(color='brown')))
#   fig.add_trace(go.Scatter(x=future_bayes['ds'], y=future_bayes['yhat'], mode='lines', name='Bayesian Regression Forecast (Pink)', line=dict(color='pink')))
    fig.add_trace(go.Scatter(x=data['ds'], y=data['y'], mode='lines', name='Actual (Black)', line=dict(color='black')))
    
    return fig, forecast_prophet[['ds', 'yhat', 'yhat_lower', 'yhat_upper']], future_lr[['ds', 'yhat']], future_arima[['ds', 'yhat']], future_lstm[['ds', 'yhat']], future_xgb[['ds', 'yhat']], future_svr[['ds', 'yhat']], future_bayes[['ds', 'yhat']]

    
# Gradio ์ธํ„ฐํŽ˜์ด์Šค ์„ค์ • ๋ฐ ์‹คํ–‰
with gr.Blocks() as app:
    with gr.Row():
        ticker_input = gr.Textbox(value="AAPL", label="Enter Stock Ticker for Forecast")
        periods_input = gr.Number(value=1825, label="Forecast Period (days)")
        forecast_button = gr.Button("Generate Forecast")
    
    forecast_chart = gr.Plot(label="Forecast Chart")
    forecast_data_prophet = gr.Dataframe(label="Prophet Forecast Data")
    forecast_data_lr = gr.Dataframe(label="Linear Regression Forecast Data")
    forecast_data_arima = gr.Dataframe(label="ARIMA Forecast Data")
    forecast_data_lstm = gr.Dataframe(label="LSTM Forecast Data")
#   forecast_data_xgb = gr.Dataframe(label="XGBoost Forecast Data")
#   forecast_data_svr = gr.Dataframe(label="SVR Forecast Data")
#   forecast_data_bayes = gr.Dataframe(label="Bayesian Regression Forecast Data")
    
    forecast_button.click(
        fn=predict_future_prices,
        inputs=[ticker_input, periods_input],
        outputs=[forecast_chart, forecast_data_prophet, forecast_data_lr, forecast_data_arima, forecast_data_lstm] #,forecast_data_xgb, forecast_data_svr, forecast_data_bayes]
    )

app.launch()