Crypto-Task-8 / app.py
Surya152002's picture
Update app.py
879b684
import streamlit as st
import yfinance as yf
import pandas as pd
from sklearn.preprocessing import MinMaxScaler
from tensorflow.keras.models import load_model
import plotly.graph_objs as go
import numpy as np
import base64
# Function to make predictions using the LSTM model
def make_predictions(model, data, scaler, look_back, prediction_days):
predictions = []
scaled_data = scaler.transform(data[-look_back:].reshape(-1, 1))
scaled_data = scaled_data.reshape((1, look_back, 1))
for _ in range(prediction_days):
# Make the prediction
predicted_price = model.predict(scaled_data)
# Inverse transform to get the actual price
predicted_price = scaler.inverse_transform(predicted_price)
predictions.append(predicted_price.ravel()[0])
# Append prediction to scaled_data for making subsequent predictions
next_input = scaler.transform(predicted_price.reshape(-1, 1))
scaled_data = np.append(scaled_data[:, 1:, :], [next_input], axis=1)
return predictions
# Function to download prediction data as a CSV file
def get_table_download_link(df):
csv = df.to_csv(index=True)
b64 = base64.b64encode(csv.encode()).decode()
href = f'<a href="data:file/csv;base64,{b64}" download="predictions.csv">Download CSV file</a>'
return href
# Streamlit app layout
st.title('Real-time Crypto Prediction with LSTM')
# User input parameters (no longer in the sidebar)
st.header('User Input Parameters')
ticker = st.selectbox('Select Ticker', ('BTC-USD', 'ETH-USD', 'LTC-USD'))
start_date = st.date_input('Start date', pd.to_datetime('2021-01-01'))
end_date = st.date_input('End date', pd.to_datetime('2023-11-01'))
look_back = st.number_input('Look Back Period',value=60)
prediction_days = st.slider('Days to Predict', 1, 30, 3)
# Load pre-trained LSTM model and scaler
with st.spinner('Loading model and scaler...'):
model = load_model('./best_model.h5') # make sure to use the correct path to your model
scaler = MinMaxScaler(feature_range=(0, 1)) # Assuming the scaler was fitted to the training data
# Fetch historical data from yfinance
with st.spinner(f'Downloading {ticker} data...'):
data = yf.download(ticker, start=start_date, end=end_date)
st.success('Downloaded data successfully!')
# Prepare data for prediction
data_close = data['Close'].values.reshape(-1, 1)
scaler.fit(data_close)
# Make real-time prediction
if len(data_close) >= look_back:
with st.spinner('Making predictions...'):
predictions = make_predictions(model, data_close, scaler, look_back, prediction_days)
# Convert predictions to a list of Python floats
predictions_list = [float(pred) for pred in predictions]
st.success('Predictions made successfully!')
# Plot the results using Plotly
fig = go.Figure()
fig.add_trace(go.Scatter(x=data.index, y=data['Close'], mode='lines+markers', name='Close Price'))
# Generate prediction dates without using the 'closed' parameter
last_date = data.index[-1]
prediction_dates = pd.date_range(start=last_date, periods=prediction_days+1)[1:]
# The [1:] slice is used to exclude the starting date and effectively achieve 'closed=right'
# Add predicted prices to the plot
fig.add_trace(go.Scatter(x=prediction_dates, y=predictions_list, mode='lines+markers', name='Predicted Price', marker=dict(color='red')))
fig.update_layout(title='Cryptocurrency Price Prediction', xaxis_title='Date', yaxis_title='Price', legend_title='Legend')
st.plotly_chart(fig, use_container_width=True)
# Display download link for predictions with actual prices included
prediction_df = pd.DataFrame(index=prediction_dates)
prediction_df['Predicted Price'] = predictions_list
prediction_df['Actual Price'] = data['Close'][-prediction_days:].values
st.markdown(get_table_download_link(prediction_df), unsafe_allow_html=True)
# Display the last prediction
st.write(f'Last Predicted Closing Price for {ticker}: ${predictions_list[-1]:.2f}')
# Simulate investment results based on predictions
# Simulate investment results based on the last prediction
initial_account_balance = 1000000
account_balance_predicted = initial_account_balance
account_balance_actual = initial_account_balance
# Get the last actual closing price and the last predicted price
last_invest_price = data['Close'].iloc[-prediction_days-1] # Price at which we "buy"
last_sell_price_predicted = predictions_list[-1] # Predicted price at which we "sell"
last_sell_price_actual = data['Close'].iloc[-prediction_days] if prediction_days <= len(data['Close']) else last_sell_price_predicted
# Update account balances based on the last day's prediction and actual price
account_balance_predicted += (last_sell_price_predicted - last_invest_price) * (account_balance_predicted / last_invest_price)
account_balance_actual += (last_sell_price_actual - last_invest_price) * (account_balance_actual / last_invest_price)
# Assuming investing at the closing price and selling at the next day's predicted/actual price
for i in range(1, prediction_days + 1):
invest_price = data['Close'].iloc[-i-1] # Price at which we "buy"
sell_price_predicted = predictions_list[-i] # Predicted price at which we "sell"
sell_price_actual = data['Close'].iloc[-i] if i <= len(data['Close']) else sell_price_predicted
# Update account balances
account_balance_predicted += (sell_price_predicted - invest_price) * (account_balance_predicted / invest_price)
account_balance_actual += (sell_price_actual - invest_price) * (account_balance_actual / invest_price)
# Display simulated investment results
st.write(f"Initial Account Balance: ${initial_account_balance:,.2f}")
st.write(f"Account Balance based on Predictions: ${account_balance_predicted:,.2f}")
st.write(f"Account Balance based on Actual Prices: ${account_balance_actual:,.2f}")
else:
st.error('Not enough data to make a prediction.')
# Refresh the page to update the predictions
if st.button("Refresh Predictions"):
st.experimental_rerun()