Fonction VBA appelant une autre fonction (bug)
Bonjour,
J'ai 2 fonctions VBA (fonction PrixObligation et fonction InterpLineaire) qui fonctionnent bien séparement.
Dans la fonction PrixObligation, il y a une variable "discountRate" qui appelle la fonction InterpLineaire.
Malheureusement au moment de calculer cette variable, on entre bien dans la fonction interpLineaire mais le résultat n'est pas retourné à la fonction PrixObligation et le code stoppe.
J'ai ajouté la commandé "Error GoTo ErrorHandler" mais systématiquement le discountRate n'est pas calculé et me renvoie donc 0 pour cette valeur.
Pouvez vous m'aider svp (pièce jointe du code) ?
Voici un exemple des paramètres d'entrée pour la fonction PrixObligation.
- Date de maturité : 31/12/2025
- Fréquence de paiement annuel : 2 fois par an
- Taux de coupon : 5%
- Date du premier coupon : 30/06/2022
- Date de valorisation : 31/12/2021
- Courbe de discount :
- Temps (années) : 0, 1, 2, 3, 4
- Taux (%) : 3, 2.8, 2.5, 2.3, 2.1
- Convention de base : "AA"
Merci d'avance,
Bonjour,
Fait un premier test en changeant le type de timeToPayement en date pour voir.
Function InterpLineaire(discountCurve As Range, timeToPayment As Date) As DoubleEnsuite met un point d'arrêt Sur le début de la boucle et fait du pas à pas pour voir la valeur des variables Menu Affichage/Fenêtre variables locales.
Aprés dis nous ce qu'il en ressort.
bonjour à tous,
ta gestion d'erreur n'est pas correcte.
voici une adaptation de ton code.
Function PrixObligation(maturityDate As Date, paymentFrequency As Integer, couponRate As Double, _
firstCouponDate As Date, valuationDate As Date, discountCurve As Range, _
dayCountConvention As String) As Double
Dim daysToMaturity As Integer
Dim couponPayment As Double
Dim discountFactor As Double
Dim timeToPayment As Double
Dim discountRate As Double
Dim timeToMaturity As Double
Dim i As Integer
Dim daysInYear As Integer
'Détermination du nombre de jours dans une année en fonction de la convention de base
Select Case dayCountConvention
Case "AA"
daysInYear = 365
Case "A5"
daysInYear = 365
Case "A0"
daysInYear = 360
Case Else
' Par défaut, utilisation de 365 jours
daysInYear = 365
End Select
' Calcul du nombre de jours jusqu'à la maturité
daysToMaturity = maturityDate - valuationDate
'Calcul du temps avant maturité pour connaitre le nombre des coupons
timeToMaturity = daysToMaturity / daysInYear
' Calcul du montant de chaque paiement de coupon
couponPayment = couponRate / paymentFrequency
' Initialisation du prix de l'obligation
PrixObligation = 0
' Calcul du prix de l'obligation en sommant les flux actualisés
For i = 1 To timeToMaturity * paymentFrequency
' Calcul du temps jusqu'au paiement du coupon
timeToPayment = (firstCouponDate - valuationDate) + (i - 1) * (daysInYear / paymentFrequency)
' Interpolation linéaire pour obtenir le taux de remise correspondant
discountRate = InterpLineaire(discountCurve, timeToPayment)
' Calcul du facteur d'actualisation
discountFactor = Exp(-discountRate * timeToPayment / daysInYear)
' Ajout du flux actualisé au prix de l'obligation
PrixObligation = PrixObligation + couponPayment * discountFactor
Next i
On Error GoTo 0 ' Réactiver la gestion des erreurs normale
' Ajout du remboursement du principal à l'échéance
PrixObligation = PrixObligation + 1 * Exp(-discountRate * daysToMaturity / daysInYear)
End Function
Function InterpLineaire(discountCurve As Range, timeToPayment As Double) As Double
Dim i As Integer
Dim x1 As Double, x2 As Double, y1 As Double, y2 As Double
' Recherche des points de la courbe les plus proches
For i = 1 To discountCurve.Rows.Count - 1
If discountCurve.Cells(i, 1).Value <= timeToPayment And discountCurve.Cells(i + 1, 1).Value >= timeToPayment Then
x1 = discountCurve.Cells(i, 1).Value
x2 = discountCurve.Cells(i + 1, 1).Value
y1 = discountCurve.Cells(i, 2).Value
y2 = discountCurve.Cells(i + 1, 2).Value
Exit For
End If
Next i
' Interpolation linéaire
If x2 <> x1 Then 'on gère le cas d'une division par 0
InterpLineaire = y1 + (timeToPayment - x1) * (y2 - y1) / (x2 - x1)
Else
InterpLineaire = 0
End If
End Function@h2so4 Merci pour la proposition mais même avec la modification.
La variable discountRate est toujours systématiquement à 0 (peu importe les scenarios) ce qui n'est pas normalement vu que c'est une interpolation linéaire entre 2 dates dont les pourcentages associés sont différents de 0.
@Jean Paul, j'ai également testé votre proposition mais malheureusement, l'interpolation renvoie également 0.
rebonjour,
quand je fais le test avec les valeurs que tu as communiquées, j'ai bien une réponse différente de 0 (1.2), Comme je ne comprends pas tes calculs je ne peux pas vérifier si c'est correct.
En fait 1.2 c’est le résultat (le prix) sans effet de l’interpolation. Si vous mettez un debug, vous verrez que la variable ”discountRate” prend tout le temps la valeur 0 ce qui fait que le résultat sera toujours 1.2. En d’autres termes discountrate est une variable qui vient diviser le prix (divisé par 1+discountRate) en fonction de l’interpolation réalisée. Et s’il est tout le temps à 0 alors, on divise par 1 et on obtient 1.2 sans l’effet discount!
re,
pour tes valeurs de test, cette partie du code n'est jamais exécutée (vérifie tes conditions)
x1 = discountCurve.Cells(i, 1).Value
x2 = discountCurve.Cells(i + 1, 1).Value
y1 = discountCurve.Cells(i, 2).Value
y2 = discountCurve.Cells(i + 1, 2).Value
Exit Forbonjour,
dans ce cas, dans ta fonction prixobligation, tu devrais vérifier ta variable de timetopayment (qui prend les valeurs successives 181,363,546,728,911,1093,1276 et 1458 avec les données fournies, valeurs pour lesquelles ta fonction interplineaire, renvoie 0) .
Re,
Exactement, c'était là mon erreur.
Merci beaucoup pour votre aide!
Bonne journée et bon week-end.
