# Configuration de l'encodage
Sys.setlocale("LC_ALL", "en_US.UTF-8")
## [1] "LC_COLLATE=en_US.UTF-8;LC_CTYPE=en_US.UTF-8;LC_MONETARY=en_US.UTF-8;LC_NUMERIC=C;LC_TIME=en_US.UTF-8"
options(encoding = "UTF-8")
# Chargement des packages nécessaires
library(quantmod)
## Warning: le package 'quantmod' a été compilé avec la version R 4.2.3
## Le chargement a nécessité le package : xts
## Warning: le package 'xts' a été compilé avec la version R 4.2.3
## Le chargement a nécessité le package : zoo
## Warning: le package 'zoo' a été compilé avec la version R 4.2.3
##
## Attachement du package : 'zoo'
## Les objets suivants sont masqués depuis 'package:base':
##
## as.Date, as.Date.numeric
## Le chargement a nécessité le package : TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
library(TTR)
library(PerformanceAnalytics)
## Warning: le package 'PerformanceAnalytics' a été compilé avec la version R
## 4.2.3
##
## Attachement du package : 'PerformanceAnalytics'
## L'objet suivant est masqué depuis 'package:graphics':
##
## legend
library(ggplot2)
## Warning: le package 'ggplot2' a été compilé avec la version R 4.2.3
library(xts)
library(lubridate)
## Warning: le package 'lubridate' a été compilé avec la version R 4.2.3
##
## Attachement du package : 'lubridate'
## Les objets suivants sont masqués depuis 'package:base':
##
## date, intersect, setdiff, union
# Fonction pour récupérer les données du CAC 40
get_cac40_data <- function(start_date = Sys.Date() - days(3*365), end_date = Sys.Date()) {
getSymbols("^FCHI", from = start_date, to = end_date, src = "yahoo")
return(FCHI)
}
# Stratégie Buy and Hold
buy_and_hold <- function(prices) {
returns <- ROC(prices, n = 1, type = "discrete")
returns[is.na(returns)] <- 0
return(returns)
}
# Stratégie Momentum basée sur la comparaison des momentums
momentum_strategy <- function(prices, fast_period = 5, slow_period = 20) {
# Calcul des momentums
mom_fast <- ROC(prices, n = fast_period)
mom_slow <- ROC(prices, n = slow_period)
# Création des signaux (long quand momentum rapide > momentum lent)
signals <- lag(ifelse(mom_fast > mom_slow, 1, -1))
signals[is.na(signals)] <- 0
# Calcul des rendements
returns <- ROC(prices, n = 1, type = "discrete")
returns[is.na(returns)] <- 0
strategy_returns <- returns * signals
return(strategy_returns)
}
# Ajout de l'indicateur de volatilité
volatility_filter <- function(prices, lookback = 20, vol_threshold = 0.2) {
returns <- ROC(prices, n = 1, type = "discrete")
returns[is.na(returns)] <- 0
vol <- rollapply(returns, width = lookback,
FUN = function(x) sd(x, na.rm = TRUE) * sqrt(252),
align = "right", fill = NA)
vol_signal <- lag(ifelse(vol < vol_threshold, 1, 0))
vol_signal[is.na(vol_signal)] <- 0
return(vol_signal)
}
# Ajout du stop-loss avec reset de position
apply_stop_loss <- function(returns, stop_loss = -0.02) {
# Vérification des entrées et conversion en xts si nécessaire
if (!is.xts(returns)) returns <- as.xts(returns)
if (length(returns) == 0) return(returns)
# Initialisation des variables
filtered_returns <- xts(rep(0, length(returns)), index(returns))
equity_curve <- xts(rep(1, length(returns)), index(returns))
peak_values <- xts(rep(1, length(returns)), index(returns))
position_active <- TRUE
# Traitement de chaque point temporel
for (i in seq_len(length(returns))) {
ret <- as.numeric(returns[i])
if (is.na(ret)) next
if (i > 1) {
equity_curve[i] <- as.numeric(equity_curve[i-1]) * (1 + ret)
peak_values[i] <- max(as.numeric(peak_values[i-1]), as.numeric(equity_curve[i]))
} else {
equity_curve[i] <- 1 + ret
peak_values[i] <- max(1, equity_curve[i])
}
if (position_active) {
if (as.numeric(equity_curve[i]) < as.numeric(peak_values[i]) * (1 + stop_loss)) {
position_active <- FALSE
} else {
filtered_returns[i] <- ret
}
} else if (ret > 0) {
position_active <- TRUE
equity_curve[i] <- 1 + ret
peak_values[i] <- max(1, equity_curve[i])
filtered_returns[i] <- ret
}
}
return(filtered_returns)
}
# Fonction principale pour l'analyse comparative
compare_strategies <- function(fast_period = 5, slow_period = 20) {
# Récupération des données
cac40 <- get_cac40_data()
prices <- Cl(cac40)
# Calcul des rendements pour chaque stratégie
bnh_returns <- buy_and_hold(prices)
mom_returns <- momentum_strategy(prices, fast_period, slow_period)
# Ajout du filtre de volatilité
vol_signal <- volatility_filter(prices)
mom_vol_returns <- mom_returns * vol_signal
# Ajout des stratégies avec stop-loss
mom_vol_sl_returns <- apply_stop_loss(mom_vol_returns)
mom_sl_returns <- apply_stop_loss(mom_returns)
# Création du tableau de comparaison
strategies <- na.omit(merge(bnh_returns, mom_returns, mom_vol_returns, mom_vol_sl_returns, mom_sl_returns))
if (nrow(strategies) == 0) {
stop("Pas assez de données pour l'analyse")
}
colnames(strategies) <- c("Buy_and_Hold", "Momentum", "Momentum_Vol", "Momentum_Vol_SL", "Momentum_SL")
# Calcul des performances
performance <- table.AnnualizedReturns(strategies)
# Conversion en base 100
equity_curves <- 100 * apply(1 + strategies, 2, cumprod)
# Création du dataframe pour ggplot
equity_df <- data.frame(
Date = index(equity_curves),
equity_curves
)
# Création du graphique avec ggplot2
p <- ggplot(equity_df, aes(x = Date)) +
geom_line(aes(y = Buy_and_Hold, color = "Buy and Hold"), linewidth = 1) +
geom_line(aes(y = Momentum, color = "Momentum"), linewidth = 1) +
geom_line(aes(y = Momentum_Vol, color = "Momentum + Vol"), linewidth = 1) +
geom_line(aes(y = Momentum_Vol_SL, color = "Momentum + Vol + SL"), linewidth = 1) +
geom_line(aes(y = Momentum_SL, color = "Momentum + SL"), linewidth = 1) +
scale_color_manual(values = c("Buy and Hold" = "black",
"Momentum" = "blue",
"Momentum + Vol" = "green",
"Momentum + Vol + SL" = "red",
"Momentum + SL" = "purple")) +
labs(title = paste0("Performance Comparée des Stratégies (Base 100)\n",
"Momentum ", fast_period, "j vs ", slow_period, "j"),
x = "Date",
y = "Performance",
color = "Stratégie") +
theme_minimal() +
theme(legend.position = "bottom",
plot.title = element_text(hjust = 0.5))
print(p)
# Calcul des performances finales en base 100
final_performance <- tail(equity_curves, 1)
print("Performance finale (base 100):")
print(final_performance)
return(list(
performance = performance,
returns = strategies,
raw_data = cac40,
equity_curves = equity_curves
))
}
# Exécution de l'analyse
results <- compare_strategies(fast_period = 5, slow_period = 20)

## [1] "Performance finale (base 100):"
## Buy_and_Hold Momentum Momentum_Vol Momentum_Vol_SL Momentum_SL
## 2025-02-18 120.892 97.53896 89.65988 215.7532 307.8603
print(results$performance)
## Buy_and_Hold Momentum Momentum_Vol Momentum_Vol_SL
## Annualized Return 0.0643 -0.0082 -0.0352 0.2874
## Annualized Std Dev 0.1653 0.1493 0.1292 0.1111
## Annualized Sharpe (Rf=0%) 0.3892 -0.0546 -0.2726 2.5864
## Momentum_SL
## Annualized Return 0.4469
## Annualized Std Dev 0.1272
## Annualized Sharpe (Rf=0%) 3.5125