Cours ajustés mensuels - adjusted_monthly

Data - Yahoo

Dernier cours ajusté (dividendes réinvestis) de chaque mois pour tous les titres de adjusted_USA et adjusted_FRA. Format pratique pour les tests CAPM / Fama-French (rendement mensuel = Adjusted_t / Adjusted_{t-1} - 1).

Couverture

Code
adj_m |> group_by(universe, month) |> summarise(n = n_distinct(ticker), .groups = "drop") |>
  ggplot(aes(month, n, color = universe)) + geom_line() + theme_minimal() + xlab("") + ylab("Titres par mois") +
  theme(legend.position = c(0.2, 0.85), legend.title = element_blank())

Portefeuille équipondéré vs. indice Total Return

Rendement mensuel moyen (équipondéré) des titres du fichier, comparé aux indices Total Return de investing (S&P 500 TR, CAC 40 Gross TR). Les écarts viennent à la fois de la pondération (équipondéré vs. capitalisation) et du biais de survie (titres encore cotés uniquement).

Code
ret <- adj_m |> filter(Adjusted > 0) |> arrange(ticker, month) |> group_by(ticker) |>
  mutate(r = Adjusted / lag(Adjusted) - 1, gap = as.numeric(month - lag(month))) |> ungroup() |>
  filter(!is.na(r), gap <= 31, abs(r) < 1)
ew <- ret |> group_by(universe, month) |> filter(n() >= 20) |>
  summarise(r = mean(r), .groups = "drop")
idx <- indices |> filter(symbol %in% c("SPXTR", "PX1GR")) |>
  mutate(month = as.Date(format(Date, "%Y-%m-01")), universe = ifelse(symbol == "SPXTR", "USA", "FRA")) |>
  group_by(universe, month) |> summarise(Close = last(Close), .groups = "drop") |> group_by(universe) |>
  arrange(month) |> mutate(r = Close / lag(Close) - 1) |> ungroup() |> filter(!is.na(r))
cmp <- bind_rows(ew |> mutate(serie = "Équipondéré (titres du fichier)"),
                 idx |> select(universe, month, r) |> mutate(serie = "Indice Total Return")) |>
  filter(month >= as.Date("1993-01-01")) |>
  group_by(universe, serie) |> arrange(month) |> mutate(y = 100 * cumprod(1 + r)) |> ungroup()
ggplot(cmp, aes(month, y, color = serie)) + geom_line() + facet_wrap(~universe, scales = "free_y") +
  scale_y_log10() + theme_minimal() + xlab("") + ylab("Base 100 (échelle log)") +
  theme(legend.position = "bottom", legend.title = element_blank())

Code
cmp |> group_by(Univers = universe, Série = serie) |>
  summarise(`Rendement annualisé (%)` = round(100 * (prod(1 + r)^(12 / n()) - 1), 2),
            `Volatilité annualisée (%)` = round(100 * sd(r) * sqrt(12), 2), .groups = "drop") |>
  print_table_conditional()
Univers Série Rendement annualisé (%) Volatilité annualisée (%)
FRA Indice Total Return 7.64 17.86
FRA Équipondéré (titres du fichier) 9.77 15.82
USA Indice Total Return 10.01 14.88
USA Équipondéré (titres du fichier) 12.44 16.26