Option Explicit Sub CalculerBase100EtRendements() ' Déclaration des variables Dim wsData As Worksheet Dim wsBase100 As Worksheet Dim wsRendements As Worksheet Dim lastRow As Long Dim lastCol As Long Dim i As Long, j As Long Dim premiereValeur As Double Application.ScreenUpdating = False Application.Calculation = xlCalculationManual Application.EnableEvents = False ' Vérifier si le fichier existe et l'ouvrir On Error Resume Next Dim wb As Workbook Set wb = ThisWorkbook ' Vérifier si la feuille Prix_Cloture existe déjà Set wsData = Nothing On Error Resume Next Set wsData = wb.Sheets("Prix_Cloture") On Error GoTo 0 If wsData Is Nothing Then MsgBox "La feuille 'Prix_Cloture' n'existe pas. Veuillez vérifier le nom de la feuille contenant les données.", vbExclamation GoTo CleanExit End If ' Créer ou réinitialiser les feuilles pour les bases 100 et rendements On Error Resume Next Set wsBase100 = wb.Sheets("Base100") If wsBase100 Is Nothing Then Set wsBase100 = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count)) wsBase100.Name = "Base100" Else wsBase100.Cells.Clear End If Set wsRendements = wb.Sheets("Rendements") If wsRendements Is Nothing Then Set wsRendements = wb.Sheets.Add(After:=wb.Sheets(wb.Sheets.Count)) wsRendements.Name = "Rendements" Else wsRendements.Cells.Clear End If On Error GoTo 0 ' Trouver la dernière ligne et colonne avec des données lastRow = wsData.Cells(wsData.Rows.Count, 1).End(xlUp).Row lastCol = wsData.Cells(1, wsData.Columns.Count).End(xlToLeft).Column ' Copier les en-têtes de colonnes wsData.Range(wsData.Cells(1, 1), wsData.Cells(1, lastCol)).Copy wsBase100.Range("A1") wsData.Range(wsData.Cells(1, 1), wsData.Cells(1, lastCol)).Copy wsRendements.Range("A1") ' Copier les dates wsData.Range(wsData.Cells(2, 1), wsData.Cells(lastRow, 1)).Copy wsBase100.Range("A2") wsData.Range(wsData.Cells(2, 1), wsData.Cells(lastRow, 1)).Copy wsRendements.Range("A2") ' Calculer les bases 100 pour chaque actif For j = 2 To lastCol premiereValeur = wsData.Cells(2, j).Value ' Vérifier si la première valeur n'est pas 0 ou vide If premiereValeur <> 0 And Not IsEmpty(premiereValeur) Then For i = 2 To lastRow If Not IsEmpty(wsData.Cells(i, j).Value) Then wsBase100.Cells(i, j).Value = (wsData.Cells(i, j).Value / premiereValeur) * 100 End If Next i Else ' Si la première valeur est 0 ou vide, chercher la première valeur non-nulle Dim k As Long Dim valeurTrouvee As Boolean valeurTrouvee = False For k = 3 To lastRow If wsData.Cells(k, j).Value <> 0 And Not IsEmpty(wsData.Cells(k, j).Value) Then premiereValeur = wsData.Cells(k, j).Value valeurTrouvee = True Exit For End If Next k If valeurTrouvee Then For i = 2 To lastRow If Not IsEmpty(wsData.Cells(i, j).Value) Then If i >= k Then wsBase100.Cells(i, j).Value = (wsData.Cells(i, j).Value / premiereValeur) * 100 Else wsBase100.Cells(i, j).Value = CVErr(xlErrNA) End If End If Next i End If End If Next j ' Calculer les rendements journaliers pour chaque actif For j = 2 To lastCol For i = 3 To lastRow If Not IsEmpty(wsData.Cells(i, j).Value) And Not IsEmpty(wsData.Cells(i - 1, j).Value) _ And wsData.Cells(i - 1, j).Value <> 0 Then wsRendements.Cells(i, j).Value = (wsData.Cells(i, j).Value / wsData.Cells(i - 1, j).Value) - 1 ' Formater en pourcentage wsRendements.Cells(i, j).NumberFormat = "0.00%" End If Next i Next j ' Création des statistiques des rendements Call CalculerStatistiquesRendements ' Mise en forme wsBase100.Range(wsBase100.Cells(1, 1), wsBase100.Cells(lastRow, lastCol)).Columns.AutoFit wsRendements.Range(wsRendements.Cells(1, 1), wsRendements.Cells(lastRow, lastCol)).Columns.AutoFit ' Créer des graphiques pour la visualisation des bases 100 Call CreerGraphiquesBase100 CleanExit: ' Réactiver les paramètres Excel Application.ScreenUpdating = True Application.Calculation = xlCalculationAutomatic Application.EnableEvents = True MsgBox "Calcul des bases 100 et des rendements terminé!", vbInformation End Sub Sub CalculerStatistiquesRendements() ' Cette sous-procédure calcule les statistiques de rendement Dim wsRendements As Worksheet Dim wsStats As Worksheet Dim lastRow As Long Dim lastCol As Long Dim i As Long, j As Long Dim rendRange As Range Set wsRendements = ThisWorkbook.Sheets("Rendements") ' Créer ou réinitialiser la feuille de statistiques On Error Resume Next Set wsStats = ThisWorkbook.Sheets("Statistiques") If wsStats Is Nothing Then Set wsStats = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) wsStats.Name = "Statistiques" Else wsStats.Cells.Clear End If On Error GoTo 0 lastRow = wsRendements.Cells(wsRendements.Rows.Count, 1).End(xlUp).Row lastCol = wsRendements.Cells(1, wsRendements.Columns.Count).End(xlToLeft).Column ' Ajouter les en-têtes wsStats.Cells(1, 1).Value = "Actif" wsStats.Cells(1, 2).Value = "Rendement Moyen" wsStats.Cells(1, 3).Value = "Volatilité (Écart-type)" wsStats.Cells(1, 4).Value = "Rendement Annualisé" wsStats.Cells(1, 5).Value = "Volatilité Annualisée" wsStats.Cells(1, 6).Value = "Ratio de Sharpe" wsStats.Cells(1, 7).Value = "Rendement Minimum" wsStats.Cells(1, 8).Value = "Rendement Maximum" ' Supposons un taux sans risque annuel de 2% Dim tauxSansRisque As Double tauxSansRisque = 0.02 / 252 ' Taux journalier (252 jours de trading par an) ' Calculer les statistiques pour chaque actif For j = 2 To lastCol ' Entête de l'actif wsStats.Cells(j, 1).Value = wsRendements.Cells(1, j).Value ' Définir la plage de données contenant les rendements Set rendRange = wsRendements.Range(wsRendements.Cells(3, j), wsRendements.Cells(lastRow, j)) ' Rendement moyen journalier wsStats.Cells(j, 2).Value = WorksheetFunction.Average(rendRange) wsStats.Cells(j, 2).NumberFormat = "0.00%" ' Volatilité (écart-type) wsStats.Cells(j, 3).Value = WorksheetFunction.StDev(rendRange) wsStats.Cells(j, 3).NumberFormat = "0.00%" ' Rendement annualisé (252 jours de trading) wsStats.Cells(j, 4).Value = (1 + wsStats.Cells(j, 2).Value) ^ 252 - 1 wsStats.Cells(j, 4).NumberFormat = "0.00%" ' Volatilité annualisée wsStats.Cells(j, 5).Value = wsStats.Cells(j, 3).Value * Sqr(252) wsStats.Cells(j, 5).NumberFormat = "0.00%" ' Ratio de Sharpe If wsStats.Cells(j, 5).Value <> 0 Then wsStats.Cells(j, 6).Value = (wsStats.Cells(j, 4).Value - (tauxSansRisque * 252)) / wsStats.Cells(j, 5).Value wsStats.Cells(j, 6).NumberFormat = "0.00" Else wsStats.Cells(j, 6).Value = "N/A" End If ' Rendement minimum wsStats.Cells(j, 7).Value = WorksheetFunction.Min(rendRange) wsStats.Cells(j, 7).NumberFormat = "0.00%" ' Rendement maximum wsStats.Cells(j, 8).Value = WorksheetFunction.Max(rendRange) wsStats.Cells(j, 8).NumberFormat = "0.00%" Next j ' Mise en forme wsStats.Range(wsStats.Cells(1, 1), wsStats.Cells(lastCol, 8)).Columns.AutoFit ' Mise en forme du tableau With wsStats.Range(wsStats.Cells(1, 1), wsStats.Cells(lastCol, 8)) .Borders.LineStyle = xlContinuous With .Borders(xlEdgeBottom) .LineStyle = xlContinuous .Weight = xlMedium End With With .Borders(xlEdgeTop) .LineStyle = xlContinuous .Weight = xlMedium End With With .Font .Name = "Calibri" .Size = 11 End With End With ' Formater la ligne d'en-tête With wsStats.Range(wsStats.Cells(1, 1), wsStats.Cells(1, 8)) .Font.Bold = True .Interior.Color = RGB(217, 217, 217) End With End Sub Sub CreerGraphiquesBase100() ' Cette sous-procédure crée des graphiques pour visualiser les bases 100 Dim wsBase100 As Worksheet Dim wsGraphiques As Worksheet Dim lastRow As Long Dim lastCol As Long Dim chtObj As ChartObject Dim cht As Chart Set wsBase100 = ThisWorkbook.Sheets("Base100") ' Créer ou réinitialiser la feuille des graphiques On Error Resume Next Set wsGraphiques = ThisWorkbook.Sheets("Graphiques") If wsGraphiques Is Nothing Then Set wsGraphiques = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count)) wsGraphiques.Name = "Graphiques" Else ' Supprimer tous les graphiques existants For Each chtObj In wsGraphiques.ChartObjects chtObj.Delete Next chtObj End If On Error GoTo 0 lastRow = wsBase100.Cells(wsBase100.Rows.Count, 1).End(xlUp).Row lastCol = wsBase100.Cells(1, wsBase100.Columns.Count).End(xlToLeft).Column ' Créer un graphique pour tous les actifs Set chtObj = wsGraphiques.ChartObjects.Add(Left:=50, Width:=700, Top:=50, Height:=400) Set cht = chtObj.Chart ' Configurer le graphique With cht .SetSourceData Source:=wsBase100.Range(wsBase100.Cells(1, 1), wsBase100.Cells(lastRow, lastCol)) .ChartType = xlLineMarkers .HasTitle = True .ChartTitle.Text = "Évolution de la Base 100 des Actifs" .Axes(xlCategory, xlPrimary).HasTitle = True .Axes(xlCategory, xlPrimary).AxisTitle.Text = "Date" .Axes(xlValue, xlPrimary).HasTitle = True .Axes(xlValue, xlPrimary).AxisTitle.Text = "Base 100" .HasLegend = True .Legend.Position = xlLegendPositionBottom End With ' Créer un graphique comparatif entre l'indice CAC 40 et les autres actifs Dim i As Long Dim topPos As Long topPos = 500 For i = 3 To lastCol Set chtObj = wsGraphiques.ChartObjects.Add(Left:=50, Width:=500, Top:=topPos, Height:=300) Set cht = chtObj.Chart ' Ajouter les séries au graphique cht.SetSourceData Source:=wsBase100.Range(wsBase100.Cells(1, 1), wsBase100.Cells(lastRow, 1)) ' Dates ' Ajouter l'indice CAC 40 (supposé être en colonne 2) cht.SeriesCollection.NewSeries With cht.SeriesCollection(1) .Values = wsBase100.Range(wsBase100.Cells(2, 2), wsBase100.Cells(lastRow, 2)) .Name = wsBase100.Cells(1, 2).Value .MarkerStyle = xlMarkerStyleNone .Format.Line.Weight = 2 End With ' Ajouter l'actif actuel cht.SeriesCollection.NewSeries With cht.SeriesCollection(2) .Values = wsBase100.Range(wsBase100.Cells(2, i), wsBase100.Cells(lastRow, i)) .Name = wsBase100.Cells(1, i).Value .MarkerStyle = xlMarkerStyleNone .Format.Line.Weight = 2 End With ' Configurer le graphique With cht .ChartType = xlLine .HasTitle = True .ChartTitle.Text = "Comparaison " & wsBase100.Cells(1, 2).Value & " vs " & wsBase100.Cells(1, i).Value .Axes(xlCategory, xlPrimary).HasTitle = False .Axes(xlValue, xlPrimary).HasTitle = True .Axes(xlValue, xlPrimary).AxisTitle.Text = "Base 100" .HasLegend = True .Legend.Position = xlLegendPositionBottom End With topPos = topPos + 350 Next i End Sub ' Cette procédure lance automatiquement toutes les étapes Sub LancerAnalyseAutomatique() ' Lancer le calcul des bases 100 et rendements Call CalculerBase100EtRendements ' Afficher la feuille des graphiques Sheets("Graphiques").Activate MsgBox "Analyse automatique terminée avec succès!", vbInformation End Sub