Spaces:
Sleeping
Sleeping
| 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) |