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"))
boxx <- tq_get("BOXX", from = as.Date("1900-01-01"))
usdchf <- tq_get("USDCHF=X", from = as.Date("1900-01-01"))

boxx |> saveRDS("stockdata/boxx.RDS")
usdchf |> saveRDS("stockdata/usdchf.RDS")
boxx <- readRDS("stockdata/boxx.RDS")
usdchf <- readRDS("stockdata/usdchf.RDS")

The Idea

As we know, Swiss interest rates are near bottom low again. The SNB target rate is at 0% again. Swiss 10-year government bonds yield 0.193%. On the other hand, US 10-year treasury bonds yield 4.04%, same as the 3-month T-bill (meaning the yield curve is flat).

This means that institutional investors could borrow Swiss francs at near 0% and invest the money in US treasuries at 4%. This is called a carry trade. The risk is that the USD/CHF exchange rate moves against you. If the USD depreciates against the CHF by more than the interest rate differential, you will lose money.

As a small private investor, you cannot borrow CHF at 0%. If you have spare cash, you might still be tempted to invest in USD treasuries to earn the higher yield.

BOXX

BOXX is an ETF issued by Alpha Architect that mimics the return of short term US treasuries. Instead of holding actual treasuries, it synthetically replicates the return using options by what’s called the “box spread”. A good explanation by ELM/Victor Haghani can be found here: https://elmwealth.com/thinking-outside-the-boxx/

For Swiss investors, BOXX is to be preferred over other vehicles that invest in T-bills directly, because it does not generate a traditional fixed income (usually a coupon) that would be taxed as income.

From the Swiss Federal Tax Administration website we find that BOXX had taxable income of CHF 0.106 at a taxable value of CHF 99.94125., that’s 0.11% in 2024.

Compare this to BIL (SPDR Bloomberg 1-3 Month T-Bill ETF) which had a taxable income of CHF 4.045 over the whole year 2024 at a taxable value of CHF 82.8584375. That is 4.88%, about the average T-bill yield for the year 2024.

BOXX ETF
BOXX ETF
BIL ETF
BIL ETF

So for a Swiss private investor, BOXX is a highly tax efficient way to invest in US treasuries.

Risk

Synthetic ETFs have some bad reputation, some investors prefer ETFs holding the “real thing”. So some people might see the risk of BOXX to be above that of BIL. I disagree but I don’t want to argue on this point here (this risk is very marginal anyway). There’s also the risk that the US government defaults on its debt. Again, from todays perspective, this risk is still very low (and we’d have plenty of more concerning issues at that point than having parked some excess cash in BOXX).

The real risk is the currency risk. If the USD depreciates against the CHF by more than the interest rate differential, you will lose money. And that has been the case in the last 12 months:

usdchf |> 
  filter(date >= as.Date("2023-01-01")) |>
  ggplot(aes(date, close)) +
  geom_line() +
  scale_y_continuous() +
  labs(title = "USD/CHF Exchange Rate",
       subtitle = "Source: Yahoo Finance",
       y = "USD/CHF",
       x = "")

boxx |> 
  filter(date >= as.Date("2023-01-01")) |>
  mutate(p = adjusted/adjusted[1L]-1) |> 
  ggplot(aes(date, p)) +
  geom_line(color = "red") +
  scale_y_continuous(labels = percent) +
  labs(title = "BOXX ETF Cumulative Return",
       subtitle = "Source: Yahoo Finance",
       y = "Return",
       x = "")

boxx |> 
  left_join(usdchf |> select(date, usdchf = close), by = "date") |>
  mutate(usdchf = na.locf(usdchf, na.rm = FALSE)) |> 
  mutate(adjusted.chf = adjusted*usdchf,
         p.chf = adjusted.chf/adjusted.chf[1L]-1) |> 
  filter(date >= as.Date("2023-01-01")) |>
  ggplot(aes(date, p.chf)) +
  geom_line(color = "blue") +
  scale_y_continuous(labels = percent) +
  labs(title = "BOXX ETF Cumulative Return in CHF",
       subtitle = "Source: Yahoo Finance",
       y = "Return",
       x = "")

Clearly, the depreciation of the USD against the CHF has more than eaten up the yield advantage of US treasuries. Since 2023 (BOXX was released end of 2022), the carry trade would have lost money for a Swiss investor (around -3%).

boxx |> 
  left_join(usdchf |> select(date, usdchf = close), by = "date") |>
  mutate(usdchf = na.locf(usdchf, na.rm = FALSE)) |> 
  mutate(adjusted.chf = adjusted*usdchf,
         r.chf = adjusted.chf/lag(adjusted.chf)-1) |>
  filter(date >= as.Date("2023-01-01")) |> 
  group_by(quarter = quarter(date, with_year = TRUE)) |> 
  summarise(r = prod(1+r.chf, na.rm = TRUE)-1) |> 
  ggplot(aes(factor(quarter), r)) +
  geom_col(fill = "blue") +
  scale_y_continuous(labels = percent) +
  labs(title = "BOXX ETF Quarterly Return in CHF",
       subtitle = "Source: Yahoo Finance",
       y = "Return",
       x = "Quarter")

The second quarter of 2025 was particularly bad, with a loss of almost 10%.

One could hope for a mean reversion of the USD/CHF exchange rate, but that’s speculation. And that’s what a carry trade is all about.