construction d'une courbe d'actualisation avec VBA

kiddus i

XLDnaute Nouveau
bonjour
je suis toujours à la rehcrehce d'une âme charitable qui pourrait m'aider car visiblement ils ont oublié qq chose dans le bouquin (du moins je pense...)
donc je reprends : travaillant dans la finance je souhaiterai réaliser un petit programme de valorisation des swap sous vba, j'ai dc acheté le bouquin qui était sensé me rendre heureux mais ca ne marche pas:confused::mad:!!!
je pense avoir isoler le pbm mais je ne sais pas comment le résoudre...
je vous fais donc suivre les codes....


Option Explicit
Option Base 1

Function CTableau(vDonnees)

'Cette fonction renvoie un tableau de double.
'Elle permet de convertir l'argument vDonnees,
'qui peut être de différents types,
'en un type unique et connu.

Dim TableauRetour(), i As Integer
'La fonction TypeName permet de connaître le type de vDonnees
Select Case TypeName(vDonnees)

Case "Range"
'C'est une plage de cellules
'vDonnees.Cells.Count compte le nombre de cellules de
'la plage vDonnees.
ReDim TableauRetour(1 To vDonnees.Cells.Count)
For i = 1 To vDonnees.Cells.Count
'Nous affectons au tableau à l'indice i
'La valeur de la cellule i
TableauRetour(i) = vDonnees.Cells(i)
Next
Case "Integer()", "Double()", "Date()"
'C'est un tableau
ReDim TableauRetour(1 To UBound(vDonnees))
For i = 1 To UBound(vDonnees)
TableauRetour(i) = vDonnees(i)
Next
Case Else
'C'est un nombre ou une date, nous l'affectons
' à un tableau à une dimension
ReDim TableauRetour(1 To 1)
TableauRetour(1) = vDonnees
End Select

CTableau = TableauRetour

End Function

Function ChangeTaux(DateDeCalcul As Date, DateDeMaturite As Date, _
dblDonnee As Double, iTypeDonnee As Integer, iFrequence As Integer, _
iBase, iTypeDonneeCible As Integer, _
iFrequenceCible As Integer, iBaseCible) As Double

'=============================================================
'Cette fonction permet la conversion d'un taux ou d'un facteur
'd'actualisation en un autre taux (ou facteur d'actualisation)
'en modifiant la base de calcul et/ou son type
'=============================================================

'Définition des variables
Dim dblFA As Double 'Facteur d'actualisation
Dim dblValRet As Double 'Variable renvoyée
Dim dblF1 As Double 'Fraction année dans la base source
Dim dblF2 As Double 'Fraction année dans la base cible


dblF1 = FractionAnnee(DateDeCalcul, DateDeMaturite, iBase)
dblF2 = FractionAnnee(DateDeCalcul, DateDeMaturite, iBaseCible)

'Conversion de la donnée initiale
'en facteur d'actualisation
Select Case iTypeDonnee

Case 0
'la donnée initiale est un taux composé
dblFA = (1 + dblDonnee / iFrequence) ^ (iFrequence * dblF1)
dblFA = 1 / dblFA
Case 1
'la donnée initiale est un taux proportionnel
dblFA = (1 + dblDonnee * dblF1)
dblFA = 1 / dblFA
Case 2
'la donnée initiale est un facteur d'acualisation
dblFA = dblDonnee
Case 3
'la donnée initiale est un taux continu
dblFA = Exp(-dblDonnee * dblF1)
Case Else
'type inconnu
dblFA = 0
End Select

Select Case iTypeDonneeCible

Case 0
'la donnée cible est un taux composé
dblValRet = (((1 / dblFA) ^ (1 / (dblF2 * _
iFrequenceCible))) - 1) * iFrequenceCible
Case 1
'la donnée cible est un taux proportionnel
dblValRet = ((1 / dblFA) - 1) * (1 / dblF2)
Case 2
'la donnée cible est un facteur d'actualisation
dblValRet = dblFA

Case 3
'la donnée cible est un taux continu
dblValRet = Log(1 / dblFA) / dblF2
Case Else
'type inconnu, la fonction ne calcul rien
dblValRet = 0
End Select

ChangeTaux = dblValRet

End Function

Function InterpolationLineaire(TableauMaturites, TableauDonnees, _
DateCalculees, Optional EstFactActua As Boolean = False, Optional _
DateDeCalcul As Date)

'=============================================================
'Cette fonction détermine à partir d'un vecteur de dates
'et d'un vecteur de données, les données interpolées
'linéairement pour les dates du vecteur DateCalculées
'=============================================================

Dim TabMat
'Tableau des maturités des données sources
Dim TabData
'Données sources
Dim TabDates
'Date à calculer
Dim i As Integer, j As Integer
'Variables de boucle
Dim TabRetour
'Données renvoyées
Dim DateCalc As Date
'Date en cours de calcul (provenant de TabDates)
Dim DateInf As Date
'Date provenant de TabMat, inférieur à DateCalc
Dim DateSup As Date
'Date provenant de TabMat, supérieure à DateCalc
Dim dblTxInf As Double
'Donnée correspondant à DateInf
Dim dblTxSup As Double
'Donnée corespondant à DateSup
Dim dblTaux As Double
'Donnée interpolée

'Conversion des arguments en tableaux
TabMat = CTableau(TableauMaturites)
TabData = CTableau(TableauDonnees)
TabDates = CTableau(DateCalculees)

'Dimensionnement du tableau de retour
ReDim TabRetour(LBound(TabDates) To UBound(TabDates))


Select Case EstFactActua

Case True
'Les données sont des facteurs d'actualisation

For i = LBound(TabDates) To UBound(TabDates)
'Boucle sur les dates à calculer

If TabDates(i) <= TabMat(1) Then
'Test des bornes, cas de la borne inférieure
dblTaux = ChangeTaux(DateDeCalcul, (TabMat(1)), _
(TabData(1)), 2, 1, 2, 0, 1, 2)

TabRetour(i) = ChangeTaux(DateDeCalcul, (TabDates(i)), _
dblTaux, 0, 1, 2, 2, 1, 2)

ElseIf TabDates(i) >= TabMat(UBound(TabMat)) Then
'Test des bornes, cas de la borne supérieure
dblTaux = ChangeTaux(DateDeCalcul, (TabMat _
(UBound(TabMat))), (TabData(UBound(TabData))), _
2, 1, 2, 0, 1, 2)

TabRetour(i) = ChangeTaux(DateDeCalcul, (TabDates(i)), _
dblTaux, 0, 1, 2, 2, 1, 2)
Else
'Cas général
For j = 1 To UBound(TabMat)
'On recherche la première date supérieure à
'la date calculée
If TabMat(j) > TabDates(i) Then
Exit For
End If
Next

'Données utiles pour l'interpolation
dblTxInf = TabData(j - 1)
dblTxSup = TabData(j)
DateInf = TabMat(j - 1)
DateSup = TabMat(j)
DateCalc = TabDates(i)

'Calcul de l'interpolation
TabRetour(i) = ((DateCalc - DateInf) * dblTxSup + _
(DateSup - DateCalc) * dblTxInf) / (DateSup - DateInf)
End If
Next


Case Else
'Les données sont des taux
For i = LBound(TabDates) To UBound(TabDates)
'boucle sur les dates à calculer
If TabDates(i) <= TabMat(1) Then
'Test des bornes, cas de la borne inférieure
TabRetour(i) = TabData(1)
ElseIf TabDates(i) >= TabMat(UBound(TabMat)) Then
'Test des bornes, cas de la borne supérieure
TabRetour(i) = TabData(UBound(TabMat))
Else
For j = 1 To UBound(TabMat)
'On rehcerche la première date supérieure à
'la date calculée
If TabMat(j) > TabDates(i) Then
Exit For
End If
Next
'Données utilisées pour l'interpolation
dblTxInf = TabData(j - 1)
dblTxSup = TabData(j)
DateInf = TabMat(j - 1)
DateSup = TabMat(j)
DateCalc = TabDates(i)

'Calcul de l'interpolation
TabRetour(i) = ((DateCalc - DateInf) * dblTxSup + _
(DateSup - DateCalc) * dblTxInf) / (DateSup - DateInf)
End If
Next
End Select

InterpolationLineaire = TabRetour

End Function

Function InterpolationCubique(TableauMaturites, TableauDonnees, _
DateCalculees, _
Optional EstFactActua As Boolean = False, Optional _
DateDeCalcul As Date)

'=============================================================
'Cette fonction détermine à partir d'un vecteur de dates
'et d'un vecteur de données, les données interpolées
'par un polynome de degré 3 pour les dates du vecteur DatesCalculées
'=============================================================

Dim TabMat
'Tableau des maturités des données sources
Dim TabData
'Données sources
Dim TabDates
'Dates à calculer
Dim i As Integer, j As Integer
'Variables de boucle
Dim TabRetour
'Données renvoyées
Dim MatriceDate(1 To 4, 1 To 4) As Double
'Matrice des coefficients des paramètres
Dim MatDateInv As Variant
'Matrice inverse de MatriceDate
Dim VecTaux(4, 1)
'Vecteur des données solutions du système
Dim VecParam
'Vecteur des paramètres calculés



'Conversion des arguments en tableau
TabMat = CTableau(TableauMaturites)
TabData = CTableau(TableauDonnees)
TabDates = CTableau(DateCalculees)

'Dimensionnement des tableaux de retour
ReDim TabRetour(LBound(TabDates) To UBound(TabDates))


For i = LBound(TabDates) To UBound(TabDates)
'Boucle sur les dates à calculer

If TabDates(i) <= TabMat(2) Then
'Test des bornes, cas de la borne inférieure
TabRetour(i) = InterpolationLineaire(TabMat, TabData, _
TabDates(i), _
EstFactActua, DateDeCalcul)(1)
ElseIf TabDates(i) >= TabMat(UBound(TabMat) - 1) Then
'Test des bornes, cas de la borne supérieure
TabRetour(i) = InterpolationLineaire(TabMat, TabData, _
TabDates(i), _
EstFactActua, DateDeCalcul)(1)
ElseIf UBound(TabMat) < 4 Then
'Pas assez de données pour éffectuer une interpolation cubique
TabRetour(i) = InterpolationLineaire(TabMat, TabData, _
TabDates(i), _
EstFactActua, DateDeCalcul)(1)
Else
For j = 3 To UBound(TabMat) - 2
'On recherche la première date supérieure à
'la date calculée
If TabMat(j) > TabDates(i) Then
Exit For
End If
Next

'On renseigne la matrice de date
MatriceDate(1, 1) = CDbl(TabMat(j - 2) ^ 3)
MatriceDate(1, 2) = TabMat(j - 2) ^ 2
MatriceDate(1, 3) = CDbl(TabMat(j - 2))
MatriceDate(1, 4) = 1
MatriceDate(2, 1) = CDbl(TabMat(j - 1) ^ 3)
MatriceDate(2, 2) = TabMat(j - 1) ^ 2
MatriceDate(2, 3) = CDbl(TabMat(j - 1))
MatriceDate(2, 4) = 1
MatriceDate(3, 1) = CDbl(TabMat(j) ^ 3)
MatriceDate(3, 2) = TabMat(j) ^ 2
MatriceDate(3, 3) = CDbl(TabMat(j))
MatriceDate(3, 4) = 1
MatriceDate(4, 1) = CDbl(TabMat(j + 1) ^ 3)
MatriceDate(4, 2) = TabMat(j + 1) ^ 2
MatriceDate(4, 3) = CDbl(TabMat(j + 1))
MatriceDate(4, 4) = 1

'On renseigne le vecteur de données
VecTaux(1, 1) = TabData(j - 2)
VecTaux(2, 1) = TabData(j - 1)
VecTaux(3, 1) = TabData(j)
VecTaux(4, 1) = TabData(j + 1)

'Inversion de la matrice de date
MatDateInv = Application.WorksheetFunction.MInverse _
(MatriceDate)

'Résolution du système
VecParam = Application.WorksheetFunction.MMult(MatDateInv, _
VecTaux)

'Calcul de la valeur interpolée
TabRetour(i) = VecParam(1, 1) * TabDates(i) ^ 3 + _
VecParam(2, 1) * TabDates(i) ^ 2 + _
VecParam(3, 1) * TabDates(i) + _
VecParam(4, 1)
End If
Next

InterpolationCubique = TabRetour

End Function

Function Interpolation(TableauMaturites, TableauDonnees, DateCalculees, _
Optional TypeInterpolation As Boolean = False, _
Optional TypeDonnees As Boolean = False, Optional _
DateDeCalcul As Date)
'=============================================================
'Cette fonction détermine à partir d'un vecteur de dates
'et d'un vecteur de données, les données interpolées
'pour les dates du vecteur DateCalculées
'=============================================================
Select Case TypeInterpolation

Case True
Interpolation = InterpolationLineaire(TableauMaturites, _
TableauDonnees, DateCalculees, TypeDonnees, DateDeCalcul)
Case Else
Interpolation = InterpolationCubique(TableauMaturites, _
TableauDonnees, DateCalculees, TypeDonnees, DateDeCalcul)
End Select


End Function

Function CourbeActualisation(DateDeCalcul As Date, TableauDatesValeurs, _
TableauMaturites, TableauDonnees, _
TableauTypeDonnees, TableauBases)

'====================================
'Cette fonction construit une courbe
'de facteurs d'actualisation
'à partir d'instruments de marché
'====================================

Dim TabDatesVal 'Tableau des dates de valeurs des données
Dim TabDatesMat 'Tableau des dates de maturités
'des données
Dim TabData 'Tableau des données
Dim TabDataType 'Tableau des types de données
Dim TabDataBase 'Tableau des bases de données
Dim TabFacActu() 'Tableau des facteurs d'actualisation
Dim TabDateFacActu() 'Tableau des dates des facteurs
'd'actualisation
Dim sTypeData As String 'Type de la donnée courante
Dim i As Integer, j As Integer 'Variable de boucle
Dim iTailleTab As Integer 'Taille des vecteurs TabFacActu et
'TabDateFacActu
Dim dblStub As Double 'Taux courant jusqu'à la date de valeur
'd'un contrat future
Dim dblCompoFut As Double 'Composition de dblStub et du future
Dim dblFrac1 As Double, dblFrac2 As Double 'Fraction d'années
Dim TabFluxOblg 'Vecteur des dates de flux
'd'un instrument PAR
Dim TabFAOblg 'Facteurs d'actualisation aux dates
'de TabFluxOblg
Dim dblSum As Double 'Variable de somme
Dim TableauSortie() As Double 'Données renvoyées
Dim dblFAtp As Double 'Facteur d'actualisation en cours de
'calcul


'Conversion des arguments en tableaux
TabDatesVal = CTableau(TableauDatesValeurs)
TabDatesMat = CTableau(TableauMaturites)
TabData = CTableau(TableauDonnees)
TabDataType = CTableau(TableauTypeDonnees)
TabDataBase = CTableau(TableauBases)

'Dimensionnement du tableau de retour
ReDim TableauSortie(3, UBound(TabDataType))

'Vérification de la cohérence des données
'il faut que tous les vecteurs comportent
'le même nombre de lignes
If UBound(TabDatesVal) <> UBound(TabDatesMat) Or UBound(TabDatesVal) _
<> UBound(TabData) _
Or UBound(TabDatesVal) <> UBound(TabDataType) Or UBound(TabDatesVal) _
<> UBound(TabDataBase) Then
'il y a une erreur, on sort de la fonction
CourbeActualisation = TableauSortie
Exit Function
End If

'Boucle sur l'ensemble des instruments
For i = 1 To UBound(TabDataType)
'Traitement en fonction du type de données
sTypeData = TabDataType(i)
Select Case sTypeData


Case "MM"
'Taux monétaires (Money Market)
'Transformation en taux composé Exact/365
dblFAtp = ChangeTaux(DateDeCalcul, (TabDatesMat(i)), _
(TabData(i)), 1, 1, (TabDataBase(i)), 0, 1, "Exact/365")

Case "FUT"
'Instrument future
'composition avec le taux à sa date de départ
'et transformation en taux composé Exact/365
dblStub = Interpolation(TabDateFacActu, TabFacActu, _
TabDatesVal(i))(1)
'dblStub contient le taux allant de la date de calcul
'à la date de départ du future
dblFrac1 = FractionAnnee(DateDeCalcul, (TabDatesVal(i)), _
"Exact/365")

dblFrac2 = FractionAnnee((TabDatesVal(i)), (TabDatesMat(i)), _
(TabDataBase(i)))
'dblCompoFut contient la composition de dblStub
'avec le future
dblCompoFut = ((1 + dblStub) ^ dblFrac1) * (1 + _
(100 - TabData(i)) * dblFrac2 / 100)

dblFrac1 = FractionAnnee(DateDeCalcul, (TabDatesMat(i)), _
"Exact/365")

'Transformation en taux composé Exact/365
dblFAtp = dblCompoFut ^ (1 / dblFrac1) - 1

Case Else
'Instrument de type obligation ou swap

'Identification de la date des flux de l'instrument
TabFluxOblg = DatesDesFlux(DateDeCalcul, (TabDatesMat(i)), _
1, , 1)
'On cherche les facteurs d'actualisation aux dates de flux
TabFAOblg = Interpolation(TabDateFacActu, TabFacActu, _
TabFluxOblg)

dblFrac1 = FractionAnnee(DateDeCalcul, (TabFluxOblg(1)), _
(TabDataBase(i)))
dblFrac2 = FractionAnnee(DateDeCalcul, (TabFluxOblg(1)), _
"Exact/365")

'Application de la formule
'Calcul de la somme
'Le premier coupon est pondéré
dblSum = ((1 + TabData(i) * 100) ^ dblFrac1 - 1) / _
((1 + TabFAOblg(1)) ^ dblFrac2)

If UBound(TabFluxOblg) > 2 Then
'Si UBound(TabFluxOblg) = 2, alors c'est
'un instrument à 2 ans.
'On cherche le facteur d'actualisation à 2 ans,
'inutile de poursuivre la somme
For j = 2 To UBound(TabFluxOblg) - 1
dblFrac2 = FractionAnnee(DateDeCalcul, _
(TabFluxOblg(j)), "Exact/365")
dblSum = dblSum + TabData(i) * 100 / _
((1 + TabFAOblg(j)) ^ dblFrac2)
Next
End If

'Le facteur d'actualisation
dblFAtp = (100 - dblSum) / (100 + TabData(i) * 100)
dblFrac1 = FractionAnnee(DateDeCalcul, (TabDatesMat(i)), _
"Exact/365")

'Transformation en taux composé Exact/365
dblFAtp = (1 / dblFAtp) ^ (1 / dblFrac1) - 1
End Select

'On ajoute le nouveau facteur d'actualisation et sa date de maturité
'aux tableaux qui nous servent pour les interpolations
iTailleTab = iTailleTab + 1
ReDim Preserve TabFacActu(iTailleTab)
ReDim Preserve TabDateFacActu(iTailleTab)
TabDateFacActu(iTailleTab) = TabDatesMat(i)
TabFacActu(iTailleTab) = dblFAtp



'On renseigne le tableau de résultats
dblFrac1 = FractionAnnee(DateDeCalcul, (TabDatesMat(i)), "Exact/365")
TableauSortie(1, i) = TabDatesMat(i)
TableauSortie(2, i) = 1 / (1 + TabFacActu(iTailleTab)) ^ dblFrac1
TableauSortie(3, i) = TabFacActu(iTailleTab)

Next

CourbeActualisation = TableauSortie

End Function
 

stefen

XLDnaute Nouveau
Re : construction d'une courbe d'actualisation avec VBA

Salut,
je te remercie d'avoir répondu à mon message, et je vais essayé d'être plus précis, cela pourrait intéresser d'autres personnes.

En fait je souhaitais faire un swap de crédit, c'est à dire donner les flux d'un tableaux d'amortissement, c'est à dire les échéances de l'amortissement à chaque période, ceux ci donné à partir d'un taux fixe.
Et en fait je veux recevoir les flux du tableau d'amortissement identique, mais au lieu du taux fixe, determiner les flux de chaque periode en fonction du taux forward de la période.
Petit exemple:
pour une période donnée: j'ai un capital de 1000€, avec un taux fixe de 5%, pour un amortissement constant j'aurai en intérêt : 1000*5%*d, où d correspond à la durée de la période. Ensuite j'ai l'amortissement, ici constant correspondant au capital divisé par le nombre de période, et enfin l'écheance egal à interet+amortissement.

Et bien je fais pareil mais au lieu de mettre le taux d'interet fixe, j'utilise le taux forward correspondant à la periode, c'est à dire si ma période d'amortissement est du 1/06/2012 au 1/09/2012, et bien je prendrais le taux forward correspondant.

Donc voila mes deux parties du swap, mon tableau d'amortissement construit avec le taux fixe, et mon autre tableau d'amortissement construit avec les taux forward.
Je veux donc que les deux jambes de mon swap soient égaux, je les actualise donc à l'aide de ma courbe de taux zéro coupon, et je devrais normalement arriver à avoir la meme chose si j'actualise la somme des flux de ma jambe fixe, et de ma jambe variable. J'y arrive très bien avec l'amortissement in fine, l'amortissement constant, et l'amortissement progressif, mais je n'y arrive pas avec un amortissement à échéance constante....
J'espère que je t'ai éclairé un peu plus...
 

Discussions similaires

Statistiques des forums

Discussions
312 084
Messages
2 085 194
Membres
102 811
dernier inscrit
caroline29260