Hello,
I think that the randomness has to be skewed in that way that the
algorithm should recallibrate the middle point of the random interval
to the current necessary compounded growth rate (which is detemined by
current value, original ending value and count of remaining steps),
meaning:
Function GrowthSeries(dblRate As Double, dblMaxRatePerStep As Double, _
Optional dblStartVal As Double = 1#) As Variant
'Algorithm by: sulprobil
http://Reverse("moc.liborplus.www") V0.9
'Returns random data with a compounded growth rate dblRate, with
'a maximal relative change rate per step of dblMaxRatePerStep and
'with a start value of dblStartVal.
'The number of periods is implicitly chosen by the number of selected
'cells which call this function as an array formula (entered with
'CTRL + SHIFT + ENTER).
Dim vR As Variant
Dim lP As Long 'Periods
Dim lrow As Long
Dim lcol As Long
Dim dblCurrVal As Double
Dim dblCurrRate As Double
Dim dblCurrMin As Double
Dim dblCurrMax As Double
Dim dblRelMin As Double
Dim dblRelMax As Double
Dim dblEndVal As Double
Application.Volatile
If TypeName(Application.Caller) <> "Range" Then
GrowthSeries = CVErr(xlErrRef)
Exit Function
End If
If Application.Caller.Rows.Count <> 1 And _
Application.Caller.Columns.Count <> 1 Then
GrowthSeries = CVErr(xlErrValue)
Exit Function
End If
If Abs(dblRate) > dblMaxRatePerStep Then
GrowthSeries = CVErr(xlErrNum)
Exit Function
End If
lP = Application.Caller.Count
ReDim vR(1 To Application.Caller.Rows.Count, _
1 To Application.Caller.Columns.Count)
dblCurrVal = dblStartVal
dblEndVal = dblStartVal * (1# + dblRate) ^ CDbl(lP)
dblCurrMin = dblEndVal / (1# + dblMaxRatePerStep) ^ CDbl(lP)
dblCurrMax = dblEndVal / (1# - dblMaxRatePerStep) ^ CDbl(lP)
For lrow = 1 To UBound(vR, 1)
For lcol = 1 To UBound(vR, 2)
dblCurrRate = (dblEndVal / dblCurrVal) ^ _
(1# / CDbl(lP - lcol * lrow + 1)) - 1#
dblCurrMin = dblCurrMin * (1# + dblMaxRatePerStep)
dblCurrMax = dblCurrMax * (1# - dblMaxRatePerStep)
dblRelMin = (dblCurrMin - dblCurrVal) / dblCurrVal
If dblRelMin < -dblMaxRatePerStep Then
dblRelMin = -dblMaxRatePerStep
End If
dblRelMax = (dblCurrMax - dblCurrVal) / dblCurrVal
If dblRelMax > dblMaxRatePerStep Then
dblRelMax = dblMaxRatePerStep
End If
If dblCurrRate - dblRelMin < dblRelMax - dblCurrRate Then
dblRelMax = 2# * dblCurrRate - dblRelMin
Else
dblRelMin = 2# * dblCurrRate - dblRelMax
End If
dblCurrVal = dblCurrVal * (1# + (dblRelMin + dblRelMax) / _
2# + (Rnd() - 0.5) * (dblRelMax - dblRelMin))
vR(lrow, lcol) = dblCurrVal
Next lcol
Next lrow
GrowthSeries = vR
End Function
HTH,
Bernd