Spaces:
Sleeping
Sleeping
File size: 6,208 Bytes
821b9f1 6d02cce 821b9f1 879b684 821b9f1 0063565 821b9f1 |
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 |
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() |