1. Dane – kursy akcji (2021–2026)

fetch <- function(ticker) {
  getSymbols(ticker, src = "yahoo", from = "2021-03-01", to = "2026-03-01",
             auto.assign = FALSE)[, 6]
}

nvda   <- fetch("NVDA")
aramco <- fetch("2222.SR")
byd    <- fetch("BYDDF")

# Miesięczne stopy strat: L_t = -(P_t - P_{t-1}) / P_{t-1} * 100
monthly_losses <- function(x) {
  m <- as.numeric(Cl(to.monthly(x)))
  round(-diff(m) / head(m, -1) * 100, 4)
}

losses <- data.frame(
  Data   = index(to.monthly(nvda))[-1],
  NVDA   = monthly_losses(nvda),
  Aramco = monthly_losses(aramco),
  BYD    = monthly_losses(byd)
) |> na.omit()

cat("Liczba obserwacji:", nrow(losses), "\n")
## Liczba obserwacji: 59

2. Kursy akcji – wykresy cen dziennych

to_df <- function(x, name) {
  data.frame(Date = index(x), Price = as.numeric(x), Stock = name)
}

prices <- bind_rows(to_df(nvda, "NVDA"), to_df(aramco, "Aramco"), to_df(byd, "BYD"))

ggplot(prices, aes(x = Date, y = Price, color = Stock)) +
  geom_line(linewidth = 0.7) +
  facet_wrap(~Stock, scales = "free_y", ncol = 1) +
  scale_color_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Ceny dzienne akcji (2021–2026)", x = NULL, y = "Cena (USD)") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none", panel.grid.minor = element_blank())


3. Miesięczne stopy strat – wykresy słupkowe

losses_long <- melt(losses, id.vars = "Data", variable.name = "Stock", value.name = "Loss")
losses_long$Index <- ave(seq_len(nrow(losses_long)), losses_long$Stock, FUN = seq_along)

ggplot(losses_long, aes(x = Index, y = Loss, fill = Loss >= 0)) +
  geom_bar(stat = "identity", width = 0.8) +
  geom_hline(yintercept = 0, color = "gray40", linewidth = 0.4) +
  facet_wrap(~Stock, ncol = 1, scales = "free_y") +
  scale_fill_manual(values = c("TRUE" = "darkred", "FALSE" = "darkgreen"),
                    labels = c("Strata", "Zysk")) +
  labs(title = "Miesięczne stopy strat (2021–2026)",
       x = "Miesiąc (L.p.)", y = "Stopa straty (%)", fill = NULL) +
  theme_minimal(base_size = 11) +
  theme(panel.grid.minor = element_blank())


4. Statystyki opisowe

desc <- losses |>
  select(-Data) |>
  summarise(across(everything(), list(
    N        = \(x) length(x),
    Srednia  = \(x) round(mean(x), 4),
    Mediana  = \(x) round(median(x), 4),
    SD       = \(x) round(sd(x), 4),
    Min      = \(x) round(min(x), 4),
    Max      = \(x) round(max(x), 4),
    Skosnosc = \(x) round(skewness(x), 4),
    Kurtoza  = \(x) round(kurtosis(x) - 3, 4)
  ), .names = "{.fn}_{.col}")) |>
  t() |> as.data.frame()

colnames(desc) <- "Wartość"
desc$Statystyka <- rownames(desc)
desc <- desc[, c("Statystyka", "Wartość")]
rownames(desc) <- NULL
print(desc, row.names = FALSE)
##       Statystyka  Wartość
##           N_NVDA  59.0000
##     Srednia_NVDA  -5.5393
##     Mediana_NVDA  -5.6197
##          SD_NVDA  14.8199
##         Min_NVDA -36.3436
##         Max_NVDA  32.0274
##    Skosnosc_NVDA   0.1001
##     Kurtoza_NVDA  -0.4698
##         N_Aramco  59.0000
##   Srednia_Aramco  -0.1617
##   Mediana_Aramco   0.3610
##        SD_Aramco   4.2379
##       Min_Aramco -12.3839
##       Max_Aramco   7.7175
##  Skosnosc_Aramco  -0.5553
##   Kurtoza_Aramco   0.4206
##            N_BYD  59.0000
##      Srednia_BYD  -1.5540
##      Mediana_BYD  -2.5112
##           SD_BYD  11.6478
##          Min_BYD -36.9218
##          Max_BYD  19.6098
##     Skosnosc_BYD  -0.7210
##      Kurtoza_BYD   0.8395

5. Histogramy z krzywą gęstości

ggplot(losses_long, aes(x = Loss, fill = Stock)) +
  geom_histogram(aes(y = after_stat(density)), bins = 20,
                 color = "white", alpha = 0.8) +
  geom_density(color = "black", linewidth = 0.8, fill = NA) +
  geom_vline(xintercept = 0, linetype = "dashed", color = "gray30") +
  facet_wrap(~Stock, scales = "free") +
  scale_fill_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Histogramy stóp strat z gęstością", x = "Stopa straty (%)", y = "Gęstość") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none", panel.grid.minor = element_blank())


6. Wykresy pudełkowe (box plots)

ggplot(losses_long, aes(x = Stock, y = Loss, fill = Stock)) +
  geom_boxplot(outlier.shape = 21, outlier.size = 2, alpha = 0.8) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray40") +
  scale_fill_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Rozkład stóp strat – box plots", x = NULL, y = "Stopa straty (%)") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none")


7. Korelacje – macierz i scatter plot matrix

cor_matrix <- cor(losses[, c("NVDA","Aramco","BYD")], method = "pearson")
cat("=== Korelacja Pearsona ===\n"); print(round(cor_matrix, 4))
## === Korelacja Pearsona ===
##           NVDA  Aramco    BYD
## NVDA    1.0000 -0.0273 0.2545
## Aramco -0.0273  1.0000 0.0612
## BYD     0.2545  0.0612 1.0000
cor_kendall <- cor(losses[, c("NVDA","Aramco","BYD")], method = "kendall")
cat("\n=== Korelacja Kendalla (tau) ===\n"); print(round(cor_kendall, 4))
## 
## === Korelacja Kendalla (tau) ===
##          NVDA Aramco    BYD
## NVDA   1.0000 0.0146 0.1642
## Aramco 0.0146 1.0000 0.0579
## BYD    0.1642 0.0579 1.0000
cor_spearman <- cor(losses[, c("NVDA","Aramco","BYD")], method = "spearman")
cat("\n=== Korelacja Spearmana ===\n"); print(round(cor_spearman, 4))
## 
## === Korelacja Spearmana ===
##          NVDA Aramco    BYD
## NVDA   1.0000 0.0224 0.2345
## Aramco 0.0224 1.0000 0.0811
## BYD    0.2345 0.0811 1.0000
cor_long <- melt(cor_matrix)
ggplot(cor_long, aes(Var1, Var2, fill = value)) +
  geom_tile(color = "white") +
  geom_text(aes(label = round(value, 3)), size = 4.5, fontface = "bold") +
  scale_fill_gradient2(low = "steelblue", mid = "white", high = "darkred",
                       midpoint = 0, limits = c(-1, 1), name = "r") +
  labs(title = "Macierz korelacji Pearsona", x = NULL, y = NULL) +
  theme_minimal(base_size = 11) +
  theme(axis.text = element_text(size = 12, face = "bold"))

ggpairs(losses[, c("NVDA","Aramco","BYD")],
        lower = list(continuous = wrap("points", alpha = 0.5, size = 1.2, color = "steelblue")),
        diag  = list(continuous = wrap("densityDiag", fill = "steelblue", alpha = 0.5)),
        upper = list(continuous = wrap("cor", size = 4.5))) +
  labs(title = "Scatter plot matrix – miesięczne stopy strat") +
  theme_minimal(base_size = 10)


8. Szeregi czasowe znormalizowane

1. Nakładające się wykresy

losses_norm <- losses |>
  mutate(across(c(NVDA, Aramco, BYD), \(x) (x - mean(x)) / sd(x)))

losses_norm_long <- melt(losses_norm, id.vars = "Data",
                         variable.name = "Stock", value.name = "Loss_z")

ggplot(losses_norm_long, aes(x = Data, y = Loss_z, color = Stock)) +
  geom_line(alpha = 0.85, linewidth = 0.7) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50") +
  scale_color_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Znormalizowane stopy strat (z-score)", x = NULL, y = "Z-score", color = NULL) +
  theme_minimal(base_size = 11) +
  theme(panel.grid.minor = element_blank())

2. Osobne wykresy z wygładzeniem

losses_norm <- losses |>
  mutate(across(c(NVDA, Aramco, BYD), \(x) (x - mean(x)) / sd(x)))

losses_norm_long <- melt(losses_norm, id.vars = "Data",
                         variable.name = "Stock", value.name = "Loss_z")

ggplot(losses_norm_long, aes(x = Data, y = Loss_z, color = Stock)) +
  geom_hline(yintercept = 0, linetype = "dashed", color = "gray50", linewidth = 0.5) +
  geom_line(alpha = 0.25, linewidth = 0.5) +                        # raw — faded
  geom_smooth(method = "loess", span = 0.2, se = FALSE, linewidth = 1.2) +  # trend
  facet_wrap(~Stock, ncol = 1) +
  scale_color_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Znormalizowane stopy strat (z-score)",
       subtitle = "Linia ciągła = trend LOESS  |  tło = surowe dane",
       x = NULL, y = "Z-score", color = NULL) +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none", panel.grid.minor = element_blank())


9. Test normalności (Shapiro-Wilk)

for (s in c("NVDA", "Aramco", "BYD")) {
  sw <- shapiro.test(losses[[s]])
  cat(sprintf("%-8s  W = %.4f  p-value = %.4f  → %s\n",
              s, sw$statistic, sw$p.value,
              ifelse(sw$p.value < 0.05, "ODRZUCAMY normalność", "Brak podstaw do odrzucenia")))
}
## NVDA      W = 0.9912  p-value = 0.9469  → Brak podstaw do odrzucenia
## Aramco    W = 0.9693  p-value = 0.1413  → Brak podstaw do odrzucenia
## BYD       W = 0.9582  p-value = 0.0410  → ODRZUCAMY normalność

10. Q-Q Plots

ggplot(losses_long, aes(sample = Loss, color = Stock)) +
  stat_qq(alpha = 0.7) +
  stat_qq_line(linewidth = 0.8) +
  facet_wrap(~Stock, scales = "free") +
  scale_color_manual(values = c(NVDA = "darkgreen", Aramco = "darkred", BYD = "darkblue")) +
  labs(title = "Q-Q Plots – stopy strat vs. rozkład normalny",
       x = "Kwantyle teoretyczne", y = "Kwantyle próby") +
  theme_minimal(base_size = 11) +
  theme(legend.position = "none")