File size: 4,257 Bytes
edd7f40
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
import gradio as gr
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import joblib
from tensorflow import keras


try:
    scaler = joblib.load("scaler_minmax.joblib")
    lstm_loaded = keras.models.load_model("lstm_stock_model.keras")
    print("Loaded OK!")
except Exception as e:
    print(f"Load error: {e} — Check files in folder.")

WINDOW_SIZE = 60

def get_last_known(close_prices_list):
    mean_close = np.mean(close_prices_list)
    return {
        "High": mean_close * 1.05, "Low": mean_close * 0.95, "Open": mean_close,
        "Log_Volume": np.log(30000000 + 1)
    }

def predict_multi_days(csv_file, days_to_predict):
    try:
        if csv_file is None:
            fig, ax = plt.subplots(figsize=(10,5))
            ax.text(0.5, 0.5, 'Upload CSV with Close column', ha='center', va='center', transform=ax.transAxes, fontsize=14)
            ax.axis('off')
            return None, fig, pd.DataFrame({"Error": ["Upload CSV"]})

        df = pd.read_csv(csv_file)
        close_col = next((col for col in df.columns if 'close' in col.lower()), None)
        if close_col is None:
            raise ValueError("No 'Close' column found.")
        close_prices_series = df[close_col].dropna()
        close_prices_list = close_prices_series.tolist()
        close_prices = np.array(close_prices_list, dtype=float).reshape(-1, 1)

        if len(close_prices) < WINDOW_SIZE:
            raise ValueError(f"Need 60+ prices (got {len(close_prices)}).")

        last_60 = close_prices[-WINDOW_SIZE:]
        last_known = get_last_known(close_prices_list)
        other_features = np.tile(list(last_known.values()), (WINDOW_SIZE, 1))
        input_data = np.hstack([last_60, other_features])
        scaled_input = scaler.transform(input_data)
        window_3d = np.expand_dims(scaled_input, axis=0)

        predictions = []
        current_window = window_3d.copy()
        for _ in range(int(days_to_predict)):
            pred_scaled = lstm_loaded.predict(current_window, verbose=0)
            pred = scaler.inverse_transform(pred_scaled)
            next_close = float(pred[0, 0])
            predictions.append(next_close)
            new_row = np.append([next_close], list(last_known.values()))
            current_window = np.roll(current_window, -1, axis=1)
            current_window[0, -1, :] = new_row

        fig, ax = plt.subplots(figsize=(12,6))
        hist_x = range(1, WINDOW_SIZE + 1)
        fut_x = range(WINDOW_SIZE + 1, WINDOW_SIZE + len(predictions) + 1)
        ax.plot(hist_x, last_60, label="Last 60 Days", color='blue', lw=2)
        ax.plot(fut_x, predictions, label=f"Predicted {days_to_predict} Days", color='red', ls='--', lw=2, marker='o')
        ax.set_title(f"AAPL Close Prediction ({days_to_predict} Days)")
        ax.set_xlabel("Days")
        ax.set_ylabel("Close Price ($)")
        ax.legend()
        ax.grid(True, alpha=0.3)
        plt.tight_layout()

        pred_df = pd.DataFrame({
            "Day": [f"Day {i+1}" for i in range(len(predictions))],
            "Predicted Close": predictions
        })

        return predictions[0] if predictions else None, fig, pred_df

    except Exception as e:
        print(f"Error: {e}")
        fig, ax = plt.subplots(figsize=(10,5))
        ax.text(0.5, 0.5, f'Error: {str(e)}', ha='center', va='center', fontsize=14)
        ax.axis('off')
        plt.tight_layout()
        return None, fig, pd.DataFrame({"Error": [str(e)]})

with gr.Blocks(title="AAPL Multi-Day Predictor") as demo:
    gr.Markdown("# AAPL Multi-Day Stock Predictor")
    gr.Markdown("Upload CSV with 'Close' column, choose days—get plot + predictions.")

    with gr.Row():
        csv_input = gr.File(label="Upload CSV", file_types=[".csv"])
        days_slider = gr.Slider(1, 90, value=30, step=1, label="Days to Predict")

    submit_btn = gr.Button("Predict", variant="primary")

    with gr.Row():
        pred_num = gr.Number(label="First Day Prediction")

    plot_out = gr.Plot(label="Historical + Future")
    table_out = gr.Dataframe(label="Predictions")

    submit_btn.click(
        fn=predict_multi_days,
        inputs=[csv_input, days_slider],
        outputs=[pred_num, plot_out, table_out]
    )

demo.launch(share=True, quiet=True)