Research Question: Are there visible relationships among interest rates, market prices (DJIA), and bond yields (10-year Treasury)?

The purpose of my analysis is to explore the potential interactions and correlations between these key economic indicators over the past 25 years. For this project, I can only use base R and create only one visiualization that answers the research question. Below is my R code and visiualization along with the interpretation.

# Function to fetch data from FRED API and handle ZIP files
fetch_fred_data_zip <- function(series_id, api_key) {

#API request URL to get ZIP
  url <- paste0("https://api.stlouisfed.org/fred/series/observations?series_id=", series_id, "&api_key=", api_key, "&file_type=json")
  
  response <- GET(url)
  
# Parse the JSON response
  json_data <- fromJSON(content(response, "text", encoding = "UTF-8"))
  
# Extract the observations data from the JSON structure
  data <- json_data$observations
  
# Convert the data to a data frame
  df <- as.data.frame(data)
  
  return(df)
}

# Setting my API Key
api_key <- "32ed361938b7652c841c1db2390334fa"

# Fetch data for DJIA, 10-Year Treasury Yield, and Unemployment Rate
djia_data <- fetch_fred_data_zip("DJIA", api_key)
dgs10_data <- fetch_fred_data_zip("DGS10", api_key)
unrate_data <- fetch_fred_data_zip("UNRATE", api_key)

# View the first few rows of each dataset
head(djia_data)
head(dgs10_data)
head(unrate_data)
align_ds <- function(df) {
  df$date <- as.Date(df$date)
  return(df)
}

djia_data <- align_ds(djia_data)
dgs10_data <- align_ds(dgs10_data)
unrate_data <- align_ds(unrate_data)

combined_data <- djia_data %>%
  inner_join(dgs10_data, by = "date") %>%
  inner_join(unrate_data, by = "date")

cleaned_data <- combined_data %>% drop_na()

str(cleaned_data)
## 'data.frame':    87 obs. of  10 variables:
##  $ realtime_start.x: chr  "2025-02-21" "2025-02-21" "2025-02-21" "2025-02-21" ...
##  $ realtime_end.x  : chr  "2025-02-21" "2025-02-21" "2025-02-21" "2025-02-21" ...
##  $ date            : Date, format: "2015-04-01" "2015-05-01" ...
##  $ value.x         : chr  "17698.18" "18024.06" "18040.37" "17757.91" ...
##  $ realtime_start.y: chr  "2025-02-21" "2025-02-21" "2025-02-21" "2025-02-21" ...
##  $ realtime_end.y  : chr  "2025-02-21" "2025-02-21" "2025-02-21" "2025-02-21" ...
##  $ value.y         : chr  "1.87" "2.12" "2.19" "2.43" ...
##  $ realtime_start  : chr  "2025-02-07" "2025-02-07" "2025-02-07" "2025-02-07" ...
##  $ realtime_end    : chr  "2025-02-07" "2025-02-07" "2025-02-07" "2025-02-07" ...
##  $ value           : chr  "5.4" "5.6" "5.3" "5.2" ...
# Check if there are any missing values
sum(is.na(cleaned_data$date))  # Check for missing dates
## [1] 0
sum(is.na(cleaned_data$value.x))  # Check for missing DJIA values
## [1] 0
sum(is.na(cleaned_data$value.y))  # Check for missing 10-Year Treasury Yield values
## [1] 0
# Convert the value columns to numeric
cleaned_data$value.x <- as.numeric(cleaned_data$value.x)
cleaned_data$value.y <- as.numeric(cleaned_data$value.y)
cleaned_data$value <- as.numeric(cleaned_data$value)

# Replace "." with NA in the relevant columns
cleaned_data$value.x[cleaned_data$value.x == "."] <- NA
cleaned_data$value.y[cleaned_data$value.y == "."] <- NA
cleaned_data$value[cleaned_data$value == "."] <- NA

# Convert the columns to numeric after replacing "."
cleaned_data$value.x <- as.numeric(cleaned_data$value.x)
cleaned_data$value.y <- as.numeric(cleaned_data$value.y)
cleaned_data$value <- as.numeric(cleaned_data$value)

# Remove rows with any remaining NA values 
cleaned_data <- cleaned_data[complete.cases(cleaned_data), ]
# Normalize all three variables to the range [0, 100] for comparison
normalize <- function(x) {
  return((x - min(x)) / (max(x) - min(x)) * 100)
}

# Normalize DJIA, 10-Year Treasury Yield, and Unemployment Rate
cleaned_data$normalized_djia <- normalize(cleaned_data$value.x)
cleaned_data$normalized_treasury <- normalize(cleaned_data$value.y)
cleaned_data$normalized_unemployment <- normalize(cleaned_data$value)

# Plotting the normalized data with a better y-axis label
plot(cleaned_data$date, cleaned_data$normalized_djia, type = "l", col = "blue", 
     xlab = "Date", ylab = "Normalized Value (0-100 scale)", 
     main = "Normalized Comparison of DJIA, 10-Year Treasury Yield, and Unemployment Rate", 
     lwd = 2, xaxt = "n", cex.main = 0.8)

# Add the normalized 10-Year Treasury Yield in red
lines(cleaned_data$date, cleaned_data$normalized_treasury, col = "red", lwd = 2)

# Add the normalized Unemployment Rate in green
lines(cleaned_data$date, cleaned_data$normalized_unemployment, col = "green", lwd = 2)

# Format the x-axis to show dates clearly (adjust as needed)
axis(1, at = seq(min(cleaned_data$date), max(cleaned_data$date), by = "2 years"),
     labels = format(seq(min(cleaned_data$date), max(cleaned_data$date), by = "2 years"), "%Y"))

# Add a legend to differentiate the lines
legend("topleft", legend = c("DJIA", "10-Year Treasury Yield", "Unemployment Rate"),
       col = c("blue", "red", "green"), lwd = 2)

Interpretation:

This visiualization reveals noticable trends amongs market prices among the DJIA, 10-Year Treasury Yield, and unemployment rate over time. A positive relationship appears between the DJIA and Treasury yields, where rising yields often coincide with a stronger stock market.During the pandemic, the data highlights a sharp spike in the unemployment rate, while both the DJIA and 10-Year Treasury Yield experienced significant declines.This reflects the economic shock caused by the pandemic, where increased unemployment signaled economic distress, leading to falling stock prices and lower bond yields. The negative correlation between the stock market and unemployment during this period reinforces the idea that market performance often deteriorates during times of economic crisis.