Programme à compléter : calcul itératif de baisse d'une valeur

Résolu/Fermé
Aldouss Messages postés 8 Date d'inscription lundi 26 janvier 2015 Statut Membre Dernière intervention 10 octobre 2018 - 26 janv. 2015 à 15:04
Aldouss Messages postés 8 Date d'inscription lundi 26 janvier 2015 Statut Membre Dernière intervention 10 octobre 2018 - 26 janv. 2015 à 15:39
Bonjour mesdames, bonjour messieurs !

J'ai un programme à remplir, quelques formules,
J'adore l'informatique, mais je suis largué ... Pourtant ce n'est pas bien compliqué, je me sens bête.

J'ai des valeurs dans un fichier Excel, je dois déterminer :
- la highwatermark en t : valeur historique la plus élevée
- le DrawDown en t (baisse de la valeur, avec la formule itérative : DDt = 1 - (1 + cours en t) / (1 + highwatermark)
Je ne comprends déjà pas cette formule .. Donc je l'ai rentrée bêtement, je préfèrerais la comprendre.
- La durée de cette baisse : DrawDownDuration (DDd t)
Formule itérative : DDd t = DDd (t-1) + 1 si DD t > 0
DDd t = 0 sinon

Et calculer ensuite le max DD et le max DDd

On considère que la baisse est effective même lorsque la valeur remonte, tant qu'elle n'a pas retrouvé le niveau initial avant d'entamer sa baisse (Si elle passe de 100 à 70, puis remonte jusqu'à 100, la baisse sera de 100 à 100, pas de 100 à 70)


J'ai 3 modules, je dois commencer par complêter celui ci :

<code>Option Explicit
Option Base 1

Function fnCumReturn(c As Variant) As Variant

'fonction calculant le rendement cumulé
'NB : c est supposé être un vecteur colonne

Dim n As Long, i As Long
Dim r() As Variant

'nombre d'observations
n = UBound(c, 1)

'définition du variant r où les rendements cumulés seront stockés
ReDim r(n - 1, 1)

'boucle sur les périodes et calcul des rendements cumulés
For i = 1 To n - 1
    r(i, 1) = c(1 + i, 1) / c(1, 1) - 1
Next i

'résultat de la fonction
fnCumReturn = r

End Function
Function fnDrawDown(r As Variant) As Variant

'fonction calculant le maximum drawdown et la maximum drawdown duration
'ARGUMENT : le vecteur des rendements cumulés (calculés à partir de la première date)
'NB : r est supposé être un vecteur colonne

Dim i As Long, n As Long
Dim mDD As Double, mDDd As Double
Dim DD() As Variant, DDd() As Variant, hwm() As Variant

'nombre d'observations

n = UBound(r, 1) 'va renvoyer la première dimension de r


'redimensionnement des variants
ReDim DD(n, 1)     'pour le drawdown
ReDim DDd(n, 1)    'pour la drawdown duration
ReDim hwm(n, 1)     'pour le highwatermark

'initialisation des valeurs initiales
DD(1, 1) = 0
DDd(1, 1) = 0
hwm(1, 1) = 0
mDD = 0: mDDd = 0


'boucle sur les périodes (de 2 à la dernière) et calcul itératif _
des drawdowns et des drawdown durations
For i = 2 To n
    
    'calcul de la nouvelle valeur max
    If r(i, 1) > hwm(i - 1, 1) Then
        hwm(i, 1) = r(i, 1)
    Else
        hwm(i, 1) = hwm(i - 1, 1)
    End If
    
    'calcul du drawdown de la période i
    
    'DD(i, 1) = DD(i, 1) + DD(i, i - 1)
    'If r(i, 1) < hwm(i - 1, 1) Then  --> ligne inutile ?? Pas de boucle If ... ?
    
        DD(i, 1) = 1 - (1 + r(i, 1)) / (1 + hwm(i, 1))
    'Else
     '   hwm(i, 1) = hwm(i - 1, 1)
    'End If
    
    'calcul de la drawdown duration (avec structure if then)

    'If hwm(i, 1) > r(i, 1) Then         's'il y a baisse dans les rendements on comptabilise ajoute 1 à la drawdownduration, sinon hausse / reprise de croissance -> DDd(i,1) remis à 0
    'Meilleure structure if à priori :
    
    If DD(i, 1) > 0 Then
        DDd(i, 1) = DDd(i - 1, 1) + 1
    Else
        DDd(i, 1) = 0
        
Next i


'calcul du maximum drawdown

For i = 2 To n
    If DD(i, 1) > DD(i - 1, 1) Then
    mDD = DD(i, 1)
    End If
    
Next i

'calcul de la max drawdown duration
For i = 2 To n
    If r(i, 1) < hwm(i - 1, 1) Then             'condition d'un mouvement de perte (rendement i < max historique en i-1)
        mDDd = mDDd + 1
        Else
        mDDd = 0                                    ' remise à 0 sinon car implique mouvement de hausse ATTENTION : prof -> fin de la baisse lorsque revenu au niveau initial -> à retravailler
    

'résultat de la fonction
fnDrawDown = Array(mDD, mDDd)

End Function


Je peux aussi mettre les autres, voir joindre les fichiers au besoin,
Mais à mon avis je galère sur un truc simple,

Je n'aime pas avoir un code à compléter, je vais devoir m'y habituer mais je suis plus à l'aise lorsqu'il s'agit de créer un code soi même de A à Z...
De plus je m'embrouille déjà sur les définitions même, de ce que je dois ensuite coder :(

N'hésitez pas à m'aider, toute contribution sera chaleureusement remerciée,
Merci à la communauté pour l'aide qu'elle m'a déjà prodigué sans le savoir (pour toutes les infos que j'ai trouvées sans avoir à poster :) )

Bon début de semaine.

2 réponses

Aldouss Messages postés 8 Date d'inscription lundi 26 janvier 2015 Statut Membre Dernière intervention 10 octobre 2018
26 janv. 2015 à 15:32
En fait c'est surtout là que j'ai du mal à voir comment coder :

calcul de la max drawdown duration
For i = 2 To n
    If DD(i, 1) > 0 Then                          'condition d'un mouvement de perte
        mDDd = mDDd + 1                     '
        Else
        mDDd = 0                                    ' remise à 0 sinon car implique mouvement de hausse ATTENTION : prof -> fin de la baisse lorsque revenu au niveau initial -> à retravailler
    



mDDd doit renvoyer la baisse la plus longue, mais c'est un LONG... Je ne peux pas l'indicer ...
je ne vois pas comment faire, en fait, sans parler de VBA : algorithmiquement parlant :(
0
Aldouss Messages postés 8 Date d'inscription lundi 26 janvier 2015 Statut Membre Dernière intervention 10 octobre 2018
26 janv. 2015 à 15:39
Je dois être fatigué, parce que sinon c'est juste que je suis bête et ça me fait mal au coeur -_-

Il suffit d'utiliser la fonction max, j'ai demandé à un collègue.

Et j'avais trouvé une autre façon, plus compliqué mais qui restait relativement simple ...

Pfff :(

'calcul du maximum drawdown

For i = 2 To n
    If DD(i, 1) > DD(i - 1, 1) Then
    mDD = DD(i, 1)
    End If
    
Next i

'calcul de la max drawdown duration
For i = 2 To n
    If DDd(i, 1) > mDDd Then
        mDDd = DDd(i, 1)                    '
    End If

Next i


Au moins je corrige mes erreurs :)
0