Sélection de portefeuilles avec OLMAR

OLMAR pour OnLine portfolio selection with Moving Average Reversion.

Cet algorithme entends profiter de l’aspect ‘mean reverting‘ des marchés grâce à une technique d’apprentissage (machine learning). Il reçoit en entrée des données, et sur la base de celles-ci, il produira une prévision pour l’incrément suivant. Cette prévision sera utilisée pour construire le portefeuille maximisant le rendement espéré en utilisant un algorithme passif-aggressif (Passive Aggressive learning). L’idée de base est de minimiser les écarts de pondération entre le portefeuille actuel et le portefeuille cible, qui incorpore les prévisions de rendements.

Prévisions des rendements

Si l’on part du principe que l’ensemble des opérateurs de marchés sont rationnels, alors on peut imaginer qu’ils vont essayer d’exploiter les opportunités d’arbitrage qui s’offrent à eux. Si le prix d’un actif s’écarte fortement à la baisse de sa valeur fondamentale, alors il sera acheté, inversement, s’il s’écarte trop à la hausse, il sera vendu. Ces opérations d’arbitrage vont ramener le prix du titre à sa valeur fondamentale, concrétisant le phénomène de retour à la moyenne. Cette hypothèse (qui a été corroborée par de nombreuses analyses empiriques) implique donc que lorsque ce phénomène se produit, il est possible de fournir une prévision robuste de l’évolution d’un titre, qui est tout simplement basée sur son évolution passée. Ainsi, l’évolution du prix en t+1 devrait être égale à l’inverse de celle en t-1.

Mathématiquement, on a :

{x}over{~}_{t+1} = 1/x_{t} doubleright P_{t+1}/P_{t}=P_{t-1}/P_{t} doubleright P_{t+1} = P_{t-1}

Mais les données journalières sont des données très bruitées alors pour filtrer ce bruit on utilise une moyenne mobile sur plusieurs jours.

{x}over{~}_{t+1}(w) =  {SMA_{t}(w)}/P_{t} = {1/w}{(P_{t}/P_{t}+P_{t-1}/P_{t}+...+P_{t-w+1}/P_{t})}

avec w la duration de la moyenne mobile.

Le schéma ci-dessous nous donne une représentation du fonctionnement de la prévision :

Prev

On voit très bien que lorsqu’il y a un écart important entre le dernier prix Pt et la moyenne mobile sur les derniers jours, alors la prévision sera d’autant importante. On remarque également que tant que le dernier prix Pt est supérieur à la moyenne mobile, alors la prévision pour l’incrément suivant est inférieure à 1, et lorsque le prix Pt est inférieur à sa moyenne mobile, la prévision est supérieure à 1, ce qui caractérise bien le phénomène de retour à la moyenne.

Comment fonctionne l’algo ?

L’idée de base est de maximiser la performance en exploitant la prévision des rendements, grâce à l’algorithme passif agressif. A chaque incrément, les poids qui seront en ligne avec les prévisions, bougeront peu, alors que ceux qui en seront éloignés vont significativement changer. Si le marché est mean reverting, alors un écart à la moyenne est une erreur qui sera corrigée par le marché. C’est l’exploitation de cette erreur qui justifie le terme d’agressif, car lors du travail d’optimisation, quand on va tenter de minimiser la distance entre le portefeuille actuel et le portefeuille cible, ce sont les titres dont les prévisions s’écartent le plus de la prévision moyenne qui subiront les réajustement les plus important. En revanche, ceux dont le prévision est proche de la prévision moyenne, changeront moins. L’idée n’est pas ici de vérifier si dans l’absolu la prévision est bonne au regard de la valeur elle même, la prévision est surtout importante par rapport à la prévision moyenne de l’univers.

Si l’on part du principe que le marché est ‘mean reverting’ alors l’équation juste au-dessus fournie une prévision robuste de l’évolution du portefeuille pour la date t+1. En t+1, sa valeur devrait être égale aux poids actuels (vecteur b) drifté des prix en t+1, soit b_{t+1} = b.x_{t+1}.

Schématiquement l’erreur est définie comme la différence entre chaque prévision et la prévision moyenne :

err =  x_{t+1}-overline{x}_{t+1}

avec overline{x}_{t+1}={{1^T x_{t+1}}/m}.

La mise à jour des poids pour l’incrément suivant sera comme suit :

b_{t+1}=b_{t}+lambda_{t+1}(x_{t+1}-overline{x}_{t+1}1) (1)

avec lambda_{t+1}=max delim{lbrace}{0,{{epsilon-b_{t}.x_{t+1}}/{delim{vert}{x_{t+1} - overline{x}_{t+1}1}{vert}^2}}}{rbrace} le multiplicateur de Lagrange.

On remarque également que le seuil de reversion est important car si la solution actuelle (le portefeuille drifté des prévisions) est supérieure au seuil de reversion (lambda vaut zéro), alors il n’est pas nécessaire de changer le portefeuille, mais lorsque ce n’est pas le cas, on change les pondérations.

Le problème revient donc à minimiser les erreurs de pondérations dues aux prévisions lorsque lambda est supérieur à zéro :

b_{t+1} = {arg min}under{b in Delta_m}delim{vert}{b - b_{t+1}}{vert}^2

Dans l’exemple de cet article, l’interdiction de vente à découvert facilite le programme d’optimisation, et nous permet d’utiliser l’algorithme du simplexe pour obtenir nos pondérations optimales (voir [3]), ce qui permet également de réduire grandement les temps de calculs.

Analyse

On voit bien en regardant l’équation (1) que la mise à jour des poids pour l’incrément suivant est fonction de deux facteurs (lambda et l’erreur de prévision). Lorsque l’erreur de prévision est faible pour un titre, x_{t+1}-overline{x}_{t+1} tend vers 0. Se faisant, il gardera le même poids qu’avant. En revanche, si l’erreur de prévision est importante, son poids sera revu à la hausse ou à la baisse, en fonction de l’ampleur de l’erreur de prévision et de son signe.

si x_{i,t+1}> overline{x}_{t+1} doubleright b_{i,t+1}nearrow » title= »x_{i,t+1}> overline{x}_{t+1} doubleright b_{i,t+1}nearrow »/></p>
<p style= et si x_{i,t+1}< overline{x}_{t+1} doubleright b_{i,t+1}searrow

On l’a vu plus haut, la prévision pour l’incrément suivant est fonction de l’écart du dernier prix par rapport à sa moyenne mobile sur plusieurs jours. Ainsi, lorsque le dernier prix s’écarte fortement de sa moyenne mobile, à la hausse ou à la baisse, il marque une certaine rupture dans sa tendance, et plus il s’écartera du marché, plus une opportunité va se concrétiser.

Définition des backtests

La méthodologie du backtest suit celle qui est mentionnée dans l’article que je cite [1]. On considère un investissement dans m actifs durant n périodes. On valorise la stratégie avec les cours de clôtures qu’on exprime de façon vectorielle avec P_{t} in {bbR^m}_{+} et où chaque élément du vecteur représente le cours de clôture de l’actif i. La variation du prix est représentée par un vecteur de prix relatif X_{t}in{bbR^m}_{+}, avec x_{t,i} = {p_{t,i}}/{p_{t-1,i}}. Un investissement à une période t est représenté par un vecteur de portefeuille b_{t}=(b_{t,1},...,b_{t,m}), où b_{t,i} représente la proportion du portefeuille investie dans l’actif i. En faisant l’hypothèse que notre stratégie est financée et que les positions short sont interdites, aucun élément de notre vecteur ne peut être négatif et la somme des poids doit être inférieure ou égale à 1.

A l’instant t, le portefeuille b_{t} produit un rendement sur la période égale à s_{t}={b_{t}}^{T}X_{t}=sum{i=1}{m}{b_{t,i}x_{t,i}}.

Comme on utilise les prix relatifs pour valoriser la stratégie, la valeur du portefeuille va croître de façon multiplicative. Après n périodes, le portefeuille va produire une valeur cumulée égale à S_{n}, qui viendra augmenter (ou baisser) la valeur initiale du portefeuille par un facteur de prod{t=1}{n}{{b_{t}}^{T}X_{t}}, qu’on peut également écrire comme S_{n}(b^n,x^n)=S_{0}prod{t=1}{n}{{b_{t}}^{T}X_{t}}S_{0} est l’investissement initiale.

Dans tous les backtests, la stratégie OLMAR est comparée à une stratégie ‘Equal Weighted‘.

Mes données

Dans un premier temps, j’ai essayé de reproduire les résultats de l’auteur en utilisant ses données (on peut les trouver ici). Elles concernent exclusivement les marchés actions américains, c’est pourquoi j’ai également décidé de tester la stratégie sur des actions européennes. Bien que j’ai essayé d’éviter tout biais dans mes backtests, il en existe toujours un peu, et notamment le biais du survivant, puisque je n’utilise que des valeurs encore existantes. Dans les données de l’auteur, dont je publie un backtest juste en dessous, il existe également un biais ‘look ahead bias’, car les données qui sont backtestées entre 1998 et 2003, sont constituées des plus grosses capitalisations de l’indice en 2003. C’est comme si dès 1998, nous connaissions les valeurs qui progresseraient le mieux jusqu’en 2003 (au regard du lien qui peut exister entre la capitalisation et la performance boursière d’un titre). Malgré tout, dans tous mes backtests, je compare la performance de la stratégie à celle d’un portefeuille équipondéré (sachant qu’il a été démontré dans la littérature financière, que l’équipondération est une stratégie qui donne souvent de meilleurs résultats que les indices de capitalisations), donc le biais existe pour les deux stratégies.

Quelques backtests

Sur un des univers de l’auteur :

Backtest_sp500

Le backtest au-dessus reprend l’univers S&P 500 définit par l’auteur (dont le lien est plus haut). Étant donné que je n’ai pas été capable de récupérer les données du titre SBC Communication, je l’ai retiré de l’univers. Le fait de retirer cette valeur diminue significativement les résultats, mais ils restent intéressant. Pour ce backtest, j’ai utilisé les paramètres conseillés par l’auteur, qui sont w = 5 et e = 10.

Le tableau ci-dessous rend compte de la sensibilité des performances au choix des paramètres w et e :

sp500_sensi_param

Remarque : ici les backtests commencent en date du 30/01/1998. Le tableau reprend la valorisation finale de la stratégie à la dernière date du backtest, sachant qu’on commence avec 1$ (ou €) d’investissement. Rappel : les frais de transactions sont nuls.

Sur un univers d’actions européennes :

Dans un premier temps, j’ai construit un univers des 30 plus grosses capitalisations françaises et allemandes, en date du 31/12/2010. J’ai effectué des backtests sur deux périodes afin de savoir s’il était possible d’extraire les paramètres optimaux pour la période ‘out-sample’. La période ‘in-sample’ court du 30/12/2005 au 31/12/2010, la période ‘out-sample’, du 31/12/2010 au 31/12/2015.

Résultats des simulations sur l’univers français : Backtests_univers_France

Résultats des simulations sur l’univers allemand : Backtests_univers_Allemagne

Il ressort des résultats que les paramètres optimaux ne semblent pas stable à travers le temps, et qu’une méthode aussi naïve ne fonctionne pas. Si j’utilise les paramètres qui ont le mieux fonctionné entre le 2006 et 2010 pour la stratégie en période ‘out-sample’, j’obtiens des résultats médiocres. Sur l’univers français, en période ‘in-sample’, les paramètres optimaux correspondaient à la combinaison w = 21 et e = 12, tandis que sur la période ‘out-sample’, ils correspondaient à w = 19 et e = 4. La réutilisation des paramètres de la période in-sample sur la période out-sample conduis à obtenir une performance de +154% alors qu’avec les paramètres optimaux j’aurais eu une performance de +275%. Même rengaine sur les autres univers !

Ces résultats montrent également que le choix de l’univers est important. En effet, contrairement aux résultats sur les univers français et américain, les résultats sur l’univers allemand sont pitoyables. Sur l’univers français, on voit que la stratégie offre une meilleure performance (et je parle ici uniquement de performance, car cette statistique serait bien différente si l’on regardait le ratio de Sharpe) que la stratégie ‘Equal Weighted’ dans plus de 82% des cas (out-sample), tandis que sur l’univers allemand, la stratégie OLMAR n’arrive pas à battre la stratégie ‘Equal Weighted’ une seule fois.

Dans les backtests ci-dessous, j’essaie d’améliorer le choix de l’univers. Chaque fin d’année, entre 2010 et 2014, je créer un nouvel univers composé des 15 sociétés possédant le meilleur alpha estimé contre l’Eurostoxx 50 dividendes net réinvestis sur 5 années, sur un univers global composé des 100 plus grosses capitalisations européennes cotant en euro, au 31 décembre 2010. L’univers ainsi définit sera utilisé pour la stratégie de l’année qui suit.

Univers global : Univers LC 100 dec 2010

Le tableau ci-dessous reprend les périodes d’estimation pour l’alpha et les univers résiduels ainsi que les résultats des simulations lorsqu’on ne fixe pas, à priori de paramètres, et enfin les résultats de la stratégie OLMAR en choisissant arbitrairement les paramètres suivants : w = 5 et e = 10, comme dans l’exemple de l’auteur.

Resultats strategie alpha

bt_strat_alpha_2011

bt_strat_alpha_2012

bt_strat_alpha_2013

bt_strat_alpha_2014

bt_strat_alpha_2015

On remarque qu’il existe dans toutes les situations des paramètres optimaux permettant de capter de façon très efficace les phénomènes de retour à la moyenne. Malheureusement, il n’existe pas encore, à ma connaissance, de méthodes pour prévoir les paramètres qu’il faudra utiliser pour les futures investissements. Cependant, l’utilisation d’univers pertinents permettant d’améliorer significativement les performances, il est possible de fixer arbitrairement des paramètres, comme je l’ai fait dans les backtests. Dans ce cas, je dirai qu’il faut user de parcimonie, car les résultats des simulations montrent que les paramètres optimaux sont rarement extrêmes.

Conclusion

L’étude des simulations numériques donne des résultats quasi similaires à ceux des auteurs du papier : les performances sont globalement bonnes puisque la stratégie enregistre de manière régulière, et sur plusieurs échantillons, des performances meilleures que la stratégie ‘Equal Weighted’. La stratégie souffre cependant de certains déficits. Les portefeuilles générés sont ultra concentrés, se faisant, les bénéfices de la diversification sont inexistants. Le deuxième déficit de cette stratégie est inhérent à beaucoup de stratégies systématiques. En utilisant uniquement des prix en input, on se passe d’informations qualitatives sur les valeurs qui vont être sélectionnées par le modèle. Ainsi, une forte baisse d’un titre, peut-être légitime (faillite, profit warning, détection de fraude, etc) et jouer un retour à la moyenne peut alors être très risqué. L’inverse est également vrai, si le titre progresse fortement. Le vendre en jouant un retour à la moyenne peut conduire à se séparer du titre trop tôt.

Il est cependant intéressant de voir que l’algorithme laisse énormément de place aux améliorations, que ce soit sur la prévision des cours ou sur l’optimisation de portefeuille, ainsi que les univers à utiliser. On a également vu qu’il existe toujours des paramètres optimaux permettant d’améliorer significativement les performances de la stratégie, il serait donc intéressant de créer une méthode permettant d’estimer ces paramètres pour les futures investissements.

La méthodologie employée pour ces backtests n’est pas sans biais, bien que j’ai essayé d’en éviter le plus possible. Cet article ne constitue en aucun cas un conseil en investissement. Il ne correspond qu’à un point de vue parmi tant d’autres. Malgré tous mes efforts pour éviter les erreurs, je ne saurais assurer qu’il n’y en a pas.

Mes scripts R :

Vous trouverez juste en dessus les scripts que j’ai réalisé pour mes analyses. Ils sont sûrement perfectible !
En plus du simplex, j’ajoute une fonction qui utilise le package Rsolnp pour effectuer le travail d’optimisation. L’intérêt de passer par ce package est de pouvoir rajouter des contraintes (sur les poids max des lignes du portefeuille par exemple) dans le solveur. Il est par contre beaucoup moins rapide que l’algorithme du simplex.

?View Code RSPLUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
### Fonction : algo_OLMAR_simplex ###
# source : On-Line Portfolio Selection with Moving Average Reversion
# Auteurs : Bin Li, Steven C. H. Hoi
# Lien internet : http://arxiv.org/ftp/arxiv/papers/1206/1206.4626.pdf
 
# Variables de la fonction :
# e : seuil de reversion
# b : vecteur des poids du portefeuille avant optimisation
# vec_rel_px : vecteur des prix relatifs
 
algo_OLMAR_simplex <- function(e, b, vec_rel_px){
 
  m <- ncol(vec_rel_px)
  b_new <- matrix(rep(0,m), ncol=m, nrow=1)
 
  x_bar <- matrix(rep(vec_rel_px%*%matrix(rep(1,m), nrow=m)/m, m), ncol=m)
  mar_rel_dev <- as.vector(vec_rel_px-x_bar)%*%as.vector(vec_rel_px-x_bar)
 
  # Lambda
  lambda <- pmax(0, (e-b*vec_rel_px)/rep(mar_rel_dev,m))
 
  b_new <- as.vector(b + lambda*(vec_rel_px-x_bar))
 
  b_new <- fn_Simplex_Optim(b_new, 1)
 
  return(b_new)
}
?View Code RSPLUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
### Fonction : fn_Simplex_Optim ###
# source : Efficient Projections onto the l1-Ball for Learning in High Dimension
# Auteurs : John Duchi, Shai Shalev-Shwartz
# Lien internet : http://ttic.uchicago.edu/~shai/papers/DuchiShSi08.pdf
 
# Variables de la fonction :
# v : les poids du portefeuille avant optimisation
# z : contrainte de poids maximum (z > 0)
 
fn_Simplex_Optim <- function(v, z){
 
  nr <- length(v)
  rho_vec <- rep(0, nr)
  rho_seq <- seq(1, nr, 1)
  new_w <- rep(0, nr)
  rang <- 0
 
  # Ordonner data en decroissant
  idx <- order(v, decreasing=TRUE)
  u <- v[idx]   # Stockage dans u
  # on doit avoir u1>u2>...>up
 
  # Ici on cherche le rang maximum pour les valeurs de rho > 0
  rho_vec <- as.matrix(u-(cumsum(u)-z)/rho_seq)
  rho_vec[which(rho_vec<0),]<-0
 
  rho_rang <- max(which(rho_vec>0))  
  theta <- (sum(u[1:rho_rang])-z)/rho_rang  
  new_w[idx[1:nr]] <- pmax(0,v[idx[1:nr]] - theta)
 
  return(new_w)
}
?View Code RSPLUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
### Fonction : algo_OLMAR_solnp ###
# source : On-Line Portfolio Selection with Moving Average Reversion
# Auteurs : Bin Li, Steven C. H. Hoi
# Lien internet : http://arxiv.org/ftp/arxiv/papers/1206/1206.4626.pdf
 
# Variables de la fonction :
# e : seuil de reversion
# b : vecteur des poids du portefeuille avant optimisation
# vec_rel_px : vecteur des prix relatifs
 
algo_OLMAR_solnp <- function(e, b, vec_rel_px){
 
library(Rsolnp)
 
  m <- ncol(vec_rel_px)
  b_new <- matrix(rep(0,m), ncol=m, nrow=1)
 
  x_bar <- matrix(rep(vec_rel_px%*%matrix(rep(1,m), nrow=m)/m, m), ncol=m)
  mar_rel_dev <- norm(as.vector(vec_rel_px-x_bar), type="2")*norm(as.vector(vec_rel_px-x_bar), type="2")
 
  # Lambda
  lambda <- pmax(0, (e-b*vec_rel_px)/mar_rel_dev)
 
  b_new <- as.vector(b + lambda*(vec_rel_px-x_bar))
  assign("b_new", b_new, envir=globalenv())
 
  # Fonction a minimiser
  algo <- function(x){
    return(norm(x-b_new, type="2")*norm(x-b_new, type="2"))
  }
 
  b_new <- solnp(pars=rep(1/m, m), fun=algo, eqfun=sum, eqB=1, LB=rep(0,m), UB=rep(1,m))$pars
 
  return(b_new)
}
?View Code RSPLUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
### Fonction : fn_Simple_Moving_Average ###
 
# Variables de la fonction :
# data : series de prix
# w : duration de la moyenne mobile (en nombre de jours)
 
fn_Simple_Moving_Average <- function(data, w){
 
  m <- ncol(data) 
 
  x_t <- as.matrix(data)
 
  x_sim <- matrix(rep(0, m), ncol=m, nrow=1)
  x_tmp <- matrix(rep(0, m), ncol=m, nrow=1)
 
  for(i in nrow(x_t):(nrow(x_t)-w+1)){
    x_tmp <- x_tmp + x_t[i,]/w
  }
 
  x_sim <- matrix(x_tmp/x_t[nrow(x_t),], nrow=1)
 
  return(x_sim)  
}

Remarque :

La fonction ci-dessous est celle que j’appelle pour conduire mes backtests. Les données qu’elle reçoit sont des prix (et non des prix relatifs). Si vous souhaitez tester les scripts sur les données de l’auteur (qui sont publiées en prix relatifs), il faudra effectuer quelques modifications. Pour des raisons de place je ne publie pas le code modifié, mais je peux très bien le fournir en cas de besoin.

?View Code RSPLUS
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
### Fonction : fn_OLMAR_Complet ###
# source : On-Line Portfolio Selection with Moving Average Reversion
# Auteurs : Bin Li, Steven C. H. Hoi
# Lien internet : http://arxiv.org/ftp/arxiv/papers/1206/1206.4626.pdf
 
# Variables de la fonction :
# data : serie de prix
# w : duration de la moyenne mobile (en nombre de jours)
# e : seuil de reversion
# inv : investissement de depart
# fees : frais de transaction
# start.date : date depart backtest
# end.date : date fin backtest
 
fn_OLMAR_Complet < -function(data, w, e, inv, fees, start.date, end.date){
 
  data<-as.matrix(data[(which(rownames(data)==start.date)-(w-1)):which(rownames(data)==end.date),])
 
  # Definition des variables pour backtest
  m <- ncol(data) # Nombre de titres dans mon univers (ou mon portefeuille)
  nr <- nrow(data)   # Nombre de jours dans la serie
  w <- w
  e <- e 
 
  w_mat <- matrix(rep(0, m), ncol=m, nrow=nr+1) 
  w_mat[1:w,] <- 1/m
 
  strat <- matrix(rep(0, nr), ncol=1, nrow=nr)
  strat_ew <- matrix(rep(0, nr), ncol=1, nrow=nr)
 
  strat[1:w,1] <- inv
  strat_ew[1:w,1] <- inv
 
  nb_titres <- matrix(rep(0, nr), ncol=1, nrow=nr)
  sub_data_univ <- matrix(rep(0, m), ncol=m, nrow=1)
  px_rebal <- matrix(rep(0, m), ncol=m, nrow=1)
 
  f_ew <- 0
  f_olmar <- 0
  tc <- fees
 
  vec_w_rebal <- matrix(rep(1/m, m), m, nrow=1)
  vec_w_ew <- matrix(rep(1/m, m), ncol=m, nrow=1)
 
  univ <- 0
  b <- matrix(rep(1/m), ncol=m, nrow=1)
 
 
  for(i in w:nr){
 
    univ <- data[,1:m]
 
    delta_w <- abs(w_mat[i-1,]-w_mat[i,]*univ[i,]/univ[i-1,]) 
 
    delta_w_ew <- abs(1/m-vec_w_ew*univ[i,]/univ[i-1,])
 
    f_olmar <- sum(delta_w)*tc
 
    f_ew <- sum(delta_w_ew)*tc
 
 
    sub_data_univ <- univ[(i-(w)+1):i,]
 
    vec_rel_px <- fn_Simple_Moving_Average(as.matrix(sub_data_univ), w)
 
    w_mat[i+1,] <- algo_OLMAR_solnp(e, w_mat[i,]*(univ[i,]/univ[i-1,]), vec_rel_px) 
 
    rel_px <- as.numeric(univ[i,]/univ[i-1,])
 
    nb_titres[i,] <- length(which(w_mat[i,]>0.005))
 
    # Valorisation des strategies
    strat[i] <- ifelse(i == w, inv, as.numeric(strat[i-1,])*(sum(w_mat[i,]*(rel_px)))-f_olmar)
 
    strat_ew[i] <- ifelse(i == w, inv, as.numeric(strat_ew[i-1,])*sum(vec_w_ew*rel_px)-f_ew)
 
  } 
 
  all_strat <- cbind(strat, strat_ew, nb_titres, w_mat[1:nr,])
 
  rownames(all_strat) <- rownames(data)
 
  all_strat <- all_strat[w:nrow(all_strat),]
 
  col_names_strat <- rbind("OLMAR", "EW", "Nb_lines", as.matrix(colnames(data)))
 
  colnames(all_strat) <- col_names_strat
 
  return(all_strat)
}

Références :

[1] Bin Li, Steven C. H. Hoi. On-Line Portfolio Selection with Moving Average Reversion. HoiThe 29th International Conference on Machine Learning (ICML2012) Edinburgh, Scotland June 26 – July 1, 2012.

[2] Bin Li, Steven C. H. Online Portfolio Selection: Principles and Algorithms. HoiCRC Press November 5, 2015 (212 Pages, ISBN 9781482249637).

[3] John Duchi, Shai Shalev-Shwartz, Yoram Singer, Tushar Chandra. Efficient Projections onto the l1-Ball for Learning in High Dimensions. Appearing on Proceedings of the 25th International Conference on Machine Learning, Helsinki, Finland, 2008.

Saisonnalité des indices boursiers, mythe ou réalité ?

Derrière ce titre, se cache un sujet très controversé de la finance, qui est celui de l’efficience des marchés financiers. Cette hypothèse suppose que les prix observés sur les marchés financiers reflètent à tout moment toute l’information disponible. Se faisant, il est impossible pour les intervenant de ces marchés de faire des gains anormaux, provenant d’une activité de prévision du prix des actifs, et les gains espérés peuvent être autant positifs que négatifs, ils sont donc censés suivre une marche totalement aléatoire. Dans ce schéma, le rôle du gérant de portefeuilles est très limité, et la gestion passive est donc privilégiée.

Pourtant, au delà des légendes urbaines, les données historiques semblent mettre en lumière certains comportements récurrents, on parle d’effet janvier, d’effet de changement de mois, d’effet week-end ou encore lundi, etc. Peut-on les attribuer à un effet saisonnier où est-ce seulement du pur hasard ? C’est ce que je vais essayer de déterminer dans les lignes ci-dessous. Le but de mon analyse n’est pas de valider ou de contredire ces thèses, mais plutôt d’essayer de repérer des schéma récurrents, et de voir s’il est possible d’en profiter.

Lire la suite

R & MySQL

Dans la lignée de mon article sur  R & Excel, je développe ici une méthode pour interfacer R avec une base de données MySQL. Dans un premier temps, je montrerai comment le faire sous Windows, puis sous Mac OS X dans un second temps. C’est pas que j’aime enfoncer des portes ouvertes, mais vous comprendrez qu’il est nécessaire d’avoir installé au préalable votre base de données MySQL et R sur votre machine…

Lire la suite

SAC Capital, retour sur l’affaire.

SAC Capital est ce que l’on appelle dans le jargon financier, un « Hedge Fund » ou souvent qualifié de fonds spéculatif. Ces fonds se différencient des fonds « classiques » par leurs techniques de gestion dîtes alternatives, souvent basées sur des modélisations mathématiques très élaborées (trading haute fréquence, algo trading, etc). Ces fonds sont souvent dédiés à une clientèle très fortunée, triée sur volet (en tout cas c’était le cas pendant longtemps, même si ce genre de produit à tendance à se démocratiser depuis quelques années), et sont également connus pour être des « black box », c’est-à-dire des structures où les stratégies de gestion sont farouchement gardées au secret. Ce sont des sociétés qui sont agréées pour investir sur tout type d’instrument financier, n’importe où dans le monde. A la différence des sociétés de gestion classiques, elles ne sont pas contraintes par des ratios de gestion, et profitent donc d’une liberté totale.

Lire la suite

R & Excel

Cet article est le premier d’une suite d’articles liés à la gestion, l’administration et le traitement des données via R. En effet, R pouvant être interfacé avec de nombreux logiciels très répandus dans le milieu professionnel ou universitaire, il peut s’avérer être un allié de choix pour des traitements laborieux et complexes.

Le tableur le plus connu, et sûrement le plus répandu, sur les ordinateurs de notre chère planète (même si la concurrence est grandissante depuis quelques années) est celui de Microsoft : Excel. Il était donc évident que cette série d’articles serait entamée par un petit tour d’horizon des choses qu’il est possible de faire en connectant R et Excel.

Lire la suite

Comment réagir face à la fin du Quantitative Easing ?

Avant de s’interroger sur la façon de réagir face à la fin du Qantitative Easing, je pense qu’il est important de bien expliquer en quoi il consiste, pourquoi il a été mis en place, et quels sont les effets de son déploiement. Une fois les fondements posés, je vais essayer de réfléchir sur les conséquences de son extinction pour enfin répondre à la question qui anime cet article « Comment réagir face à la baisse du QE ? ».

Lire la suite

Présentation de R

La finance est très consommatrice de données économiques et financières, et un des enjeux majeurs pour les opérateurs de marchés est la gestion de ces données. Dans un monde où les choses évoluent de plus en plus rapidement, le délai entre le traitement des données et la prise de décision doit être réduit au maximum, sans pour autant sacrifier la robustesse des résultats.

Lire la suite

La culture financière des français

A l’heure où l’on commence à voir les limites du système de retraite par répartition,  les sirènes du système par capitalisation commencent à se faire entendre et il ne serait pas étonnant de le voir prendre une place de plus en plus importante dans le paysage français. Il devient alors primordial pour l’investisseur final de comprendre comment fonctionne ce système.

Pourtant, une étude à l’initiative de l’Institut pour l’Education Financière du Public, et menée par le Centre de Recherche pour l’Etude et l’Observation des Conditions de Vie (en juin 2011) dresse un constat affligeant de la culture financière des Français. Même pour les principes les plus rudimentaires, les Français montrent un réel déficit de connaissance. Et cela ne s’arrange pas avec le temps !

Lire la suite