短缺概率的蒙特卡罗模拟——VBA

短缺概率的蒙特卡罗模拟——VBA,vba,excel,Vba,Excel,我正在VBA的一个项目中工作,根据下面的公式,给出一系列模拟的终端股价值,以确定短缺的概率 St=S0e(µ− σ^2/2)t+σBt,其中Bt是标准布朗运动,如sqrt(t) 下面是我到目前为止所做的代码和注释 Option Explicit 'The following is a subroutine that generates the random terminal stock prices 'An array is passed into it by reference so tha

我正在VBA的一个项目中工作,根据下面的公式,给出一系列模拟的终端股价值,以确定短缺的概率

St=S0e(µ− σ^2/2)t+σBt,其中Bt是标准布朗运动,如sqrt(t)

下面是我到目前为止所做的代码和注释

Option Explicit

'The following is a subroutine that generates the random terminal stock prices
'An array is passed into it by reference so that the populated values are available to the caller

Private Sub GenerateRandomTerminalStockPrices(ByVal sNaught As Double, _
                                              ByVal r As Double, _
                                              ByVal sigma As Double, _
                                              ByVal t As Double, _
                                              ByVal nSize As Long, _
                                              ByRef STerminal() As Double)

  Dim i As Long
  Dim Drift As Double
  Dim SigmaSqrtT As Double

  'This creates the drift term of the stock price
  Drift = (r - 0.5 * sigma * sigma) * t

  'This creates the Standard Brownian Motion parameter
  SigmaSqrtT = sigma * (t ^ 0.5)

  'The following creates simulated terminal price values for purposes of Monte Carlo Simulation
  For i = 1 To nSize
    STerminal(i) = sNaught * Exp(Drift + SigmaSqrtT * Excel.WorksheetFunction.NormSInv(Rnd()))
  Next i

End Sub

'Creates the probability of shortfall equation
Function Prshortfall(sNaught As Double, r As Double, sigma As Double, t As Double, n As Double)

  'Creating variables of use in the equation
  Dim i As Long
  Dim V() As Variant
  Dim terminalstockprices() As Double
  Dim probability As Double
  Dim variance As Double
  Dim sum As Double
  Dim squaredvalue As Double
  Dim totalvalue As Double
  Dim riskfree As Double
  Dim ret As Double
  Dim averagevalue As Double

  'Specifying parameters of arrays
  ReDim V(1, 1 To 3) As Variant
  ReDim terminalstockprices(n) As Double

  'Setting initial values to 0 for certain variables
  riskfree = 0.02
  sum = 0#
  squaredvalue = 0#
  totalvalue = 0#


  'Generating the terminal values.  Notice that the array is passed by reference
  Call GenerateRandomTerminalStockPrices(sNaught, r, sigma, t, n, terminalstockprices)

  'Tests each terminal stock price in relation to the risk free rate and keeps count if less than risk free rate
  For i = 1 To n
    totalvalue = totalvalue + terminalstockprices(i)
    squaredvalue = squaredvalue + terminalstockprices(i) * terminalstockprices(i)
    ret = (terminalstockprices(i) / sNaught) - 1
    If ret < riskfree Then
      sum = sum + 1
    End If
  Next i

  'Solves for probability, average price, and price variance based on the outcome of simulation
  probability = sum / n
  averagevalue = totalvalue / n
  variance = (squaredvalue - averagevalue * sum) / (n - 1)

  'Outputs the probability, average price, and price standard error
  V(1, 1) = probability
  V(1, 2) = averagevalue
  V(1, 3) = Sqr(variance / n)

  Prshortfall = V

End Function
选项显式
下面是一个生成随机终端股价的子程序
'通过引用将数组传递给它,以便调用者可以使用填充的值
私有子发电商终端价格(比瓦尔·斯纳认为是双倍_
ByVal r作为双倍_
ByVal sigma作为双精度_
ByVal t作为双倍_
拜瓦尔:只要_
ByRef STerminal()作为双精度)
我想我会坚持多久
暗漂双
Dim SigmaSqrtT为双精度
这就产生了股价的漂移项
漂移=(r-0.5*西格玛*西格玛)*t
'这将创建标准的布朗运动参数
SigmaSqrtT=西格玛*(t^0.5)
“以下创建模拟终端价格值,用于蒙特卡罗模拟
对于i=1到nSize
STerminal(i)=sNaught*Exp(Drift+SigmaSqrtT*Excel.WorksheetFunction.NormSInv(Rnd())
接下来我
端接头
'创建短缺概率方程
函数Prshortfall(sNaught为Double,r为Double,sigma为Double,t为Double,n为Double)
'创建方程中使用的变量
我想我会坚持多久
Dim V()作为变量
Dim terminalstockprices()为双精度
双重模糊概率
模糊方差为双精度
双份点心
Dim squaredvalue作为Double
将总值设置为双精度
双重无风险
双倍调暗
将平均值设置为双精度
'指定数组的参数
ReDim V(1,1到3)作为变型
将终端价格(n)重拨为双精度
'将某些变量的初始值设置为0
无风险=0.02
总和=0#
平方值=0#
totalvalue=0#
'生成终端值。请注意,数组是通过引用传递的
调用生成器TerminalsTokPrices(sNaught、r、sigma、t、n、TerminalsTokPrices)
测试每个终端股价与无风险利率的关系,如果低于无风险利率,则保持计数
对于i=1到n
totalvalue=totalvalue+终端价格(i)
squaredvalue=squaredvalue+终端价格(i)*终端价格(i)
ret=(终端价格(i)/sNaught)-1
如果ret<无风险,则
总和=总和+1
如果结束
接下来我
根据模拟结果求解概率、平均价格和价格差异
概率=总和/n
平均值=总值/n
方差=(平方值-平均值*总和)/(n-1)
'输出概率、平均价格和价格标准误差
V(1,1)=概率
V(1,2)=平均值
V(1,3)=Sqr(方差/n)
Prshortfall=V
端函数
我已经使用=prshortfall(100,0.02,0.04,1100)测试了代码,但是在一个单元格中只得到了0的输出,而不是我期望得到的概率、平均价格和价格标准错误的3个输出


是否有人对哪里可能存在编码问题或输入错误有任何建议?

可能是单元格的格式

a包含以下内容:

您必须捕获a(1,1)a(1,2)a(1,3)的值,并在单元格中进行设置。可能有必要将这些单元格的格式更改为带小数点的数字

编辑

'Solves for probability, average price, and price variance based on the outcome of simulation
  probability = sum / n
  averagevalue = totalvalue / n
  variance = (squaredvalue - averagevalue * sum) / (n - 1)

  'Outputs the probability, average price, and price standard error
  V(1, 1) = probability
  V(1, 2) = averagevalue
  V(1, 3) = Sqr(variance / n)

  '3 results are in one variable and is the return value
  Prshortfall = V(1, 1) & " " & V(1, 2) & " " & V(1, 3)

End Function
结果

'Solves for probability, average price, and price variance based on the outcome of simulation
  probability = sum / n
  averagevalue = totalvalue / n
  variance = (squaredvalue - averagevalue * sum) / (n - 1)

  'Outputs the probability, average price, and price standard error
  V(1, 1) = probability
  V(1, 2) = averagevalue
  V(1, 3) = Sqr(variance / n)

  '3 results are in one variable and is the return value
  Prshortfall = V(1, 1) & " " & V(1, 2) & " " & V(1, 3)

End Function

简单的答案是需要一个数组来获取输出

选择B1:D1并输入您的

=prshortfall(100,0.02,0.04,1,100)
然后CSE它,你有你的号码

数组公式需要通过ctrl+shift+enter确认

编辑
我忘了我换了电话线

Prshortfall = V


因此,该解决方案仅在使用2行范围(如A1:B3)时有效。很抱歉:P

在模块顶部添加

选项Base 1

或者将v线更改为

尺寸v(1到1,1到3)


对不起,我删除了第一个Dim v()作为变体,并且没有在我的版本中重新命名。

Hmmh所以看起来代码正在执行我想要的操作。这可能是我如何在Excel中输入公式的问题吗?现在我只是输入=Prshortfall(100,0.02,0.04,1100),我读到您可能需要按ctrl+shift+enter?结果是一个数组,其中包含多个数字。请在代码中尝试以下操作:Prshortfall=V(1,1)&“|”&V(1,2)&“|”&V(1,3)。现在您将在一个单元格中获得3个结果。。。您必须将每个数字与其他数字分开,并可能通过VBA进行设置。另一种方法是将计算分为3个不同的函数。我用这个例子编辑了我的答案。啊,很有趣。这是一种独特的方法。我会尽我所能的。德克·雷切尔的回答是我不知道的。这更容易,而且你的想法是正确的。:)非常感谢。虽然它仍然输出3个零,但我不确定其原因。@Trevor我完全错过了这个。。。我弄乱了你的代码,用数组(概率、平均值、Sqr(方差/n))替换了
Prshortfall=V
。。。对不起,P
Prshortfall = Array(probability, averagevalue, Sqr(variance / n))