library(tidyverse)
library(lubridate)
library(scales)
library(ggrepel)
library(tidyquant)
library(jsonlite)
theme_set(theme_minimal())
invisible(Sys.setlocale("LC_TIME", "en_US.UTF-8"))

library(ggcorrplot)
library(patchwork)
assets <- tq_get(c("GLD", "BTC-USD", "QQQ", "SPY", "TLT", "EEM"), from = 0)
nvda_msft <- tq_get(c("NVDA", "MSFT"), from = as.Date("2024-01-01"))

assets |> saveRDS("data/assets.RDS")
nvda_msft |> saveRDS("data/nvda_msft.RDS")
assets <- readRDS("data/assets.RDS")
nvda_msft <- readRDS("data/nvda_msft.RDS")
assets |> 
  filter(date >= as.Date("2025-01-01")) |>
  group_by(symbol) |>
  mutate(p = adjusted / first(adjusted) * 100) |> 
  ggplot(aes(date, p, color = symbol)) +
  geom_line(size = 1) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_color_manual(values = c(
    "GLD" = "#FFD700",
    "BTC-USD" = "#FF9900",
    "QQQ" = "#1E90FF",
    "SPY" = "#228B22",
    "TLT" = "#8A2BE2",
    "EEM" = "#FF4500"
  )) +
  scale_x_date(date_labels = "%b %y", date_breaks = "1 month") +
  labs(title = "YTD Performance of Selected Assets in 2025",
       subtitle = "Market Correction in November 2025",
       x = NULL,
       y = "Performance (Base 100)", color = NULL) +
  theme_minimal() +
  theme(legend.position = "bottom")

After the sell-off in Bitcoin that started end of October 2025, Bitcoin has been the worst performing asset of our selection year-to-date (-5.7%).

Gold is still top after a slight shift down, it’s -3.0363485% below from its ATH.

# same but bar chart YTD performance
assets |> 
  filter(date >= as.Date("2025-01-01")) |>
  group_by(symbol) |>
  summarise(ret = last(adjusted) / first(adjusted) - 1) |> 
  ggplot(aes(reorder(symbol, ret), ret, fill = symbol)) +
  geom_col() +
  geom_text(aes(label = scales::percent(ret, accuracy = 0.1)), 
            position = position_stack(vjust = 0.5), color = "white", size = 5) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_fill_manual(values = c(
    "GLD" = "#FFD700",
    "BTC-USD" = "#FF9900",
    "QQQ" = "#1E90FF",
    "SPY" = "#228B22",
    "TLT" = "#8A2BE2",
    "EEM" = "#FF4500"
  )) +
  labs(title = "YTD Performance of Selected Assets in 2025",
       subtitle = "Market Correction in November 2025",
       x = NULL,
       y = "YTD Return", fill = NULL) +
  theme_minimal() +
  theme(legend.position = "none")

Emerging markets finally made ground after lagging the US market for years.

assets |> 
  filter(date >= as.Date("2020-01-01"),
         symbol %in% c("SPY", "EEM")) |>
  group_by(symbol, year = year(date)) |>
  mutate(p = adjusted / first(adjusted) * 100) |>
  ggplot(aes(date, p, color = symbol)) +
  geom_line(size = 1) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_color_manual(values = c(
    "SPY" = "#228B22",
    "EEM" = "#FF4500"
  )) +
  scale_x_date(date_labels = "%b %y", date_breaks = "6 month") +
  labs(title = "US vs Emerging Markets Since 2020",
       subtitle = "Emerging Markets Catching Up in 2025",
       x = NULL,
       y = "Performance (Base 100)", color = NULL) +
  theme_minimal() +
  theme(legend.position = "bottom") +
  facet_wrap(~year, scale = "free_x")

Correlations

If I remember correctly, the news that bitcoin was under pressure came on a weekend, when the markts were closed. Bitcoin and tech stocks have grown a weird interdependence over the last years.

assets |> 
  filter(date >= as.Date("2024-01-01"),
         symbol %in% c("BTC-USD", "QQQ")) |> 
  group_by(symbol) |> 
  mutate(r = adjusted/lag(adjusted) - 1) |>
  group_by(symbol, week = floor_date(date, "week")) |> 
  summarise(r = prod(1 + r, na.rm = TRUE) - 1) |> 
  ggplot(aes(week, r, fill = symbol)) +
  geom_col() +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_fill_manual(values = c(
    "BTC-USD" = "#FF9900",
    "QQQ" = "#1E90FF"
  )) +
  labs(title = "Weekly Returns: Bitcoin vs QQQ Since 2024",
       subtitle = "Increased Correlation Over Time",
       x = NULL,
       fill = NULL,
       y = "Weekly Return", color = NULL) +
  theme_minimal() +
  theme(legend.position = "bottom")

Talk on AI Bubble

There is talk on there being an AI bubble (very likely) and the risk of it popping soon (not sure). The market is surely overheated. Thre question is what the catalyst for a correction would be.

nvda_msft |> 
  filter(date >= as.Date("2025-01-01")) |>
  group_by(symbol) |>
  mutate(p = adjusted / first(adjusted) * 100) |> 
  ggplot(aes(date, p, color = symbol)) +
  geom_line(size = 1) +
  scale_y_continuous(labels = scales::percent_format(scale = 1)) +
  scale_color_manual(values = c(
    "NVDA" = "#76B900",
    "MSFT" = "#F25022"
  )) +
  scale_x_date(date_labels = "%b %y", date_breaks = "1 month") +
  labs(title = "YTD Performance of NVDA and MSFT in 2025",
       subtitle = "AI Stocks Under Pressure?",
       x = NULL,
       y = "Performance (Base 100)", color = NULL) +
  theme_minimal() +
  theme(legend.position = "bottom")

Valuation

CAPE ratios are record high at 39.5 for the S&P 500 (source: https://www.multpl.com/shiller-pe). Only in 1999 before the dotcom bubble burst, it was higher at 44.2.

QQQ also at a high PE of around 35 (non-Shiller PE).