Introduction

Navigating the Economic Labyrinth: Illuminating the Path Ahead

Picture the economy as a vast, intricate labyrinth. Within its winding corridors lie hidden clues about the future—fluctuations in stock prices, shifts in consumer behavior, and whispers of policy changes. Those who can decipher these signals gain a powerful advantage, able to anticipate turns in the market, make strategic investments, and guide policy decisions for the greater good.

However, navigating this economic maze is no simple feat. It requires sophisticated tools and methods to unravel the complexities and provide clear insights into future trends. This is where data and advanced algorithms come into play, transforming the way we understand and predict economic movements.

The Power of Data and Algorithms in Economic Forecasting

In the realm of economic forecasting, data is the cornerstone. High-quality, reliable data allows us to paint an accurate picture of historical trends, understand current conditions, and make informed predictions about the future. But raw data alone isn’t enough. To truly harness its power, we need advanced algorithms that can process vast amounts of information, detect patterns, and forecast future events with remarkable accuracy.

One of the most powerful tools in this arena is Prophet, an open-source forecasting model developed by Facebook. Prophet excels in handling time series data, making it ideal for predicting economic indicators like housing prices, inflation rates, and income levels. Its flexibility and robustness allow it to model complex seasonal effects, holidays, and sudden changes in trends, providing a comprehensive view of the economic landscape.

Overview of Prophet Model and Its Capabilities

Prophet is designed to make forecasting simple and intuitive, even for those who are not experts in data science. It uses an additive model to decompose time series data into three main components: trend, seasonality, and holidays.

  • Trend: Captures the long-term increase or decrease in the data.
  • Seasonality: Accounts for periodic fluctuations that repeat at regular intervals, such as yearly, monthly, or weekly patterns.
  • Holidays: Incorporates the effects of specific events or holidays that can impact the data.

Prophet’s strength lies in its ability to handle missing data, outliers, and large datasets efficiently. It can automatically detect changepoints—moments where the time series data exhibits abrupt changes in trend—and adjust its forecasts accordingly. This makes it particularly suited for economic data, which often exhibits such irregularities due to policy changes, economic shocks, and other external factors.

In this article, we will embark on an exciting journey into the heart of economic forecasting using the Prophet model. We will explore how to fetch real-world data, preprocess it, and generate forecasts that offer a glimpse into the future of key economic indicators. By the end, you will not only understand the mechanics of economic forecasting but also appreciate its potential to empower informed decision-making and shape a more prosperous and equitable economic landscape.

Understanding Economic Indicators

The Importance of Key Economic Indicators

Accurate economic predictions depend on robust datasets. Comprehensive, high-quality data captures the nuances of the economic landscape, enabling reliable analysis of historical trends and current conditions. Without reliable data, forecasts can be skewed, leading to misguided decisions with significant economic repercussions.

Key Datasets

  1. ITB (iShares U.S. Home Construction ETF): Tracks the performance of the U.S. home construction sector, serving as a barometer for the housing market’s health.
  2. CPIAUCSL (Consumer Price Index for All Urban Consumers): Measures changes in the cost of living by tracking average price changes over time for a basket of consumer goods and services.
  3. MEHOINUSA672N (Median Household Income in the United States): Provides a measure of economic well-being by tracking median household income levels.

Analyzing Housing Market Trends

Housing Market Volatility

The housing market, represented by the iShares U.S. Home Construction ETF (ITB), shows significant volatility, particularly around economic crises such as the 2008 financial collapse and the recent COVID-19 pandemic. Despite these fluctuations, the long-term trend indicates a steady rise in housing market values, reflecting the growing demand for housing and the overall expansion of the real estate sector.

This line graph shows the actual values of the housing market over time. It provides insights into periods of growth, stagnation, and decline, highlighting the sensitivity of the housing market to broader economic conditions and policy changes.

The housing market’s performance is crucial because it influences consumer confidence, employment rates, and overall economic stability. A thriving housing market typically signifies economic growth, while downturns can indicate broader economic problems.

Housing Market Influences

Several factors drive the housing market’s performance, including interest rates, economic growth, and demographic trends. Lower interest rates make borrowing cheaper, encouraging more people to buy homes. Economic growth increases household incomes, making homeownership more affordable. Demographic trends, such as population growth and urbanization, increase demand for housing.

Understanding Inflation Trends

Consumer Price Index (CPI) Insights

The Consumer Price Index (CPI) is a crucial economic metric that tracks changes in the cost of living over time. The actual values of the CPI show a consistent upward trend, indicating persistent inflation. Monitoring inflation is essential for maintaining economic stability and planning future policies.

This line graph illustrates the steady increase in the cost of living, emphasizing the need to understand inflation trends and anticipate shifts in monetary policy and consumer behavior.

Inflation impacts all aspects of the economy, from purchasing power to interest rates. Persistent inflation can erode the value of money, making it more expensive for consumers to purchase goods and services. For businesses, inflation can increase costs, which might lead to higher prices for their products and services.

Impact of Inflation on the Economy

Inflation affects everyone differently. For consumers, rising prices mean reduced purchasing power. For businesses, higher input costs can squeeze profit margins unless they can pass these costs on to consumers. Governments and policymakers monitor inflation closely because it can influence economic decisions and monetary policy, such as interest rate adjustments.

Income Distribution and Economic Well-Being

Median Household Income

Median household income data provides a measure of economic well-being by tracking income levels over time. It highlights periods of income growth, stagnation, and decline, reflecting the broader economic conditions and policies in place.

This line graph shows the actual values of median household income in the U.S., adjusted for inflation, over time. Understanding these trends helps assess economic equality and the overall standard of living.

Income levels directly affect consumer spending, which drives economic growth. Stagnant or declining incomes can lead to reduced spending, which can slow down the economy. Conversely, rising incomes can boost spending and economic activity.

Factors Affecting Income Levels

Several factors influence income levels, including education, employment opportunities, and economic policies. Higher education levels generally lead to higher incomes. Economic policies that promote job creation and fair wages also contribute to income growth. Conversely, economic downturns and job losses can result in income stagnation or decline.

Forecasting with Prophet

Unleashing the Power of Prophet

With our data cleaned and prepared, we can now use the Prophet model to generate forecasts. Prophet is effective for time series data with seasonality and trends, making it ideal for predicting economic indicators.

Prophet Model Decomposition

Prophet decomposes time series data into several components: trend, seasonality, and holidays. Understanding these components helps us interpret the forecasts more accurately.

This image shows the decomposition of the CPI forecast into trend, holidays, yearly, and weekly components. The trend component captures the overall direction of the CPI, while the seasonal components show recurring patterns, and the holidays component accounts for specific events affecting the CPI.

Decomposing the data allows us to see underlying patterns and trends that might not be immediately visible. For example, we can understand how holidays impact consumer prices or how seasonal trends affect housing market dynamics.

Housing Market Forecast with Prophet

Housing Market Forecast Insights

Using the Prophet model, we generate a forecast for the housing market. This forecast provides a glimpse into future trends, helping policymakers, businesses, and investors make informed decisions.

This image depicts the housing market forecast using the Prophet model, including historical data and forecasted values with a confidence interval. The forecast suggests continued growth in the housing market, albeit with potential volatility.

Forecasting the housing market helps in planning for future demand and addressing potential challenges. It can inform policy decisions related to housing affordability and construction regulations.

Housing Market Decomposition

This image shows the decomposition of the housing market forecast into trend, holidays, yearly, and weekly components. It reveals the underlying patterns in the housing market data, highlighting the factors driving long-term growth and seasonal fluctuations.

Understanding these components helps identify the drivers behind housing market trends, such as economic policies, population growth, or seasonal buying patterns.

Income Forecast with Prophet

Income Trends and Forecast

The forecast for median household income provides valuable insights into future economic well-being. It shows a steady increase in household income, though with variability reflecting economic uncertainties.

This image depicts the median household income forecast using the Prophet model, including historical data and forecasted values with a confidence interval.

Forecasting income trends helps policymakers and businesses plan for future economic conditions. For example, rising incomes might lead to increased consumer spending, while stagnant incomes could signal potential economic challenges.

Income Decomposition

This image shows the decomposition of the median household income forecast into trend, holidays, yearly, and weekly components. It highlights the long-term growth trends and seasonal patterns in household income data.

Decomposing income data helps identify the factors driving income changes, such as economic policies, labor market conditions, and seasonal employment trends.

Comparing CPI and Income Trends

Overlaying CPI and Income

Understanding the relationship between CPI and household income is crucial for assessing economic stability and planning policies.

This image overlays the Consumer Price Index (CPI) and median household income in the U.S., adjusted for inflation, on the same plot. It compares their trends over time, showing the relationship between rising costs of living and household income levels.

Comparing CPI and income trends helps assess the impact of inflation on purchasing power. If incomes rise at a slower rate than CPI, households might struggle to maintain their standard of living.

Conclusion

The Relevance and Usefulness of Forecasting Insights

Prophet is a powerful tool for economic forecasting, capable of handling complex time series data with ease. By leveraging reliable datasets and advanced algorithms, we can gain valuable insights into future economic trends. These insights are crucial for policymakers, businesses, and investors.

  • Policymakers can use these forecasts to design strategies that promote economic stability, growth, and inclusivity. Understanding the interplay between housing, inflation, and income helps in crafting effective policies.
  • Businesses can adjust their pricing strategies and cost management practices based on forecasted economic conditions. This helps them navigate market uncertainties and capitalize on emerging opportunities.
  • Investors can identify sectors likely to perform well under specific economic conditions. For instance, real estate may be a good investment during periods of strong housing market growth.

Final Thoughts on Leveraging Predictions for Better Decision-Making

Economic forecasting is a powerful tool that, when used responsibly, can significantly enhance decision-making at all levels. Continuous validation, transparency, and ethical considerations must guide the development and application of these tools to ensure they contribute to a more sustainable and inclusive economic future.

Forecasting models like Prophet, when combined with high-quality data and thoughtful analysis, provide a deeper understanding of economic trends and their potential impacts. This knowledge empowers stakeholders to make informed decisions that can drive growth, stability, and prosperity.

For those interested in the complete code, including data fetching, preprocessing, model fitting, and visualization, refer to the detailed code snippets provided at the end of this article.

Appendix: Complete Code Snippets

Fetching and Plotting Raw Data

import yfinance as yf
import pandas as pd
from pandas_datareader.data import DataReader
import plotly.express as px
import plotly.graph_objects as go
import logging
from datetime import datetime

# Set up basic logging to capture information on the process
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(message)s')

# Fetch and prepare data
def fetch_and_prepare_data(ticker, start_date, end_date, frequency='MS'):
    """Fetch financial data based on ticker and prepare it for plotting."""
    try:
        data = yf.download(ticker, start=start_date, end=end_date, progress=False)
        data = data['Close'].resample(frequency).last()
        if data.empty:
            raise ValueError(f"Fetched empty DataFrame for ticker: {ticker}")
        data = data.reset_index()
        data.columns = ['Date', 'Value']
        logging.info(f"Data successfully fetched for {ticker}")
        return data
    except Exception as e:
        logging.error(f"Error fetching data for {ticker}: {e}")
        return pd.DataFrame(columns=['Date', 'Value'])

# Plot actual values using Plotly
def plot_actual_values_plotly(data, title, y_axis_info, y_axis_desc, metric_desc, save_to_file=False):
    """Plot the actual values of the data using Plotly."""
    fig = px.line(data, x='Date', y='Value', title=title, labels={'Date': 'Date', 'Value': y_axis_info})
    
    fig.update_traces(mode='lines', line=dict(width=2, color='blue'))
    
    # Add hover text for better understanding
    hover_text = [f"{date}: {value:.2f} ({y_axis_desc})" for date, value in zip(data['Date'], data['Value'])]
    fig.update_traces(hoverinfo='text', hovertext=hover_text)
    
    fig.update_layout(
        hovermode='x unified',
        template='plotly_white',
        title={
            'text': title,
            'y': 0.95,
            'x': 0.5,
            'xanchor': 'center',
            'yanchor': 'top'
        },
        xaxis_title='Date',
        yaxis_title=y_axis_info,
        font=dict(size=14, color='black'),
        margin=dict(l=80, r=60, t=100, b=120),
        annotations=[
            go.layout.Annotation(
                text=metric_desc,
                xref="paper", yref="paper",
                x=0.5, y=-0.15,
                showarrow=False,
                font=dict(size=12, color='black'),
                align='center'
            )
        ]
    )
    
    fig.show()
    
    if save_to_file:
        try:
            import kaleido
        except ImportError:
            logging.error("Kaleido is required for saving images. Please install it using 'pip install kaleido'")
            return
        filename = f"{title.replace(' ', '_').lower()}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
        fig.write_image(filename)
        logging.info(f"Plot saved to {filename}")

# Main function to fetch data and plot
def main():
    start_date = "2010-01-01"
    end_date = pd.Timestamp.today().strftime('%Y-%m-%d')

    tickers_info = {
        "AAPL": {
            "title": "Apple Inc. (AAPL) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Apple Inc.",
            "metric_desc": "This chart tracks the closing stock price of Apple Inc. (AAPL)."
        },
        "MSFT": {
            "title": "Microsoft Corporation (MSFT) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Microsoft Corporation",
            "metric_desc": "This chart tracks the closing stock price of Microsoft Corporation (MSFT)."
        },
        "AMZN": {
            "title": "Amazon.com Inc. (AMZN) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Amazon.com Inc.",
            "metric_desc": "This chart tracks the closing stock price of Amazon.com Inc. (AMZN)."
        },
        "GOOGL": {
            "title": "Alphabet Inc. (GOOGL) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Alphabet Inc.",
            "metric_desc": "This chart tracks the closing stock price of Alphabet Inc. (GOOGL)."
        },
        "TSLA": {
            "title": "Tesla Inc. (TSLA) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Tesla Inc.",
            "metric_desc": "This chart tracks the closing stock price of Tesla Inc. (TSLA)."
        },
        "GOGO": {
            "title": "Gogo Inc. (GOGO) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Gogo Inc.",
            "metric_desc": "This chart tracks the closing stock price of Gogo Inc. (GOGO)."
        },
        "APRN": {
            "title": "Blue Apron Holdings Inc. (APRN) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Blue Apron Holdings Inc.",
            "metric_desc": "This chart tracks the closing stock price of Blue Apron Holdings Inc. (APRN)."
        },
        "HAIN": {
            "title": "Hain Celestial Group Inc. (HAIN) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Hain Celestial Group Inc.",
            "metric_desc": "This chart tracks the closing stock price of Hain Celestial Group Inc. (HAIN)."
        },
        "ETSY": {
            "title": "Etsy Inc. (ETSY) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Etsy Inc.",
            "metric_desc": "This chart tracks the closing stock price of Etsy Inc. (ETSY)."
        },
        "RIOT": {
            "title": "Riot Platforms Inc. (RIOT) Actual Values",
            "y_axis_info": "Stock Price (in USD)",
            "y_axis_desc": "Closing stock price of Riot Platforms Inc.",
            "metric_desc": "This chart tracks the closing stock price of Riot Platforms Inc. (RIOT)."
        }
    }

    for ticker, info in tickers_info.items():
        data = fetch_and_prepare_data(ticker, start_date, end_date)
        if not data.empty:
            plot_actual_values_plotly(
                data, 
                info["title"], 
                info["y_axis_info"], 
                info["y_axis_desc"], 
                info["metric_desc"],
                save_to_file=True
            )

if __name__ == "__main__":
    main()

Fitting the Prophet Model and Generating Forecasts – Full Code

import yfinance as yf
import pandas as pd
from pandas_datareader.data import DataReader
from prophet import Prophet
from prophet.diagnostics import cross_validation, performance_metrics
from prophet.plot import add_changepoints_to_plot, plot_cross_validation_metric, plot_components_plotly
import plotly.graph_objects as go
from plotly.subplots import make_subplots
import logging
from datetime import datetime
from joblib import Parallel, delayed
import multiprocessing
import kaleido as kld

# Set up basic logging to capture information on the process
logging.basicConfig(level=logging.INFO)

# Fetch and prepare data
def fetch_and_prepare_data(ticker, start_date, end_date, frequency='MS'):
    """Fetch financial data based on ticker and prepare it for Prophet modeling."""
    try:
        if ticker in ['CPIAUCSL', 'MEHOINUSA672N']:
            data = DataReader(ticker, 'fred', start_date, end_date).asfreq(frequency).interpolate()
        else:
            data = yf.download(ticker, start=start_date, end=end_date, progress=False)
            data = data['Close'].resample(frequency).last()
        if data.empty:
            raise ValueError("Fetched empty DataFrame.")
        data = data.reset_index()
        data.columns = ['ds', 'y']
        logging.info(f"Data successfully fetched for {ticker}")
        return data
    except Exception as e:
        logging.error(f"Error fetching data for {ticker}: {e}")
        return pd.DataFrame(columns=['ds', 'y'])

# Fit Prophet model
def fit_prophet_model(data, periods, frequency, changepoint_prior_scale):
    """Fit a Prophet model with specified parameters."""
    try:
        model = Prophet(
            daily_seasonality=False,
            weekly_seasonality=True,
            yearly_seasonality=True,
            seasonality_mode='multiplicative',
            changepoint_prior_scale=changepoint_prior_scale
        )
        model.add_country_holidays(country_name='US')
        model.fit(data)
        future = model.make_future_dataframe(periods=periods, freq=frequency)
        forecast = model.predict(future)
        df_cv = cross_validation(model, initial='3650 days', period='180 days', horizon='365 days')
        df_p = performance_metrics(df_cv)
        mae = df_p['mae'].mean()
        return model, forecast, mae
    except Exception as e:
        logging.error(f"Error during Prophet model fitting: {e}")
        return None, None, float('inf')

# Forecast using Prophet
def forecast_with_prophet(data, periods, frequency='MS', iterations=1):
    """Create and apply a Prophet model to forecast future values."""
    if data.empty or len(data) < 2:
        logging.error("Insufficient data to fit model.")
        return None, None
    try:
        best_model = None
        best_forecast = None
        best_mae = float('inf')
        
        def run_iteration():
            return fit_prophet_model(data, periods, frequency, changepoint_prior_scale=0.05)

        num_cores = multiprocessing.cpu_count()
        logging.info(f"Using {num_cores} cores for parallel processing.")
        
        if num_cores > 1:
            results = Parallel(n_jobs=num_cores)(delayed(run_iteration)() for _ in range(iterations))
            for model, forecast, mae in results:
                if mae < best_mae:
                    best_mae = mae
                    best_model = model
                    best_forecast = forecast
        else:
            for i in range(iterations):
                model, forecast, mae = run_iteration()
                if mae < best_mae:
                    best_mae = mae
                    best_model = model
                    best_forecast = forecast
                logging.info(f"Iteration {i+1}: MAE = {mae}")
        
        logging.info("Forecast successfully created.")
        return best_forecast, best_model
    except Exception as e:
        logging.error(f"Error during forecasting with Prophet: {e}")
        return None, None

# Perform cross-validation
def perform_cross_validation(model, initial, period, horizon):
    """Perform cross-validation to evaluate the model."""
    if model is None:
        return None, None
    try:
        df_cv = cross_validation(model, initial=initial, period=period, horizon=horizon)
        df_p = performance_metrics(df_cv)
        plot_cross_validation_metric(df_cv, metric='mae')
        logging.info("Cross-validation completed successfully.")
        return df_cv, df_p
    except Exception as e:
        logging.error(f"Error during cross-validation: {e}")
        return None, None

# Plot forecasts
def plot_forecasts(data, forecast, model, title, save_to_file=False):
    """Generate interactive Plotly plots for better visualization."""
    if forecast is None:
        logging.error(f"Forecast for {title} is None, skipping plot.")
        return

    fig = go.Figure()

    # Historical data
    fig.add_trace(go.Scatter(x=data['ds'], y=data['y'], mode='lines', name='Historical', line=dict(color='blue')))

    # Forecast data
    fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat'], mode='lines', name='Forecast', line=dict(color='red', dash='dash')))
    fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill=None, mode='lines', line=dict(color='gray'), showlegend=False))
    fig.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='lines', line=dict(color='gray'), showlegend=False))

    # Annotations
    peak = forecast.loc[forecast['yhat'] == forecast['yhat'].max()]
    if not peak.empty:
        fig.add_annotation(x=peak['ds'].values[0], y=peak['yhat'].values[0], text=f"Peak: {peak['yhat'].values[0]:.2f}", showarrow=True, arrowhead=2)

    fig.update_layout(title=title, xaxis_title='Date', yaxis_title='Value', template='plotly_white')
    fig.show()

    if save_to_file:
        try:
            kld
        except ImportError:
            logging.error("Kaleido is required for saving images. Please install it using 'pip install kaleido'")
            return
        filename = f"{title.replace(' ', '_').lower()}_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
        fig.write_image(filename)
        logging.info(f"Plot saved to {filename}")

# Plot decomposition
def plot_decomposition(model, forecast, title, save_to_file=False):
    """Generate decomposition plots using Plotly."""
    if model is None or forecast is None:
        logging.error(f"Cannot plot decomposition for {title}, model or forecast is None.")
        return
    fig = plot_components_plotly(model, forecast)
    fig.update_layout(title=f"{title} - Decomposition")
    fig.show()

    if save_to_file:
        try:
            import kaleido
        except ImportError:
            logging.error("Kaleido is required for saving images. Please install it using 'pip install kaleido'")
            return
        filename = f"{title.replace(' ', '_').lower()}_decomposition_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
        fig.write_image(filename)
        logging.info(f"Decomposition plot saved to {filename}")

def main(save_to_file=False):
    start_date = "1990-01-01"
    end_date = pd.Timestamp.today().strftime('%Y-%m-%d')
    forecast_periods = 180  # Forecasting for 15 years with monthly data
    iterations = 1  # Number of iterations can be changed here

    # Data fetching and model preparation
    housing_data = fetch_and_prepare_data("ITB", start_date, end_date)
    print("Housing Data:", housing_data.head())
    if housing_data.empty:
        logging.error("Housing data is empty after fetching.")
    else:
        logging.info("Housing data fetched successfully.")

    cpi_data = fetch_and_prepare_data('CPIAUCSL', start_date, end_date)
    print("CPI Data:", cpi_data.head())
    income_data = fetch_and_prepare_data('MEHOINUSA672N', start_date, end_date)
    print("Income Data:", income_data.head())

    # Model application and forecasting
    housing_forecast, housing_model = forecast_with_prophet(housing_data, forecast_periods, iterations=iterations)
    print("Housing Forecast:", housing_forecast.head() if housing_forecast is not None else "None")
    if housing_forecast is None:
        logging.error("Housing forecast is None after model fitting.")
    else:
        logging.info("Housing forecast created successfully.")

    cpi_forecast, cpi_model = forecast_with_prophet(cpi_data, forecast_periods, iterations=iterations)
    income_forecast, income_model = forecast_with_prophet(income_data, forecast_periods, iterations=iterations)

    # Validation and performance evaluation
    if housing_model is not None:
        perform_cross_validation(housing_model, '3650 days', '180 days', '365 days')

    if cpi_model is not None:
        perform_cross_validation(cpi_model, '3650 days', '180 days', '365 days')

    if income_model is not None:
        perform_cross_validation(income_model, '3650 days', '180 days', '365 days')

    # Decomposition plots
    print("Displaying decomposition plots for all datasets...")
    plot_decomposition(housing_model, housing_forecast, 'Housing Market Forecast', save_to_file=True)
    plot_decomposition(cpi_model, cpi_forecast, 'CPI Forecast', save_to_file=True)
    plot_decomposition(income_model, income_forecast, 'Income Forecast', save_to_file=True)

    # Forecast plots
    print("Displaying forecast plots for all datasets...")
    plot_forecasts(housing_data, housing_forecast, housing_model, 'Housing Market Forecast', save_to_file=True)
    plot_forecasts(cpi_data, cpi_forecast, cpi_model, 'CPI Forecast', save_to_file=True)
    plot_forecasts(income_data, income_forecast, income_model, 'Income Forecast', save_to_file=True)

    # Combined plot
    print("Displaying combined plots for all datasets...")
    fig_combined = make_subplots(rows=3, cols=1, subplot_titles=['Housing Market Forecast', 'CPI Forecast', 'Income Forecast'])

    for i, (data, forecast, title) in enumerate(zip([housing_data, cpi_data, income_data],
                                                    [housing_forecast, cpi_forecast, income_forecast],
                                                    ['Housing Market Forecast', 'CPI Forecast', 'Income Forecast'])):
        if forecast is not None:
            fig_combined.add_trace(go.Scatter(x=data['ds'], y=data['y'], mode='lines', name=f'{title} - Historical', line=dict(color='blue')), row=i+1, col=1)
            fig_combined.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat'], mode='lines', name=f'{title} - Forecast', line=dict(color='red', dash='dash')), row=i+1, col=1)
            fig_combined.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_lower'], fill=None, mode='lines', line=dict(color='gray'), showlegend=False), row=i+1, col=1)
            fig_combined.add_trace(go.Scatter(x=forecast['ds'], y=forecast['yhat_upper'], fill='tonexty', mode='lines', line=dict(color='gray'), showlegend=False), row=i+1, col=1)

    fig_combined.update_layout(height=900, title_text="Combined Forecasts")
    fig_combined.show()

    if save_to_file:
        try:
            import kaleido
        except ImportError:
            logging.error("Kaleido is required for saving images. Please install it using 'pip install kaleido'")
            return
        filename = f"combined_forecasts_{datetime.now().strftime('%Y%m%d_%H%M%S')}.png"
        fig_combined.write_image(filename)
        logging.info(f"Combined plot saved to {filename}")

    # Summary of diagnostic statements
    print("\nSummary of Diagnostic Statements:")
    print("Housing Data:", housing_data.head())
    print("Housing Forecast:", housing_forecast.head() if housing_forecast is not None else "None")
    print("CPI Data:", cpi_data.head())
    print("Income Data:", income_data.head())

if __name__ == "__main__":
    main(save_to_file=True)

Last Update: June 4, 2024