Arret fonction VBA

Arret fonction VBA - VB/VBA/VBS - Programmation

Marsh Posté le 02-10-2018 à 12:13:25    

Bonjour,
 
Me remettant au VBA après un long arret, je me suis lance dans quelques exercices habituellement assez simples, mais qui, finalement, posent des soucis qui ont l'air lies au language lui-meme. Voila le bout de code concerne :
 

Code :
  1. Function vanillaCallCRR(spot As Double, strike As Double, RFIR As Double, vol As Double, maturity As Double, nbSteps As Integer) As Double
  2. Dim size As Long
  3. size = (nbSteps + 1) * (nbSteps + 2) / 2
  4. Dim step, up, down, upProb As Double
  5. step = maturity / nbSteps
  6. up = Exp((RFIR + vol) * Sqr(step))
  7. down = Exp((RFIR - vol) * Sqr(step))
  8. upProb = (1 - Exp(-vol * Sqr(step))) / (Exp(vol * Sqr(step)) - Exp(-vol * Sqr(step)))
  9. Dim assetPriceTree() As Double
  10. ReDim assetPriceTree(nbSteps + 1)
  11. assetPriceTree(1) = spot * up ^ nbSteps
  12. For i = 2 To nbSteps + 1
  13.     assetPriceTree(i) = assetPriceTree(i - 1) * down / up
  14. Next i
  15.    
  16. Dim optionPriceTree() As Double
  17. ReDim optionPriceTree(size)
  18. For i = 1 To nbSteps + 1
  19.     optionPriceTree(nbSteps * (nbSteps + 1) / 2 + i) = Max(assetPriceTree(i) - strike, 0)
  20. Next i
  21. For i = nbSteps - 1 To 0 Step -1
  22.     For j = 1 To i + 1
  23.         optionPriceTree(i * (i + 1) / 2 + j) = (upProb * optionPriceTree((i + 1) * (i + 2) / 2 + j) + (1 - upProb) * optionPriceTree((i + 1) * (i + 2) / 2 + (j + 1))) * Exp(-RFIR * Sqr(step))
  24.     Next j
  25. Next i
  26.    
  27. vanillaCallCRR = optionPriceTree(1)
  28. End Function


 
Premier test sur un set de parametre simple : (100, 100, 0, 0.2, 1, 10). Cela semble fonctionner, donc je fais varier le dernier parametre pour tester, et il semblerait qu'au dela d'une certaine limite, le code ne fonctionne plus : pour nbSteps <=179, la fonction affiche une valeur, mais pour nbSteps>179, je me retrouve avec #Value. En utilisant le debugeur, il s'avere que le code s'arrete sans raison et sans alerte a la ligne 4. En remplacant ladite ligne par les lignes suivantes :  
 

Code :
  1. size = nbSteps + 1
  2. size = size * (nbSteps + 2)
  3. size = size / 2


 
autrement dit, exactement la meme operation, mais decompose en plusieurs lignes, le code se poursuit... jusque le premier appel de la ligne 21... qui realise effectivement une operation du meme type, mais qui est plus compliquee a changer, et, surtout, rendra le code bien plus lourd a executer.
 
Dernier point : en transformant cette fonction en macro, le code s'execute sans souci, meme avec un paramètre nbSteps bien supérieure. Bref, on dirait que les fonctions appelables sous Excel sous soumises à des contraintes supplémentaires par rapport aux macros. Est-ce le cas? Si oui, est-ce contournable? Si non, quelqu'un aurait-il une idée sur l'origine du problème?
 
D'avance, merci :)
 
Viserion

Reply

Marsh Posté le 02-10-2018 à 12:13:25   

Reply

Marsh Posté le 03-10-2018 à 01:10:24    

Bonjour,
 
Tu devrais déclarer toutes les variables avec le type adéquat.
 
En tête de module

Code :
  1. Option Explicit

n'est pas superflu
 
D'autre par le type Long n'est pas adapté quand on divise par 2 !


---------------
Cordialement, Patrice
Reply

Marsh Posté le 03-10-2018 à 10:50:06    

Merci pour ta réponse, j'avais effectivement oublié le Option Explicit :/ Comme je l'ai dit, mes réflexes de VBA sont loin... Après, dans cet exemple spécifique, les seules variables non declarées sont le i et le j pour les boucles.
 
Pour ton autre remarque, le type Long (ou Integer) n'est peut-être pas adapté quand on divise par 2, mais le type Double me semblait encore moins adapté quand il s'agissait de définir un tableau. La formule utilisée assurant que size serait toujours entier, j'ai privilégié un type d'entier. Mais, de toute manière, je viens d'essayer de changer, et mon problème reste le même :/

Reply

Marsh Posté le 03-10-2018 à 12:30:39    

C'est bizarre car si on prend ta valeur à partir de laquelle ça déconne (180) ça donne 181*182 (32 942) puis on divise par 2. Alors que la précédente était 179, donc 180*181 soit 32 580.
Entre 32 580 et 32 942 on passe la valeur de 32 768 qui correspond à 2^15 ou 2*2^14. Donc ça ressemble quand même méchament à un overflow. Je dirais qu'il faut essayer de changer le type de nbSteps, même si ce dernier semble correct...


Message édité par MaybeEijOrNot le 03-10-2018 à 12:31:23

---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Marsh Posté le 03-10-2018 à 13:52:17    

Effectivement, en changeant le type de nbSteps (et non de size, comme je l'avais teste precedemment) en double, cela fonctionne. J'avoue être assez étonné de ne pas pouvoir utiliser d'integer pour calculer un long ou un double...
 
Merci, en tout cas :)

Reply

Marsh Posté le 03-10-2018 à 17:12:55    

Ce n'est pas ça, c'est le résultat qui est transformé en double, le temps du calcul, c'est le type de tes données utilisées dans le calcul qui sont utilisées.
On ne mélange pas les choux et les carottes.


---------------
C'est en écrivant n'importe quoi qu'on devient n'importe qui.
Reply

Sujets relatifs:

Leave a Replay

Make sure you enter the(*)required information where indicate.HTML code is not allowed