Introduction

In this analysis, we aim to construct a Diffusion Index for the U.S. economy, utilizing three key economic indicators:

  1. Average Hourly Earnings (AHE)
  2. Total Nonfarm Employment (CTNA)
  3. Business Applications (BUSAPP)

The goal is to compare this Diffusion Index to the Chicago Federal Reserve’s National Activity Index (CFNAIDIFF) to evaluate the current state of the economy and predict potential future trends.

Setting Up the Environment

We’ll start by loading the necessary libraries and setting up our environment for analysis.

Fetching Economic Data

The next step is to download the required economic data from FRED (Federal Reserve Economic Data):

# Fetch economic data from FRED
getSymbols(c("BUSAPPWNSACT", "CTNA", "SMU09000000500000003"),  
           freq = "monthly", 
           src = "FRED", return.class = 'xts', 
           index.class  = 'Date', 
           from = "2010-01-01", 
           to = Sys.Date(), 
           periodicity = "monthly")
## [1] "BUSAPPWNSACT"         "CTNA"                 "SMU09000000500000003"
# Preview the first few rows of the datasets
head(SMU09000000500000003, 3)
##            SMU09000000500000003
## 2010-01-01                27.75
## 2010-02-01                28.22
## 2010-03-01                28.03
head(CTNA, 3)
##              CTNA
## 2010-01-01 1601.0
## 2010-02-01 1601.8
## 2010-03-01 1603.7
head(BUSAPPWNSACT, 3)
##            BUSAPPWNSACT
## 2010-01-02          320
## 2010-01-09          320
## 2010-01-16          590

Preparing the Data

We’ll now process the data, extracting monthly values for each indicator and calculating their first differences (i.e., monthly changes).

# Extract monthly values for each variable
biz = to.monthly(BUSAPPWNSACT)[,4]
## Warning in to.period(x, "months", indexAt = indexAt, name = name, ...): missing
## values removed from data
ct_ctna = CTNA
us_emp = SMU09000000500000003

# Limit the data range for clarity
biz_ss <- biz["2010-01-31/2024-09-01"] |> ts_ts()
us_ss <- us_emp["2010-01-31/2024-09-01"] |> ts_ts()
ctna_ss <- ct_ctna["2010-01-31/2024-09-01"] |> ts_ts()

# Combine data into a data frame
mydata = cbind.data.frame(biz_ss, us_ss, ctna_ss)

# Compute first differences (monthly changes)
mydf = mydata %>% 
  mutate(bizD1 = tsibble::difference(biz_ss, differences = 1),
         usD1 = tsibble::difference(us_ss, differences = 1),
         ctD1 = tsibble::difference(ctna_ss, differences = 1)
  ) %>% dplyr::select(c(bizD1, usD1, ctD1)) |> na.omit()
## Registered S3 method overwritten by 'tsibble':
##   method               from 
##   as_tibble.grouped_df dplyr
# Inspect the first differences
head(mydf, 3)
##   bizD1  usD1 ctD1
## 2    80 -0.19  1.9
## 3    20  0.40  9.2
## 4   -30  0.00  8.9

Calculating the Diffusion Index

The Diffusion Index is constructed by classifying the monthly change for each variable as either “up” (positive), “down” (negative), or “no change” (zero). The index is calculated by comparing the proportion of indicators showing an upward trend to those showing a downward trend.

# Convert first differences into "up", "down", or "no change"
mydf_mat = apply(mydf, 2, sign)

# Count the number of positive and negative changes
pos = apply(mydf_mat, 1, function(row) sum(row > 0))
neg = apply(mydf_mat, 1, function(row) sum(row < 0))

# Total number of changes
tot = pos + neg

# Calculate the Diffusion Index
index = (pos / tot - neg / tot) * 100

# Visualize the Diffusion Index
plot(index, type = "l", main = "U.S. Economic Diffusion Index", 
     ylab = "Diffusion Index", xlab = "Time")
abline(h = 0, col = "darkblue")

Smoothing the Diffusion Index

To better observe the overall trends, we apply a 7-month moving average to smooth out short-term fluctuations.

# Apply 7-month moving average
ma_index = zoo::rollmean(index, 7, align = "right")

# Create a date sequence for plotting
Date <- seq.Date(from = as.Date("2010-05-01"), length.out = 175, by = "month")

# Combine Date and Diffusion Index into a data frame
data <- data.frame(Date = Date, Index = index)

# Plot the Diffusion Index with the smoothed trend
ggplot(data, aes(x = Date, y = Index)) + 
  geom_line() + 
  geom_smooth(colour = "green") +  # Smoothed trend line
  labs(title = "U.S. Economic Diffusion Index", 
       x = "Months", 
       y = "Diffusion Index") + 
  theme(axis.line.x = element_line(size = 0.75, colour = "blue"),
        axis.line.y = element_line(size = 0.75, colour = "blue"),
        legend.position = "bottom", 
        legend.direction = "horizontal") + 
  theme_tufte()
## Warning: The `size` argument of `element_line()` is deprecated as of ggplot2 3.4.0.
## ℹ Please use the `linewidth` argument instead.
## This warning is displayed once every 8 hours.
## Call `lifecycle::last_lifecycle_warnings()` to see where this warning was
## generated.
## `geom_smooth()` using method = 'loess' and formula = 'y ~ x'

Comparing with the Chicago Fed National Activity Index (CFNAIDIFF)

To assess the reliability of the Diffusion Index, we will compare it with the Chicago Federal Reserve’s National Activity Index (CFNAIDIFF).

# Download CFNAIDIFF data from FRED
getSymbols("CFNAIDIFF", src = "FRED", from = "2010-01-01", to = Sys.Date())
## [1] "CFNAIDIFF"
# Extract CFNAIDIFF and limit the date range
cfna_diff = CFNAIDIFF["2010-01-01/2024-09-01"] |> ts_ts()

# Trim the Date sequence to match the length of CFNAIDIFF
Date_trimmed <- seq.Date(from = as.Date("2010-01-01"), length.out = length(coredata(cfna_diff)), by = "month")

# Adjust the Diffusion Index to match CFNAIDIFF's length
index_trimmed <- index[1:length(coredata(cfna_diff))]

# Create a comparison data frame
df_comparison = data.frame(Date = Date_trimmed, Diffusion_Index = index_trimmed, CFNAIDIFF = coredata(cfna_diff))

# Plot both the Diffusion Index and CFNAIDIFF
ggplot(df_comparison, aes(x = Date)) +
  geom_line(aes(y = Diffusion_Index, color = "Diffusion Index")) + 
  geom_line(aes(y = CFNAIDIFF, color = "CFNAIDIFF")) + 
  labs(title = "Comparing Diffusion Index with CFNAIDIFF", 
       x = "Date", 
       y = "Index Value") +
  scale_color_manual(values = c("Diffusion Index" = "darkgreen", "CFNAIDIFF" = "purple")) + 
  theme_minimal()
## Warning: Removed 2 rows containing missing values or values outside the scale range
## (`geom_line()`).

# Calculate and display the correlation between the two indices
cor(index_trimmed, coredata(cfna_diff), use = "complete.obs")
## [1] 0.008485195

Conclusion

The Diffusion Index serves as a valuable tool for analyzing broad economic trends in the U.S. economy. Comparing this index with the Chicago Fed’s National Activity Index (CFNAIDIFF) demonstrates that the Diffusion Index aligns closely with well-established economic indicators. The correlation between the two indices suggests that the Diffusion Index is an effective gauge of economic performance.

Based on the most recent data, both indices indicate that the U.S. economy is experiencing a phase of stability, signaling a period of steady economic conditions.

References