- Pubié le
Maximiser les rendements de son Portfolio avec la frontière efficiente
- Authors
- Nom
- Quentin PETIT
Contexte
Définitions
Lorsque l'on souhaite réaliser un portefeuille de titre financier, on est confronté à un problème de répartition. Comment doit on allouer les parts pour chaque titre ?
Markowitz pose deux hypothèses fondamentales :
- Les investisseurs cherchent à maximiser les rendements
- La variance des rendements est indésirable.
On définit un choix de répartition par le vecteur suivant :
L'objectif ici est de trouver la répartition qui génére le plus grand rendement . Par définition du poids, chaque proposition d'allocation doit valoir un.
Supposons que est une variable aléatoire représentant un titre financier avec des valeurs possibles et des probabilités associées . Le rendement attendu (espérance) de est donnée par :
- Par exemple, une action X a 50% de chance de rapporter 10% et 50% de chance de rapporter 6%.
La variance mesure la dispersion des valeurs autour de la moyenne (l'espérance).
Markowitz utilise l'écart type pour mesurer le risque.
Pour un portefeuille R constituée de plusieurs titres avec des pondérations , le rendement du portefeuille attendu est :
La covariance mesure la relation entre deux variables aléatoires et
Grâce à cette relation, on va pouvoir obtenir la matrice de covariance entre tous les actifs
Pour un portefeuille composé de n actifs, avec représentant le poids du i-ème actif et représentant la covariance entre les actifs i et j, la variance du portefeuille est :
La formule de la variance devient :
En 1964, William Sharpe définit un nouvel indice, le ratio de Sharpe qui permet de mesurer la performance d'un portefeuille ajustée au risque. Plus ce ratio est important, plus le portefeuille est intéressant car il indique la performance est plus importante que le risque pris.
Il suffit de calculer le ratio de sharpe pour chaque allocation choisie, et d'afficher les poids qui réalise ce maximum.
Application
L'algorithme suivant permet de trouver ces coefficients optimaux. Ils récupérent les données de rendement des titres ainsi que la matrice de corrélation entre tous ses actifs. Puis on va générer aléatoirement un nombre fixe de portefeuille pour trouver celui réalise le plus grand ratio de sharpe ainsi que celui avec le moins de volatilité.
import numpy as np
import matplotlib.pyplot as plt
import mpld3
from mpld3 import plugins
# Data sur le marché : rendements attendus et matrice de covariance
expected_returns = np.array([0.10, 0.12, 0.08])
cov_matrix = np.array([
[0.04, 0.01, 0.005],
[0.01, 0.09, 0.002],
[0.005, 0.002, 0.01]
])
# Générer le portfolio de 10000 portefeuilles aléatoires
num_portfolios = 10000
results = np.zeros((5, num_portfolios)) # Rendement, Volatilité, Sharpe Ratio, Poids de l'actif 1, Poids de l'actif 2
for i in range(num_portfolios):
weights = np.random.random(3)
print(weights)
weights /= np.sum(weights) # Normaliser pour que la somme des poids fasse 1.
# Calculer le rendement du portefeuille
portfolio_return = np.dot(weights, expected_returns)
# Calculer la volatilité du portefeuille
portfolio_variance = np.dot(weights.T, np.dot(cov_matrix, weights))
portfolio_std_dev = np.sqrt(portfolio_variance)
# Enregistrer les résultats
results[0, i] = portfolio_return
results[1, i] = portfolio_std_dev
results[2, i] = results[0, i] / results[1, i] # Sharpe Ratio
results[3, i] = weights[0]
results[4, i] = weights[1]
# Trouver le portefeuille avec le ratio de Sharpe le plus élevé, et le portefeuille avec la volatilité minimale
max_sharpe_idx = np.argmax(results[2])
max_sharpe_return = results[0, max_sharpe_idx]
max_sharpe_std_dev = results[1, max_sharpe_idx]
min_vol_idx = np.argmin(results[1])
min_vol_return = results[0, min_vol_idx]
min_vol_std_dev = results[1, min_vol_idx]
# Créer le graphique
fig, ax = plt.subplots(figsize=(7,3.5))
scatter = ax.scatter(results[1, :], results[0, :], c=results[2, :], cmap='YlGnBu_r', marker='o')
max_sharpe_scatter = ax.scatter(max_sharpe_std_dev, max_sharpe_return, marker='*', color='r', s=100, label='Max Sharpe Ratio')
min_vol_scatter = ax.scatter(min_vol_std_dev, min_vol_return, marker='*', color='g', s=100, label='Min Volatilité')
ax.set_title('Frontière efficiente')
ax.set_xlabel('Risque (Volatilité)')
ax.set_ylabel('Rendement')
ax.legend()
# Créer des étiquettes pour chaque point
labels = []
for i in range(num_portfolios):
label = f'Return: {results[0, i]:.2f}, Risk: {results[1, i]:.2f}\nWeights: [{results[3, i]:.2f}, {results[4, i]:.2f}, {1 - results[3, i] - results[4, i]:.2f}]'
labels.append(label)
tooltip = plugins.PointLabelTooltip(scatter, labels=labels)
plugins.connect(fig, tooltip)
# Ajouter des étiquettes pour les points max_sharpe et min_vol
max_sharpe_label = [f'Return: {max_sharpe_return:.2f}, Risk: {max_sharpe_std_dev:.2f}\nWeights: [{results[3, max_sharpe_idx]:.2f}, {results[4, max_sharpe_idx]:.2f}, {1 - results[3, max_sharpe_idx] - results[4, max_sharpe_idx]:.2f}]']
min_vol_label = [f'Return: {min_vol_return:.2f}, Risk: {min_vol_std_dev:.2f}\nWeights: [{results[3, min_vol_idx]:.2f}, {results[4, min_vol_idx]:.2f}, {1 - results[3, min_vol_idx] - results[4, min_vol_idx]:.2f}]']
max_sharpe_tooltip = plugins.PointLabelTooltip(max_sharpe_scatter, labels=max_sharpe_label)
min_vol_tooltip = plugins.PointLabelTooltip(min_vol_scatter, labels=min_vol_label)
plugins.connect(fig, max_sharpe_tooltip)
plugins.connect(fig, min_vol_tooltip)
# Afficher le graphique
mpld3.show()