Malicious Office (OLE) — malware analysis report

Static analysis result for SHA-256 c51e216c9fd96a4f…

MALICIOUS

Office (OLE)

657.0 KB Created: 2004-04-06 20:50:55 Authoring application: Microsoft Excel First seen: 2015-09-01
MD5: f3317192af8d939daa4de6f7e836956f SHA-1: e3a7a0bfe1ed4eb96e464e67c9813aa5cb79f4dc SHA-256: c51e216c9fd96a4f8192b26a710138709943fe57cfce89f06ce6f5450b7cf424
206 Risk Score

Malware Insights

MITRE ATT&CK
T1059.005 Visual Basic T1203 Exploitation for Client Execution

The file is an Excel document containing a large VBA macro. Critical heuristics indicate potential Shell calls and LOLBin references within the VBA code, specifically triggered by the Workbook_Open event. The macro likely attempts to download and execute a secondary payload from one of the embedded URLs.

Heuristics 8

  • VBA macros detected medium 6 related findings OLE_VBA_MACROS
    Document contains VBA macro code
  • Potential Shell call in VBA critical OLE_VBA_SHELL
    Potential Shell call in VBA
    Matched line in script
    Shell "rundll32.exe shdocvw.dll,OpenURL " & fil, vbNormalFocus
  • LOLBin reference in VBA critical OLE_VBA_LOLBIN
    LOLBin reference in VBA
    Matched line in script
    Shell "rundll32.exe shdocvw.dll,OpenURL " & fil, vbNormalFocus
  • VBA p-code auto-exec with execution tokens high OLE_VBA_PCODE_AUTOEXEC_EXEC
    Compiled VBA/cache stream contains an auto-execution token together with shell/download/object-execution tokens. This catches p-code-only or source-extraction-failure macro documents where visible source is unavailable.
  • Workbook_Open macro low OLE_VBA_WBOPEN
    Workbook_Open macro
    Matched line in script
    Private Sub Workbook_Open()
  • Auto_Open macro low OLE_VBA_AUTO
    Auto_Open macro
    Matched line in script
    Sub auto_open()
  • Auto_Close macro low OLE_VBA_AUTOCLOSE
    Auto_Close macro
    Matched line in script
    Sub auto_close()
  • Embedded URL info EMBEDDED_URL
    One or more URLs were extracted from the document. The URL itself is not a detection — see the per-URL labels for which channel (macro, JS, link annotation, document body, ...) reached each URL.
    URL http://www.cema.edu.ar/~jvarela In document text (OLE body)
    • http://www.cema.edu.ar/~jvarela/Instalado.htmIn document text (OLE body)

Extracted artifacts 1

Files carved from inside the sample during analysis.

FilenameKindSourceSize
macros.bas vba-macro oletools.olevba.extract_macros (decoded VBA source) 262984 bytes
SHA-256: 5105b1d2ba3dd03e0abc397d58c4d8b46423a38d1956e49f5f2d5bd93a2fd229
Preview script
First 1,000 lines of the extracted script
Attribute VB_Name = "Sensibilidad"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Attribute VB_Control = "ComboBox1, 1, 0, MSForms, ComboBox"
Attribute VB_Control = "ComboBox2, 2, 1, MSForms, ComboBox"

Option Explicit
Dim sireca As Long
Function convi2(qcolumnas As Long, qlineas As Long) As String
Attribute convi2.VB_ProcData.VB_Invoke_Func = " \n14"
Dim c As Long
Dim d As Long
Dim e As Long
d = 64
e = 64
For c = 1 To qcolumnas
d = d + 1
If d > 90 Then d = 65: e = e + 1
Next c
convi2 = IIf(e > 64, Chr(e), "") + Chr(d) + Trim(Str(qlineas))
End Function

Private Sub ComboBox1_Click()
Dim i As Long
Dim ql As Long
Dim a As Long
Dim si As Long
Dim i2 As Long
Dim v1 As Double
Dim v2 As Double
Dim v3 As Boolean
Dim xx As Variant
si = 0
On Error Resume Next
If sireca = 1 Then Exit Sub
Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("A1").Select
Application.ActiveWorkbook.Worksheets("Sensibilidad").Unprotect "24059860"
Application.ScreenUpdating = False
i = ComboBox1.ListIndex
Range("a2").Activate
If i = -1 Then Application.ActiveWorkbook.Worksheets("Sensibilidad").Protect "24059860": Exit Sub
ql = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
Application.ActiveWorkbook.Worksheets("Datos").Range(convi2(i + 2, 5) + ":" + convi2(i + 2, ql + 4)).Copy (Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("AA1:" + convi2(27, ql)))
For i2 = 1 To 170
If Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i2).Value = "" Then
i2 = i2 - 1
Exit For
Else
If i2 - 1 <> i Then
Range("a" + Trim(Str(i2 + si + 5))).Value = Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i2).Value
Application.ActiveWorkbook.Worksheets("Datos").Range(convi2(i2 + 1, 5) + ":" + convi2(i2 + 1, ql + 4)).Copy (Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("Ab1:" + convi2(28, ql)))
Range("b" + Trim(Str(i2 + si + 5))).Formula = "=CORREL(aa1:aa" + Trim(Str(ql)) + ",ab1:ab" + Trim(Str(ql)) + ")"
Range("b" + Trim(Str(i2 + si + 5))).Calculate
Range("b" + Trim(Str(i2 + si + 5))).Value = Range("b" + Trim(Str(i2 + si + 5))).Value2
Else
si = -1
End If
End If
Next i2
If i2 = 171 Then i2 = 170
Range("b6:b" + Trim(Str(i2 + si + 5))).NumberFormat = "0.0000"
Range("A6:b" + Trim(Str(i2 + si + 5))).Select
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    Selection.Borders(xlInsideVertical).LineStyle = xlNone
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
    
    Range("A6:A" + Trim(Str(i2 + si + 5))).Select
    
    Selection.Borders(xlDiagonalDown).LineStyle = xlNone
    Selection.Borders(xlDiagonalUp).LineStyle = xlNone
    With Selection.Borders(xlEdgeLeft)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeTop)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeBottom)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    With Selection.Borders(xlEdgeRight)
        .LineStyle = xlContinuous
        .Weight = xlMedium
        .ColorIndex = xlAutomatic
    End With
    Selection.Borders(xlInsideHorizontal).LineStyle = xlNone
    
     ' Ordenar
    
    v3 = True
    While v3
    Err.Clear
    v3 = False
    For i = 2 To i2 + si
    v1 = CDbl(Range("B" + Trim(Str(i + si + 5))))
    v2 = CDbl(Range("B" + Trim(Str(i + 1 + si + 5))))
    If Abs(v1) > Abs(v2) Or (Abs(v1) = Abs(v2) And v1 > v2) Then
    xx = Range("A" + Trim(Str(i + 1 + si + 5))).Value
    If Err.Number <> 0 Then Exit For
    Range("A" + Trim(Str(i + 1 + si + 5))).Value = Range("A" + Trim(Str(i + si + 5))).Value
    Range("A" + Trim(Str(i + si + 5))).Value = xx
    xx = Range("B" + Trim(Str(i + 1 + si + 5))).Value
    Range("B" + Trim(Str(i + 1 + si + 5))).Value = Range("B" + Trim(Str(i + si + 5))).Value
    Range("B" + Trim(Str(i + si + 5))).Value = xx
    v3 = True
    End If
    Next i
    Wend
    
    ActiveSheet.ChartObjects(1).Activate
    ActiveChart.SetSourceData Source:=Sheets("Sensibilidad").Range("A6:B" + Trim(Str(i2 + si + 5))), PlotBy:=xlColumns

Range("a2").Select
Range("a6").Activate
Application.ScreenUpdating = True
Application.ActiveWorkbook.Worksheets("Sensibilidad").Protect "24059860"
Application.ActiveWorkbook.Worksheets("Sensibilidad").EnableCalculation = False
Application.ActiveWorkbook.Worksheets("Sensibilidad").EnableCalculation = True
Application.ActiveWorkbook.Worksheets("Sensibilidad").Calculate
On Error GoTo 0
ComboBox2_Click
End Sub





Private Sub ComboBox2_Click()
Dim i As Long
Dim ql As Long
On Error Resume Next
Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("A1").Select
Application.ActiveWorkbook.Worksheets("Sensibilidad").Unprotect "24059860"
i = ComboBox2.ListIndex

Range("a2").Activate
Range("a6").Activate
If i = -1 Then Application.ActiveWorkbook.Worksheets("Sensibilidad").Protect "24059860": Exit Sub
ql = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
Application.ActiveWorkbook.Worksheets("Datos").Range(convi2(i + 2, 5) + ":" + convi2(i + 2, ql + 4)).Copy (Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("Ab1:" + convi2(28, ql)))
Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("f4:f5").NumberFormat = Application.ActiveWorkbook.Worksheets("Sensibilidad").Range("aa1:aa1").NumberFormat
Application.ActiveWorkbook.Worksheets("Sensibilidad").Protect "24059860"
Application.ActiveWorkbook.Worksheets("Sensibilidad").EnableCalculation = False
Application.ActiveWorkbook.Worksheets("Sensibilidad").EnableCalculation = True
Application.ActiveWorkbook.Worksheets("Sensibilidad").Calculate
On Error GoTo 0
End Sub

Private Sub Worksheet_Activate()
Dim i As Long
Dim xx As Long
Dim xx2 As Long
Dim ql As Long
Dim phs As Variant
xx = -1
xx2 = -1
On Error Resume Next
sireca = 1
phs = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
phs = Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 2)
If Err.Number <> 0 Then
MsgBox "No debe eliminar ni cambiar de nombre las hojas creadas", vbOKOnly, "Error en la aplicacion"
sireca = 0
On Error GoTo 0
Exit Sub
End If
Application.ActiveWorkbook.Worksheets("Sensibilidad").Unprotect "24059860"
ql = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
Range("f4:g4").FormulaArray = "=+LINEST(AA1:AA" + Trim(Str(ql)) + ",Ab1:Ab" + Trim(Str(ql)) + ",TRUE,FALSE)"
Range("a2").Value = ""

xx = ComboBox1.ListIndex
xx2 = ComboBox2.ListIndex
ComboBox1.Clear
ComboBox2.Clear
For i = 1 To 170
If Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i).Value = "" Then
i = i - 1
Exit For
Else
ComboBox1.AddItem (Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i).Value)
ComboBox2.AddItem (Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i).Value)
End If
Next i
If xx = -1 Or xx > ComboBox1.ListCount - 1 Then ComboBox1.ListIndex = 0
If xx2 = -1 Or xx2 > ComboBox2.ListCount - 1 Then ComboBox2.ListIndex = 0
If xx <> -1 Then ComboBox1.ListIndex = xx
If xx2 <> -1 Then ComboBox2.ListIndex = xx2
Application.ActiveWorkbook.Worksheets("Sensibilidad").Protect "24059860"
sireca = 0
ComboBox1_Click
On Error GoTo 0
End Sub



Attribute VB_Name = "Estadísticas"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True
Attribute VB_Control = "ComboBox1, 1, 0, MSForms, ComboBox"

Option Explicit
Dim sireca As Long
Function convi2(qcolumnas As Long, qlineas As Long) As String
Attribute convi2.VB_ProcData.VB_Invoke_Func = " \n14"
Dim c As Long
Dim d As Long
Dim e As Long
d = 64
e = 64
For c = 1 To qcolumnas
d = d + 1
If d > 90 Then d = 65: e = e + 1
Next c
convi2 = IIf(e > 64, Chr(e), "") + Chr(d) + Trim(Str(qlineas))
End Function
Private Sub ComboBox1_Change()

End Sub

Private Sub ComboBox1_Click()
Dim i As Long
Dim ql As Long
Dim a As Long
On Error Resume Next
If sireca = 1 Then Exit Sub
Application.ActiveWorkbook.Worksheets("Estadísticas").Range("A1").Select
Application.ActiveWorkbook.Worksheets("Estadísticas").Unprotect "24059860"
Application.ScreenUpdating = False
i = ComboBox1.ListIndex
Range("a2").Activate
If i = -1 Then Application.ActiveWorkbook.Worksheets("Estadísticas").Protect "24059860": Exit Sub
Application.ActiveWorkbook.Worksheets("Estadísticas").Cells(4, 2).Value = Application.ActiveWorkbook.Worksheets("Datos").Cells(4, i + 2).Value
ql = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
Application.ActiveWorkbook.Worksheets("Datos").Range(convi2(i + 2, 5) + ":" + convi2(i + 2, ql + 4)).Copy (Application.ActiveWorkbook.Worksheets("Estadísticas").Range("AA1:" + convi2(27, ql)))
Application.ActiveWorkbook.Worksheets("Estadísticas").Range("E3:F42").NumberFormat = Application.ActiveWorkbook.Worksheets("Estadísticas").Range("aa1:aa1").NumberFormat
Application.ActiveWorkbook.Worksheets("Estadísticas").Range("B5:B9").NumberFormat = Application.ActiveWorkbook.Worksheets("Estadísticas").Range("aa1:aa1").NumberFormat
Application.ActiveWorkbook.Worksheets("Estadísticas").Range("F3:J42").EntireColumn.AutoFit
Range("a2").Activate
Application.ActiveWorkbook.Worksheets("Estadísticas").Protect "24059860"
Application.ScreenUpdating = True
Application.ActiveWorkbook.Worksheets("Estadísticas").EnableCalculation = False
Application.ActiveWorkbook.Worksheets("Estadísticas").EnableCalculation = True
Application.ActiveWorkbook.Worksheets("Estadísticas").Calculate
On Error GoTo 0
End Sub

Private Sub Worksheet_Activate()
Dim i As Long
Dim xx As Long
Dim phs As Variant
On Error Resume Next
sireca = 1
phs = Application.ActiveWorkbook.Worksheets("Resumen").Cells(3, 2)
phs = Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 2)
If Err.Number <> 0 Then
MsgBox "No debe eliminar ni cambiar de nombre las hojas creadas", vbOKOnly, "Error en la aplicacion"
sireca = 0
On Error GoTo 0
Exit Sub
End If
Application.ActiveWorkbook.Worksheets("Estadísticas").Unprotect "24059860"
Range("a2").Value = ""
xx = ComboBox1.ListIndex
ComboBox1.Clear
For i = 1 To 170
If Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i).Value = "" Then
i = i - 1
Exit For
Else
ComboBox1.AddItem (Application.ActiveWorkbook.Worksheets("Datos").Cells(3, 1 + i).Value)
End If
Next i
ComboBox1.ListIndex = 0
If xx <> -1 Then ComboBox1.ListIndex = xx
Application.ActiveWorkbook.Worksheets("Estadísticas").Protect "24059860"
sireca = 0
ComboBox1_Click
On Error GoTo 0
End Sub



Attribute VB_Name = "Resumen"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True



Attribute VB_Name = "Datos"
Attribute VB_Base = "0{00020820-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True


Attribute VB_Name = "ThisWorkbook"
Attribute VB_Base = "0{00020819-0000-0000-C000-000000000046}"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = True
Attribute VB_Exposed = True
Attribute VB_TemplateDerived = False
Attribute VB_Customizable = True

Option Explicit
Private Sub Workbook_BeforeClose(Cancel As Boolean)
' No pregunta si quiere guardar y descarta cambios
ThisWorkbook.Saved = True
End Sub
Private Sub Workbook_BeforeSave(ByVal SaveAsUI As Boolean, Cancel As Boolean)
If ThisWorkbook.IsAddin = True Then
On Error Resume Next
If Right(ThisWorkbook.Name, 3) = "xls" Then
Cancel = False
Else
Cancel = True
End If
On Error GoTo 0
Else
Hoja1.Cells(11, 2) = versions + " necesita que abra el libro habilitando macros"
End If
End Sub
Private Sub Workbook_Open()
Dim i As Long
Hoja1.Cells(11, 2).Value = "Cargando....."
Randomize
pregunte = False
' Clear inputs
For i = 1 To maxinp
inputs(i, 1) = ""
inputs(i, 2) = ""
inputs(i, 3) = ""
inputs(i, 4) = ""
Next i
' Clear Outputs
For i = 1 To maxout
outputs(i, 1) = ""
outputs(i, 2) = ""
outputs(i, 3) = ""
Next i
' Disable simulacion
Simulacion = False

' Ve si es para instalar o ejecutar
If ThisWorkbook.IsAddin = False Then
insta.Show
Else
creatoole
End If
End Sub



Attribute VB_Name = "bestfitdist"
Option Explicit
Option Private Module
Function bestfit_Binomial(Probabilidad As Double, Intentos As Long, nombre_variable As String) As Long
Attribute bestfit_Binomial.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa probabilidad debe estar entre 0 y 1. El número de intentos debe ser mayor a 0.\r\nEl nombre de la variable debe estar entre comillas."
Dim sum As Long
Dim i As Long
If Probabilidad < 0 Or Probabilidad > 1 Then bestfit_Binomial = CVErr(xlErrNA): Exit Function
If Intentos <= 0 Then bestfit_Binomial = CVErr(xlErrNA): Exit Function

sum = 0
For i = 0 To Intentos - 1
sum = sum + bestfit_Bernoulli(Probabilidad, nombre_variable)
Next i
bestfit_Binomial = sum

End Function
Function bestfit_BinomialNegativa(Probabilidad As Double, Exitos As Long, nombre_variable As String) As Long
Attribute bestfit_BinomialNegativa.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa probabilidad debe estar entre 0 y 1. El número de éxitos debe ser mayor a 0.\r\nEl nombre de la variable debe estar entre comillas."
Dim sum As Long
If Exitos <= 0 Then bestfit_BinomialNegativa = CVErr(xlErrNA): Exit Function
If Probabilidad < 0 Or Probabilidad > 1 Then bestfit_BinomialNegativa = CVErr(xlErrNA): Exit Function

sum = 0
Dim i As Long
For i = 0 To Exitos - 1
sum = sum + bestfit_Geometrica(Probabilidad, nombre_variable)
Next i
bestfit_BinomialNegativa = sum
End Function
Function bestfit_Geometrica(Probabilidad As Double, nombre_variable As String) As Long
Attribute bestfit_Geometrica.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa probabilidad debe estar entre 0 y 1.\r\nEl nombre de la variable debe estar entre comillas."
If Probabilidad < 0 Or Probabilidad > 1 Then bestfit_Geometrica = CVErr(xlErrNA): Exit Function
bestfit_Geometrica = Int(Log(bestfit_Uniforme(0, 1, nombre_variable)) / Log(1 - Probabilidad))
End Function

Function bestfit_Hipergeometrica(Intentos As Long, Poblacion As Long, Exitos_Posibles As Long, nombre_variable As String) As Long
Attribute bestfit_Hipergeometrica.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nIntentos, población y éxitos posibles deben ser mayoesr a 0. Población debe ser mayor a éxitos posibles.\r\nEl nombre de la variable debe estar entre comillas."
Dim i As Long
Dim count As Long
Dim p As Double
If Intentos <= 0 Then bestfit_Hipergeometrica = CVErr(xlErrNA): Exit Function
If Poblacion < 1 Then bestfit_Hipergeometrica = CVErr(xlErrNA): Exit Function
If Poblacion <= Intentos Then bestfit_Hipergeometrica = CVErr(xlErrNA): Exit Function
If Exitos_Posibles < 0 Then bestfit_Hipergeometrica = CVErr(xlErrNA): Exit Function

count = 0
For i = 0 To Intentos - 1
p = CDbl(Exitos_Posibles) / CDbl(Poblacion)
If bestfit_Bernoulli(p, nombre_variable) = 1 Then count = count + 1: Exitos_Posibles = Exitos_Posibles - 1
Poblacion = Poblacion - 1
Next i
bestfit_Hipergeometrica = count

End Function

Function bestfit_Pascal(Probabilidad As Double, Exitos As Long, nombre_variable As String) As Long
Attribute bestfit_Pascal.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa probabilidad debe estar entre 0 y 1. El número de intentos debe ser mayor a 0.\r\nEl nombre de la variable debe estar entre comillas."
If Exitos <= 0 Then bestfit_Pascal = CVErr(xlErrNA): Exit Function
If Probabilidad < 0 Or Probabilidad > 1 Then bestfit_Pascal = CVErr(xlErrNA): Exit Function
bestfit_Pascal = bestfit_BinomialNegativa(Probabilidad, Exitos, nombre_variable) + Exitos
End Function

Function bestfit_Poisson(Ocurrencia As Double, nombre_variable As String) As Long
Attribute bestfit_Poisson.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa tasa de ocurrencia debe ser mayor a 0.\r\nEl nombre de la variable debe estar entre comillas."
Dim b As Double
Dim i As Long
If Ocurrencia <= 0 Then bestfit_Poisson = CVErr(xlErrNA): Exit Function
b = 1
If Exp(-Ocurrencia) <= 0 Then bestfit_Poisson = CVErr(xlErrNA): Exit Function
While b >= Exp(-Ocurrencia)
b = b * bestfit_Uniforme(0, 1, nombre_variable)
i = i + 1
Wend
bestfit_Poisson = i - 1
End Function
Function bestfit_Potencia(param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Potencia.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de forma y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Potencia = CVErr(xlErrNA): Exit Function
bestfit_Potencia = bestfit_Uniforme(0, 1, nombre_variable) ^ (1 / param_alfa)
End Function
Function bestfit_Arcoseno(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Arcoseno.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim q As Double
If Limite_inferior >= Limite_superior Then bestfit_Arcoseno = CVErr(xlErrNA): Exit Function
q = Sin(1.5707963267949 * bestfit_Uniforme(0, 1, nombre_variable))
bestfit_Arcoseno = Limite_inferior + (Limite_superior - Limite_inferior) * q * q
End Function

Function bestfit_Bernoulli(Probabilidad As Double, nombre_variable As String) As Long
Attribute bestfit_Bernoulli.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLa probabilidad debe estar entre 0 y 1.\r\nEl nombre de la variable debe estar entre comillas."
If Probabilidad < 0 Or Probabilidad > 1 Then bestfit_Bernoulli = CVErr(xlErrNA): Exit Function
If bestfit_Uniforme(0, 1, nombre_variable) < Probabilidad Then
bestfit_Bernoulli = 1
Else
bestfit_Bernoulli = 0
End If
End Function

Function bestfit_Coseno(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Coseno.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim a As Double
Dim b As Double
Dim x As Double
If Limite_inferior >= Limite_superior Then bestfit_Coseno = CVErr(xlErrNA): Exit Function
a = 0.5 * (Limite_inferior + Limite_superior)
b = (Limite_superior - Limite_inferior) / 3.14159265358979
x = bestfit_Uniforme(-1, 1, nombre_variable)
bestfit_Coseno = a + b * Atn(x / Sqr(-x * x + 1))
End Function

Function bestfit_DobleLog(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_DobleLog.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim a As Double
Dim b As Double
If Limite_inferior >= Limite_superior Then bestfit_DobleLog = CVErr(xlErrNA): Exit Function

a = 0.5 * (Limite_inferior + Limite_superior)
b = 0.5 * (Limite_superior - Limite_inferior)
    If bestfit_Bernoulli(0.5, nombre_variable) = 1 Then
    bestfit_DobleLog = a + b * bestfit_Uniforme(0, 1, nombre_variable) * bestfit_Uniforme(0, 1, nombre_variable)
    Else
    bestfit_DobleLog = a - b * bestfit_Uniforme(0, 1, nombre_variable) * bestfit_Uniforme(0, 1, nombre_variable)
    End If
End Function


Function bestfit_Beta(param_alfa As Double, param_beta As Double, Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Beta.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nParam Alfa y Beta son los parámetros de forma y deben ser positivos.\r\nEl nombre de la variable debe estar entre comillas."
Dim y1 As Double
Dim y2 As Double
If Limite_inferior >= Limite_superior Then bestfit_Beta = CVErr(xlErrNA): Exit Function
If param_alfa <= 0 Or param_beta <= 0 Then bestfit_Beta = CVErr(xlErrNA): Exit Function
    y1 = bestfit_Gamma(0, 1, param_alfa, nombre_variable)
    y2 = bestfit_Gamma(0, 1, param_beta, nombre_variable)
    If param_alfa < param_beta Then
    bestfit_Beta = Limite_superior - (Limite_superior - Limite_inferior) * y2 / (y1 + y2)
    Else
    bestfit_Beta = Limite_inferior + (Limite_superior - Limite_inferior) * y1 / (y1 + y2)
    End If
End Function

Function bestfit_Cauchi(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Cauchi.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Cauchi = CVErr(xlErrNA): Exit Function
bestfit_Cauchi = Corrimiento + param_alfa * Tan(3.14159265358979 * (bestfit_Uniforme(-0.5, 0.5, nombre_variable)))
End Function

Function bestfit_Chi2(Grados_de_libertad As Long, nombre_variable As String) As Double
Attribute bestfit_Chi2.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nLos grados de libertad deben ser mayores a 0.\r\nEl nombre de la variable debe estar entre comillas."
If Grados_de_libertad < 1 Then bestfit_Chi2 = CVErr(xlErrNA): Exit Function
bestfit_Chi2 = bestfit_Gamma(0, 2, 0.5 * CDbl(Grados_de_libertad), nombre_variable)
End Function


Function bestfit_Erlang(param_alfa As Double, param_beta As Long, nombre_variable As String) As Double
Attribute bestfit_Erlang.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo. Param Beta es el parámetro de forma y debe ser un entero positivo.\r\nEl nombre de la variable debe estar entre comillas."
Dim prod As Double
Dim i As Long
If param_alfa <= 0 Or param_beta <= 0 Then bestfit_Erlang = CVErr(xlErrNA): Exit Function

prod = 1
For i = 0 To param_beta - 1
prod = prod * bestfit_Uniforme(0, 1, nombre_variable)
Next i
bestfit_Erlang = -param_alfa * Log(prod)

End Function

Function bestfit_Fisher(Grados_de_libertad1 As Long, Grados_de_libertad2 As Long, nombre_variable As String) As Double
Attribute bestfit_Fisher.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nLos grados de libertad deben ser enteros mayores a 0.\r\nEl nombre de la variable debe estar entre comillas."
If Grados_de_libertad1 < 1 Or Grados_de_libertad2 < 1 Then bestfit_Fisher = CVErr(xlErrNA): Exit Function
bestfit_Fisher = (bestfit_Chi2(Grados_de_libertad1, nombre_variable) / Grados_de_libertad1) / (bestfit_Chi2(Grados_de_libertad2, nombre_variable) / Grados_de_libertad2)
End Function

Function bestfit_GammaInvertida(param_alfa As Double, param_beta As Double, nombre_variable As String) As Double
Attribute bestfit_GammaInvertida.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa y Beta son los parámetros de escala y forma y deben ser positivos.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Or param_beta <= 0 Then bestfit_GammaInvertida = CVErr(xlErrNA): Exit Function
bestfit_GammaInvertida = 1 / bestfit_Gamma(0, 1 / param_alfa, param_beta, nombre_variable)
End Function

Function bestfit_Laplace(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Laplace.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Laplace = CVErr(xlErrNA): Exit Function

    If bestfit_Bernoulli(0.5, nombre_variable) = 1 Then
    bestfit_Laplace = Corrimiento + param_alfa * Log(bestfit_Uniforme(0, 1, nombre_variable))
    Else
    bestfit_Laplace = Corrimiento - param_alfa * Log(bestfit_Uniforme(0, 1, nombre_variable))
    End If

End Function

Function bestfit_Logaritmica(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Logaritmica.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim a As Double
Dim b As Double
If Limite_inferior >= Limite_superior Then bestfit_Logaritmica = CVErr(xlErrNA): Exit Function

a = Limite_inferior
b = Limite_superior - Limite_inferior
bestfit_Logaritmica = a + b * bestfit_Uniforme(0, 1, nombre_variable) * bestfit_Uniforme(0, 1, nombre_variable)

End Function

Function bestfit_LogNormal(Corrimiento As Double, media As Double, desviacion As Double, nombre_variable As String) As Double
Attribute bestfit_LogNormal.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nDesviación debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If desviacion <= 0 Then bestfit_LogNormal = CVErr(xlErrNA): Exit Function
bestfit_LogNormal = Corrimiento + Exp(bestfit_Normal(media, desviacion, nombre_variable))
End Function

Function bestfit_Normal(media As Double, desviacion As Double, nombre_variable As String) As Double
Attribute bestfit_Normal.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nDesviación debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
Dim p As Double
Dim p1 As Double
Dim p2 As Double
If desviacion <= 0 Then bestfit_Normal = CVErr(xlErrNA): Exit Function
    While 1 = 1
    p1 = bestfit_Uniforme(-1, 1, nombre_variable)
    p2 = bestfit_Uniforme(-1, 1, nombre_variable)
    p = p1 * p1 + p2 * p2
    If p < 1 Then bestfit_Normal = media + desviacion * p1 * (-2 * Log(p) / p) ^ (1 / 2): Exit Function
    Wend

End Function
Function bestfit_NormalTruncada(media As Double, desviacion As Double, Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Dim p As Double
Dim p1 As Double
Dim p2 As Double
If desviacion <= 0 Then bestfit_NormalTruncada = CVErr(xlErrNA): Exit Function
If Limite_inferior >= Limite_superior Then bestfit_NormalTruncada = CVErr(xlErrNA): Exit Function
While 1 = 1
    p1 = bestfit_Normal(media, desviacion, nombre_variable)
    If p1 >= Limite_inferior And p1 <= Limite_superior Then bestfit_NormalTruncada = p1: Exit Function
    Wend
End Function

Function bestfit_Parabolica(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Parabolica.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim x As Double
Dim a As Double
Dim b As Double
Dim ymax As Double
Dim usf As Double
If Limite_inferior >= Limite_superior Then bestfit_Parabolica = CVErr(xlErrNA): Exit Function
x = 0.5 * (Limite_inferior + Limite_superior)
If (x < Limite_inferior Or x > Limite_superior) Then
    usf = 0
    Else
    a = 0.5 * (Limite_inferior + Limite_superior)
    b = 0.5 * (Limite_superior - Limite_inferior)
    ymax = 3 / (4 * b)
    usf = ymax * (1 - (x - a) * (x - a) / (b * b))
    End If
ymax = usf
bestfit_Parabolica = userSpecified("bestfit_Parabolica", Limite_inferior, Limite_superior, 0, ymax)

End Function

Function bestfit_Pareto(param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Pareto.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de forma y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Pareto = CVErr(xlErrNA): Exit Function
bestfit_Pareto = bestfit_Uniforme(0, 1, nombre_variable) ^ (-1 / param_alfa)
End Function

Function bestfit_Pearsons6(param_alfa As Double, param_beta As Double, param_gamma As Double, nombre_variable As String) As Double
Attribute bestfit_Pearsons6.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala. Param Beta y Gama  son los parámetros de forma y deben ser positivos.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Or param_beta <= 0 Or param_gamma <= 0 Then bestfit_Pearsons6 = CVErr(xlErrNA): Exit Function
bestfit_Pearsons6 = bestfit_Gamma(0, param_alfa, param_beta, nombre_variable) / bestfit_Gamma(0, param_alfa, param_gamma, nombre_variable)
End Function

Function bestfit_Rayleigh(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Rayleigh.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Rayleigh = CVErr(xlErrNA): Exit Function
bestfit_Rayleigh = Corrimiento + param_alfa * (-Log(bestfit_Uniforme(0, 1, nombre_variable))) ^ (1 / 2)
End Function

Function bestfit_TStudent(Grados_de_libertad As Long, nombre_variable As String) As Double
Attribute bestfit_TStudent.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nLos grados de libertad deben ser mayores a 0.\r\nEl nombre de la variable debe estar entre comillas."
If Grados_de_libertad <= 0 Then bestfit_TStudent = CVErr(xlErrNA): Exit Function
bestfit_TStudent = bestfit_Normal(0, 1, nombre_variable) / ((bestfit_Chi2(Grados_de_libertad, nombre_variable) / Grados_de_libertad) ^ (1 / 2))
End Function


Function bestfit_Uniforme(Limite_inferior As Double, Limite_superior As Double, nombre_variable As String) As Double
Attribute bestfit_Uniforme.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior.\r\nEl nombre de la variable debe estar entre comillas."
Dim stcal As String
If Limite_inferior >= Limite_superior Then bestfit_Uniforme = CVErr(xlErrNA): Exit Function
bestfit_Uniforme = (Limite_superior - Limite_inferior) * Rnd + Limite_inferior
End Function

Function bestfit_Exponencial(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Exponencial.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Exponencial = CVErr(xlErrNA): Exit Function
bestfit_Exponencial = Corrimiento + (-(param_alfa) * Log(bestfit_Uniforme(0, 1, nombre_variable)))
End Function

Function bestfit_Gumbel(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Gumbel.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Gumbel = CVErr(xlErrNA): Exit Function
bestfit_Gumbel = Corrimiento + param_alfa * Log(-Log(bestfit_Uniforme(0, 1, nombre_variable)))
End Function

Function bestfit_Logistica(Corrimiento As Double, param_alfa As Double, nombre_variable As String) As Double
Attribute bestfit_Logistica.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa es el parámetro de escala y debe ser positivo.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Then bestfit_Logistica = CVErr(xlErrNA): Exit Function
bestfit_Logistica = Corrimiento - param_alfa * Log(1 / bestfit_Uniforme(0, 1, nombre_variable) - 1)
End Function

Function bestfit_UniformeEntera(Limite_inferior As Long, Limite_superior As Long, nombre_variable As String) As Long
Attribute bestfit_UniformeEntera.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior y ambos enteros.\r\nEl nombre de la variable debe estar entre comillas."
If Limite_inferior >= Limite_superior Then bestfit_UniformeEntera = CVErr(xlErrNA): Exit Function
bestfit_UniformeEntera = Limite_inferior + Int((Limite_superior - Limite_inferior + 1) * bestfit_Uniforme(0, 1, nombre_variable))
End Function

Function bestfit_Weibull(Corrimiento As Double, param_alfa As Double, param_beta As Double, nombre_variable As String) As Double
Attribute bestfit_Weibull.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa y Beta son los parámetros de escala y forma y deben ser positivos.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Or param_beta <= 0 Then bestfit_Weibull = CVErr(xlErrNA): Exit Function
bestfit_Weibull = Corrimiento + param_alfa * ((-Log(bestfit_Uniforme(0, 1, nombre_variable))) ^ (1 / param_beta))
End Function

Function bestfit_Triangular(Limite_inferior As Double, Limite_superior As Double, moda As Double, nombre_variable As String) As Double
Attribute bestfit_Triangular.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nEl límite inferior debe ser menor al límite superior. Moda debe estar entre estos dos valores.\r\nEl nombre de la variable debe estar entre comillas."
Dim r As Double
Dim a As Double
Dim b As Double
Dim c As Double
a = Limite_inferior
b = moda
c = Limite_superior
If Limite_inferior >= Limite_superior Then bestfit_Triangular = CVErr(xlErrNA): Exit Function
If moda < Limite_inferior Or moda > Limite_superior Then bestfit_Triangular = CVErr(xlErrNA): Exit Function

r = bestfit_Uniforme(0, 1, nombre_variable)

If (c - a) = 0 Then
bestfit_Triangular = a + (((c - a) * (b - a) * r) ^ (1 / 2))
Exit Function
End If

If r < (b - a) / (c - a) Then
bestfit_Triangular = a + (((c - a) * (b - a) * r) ^ (1 / 2))
Else
bestfit_Triangular = c - ((((c - a) * (c - b)) * (1 - r)) ^ (1 / 2))
End If

End Function
Function bestfit_Gamma(Corrimiento As Double, param_alfa As Double, param_beta As Double, nombre_variable As String) As Double
Attribute bestfit_Gamma.VB_Description = "Devuelve un número aleatorio dentro de la funcion de probabilidad durante la simulación.\r\nParam Alfa y Beta son los parámetros de escala y forma y deben ser positivos.\r\nEl nombre de la variable debe estar entre comillas."
If param_alfa <= 0 Or param_beta <= 0 Then bestfit_Gamma = CVErr(xlErrNA): Exit Function

Dim aa As Double
Dim BB As Double
Dim q As Double
Dim t As Double
Dim DD As Double
Dim cc As Double
Dim a As Double
Dim b As Double
Dim c As Double
Dim p As Double
Dim p1 As Double
Dim p2 As Double
Dim y As Double
Dim v As Double
Dim w As Double
Dim z As Double

a = Corrimiento
b = param_alfa
c = param_beta
aa = 1
If c >= 1 Then aa = 1 / ((2 * c - 1) ^ (1 / 2))
BB = c - Log(4)
q = c + 1 / aa
t = 4.5
DD = 1 + Log(t)
cc = 1 + c / 2.71828182845905
' c<1
    If (c < 1) Then
    While 1 = 1
    p = cc * bestfit_Uniforme(0, 1, nombre_variable)
    
        If p > 1 Then
        y = -Log((cc - p) / c)
        If bestfit_Uniforme(0, 1, nombre_variable) <= y ^ (c - 1) Then bestfit_Gamma = a + b * y: Exit Function
        End If
        If p <= 1 Then
        y = p ^ (1 / c)
        If bestfit_Uniforme(0, 1, nombre_variable) <= Exp(-y) Then bestfit_Gamma = a + b * y: Exit Function
        End If
    Wend
    End If
' C=1
If c = 1 Then bestfit_Gamma = bestfit_Exponencial(a, b, nombre_variable): Exit Function
'C>1
If c > 1 Then
While 1 = 1
p1 = bestfit_Uniforme(0, 1, nombre_variable)
p2 = bestfit_Uniforme(0, 1, nombre_variable)
v = aa * Log(p1 / (1 - p1))
y = c * Exp(v)
z = p1 * p1 * p2
w = BB + q * v - y
If w + DD - t * z >= 0 Then bestfit_Gamma = a + b * y: Exit Function
If w >= Log(z) Then bestfit_Gamma = a + b * y: Exit Function
Wend
End If
End Function




Private Function userSpecified(funcionl As String, xMin As Double, xMax As Double, ymin As Double, ymax As Double)
Dim x As Double
Dim y As Double
Dim a As Double
Dim b As Double
Dim areamax As Double
Dim funcionllama As Long
Dim usf As Double
areamax = (xMax - xMin) * (ymax - ymin)
Do While 1 = 1
x = bestfit_Uniforme(0, areamax, "No importa") / (ymax - ymin) + xMin
y = bestfit_Uniforme(ymin, ymax, "No importa")
funcionllama = 0
' bestfit_Parabolica
If funcionl = "bestfit_Parabolica" Then
funcionllama = 1
    If (x < xMin Or x > xMax) Then
    usf = 0
    Else
    a = 0.5 * (xMin + xMax)
    b = 0.5 * (xMax - xMin)
    ymax = 3 / (4 * b)
    usf = ymax * (1 - (x - a) * (x - a) / (b * b))
    End If
End If
If funcionllama = 0 Then MsgBox "No esta definida la funcion en userspecified"
If y <= usf Then Exit Do
Loop
userSpecified = x
End Function



Attribute VB_Name = "distribuciones"
Option Explicit
Global Simulacion As Boolean

Global inputs(150, 4) As String
Global correlas(150, 4) As String
Global Const maxinp = 150
Global Const versions = "Simulación 4.0"
Global outputs(20, 3) As String
Global Const maxout = 20
Global lasiter As Long
Global okincorr As Boolean
Global registrado As Boolean
Global tiempouso As Long
Global codregi As Long
Global pregunte As Boolean
Function Put_Amer_Bin(Valor_del_Activo As Double, Precio_Ejercicio As Double, Tasa_Libre_de_Riesgo As Double, Volatilidad As Double, Tiempo As Double, Optional Nodos_Arbol_Binomial As Long) As Double
Attribute Put_Amer_Bin.VB_Description = "Función agregada de la librería de simulación 3.0.\r"
Attribute Put_Amer_Bin.VB_ProcData.VB_Invoke_Func = " \n14"
Dim delta_t As Double
Dim varup As Double
Dim vardown As Double
Dim r As Double
Dim p As Double
Dim q As Double
Dim nIndex As Long
Dim nstate As Long
On Error Resume Next
If Nodos_Arbol_Binomial = 0 Then Nodos_Arbol_Binomial = 5
    delta_t = Tiempo / Nodos_Arbol_Binomial
    varup = Exp(Volatilidad * Sqr(delta_t))
    vardown = Exp(-Volatilidad * Sqr(delta_t))
    r = Exp(Tasa_Libre_de_Riesgo * delta_t)
    p = (r - vardown) / (r * (varup - vardown))
    q = 1 / r - p
    Dim OptionReturnEnd() As Double
    Dim OptionReturnMiddle() As Double
    ReDim OptionReturnEnd(Nodos_Arbol_Binomial + 1)

    For nstate = 0 To Nodos_Arbol_Binomial
          OptionReturnEnd(nstate) = calculamaximo(Precio_Ejercicio - Valor_del_Activo * _
            varup ^ nstate * vardown ^ (Nodos_Arbol_Binomial - nstate), 0)

    Next nstate
    
    For nIndex = Nodos_Arbol_Binomial - 1 To 0 Step -1
        ReDim OptionReturnMiddle(nIndex)
        For nstate = 0 To nIndex
           OptionReturnMiddle(nstate) = calculamaximo(Precio_Ejercicio - Valor_del_Activo * _
                 varup ^ nstate * vardown ^ (nIndex - nstate), _
                 q * OptionReturnEnd(nstate) + _
                 p * OptionReturnEnd(nstate + 1))
        Next nstate
        ReDim OptionReturnEnd(nIndex)
        For nstate = 0 To nIndex
            OptionReturnEnd(nstate) = OptionReturnMiddle(nstate)
        Next nstate
    Next nIndex
    Put_Amer_Bin = OptionReturnMiddle(0)
    On Error GoTo 0
End Function

Function Call_Amer_Bin(Valor_del_Activo As Double, Precio_Ejercicio As Double, Tasa_Libre_de_Riesgo As Double, Volatilidad As Double, Tiempo As Double, Optional Nodos_Arbol_Binomial As Long) As Double
Attribute Call_Amer_Bin.VB_Description = "Función agregada de la librería de simulación 3.0.\r"
Attribute Call_Amer_Bin.VB_ProcData.VB_Invoke_Func = " \n14"
Dim delta_t As Double
Dim varup As Double
Dim vardown As Double
Dim r As Double
Dim p As Double
Dim q As Double
Dim nIndex As Long
Dim nstate As Long
On Error Resume Next
If Nodos_Arbol_Binomial = 0 Then Nodos_Arbol_Binomial = 5
    delta_t = Tiempo / Nodos_Arbol_Binomial
    varup = Exp(Volatilidad * Sqr(delta_t))
    vardown = Exp(-Volatilidad * Sqr(delta_t))
    r = Exp(Tasa_Libre_de_Riesgo * delta_t)
    p = (r - vardown) / (r * (varup - vardown))
    q = 1 / r - p
    Dim OptionReturnEnd() As Double
    Dim OptionReturnMiddle() As Double
    ReDim OptionReturnEnd(Nodos_Arbol_Binomial + 1)

    For nstate = 0 To Nodos_Arbol_Binomial
    OptionReturnEnd(nstate) = calculamaximo(Valor_del_Activo * varup ^ nstate * vardown ^ (Nodos_Arbol_Binomial - nstate) - Precio_Ejercicio, 0)
    Next nstate
    
    For nIndex = Nodos_Arbol_Binomial - 1 To 0 Step -1
        ReDim OptionReturnMiddle(nIndex)
        For nstate = 0 To nIndex
           OptionReturnMiddle(nstate) = calculamaximo(Valor_del_Activo * varup ^ nstate * vardown ^ (nIndex - nstate) - Precio_Ejercicio, q * OptionReturnEnd(nstate) + p * OptionReturnEnd(nstate + 1))
        Next nstate
        ReDim OptionReturnEnd(nIndex)
        For nstate = 0 To nIndex
            OptionReturnEnd(nstate) = OptionReturnMiddle(nstate)
        Next nstate
    Next nIndex
    Call_Amer_Bin = OptionReturnMiddle(0)
On Error GoTo 0
End Function


Function Call_Eur_Bin(Valor_del_Activo As Double, Precio_Ejercicio As Double, Tasa_Libre_de_Riesgo As Double, Volatilidad As Double, Tiempo As Double, Optional Nodos_Arbol_Binomial As Long) As Double
Attribute Call_Eur_Bin.VB_Description = "Función agregada de la librería de simulación 3.0.\r"
Attribute Call_Eur_Bin.VB_ProcData.VB_Invoke_Func = " \n14"
Dim delta_t As Double
Dim varup As Double
Dim vardown As Double
Dim r As Double
Dim p As Double
Dim q As Double
Dim nIndex As Long
Dim nstate As Long
On Error Resume Next
If Nodos_Arbol_Binomial = 0 Then Nodos_Arbol_Binomial = 5
    delta_t = Tiempo / Nodos_Arbol_Binomial
    varup = Exp(Volatilidad * Sqr(delta_t))
    vardown = Exp(-Volatilidad * Sqr(delta_t))
    r = Exp(Tasa_Libre_de_Riesgo * delta_t)
    p = (r - vardown) / (r * (varup - vardown))
    q = 1 / r - p
    Call_Eur_Bin = 0
    For nIndex = 0 To Nodos_Arbol_Binomial
        Call_Eur_Bin = Call_Eur_Bin + CalculaCombin(Nodos_Arbol_Binomial, nIndex) * p ^ nIndex * q ^ (Nodos_Arbol_Binomial - nIndex) * calculamaximo(Valor_del_Activo * varup ^ nIndex * vardown ^ (Nodos_Arbol_Binomial - nIndex) - Precio_Ejercicio, 0)
    Next nIndex
On Error GoTo 0
End Function


Function Put_Eur_Bin(Valor_del_Activo As Double, Precio_Ejercicio As Double, Tasa_Libre_de_Riesgo As Double, Volatilidad As Double, Tiempo As Double, Optional Nodos_Arbol_Binomial As Long) As Double
Attribute Put_Eur_Bin.VB_Description = "Función agregada de la librería de simulación 3.0.\r"
Attribute Put_Eur_Bin.VB_ProcData.VB_Invoke_Func = " \n14"
Dim delta_t As Double
Dim varup As Double
Dim vardown As Double
Dim r As Double
Dim p As Double
Dim q As Double
Dim nIndex As Long
Dim nstate As Long
On Error Resume Next
If Nodos_Arbol_Binomial = 0 Then Nodos_Arbol_Binomial = 5
    delta_t = Tiempo / Nodos_Arbol_Binomial
    varup = Exp(Volatilidad * Sqr(delta_t))
    vardown = Exp(-Volatilidad * Sqr(delta_t))
    r = Exp(Tasa_Libre_de_Riesgo * delta_t)
    p = (r - vardown) / (r * (varup - vardown))
    q = 1 / r - p
    Put_Eur_Bin = 0
    For nIndex = 0 To Nodos_Arbol_Binomial
        Put_Eur_Bin = Put_Eur_Bin + CalculaCombin(Nodos_Arbol_Binomial, nIndex) * p ^ nIndex * q ^ (Nodos_Arbol_Binomial - nIndex) * calculamaximo(Precio_Ejercicio - varup ^ nIndex * vardown ^ (Nodos_Arbol_Binomial - nIndex) * Valor_del_Activo, 0)
    Next nIndex
On Error GoTo 0
End Function
…