import gradio as gr import pandas as pd import numpy as np from datetime import datetime, timedelta import yfinance as yf from sklearn.preprocessing import MinMaxScaler from tensorflow.keras.models import Sequential from tensorflow.keras.layers import LSTM, Dense import plotly.graph_objects as go def fetch_ethereum_data(): """ Fetch historical Ethereum price data using yfinance. Returns DataFrame with datetime index and price information. The data is sampled hourly for the past week. """ eth_ticker = yf.Ticker("ETH-USD") # Get hourly data for the past week hist_data = eth_ticker.history(period="7d", interval="1h") # Keep the datetime index and Close price return hist_data[['Close']] def prepare_data(data, sequence_length=24): """ Prepare data for LSTM model by creating sequences and scaling. Args: data: DataFrame with price data and datetime index sequence_length: Number of time steps to use for prediction (default: 24 hours) """ # Scale the data scaler = MinMaxScaler() scaled_data = scaler.fit_transform(data['Close'].values.reshape(-1, 1)) # Create sequences for training X, y = [], [] for i in range(sequence_length, len(scaled_data)): X.append(scaled_data[i-sequence_length:i, 0]) y.append(scaled_data[i, 0]) X = np.array(X) y = np.array(y) # Reshape X for LSTM input X = X.reshape(X.shape[0], X.shape[1], 1) return X, y, scaler def create_model(sequence_length): """ Create and compile LSTM model for time series prediction. Uses a two-layer LSTM architecture followed by dense layers. """ model = Sequential([ LSTM(50, return_sequences=True, input_shape=(sequence_length, 1)), LSTM(50, return_sequences=False), Dense(25), Dense(1) ]) model.compile(optimizer='adam', loss='mse') return model def predict_future_prices(model, last_sequence, scaler, days=7): """ Predict future prices using the trained model. Args: model: Trained LSTM model last_sequence: Last sequence of known prices scaler: Fitted MinMaxScaler days: Number of days to predict (default: 7) """ future_predictions = [] current_sequence = last_sequence.copy() # Convert days to hours since we're using hourly data hours = days * 24 for _ in range(hours): # Predict next price scaled_prediction = model.predict(current_sequence.reshape(1, -1, 1), verbose=0) # Inverse transform to get actual price prediction = scaler.inverse_transform(scaled_prediction)[0][0] future_predictions.append(prediction) # Update sequence for next prediction current_sequence = np.roll(current_sequence, -1) current_sequence[-1] = scaled_prediction return future_predictions def create_prediction_plot(historical_data, future_predictions, future_dates): """ Create an interactive plot showing the last week of historical prices and week-ahead predictions with hourly granularity. Args: historical_data: DataFrame with historical price data and datetime index future_predictions: List of predicted prices future_dates: List of future datetime indices for predictions """ fig = go.Figure() # Plot historical data using the datetime index fig.add_trace(go.Scatter( x=historical_data.index, y=historical_data['Close'], name='Historical Prices', line=dict(color='blue') )) # Plot predictions fig.add_trace(go.Scatter( x=future_dates, y=future_predictions, name='Predictions', line=dict(color='red', dash='dash') )) fig.update_layout( title='Ethereum Price Prediction (Hourly)', xaxis_title='Date', yaxis_title='Price (USD)', hovermode='x unified' ) return fig def predict_ethereum(): """ Main function for Gradio interface that orchestrates the prediction process. Handles hourly data and generates predictions for the next week. """ # Fetch and prepare data data = fetch_ethereum_data() sequence_length = 24 # Use 24 hours of data for prediction X, y, scaler = prepare_data(data, sequence_length) # Create and train model model = create_model(sequence_length) model.fit(X, y, epochs=50, batch_size=32, verbose=0) # Prepare last sequence for prediction last_sequence = scaler.transform(data['Close'].values[-sequence_length:].reshape(-1, 1)) # Generate future predictions future_predictions = predict_future_prices(model, last_sequence, scaler) # Create future dates (hourly intervals) last_date = data.index[-1] future_dates = [last_date + timedelta(hours=i+1) for i in range(len(future_predictions))] # Create and return plot fig = create_prediction_plot(data, future_predictions, future_dates) return fig # Create Gradio interface iface = gr.Interface( fn=predict_ethereum, inputs=None, outputs=gr.Plot(), title="Ethereum Price Prediction", description="Click to generate a 7-day price prediction for Ethereum based on hourly historical data.", theme=gr.themes.Base() ) if __name__ == "__main__": iface.launch()