VBA függvény paramétereinek bekérése Inputbox-al

VBA függvény paramétereinek bekérése Inputbox-al
2020-11-22T17:28:00+01:00
2020-11-22T23:12:53+01:00
2022-10-15T21:25:27+02:00
Orosz Rebeka
Szeretnék egy pénzügyi modellre egy teljeskörű kalkulátort VBA_ban ahol a felhasználó adja meg a paraméterek értékeit egyenként inputbox segítségével. Azonban még nem csináltam ilyen For Each ciklussal Inputbox-ot és legtöbbször hibakódba futok a kódom egyelőre így néz ki, azt nem tudom, hogyan lehetne hogy a Variables Tömb minden elemére az inputboxban megadott értéket elmentse és majd azzal számolja ki a képlettel az eredményt.
A másik része ami még kérdéses, hogy a DIV- változót ami opcionális jól adtam-e meg ott az lenne a lényeg, hogy ha van DIV(osztalék) akkor az S értéket még korrigálni kell, de ha nincs akkor maradhat a sima S. Előre is köszönöm a válaszokat!

Function CND(X) Dim X As Double CND = Application.WorksheetFunction.NormDist(X, 0, 1, True) End Function Function BlackScholes(S, S_korr, K, r, T, backt, divt, v, PutCall, Optional DIV) Dim PutCall As String Dim S, K, r, T, backt, divt, v, DIV As Double Dim d1, d2 As Double Dim Variables, Value Variables = Array(S, S_korr, K, r, T, backt, divt, v, DIV) For Each Value In Variables Value = Application.InputBox("Add meg a(z) " & Value & "-t") If IsMissing(DIV) Then S = S ElseIf S = S_korr Then S_korr = S - DIV * Exp(-r * divt) End If d1 = (Log(S / K) + 0.5 * v ^ 2 * (T - backt)) / (v * Sqr(T - backt)) d2 = d1 - (v * Sqr(T - backt)) bs_call = S * CND(d) - Exp(-r * T) * K * CND(d2) Select Case PutCall Case "Call " BlackScholes = bs_call Case " Put " BlackScholes = bs_call - S + K * Exp(-r * T) End Select End Function
Mutasd a teljes hozzászólást!

  • Szia!
    1. észrevétel:
    Ha paramétereket határozol meg a függvény bemeneti értékeként, akkor azokat nem szabad ismételten definiálni az eljáráson belül! Az adattípust a paraméterlistában adhatod meg. Pl. 

    Function CND(x As Double) As Long 'ezzel meghatározod, hogy a függvény milyen adattípussal térjen vissza.
    Ezeket a paramétereket a meghívandó függvényen kívül kell bekérned és utána együtt megadni a függvény meghívásakor. 
    Ez igaz a CND és a BlackScholes függvényedre is.
    2. Az Excelben egy csomó pénzügyi kalkulátor függvény van, nem lehet azok közül választanod egyet?
    Üdv.
    Mutasd a teljes hozzászólást!
  • Igen azóta rájöttem, hogy ha így akarom hogy a felhasználó adja meg a bemeneti értékeket akkor nem függvényt kell használnom. Igazából ott vagyok most elakadva, hogy bekérjem ezeket az értékeket úgy hogy ellenőrizve legyen hogy helyes/alkalmazható értéket adtak meg, esetleg ebben tudsz segíteni? A PutCall-nál lenne egyedül,hogy az a feltétel, hogy "put" vagy "call" értéket ad meg a felhasználó. A többinél általában az hogy egy 0-nál nagyobb, bár lesz olyan ahol mondjuk 1-nél kisebbnek is kell lennie.
    Sajnos ez egy házi feladat hogy VBA ban csináljuk meg hiába van rá esetleg más egyszerűbb megoldás excelben, és kicsit sürget az idő ugyhogy nagyon hálás lennék ha tudsz most esetleg segíteni. :) 

    Sub BlackScholes() ' A bemeneti értékek: ' PutCall = put vagy call opció ' S = jelenlegi spot árfolyam ' S_korr = korrigált árfolyam ' K = kötési árfolyam ' r = loghozam ' T = futamidő ' backT = hátralévő idő ' sigma = volatilitás ' Div = osztalékfizetés értéke ' divT = osztalékig tartó időszak Dim PutCall As String Dim S, K, r, T, backT, divT, v, Div As Double Dim d1, d2 As Double Do PutCall = InputBox("Put vagy Call opciót árazzunk?", _ Title:="Bemeneti értékek megadása", Type:=2) Loop While PutCall ?? Do S = InputBox("Írja be a spot árfolyamot", _ Title:="Bemeneti értékek megadása", Type:=1) Loop While S < 0 If Div = 0 & divT = 0 Then S = S ElseIf S = S_korr Then S_korr = S - Div * Exp(-r * divT) End If d1 = (Log(S / K) + 0.5 * v ^ 2 * (T - backT)) / (v * Sqr(T - backT)) d2 = d1 - (v * Sqr(T - backT)) bs_call = S * CND(d) - Exp(-r * T) * K * CND(d2) Select Case PutCall Case "Call " BlackScholes = bs_call Case " Put " BlackScholes = bs_call - S + K * Exp(-r * T) End Select End Sub
    Mutasd a teljes hozzászólást!
  • Szia!
    A változók definiálásánál minden változó után meg kell adnod a típusát, nem elég a sor végére írni a típust! Tehát

    Dim S As Double, K As Double ....
     
    Nincs definiálva pl az S_korr változód.
    A modul legelejére - eljárásokon kívül -  írd be ezt:

    Option Explicit
    Ez azt eredményezi, hogy a VBA ellenőrzi, hogy minden változót definiáltál-e használat előtt, tovább figyeli, hogy ne legyenek azonos nevű változóid.
    Az Inputbox "függvény" kétféle változatban létezik. Ha ellenőrzött adattípust szeretnél bekérni, akkor az Application.Inputbox függvényt kell használnod.
    A PutCall bekérésnél lehet például a ciklus visszaforgatási feltétel:

    Loop While PutCall <>"Put" And PutCall <>"Call"
    Egyelőre ennyi.
    Üdv.
    Mutasd a teljes hozzászólást!
  • Kijavítottam amiket írtál köszönöm szépen! De egy olyan kérdésem lenne, hogy a PutCall-nál ha azt szeretném hogy vagy "put" vagy "call" legyen akkor nem Or-t kéne használnom? Ugyanezt alkalmaztam a sigmára aminek meg 0 és 1 között kéne lennie. Az S_korr.t meg azért nem írom bele mert azt én akarom majd kiszámoltatni ha szükség van rá, azt majd egy If feltétellel szeretném megtenni. Így alakultak akkor a bemeneti értékek bekérése:
    Do    
    PutCall = Application.InputBox("Put vagy Call opciót árazzunk?", _    
    Title:="Bemeneti értékek megadása", Type:=2)  
    Loop While PutCall <> "put" Or PutCall <> "call"
    Do    
    S = Application.InputBox("Írja be a spot árfolyamot", _    
    Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While S < 0  
    Do    
    K = Application.InputBox("Írja be a kötési árfolyamot", _    
    Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While K < 0
    Do    
    r = Application.InputBox("Írja be a releváns loghozamot", _    
    Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While r < 0 Or r > 1
    Do      
    T = Application.InputBox("Írja be a futamidőt", _      
    Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While T < 0  
    Do      
    backT = Application.InputBox("Írja be a hátralévő időt", _      
    Title:="Bemeneti értékek megadása", Default:=0, Type:=1)  
    Loop While backT < 0  
    Do      
    sigma = Application.InputBox("Írja be a volatilitás értékét", _      
    Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While sigma < 0 And sigma > 1  
    Do      
    Div = Application.InputBox("Írja be az osztalék értékét (ha van )", _      
    Title:="Bemeneti értékek megadása", Default:=0, Type:=1)  
    Loop While Div < 0  
    Do      
    divT = Application.InputBox("Írja be az osztalék kifizetéséig hátralévő időt", _      
    Default:=0, Title:="Bemeneti értékek megadása", Type:=1)  
    Loop While divT < 0
    Mutasd a teljes hozzászólást!
  • Közben próbálkozom, a put call-nál már rájöttem hogy igen And-kell, azonban a többinél hibát jelez de nem ír semmi konkrétat, hogy miért nem jó az érték amit megadok. :( csak például már az S bekérésénél valami gond van pedig pozitív számot adok meg. Köszönöm a válaszod!
    Mutasd a teljes hozzászólást!
  • Szia!
    Nálam végigment a bekérésen. De írtam hozzá privit még.
    Milyen hibát jelez? Neked kell megvizsgálni, hogy jó-e az érték.
    Üdv.
    Mutasd a teljes hozzászólást!
  • Run-time Error 6-ot ír valamiért, gondolom akkor az értékkel van baja, én például 1200-at adtam meg az S-re és nem tetszett neki.
    Mutasd a teljes hozzászólást!
  • Szia!
    Valamelyik változód értéke túlcsordul (overflow).
    Melyik sornál jelentkezik a hiba?
    Üdv.
    Mutasd a teljes hozzászólást!
  • S = Application.InputBox("Írja be a spot árfolyamot", _     Title:="Bemeneti értékek megadása", Type:=1) - ennél, de felcseréltem párat és a többinél is ezt csinálja :/
    Mutasd a teljes hozzászólást!
  • Megmutatnád az elején a változók definiálását is?
    Milyen számot adsz meg az S -nek?
    Illetve az egész makrót a mostani állapotában?
    Mutasd a teljes hozzászólást!
  • Dim PutCall As String
    Dim S As Double, K As Double, r As Double, S_korr As Double
    Dim T As Double, backT As Double
    Dim sigma As Double, Div As Double, divT As Double
    Dim d1 As Double, d2 As Double, bs_call As Double, bs_result As Double

    több számmal is próbálkoztam, de 1200, 12000 ilyesmi értékek körül.
    Mutasd a teljes hozzászólást!
  • Szia!
    Annak nem lenne szabad problémát okozni.
    Gyanús, hogy más okozza a gondot.
    Üdv.
    Mutasd a teljes hozzászólást!
  • Akkor nem tudom mi lehet a probléma, utánajárok. Még egy olyan kérdésem lenne, hogy akkor amiket beírtam feltételek akkor tuti jók-e lehet akkor csak az én gépemen nem akar végigfutni. 
    ha azt akarom, hogy r az 0 és egy között legyen akkor ez így jó? 

    Do r = Application.InputBox("Írja be a releváns loghozamot", _ Title:="Bemeneti értékek megadása", Type:=1) Loop While r < 0 Or r > 1
    A kódom a bemeneti rész után pedig egyelőre így néz ki: kicsit változtattam lesz egy érték ami attól függ a q mekkora ez a b értékben lesz ez így szerinted lefutna ha menne nekem? 

    If q = 0 Then b = r ElseIf q <> 0 Then b = r - q End If d1 = (Log(S / K) + (b + 0.5 * sigma ^ 2) * (T - backT)) / (sigma * Sqr(T - backT)) d2 = d1 - (sigma * Sqr(T - backT)) bs_call = S * CND(d1) - Exp(-r * T) * K * CND(d2) Select Case PutCall Case "Call " bs_result = bs_call Case " Put " bs_result = bs_call - S + K * Exp(-r * T) End Select Cells(3, 7).Value = bs_result
    És akkor az eredményt kiadná elvileg az adott cellába.
    Köszönöm4
    Mutasd a teljes hozzászólást!
  • Szia!
    Attól eltekintve, hogy ott még kell változókat definiálnod, elvileg le kell futnia.
    Az más kérdés, hogy pl. zéróosztó stb. hiba keletkezhet, ha az adatok nem kompatibilisek a számításhoz.
    Üdv.
    Mutasd a teljes hozzászólást!
Tetszett amit olvastál? Szeretnél a jövőben is értesülni a hasonló érdekességekről?
abcd