Knowledge Base Article

vCalc Groovy Code Sample

Input and output Strings

def V = args.V.tokenize(',')             //Convert input string to array with cells for each comma separated value
assert (V.size == 3):"V is not 3D"  //This confirms that there were three comma separated values in V.

def x = V[0].toBigDecimal()           //Convert strings in V to numeric (BigDecimal) variables (x, y, z)
def y = V[1].toBigDecimal()
def z = V[2].toBigDecimal()

def xyz = "$x, $y, $z"                      //This creates a single string with the comma separated values of x, y and z

return xyz

Inputs as Vectors and Matrices

You can set an input parameter to be a matrix up to 6x6 or vector up to 1x4 using the Equation Editor UI.  It will automatically create the end user interface for the entry of vectors and matrices.  Once a matrix or vector is designated, you can get to the cell values using the .getAt() command.  The following code example shows the syntax for this:

                def Matrix =  [[1,2,3,5,4,3],[6,7,8,5,7,2],[1,2,3,5,4,3],[6,1,8,5,7,2],[1,2,3,5,4,3],[6,7,8,5,7,2]]
                def Vector = [1,2,5,7]

                def f = Matrix.getAt(3).getAt(4)
                def g = Vector.getAt(2) 

In this case, f is equal to 7 and g is equal to 5.  Remember that Groovy (and Java) arrays are index from zero.  

Groovy Tables

//  In this equation, Snow Water Equivalent, the programmer uses an internal Groovy table to define the density of different types of snow.

//  values for snow Type : New snow,Damp new snow,Settled snow,Depth hoar,Wind packed snow,Firn (granular snow),Very wet snow and firn,Glacier ice

def coverage = args.coverage.to("m^2")            // user input and conversion to meters squared
def snow_depth = args.snow_depth.to("m")     // user input conversion to meters
def snow_type = args.snow_type                         // user input
assert snow_depth >= 0.0.to("m")   : "snow Depth can not be negative"

def snow_density = ["New snow":60,                 // density is expressed in   kg/m3
                       "Damp new snow":150,
                       "Settled snow":250,
                       "Depth hoar":200,
                       "Wind packed snow":375,
                       "Firn (granular snow)":615,
                       "Very wet snow and firn":750,
                       "Glacier ice":868,
                       "Melt":999.8395]
                      
def density = snow_density[snow_type]            //Returns the table value of snow_density indexed by snow_type

def SWE  = snow_depth * density."kg/m^3"*coverage
        
def water = SWE *  (1.0.("gal")/3.78."kg") 
return water

Subroutines in Groovy

//This is a subroutine used repeatedly in Black-Scholes 
//to approximate an integral of the normal distribution.
// It has one input X and returns CND.
def CND = {  
X
def a1 = 0.31938153
def a2 = -0.356563782
def a3 = 1.781477937
def a4 = -1.821255978
def a5 = 1.330274429

def L = abs(X)
def K = 1 / (1 + 0.2316419 * L)
def CND = 1 - 1 / sqrt(2 * PI) * exp(-L**2 / 2) * (a1 * K + a2 * K**2 + a3 * K**3 + a4 * K**4 + a5 * K**5)
if ( X < 0) CND = 1 - CND
return CND
}

//  This is the beginning of the main Black-Scholes algorithm

//User Inputs
def cp = args.CallPut //Call or put
def S = args.S // Stock price
def X = args.X // Strike Price
def T = args.T.to("year").estimatedValue // Years to maturity then converted to a real number.
def v = args.v/100 // volatility converted from % integer to real
def r = args.r/100 // Risk-free rate converted from % integer to real

//assert statements to validate input parameter values
assert S>0: "Strike price must be greater than zero"
assert X>0: "Stock price must be greater than zero"
assert v>=0: "Volatility must be greater than or equal to zero"
assert r>=0: "Risk-free investment rate must be greater than or equal to zero"

def BS = 0  //Initialize the Black-Scholes output parameter
def cnd1 = 0
def cnd2 = 0

def d1 = (log(S/X)  + (r + v**2/2) * T) / (v * sqrt(T))
def d2 = d1 - v*sqrt(T)

switch (cp) {
   case "Call":
     cnd1 = CND(d1)
     cnd2 = CND(d2)
     BS = S * cnd1 - X* exp(-r * T) * cnd2
     break
   case "Put":
     d1 = d1 * -1
     d2 = d2 * -1
     cnd1 = CND(d1)
     cnd2 = CND(d2)
     BS = X * exp(-r * T) * cnd2 - S * cnd1
     break     
   }

return BS

A word on Groovy asserts

In Groovy, an assert statement is followed by a logical statement.  If the logical statement resolves to true, the program continues.  If not, the message is returned and the program is halted.  This is somewhat different than how many other languages handle condition checking, but it does work well.  It is often used for boundary conditions including division by zero as in the following example divides 14.4 by an input number:

def x = args.x

assert ( x > 0):"X is less than zero!"

return 14.4/x

Common Groovy (Java) Constants

PI  -  The two capital letters of "P" and "I” together is a java reserved string that is translated into our beloved (3.14 …..).  
E - The capital letter ‘e’ by itself is another java reserved string that is translated into E (the base of the natural log).