Libraries & Packages

#install.packages("tidyquant")
#install.packages("tidyverse")
#install.packages("recipes")


library(tidyquant)
## Registered S3 method overwritten by 'quantmod':
##   method            from
##   as.zoo.data.frame zoo
## ── Attaching core tidyquant packages ─────────────────────── tidyquant 1.0.11 ──
## ✔ PerformanceAnalytics 2.0.8      ✔ TTR                  0.24.4
## ✔ quantmod             0.4.27     ✔ xts                  0.14.1
## ── Conflicts ────────────────────────────────────────── tidyquant_conflicts() ──
## ✖ zoo::as.Date()                 masks base::as.Date()
## ✖ zoo::as.Date.numeric()         masks base::as.Date.numeric()
## ✖ PerformanceAnalytics::legend() masks graphics::legend()
## ✖ quantmod::summary()            masks base::summary()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors
library(tidyverse)
## ── Attaching core tidyverse packages ──────────────────────── tidyverse 2.0.0 ──
## ✔ dplyr     1.1.4     ✔ readr     2.1.5
## ✔ forcats   1.0.0     ✔ stringr   1.5.1
## ✔ ggplot2   3.5.2     ✔ tibble    3.2.1
## ✔ lubridate 1.9.4     ✔ tidyr     1.3.1
## ✔ purrr     1.0.4     
## ── Conflicts ────────────────────────────────────────── tidyverse_conflicts() ──
## ✖ dplyr::filter() masks stats::filter()
## ✖ dplyr::first()  masks xts::first()
## ✖ dplyr::lag()    masks stats::lag()
## ✖ dplyr::last()   masks xts::last()
## ℹ Use the conflicted package (<http://conflicted.r-lib.org/>) to force all conflicts to become errors

Data Preparation

# Download Yahoo Finance data: Bitcoin, Gold, VIX
symbols <- c("BTC-USD", "GC=F", "^VIX")
market_data <- tq_get(symbols, 
                      from = "2020-01-01", 
                      to = "2025-01-01") %>%
  select(symbol, date, adjusted) %>%
  pivot_wider(names_from = symbol, values_from = adjusted) %>%
  rename(BTC = `BTC-USD`, Gold = `GC=F`, VIX = `^VIX`)

# Download DXY (U.S. Dollar Index) from FRED
getSymbols("DTWEXBGS", src = "FRED")
## [1] "DTWEXBGS"
dxy <- DTWEXBGS %>%
  as_tibble(rownames = "date") %>%
  rename(DXY = DTWEXBGS) %>%
  mutate(date = as.Date(date))

# Ensure date formats match
market_data <- market_data %>%
  mutate(date = as.Date(date))

# Merge DXY with Yahoo data
market_data <- market_data %>%
  left_join(dxy, by = "date") %>%
  drop_na(BTC, Gold, VIX, DXY)

# Save the full dataset for later reuse
saveRDS(market_data, file = "market_data.rds")

# Preview
head(market_data)
## # A tibble: 6 × 5
##   date         BTC  Gold   VIX   DXY
##   <date>     <dbl> <dbl> <dbl> <dbl>
## 1 2020-01-02 6985. 1524.  12.5  115.
## 2 2020-01-03 7345. 1549.  14.0  115.
## 3 2020-01-06 7769. 1566.  13.9  115.
## 4 2020-01-07 8164. 1572.  13.8  115.
## 5 2020-01-08 8080. 1557.  13.4  115.
## 6 2020-01-09 7879. 1552.  12.5  115.

Research question

Does Bitcoin behave like a non-traditional store of value by demonstrating a relationship with traditional financial indicators such as gold prices, the U.S. Dollar Index (DXY), and the Volatility Index (VIX)?

Cases

Each case is a daily observation from January 1, 2020 through January 1, 2025. There are approximately 1,250 observations, each representing a trading day with associated financial index values.

Data collection

The data was collected via the tidyquant R package using public APIs from Yahoo Finance and the Federal Reserve Economic Database (FRED).

Type of study

This is an observational study.

Data Source

Describe your variables?

All variables are quantitative (numerical): - Response Variable: BTC (daily adjusted closing price of Bitcoin) - Explanatory Variables: Gold, VIX, and DXY

Relevant summary statistics

summary(market_data)
##       date                 BTC              Gold           VIX       
##  Min.   :2020-01-02   Min.   :  4971   Min.   :1477   Min.   :11.86  
##  1st Qu.:2021-04-05   1st Qu.: 19755   1st Qu.:1777   1st Qu.:15.89  
##  Median :2022-07-03   Median : 32212   Median :1871   Median :19.63  
##  Mean   :2022-07-02   Mean   : 36318   Mean   :1941   Mean   :21.42  
##  3rd Qu.:2023-09-29   3rd Qu.: 50745   3rd Qu.:1989   3rd Qu.:25.00  
##  Max.   :2024-12-31   Max.   :106141   Max.   :2788   Max.   :82.69  
##       DXY       
##  Min.   :110.5  
##  1st Qu.:115.3  
##  Median :119.8  
##  Mean   :119.1  
##  3rd Qu.:122.4  
##  Max.   :129.5
# Correlation matrix
cor(market_data %>% select(BTC, Gold, VIX, DXY), use = "complete.obs")
##             BTC       Gold        VIX       DXY
## BTC   1.0000000  0.7218713 -0.4923616 0.1074581
## Gold  0.7218713  1.0000000 -0.4052554 0.4209922
## VIX  -0.4923616 -0.4052554  1.0000000 0.0575892
## DXY   0.1074581  0.4209922  0.0575892 1.0000000
# Scatterplot matrix
pairs(~ BTC + Gold + VIX + DXY, data = market_data)

Time Series Visualizations

market_data_long <- market_data %>%
  pivot_longer(cols = c(BTC, Gold, DXY, VIX), names_to = "Asset", values_to = "Price")

ggplot(market_data_long, aes(x = date, y = Price, color = Asset)) +
  geom_line(alpha = 0.7) +
  facet_wrap(~ Asset, scales = "free_y", ncol = 1) +
  labs(title = "Price Trends Over Time (2020–2024)",
       x = "Date", y = "Adjusted Price / Index Value") +
  theme_minimal()

Regression Model and Interpretation

# Run multiple regression
model <- lm(BTC ~ Gold + VIX + DXY, data = market_data)
summary(model)
## 
## Call:
## lm(formula = BTC ~ Gold + VIX + DXY, data = market_data)
## 
## Residuals:
##    Min     1Q Median     3Q    Max 
## -32099  -9996  -1510   9169  34660 
## 
## Coefficients:
##              Estimate Std. Error t value Pr(>|t|)    
## (Intercept) 41418.030  10433.533   3.970 7.61e-05 ***
## Gold           57.331      1.791  32.012  < 2e-16 ***
## VIX          -478.057     52.226  -9.154  < 2e-16 ***
## DXY          -891.258     98.955  -9.007  < 2e-16 ***
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 13420 on 1240 degrees of freedom
## Multiple R-squared:  0.5953, Adjusted R-squared:  0.5944 
## F-statistic: 608.1 on 3 and 1240 DF,  p-value: < 2.2e-16

Interpretation of Regression

The linear model shows that: > - Gold has a strong positive coefficient (β = 57.33, p < 0.001), indicating that Bitcoin tends to rise when gold rises. > - DXY has a strong negative coefficient (β = –891.26, p < 0.001), consistent with store-of-value behavior (as the dollar weakens, BTC strengthens). > - VIX also has a strong negative coefficient (β = –478.06, p < 0.001), suggesting that Bitcoin tends to decline in periods of high market volatility.

The model’s R-squared value is 0.60, meaning it explains approximately 60% of Bitcoin’s daily price variation from 2020–2025.

Final Answer to Research Question

Based on both the visual trends and regression analysis, Bitcoin appears to behave partially like a non-traditional store of value. It shows a strong positive relationship with gold, a strong negative relationship with the U.S. Dollar Index, and a strong negative relationship with the VIX (volatility index).

These patterns suggest that Bitcoin shares several characteristics with traditional stores of value — particularly in how it reacts to inflationary or dollar-weakening pressures — but it also exhibits high volatility and speculative behavior. Its store-of-value status continues to evolve, showing potential alignment with traditional safe havens but with caveats tied to its market maturity and risk profile.