File size: 4,296 Bytes
b7d2c24
 
 
2162ce8
a3a681d
f901f42
b7d2c24
 
 
 
 
 
 
a3a681d
b7d2c24
a3a681d
 
 
b7d2c24
 
 
 
 
f901f42
b7d2c24
a3a681d
b7d2c24
 
 
 
 
 
a3a681d
b7d2c24
 
3abebba
2162ce8
b7d2c24
 
08d18c6
 
e403d05
 
 
 
 
 
 
 
08d18c6
3abebba
e403d05
3abebba
e403d05
3abebba
 
 
08d18c6
 
a3a681d
3abebba
 
 
 
 
 
 
 
 
b7d2c24
3abebba
08d18c6
b7d2c24
08d18c6
 
 
b7d2c24
08d18c6
 
e403d05
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
08d18c6
 
 
2162ce8
 
 
 
 
 
 
 
 
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
import streamlit as st
from datetime import date
import yfinance as yf
import pandas as pd  # Importing pandas to avoid NameError
from prophet import Prophet
from prophet.plot import plot_plotly
from plotly import graph_objs as go

# Constants for date range
START = "2015-01-01"
TODAY = date.today().strftime("%Y-%m-%d")

# Streamlit app title
st.title('Stock & Cryptocurrency Forecast App')

# Stock and cryptocurrency selection
assets = ('GOOG', 'AAPL', 'MSFT', 'GME', 'BTC-USD', 'ETH-USD')  # Added BTC and ETH
selected_asset = st.selectbox('Select dataset for prediction', assets)

# Years of prediction slider
n_years = st.slider('Years of prediction:', 1, 4)
period = n_years * 365

@st.cache_data
def load_data(ticker):
    """Load stock or cryptocurrency data from Yahoo Finance."""
    data = yf.download(ticker, START, TODAY)
    data.reset_index(inplace=True)
    return data

# Load data and show loading state
data_load_state = st.text('Loading data...')
data = load_data(selected_asset)
data_load_state.text('Loading data... done!')

# Display raw data for debugging purposes
st.subheader('Raw Data')
st.write(data.tail())

# Check if 'Close' column exists before converting
if 'Close' in data.columns:
    # Check data types of the DataFrame
    st.write("Data Types:")
    st.write(data.dtypes)

    # Display unique values in the 'Close' column for debugging
    st.write("Unique values in 'Close' column:")
    st.write(data['Close'].unique())

    # Ensure 'Close' prices are numeric and handle any missing values
    try:
        # Convert to numeric with coercion for invalid parsing
        data['Close'] = pd.to_numeric(data['Close'], errors='coerce')
        # Drop rows with NaN values in 'Close'
        data.dropna(subset=['Close'], inplace=True)
    except Exception as e:
        st.error(f"Error converting 'Close' prices to numeric: {e}")
else:
    st.error("The 'Close' column is missing from the data. Please check the selected asset.")

# Check if there is valid data after processing
if not data.empty and 'Close' in data.columns:
    # Plot raw data function
    def plot_raw_data():
        fig = go.Figure()
        fig.add_trace(go.Scatter(x=data['Date'], y=data['Open'], name="Open Price", line=dict(color='blue')))
        fig.add_trace(go.Scatter(x=data['Date'], y=data['Close'], name="Close Price", line=dict(color='orange')))
        fig.layout.update(title_text='Time Series Data with Rangeslider', xaxis_rangeslider_visible=True)
        st.plotly_chart(fig)

    # Call the plotting function if there's enough data
    plot_raw_data()

    # Prepare data for Prophet model
    df_train = data[['Date', 'Close']]
    df_train = df_train.rename(columns={"Date": "ds", "Close": "y"})

    # Create and fit the Prophet model
    m = Prophet()
    
    try:
        m.fit(df_train)
        
        # Create future dataframe and make predictions
        future = m.make_future_dataframe(periods=period)
        forecast = m.predict(future)

        # Show forecast data and plot forecast
        st.subheader('Forecast Data')
        st.write(forecast[['ds', 'yhat', 'yhat_lower', 'yhat_upper']].tail())
        st.write(f'Forecast plot for the next {n_years} years')

        fig1 = plot_plotly(m, forecast)
        st.plotly_chart(fig1)

        # Show forecast components
        st.subheader("Forecast Components")
        fig2 = m.plot_components(forecast)
        st.plotly_chart(fig2)

        # Additional Insights: Displaying key metrics
        st.subheader("Key Metrics")
        latest_data = forecast.iloc[-1]
        st.write(f"Predicted Price: ${latest_data['yhat']:.2f}")
        st.write(f"Lower Bound: ${latest_data['yhat_lower']:.2f}")
        st.write(f"Upper Bound: ${latest_data['yhat_upper']:.2f}")

    except Exception as e:
        st.error(f"Error fitting model: {e}")

else:
    st.error("No valid data available to make predictions.")

# User Guidance Section
st.sidebar.header("User Guidance")
st.sidebar.write("""
This application allows you to predict stock prices or cryptocurrency values based on historical data.
- Select a stock or cryptocurrency from the dropdown menu.
- Use the slider to choose how many years into the future you want to predict.
- View the forecasted prices along with confidence intervals.
""")