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 Double

Ensuite 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.

discountrate

@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 For

re,

c'est bizarre, parce que lorsque j'utilise les valeurs test pour pour calculer l'interpolation pour le point 2.5 j'obtiens bien 2.4%!
Je ne comprends pourquoi ces conditions ne sont pas respectées quand la fonction interplineaire est appelée par la fonction prixobligation.

interpolation

bonjour,

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.

Rechercher des sujets similaires à "fonction vba appelant bug"