Hi
I've been learning nim and playing around with decimal from : https://github.com/status-im/nim-decimal
I'm written some sample code below to calulate a finance thing called weighted average cost of capital.
In the example below I wanted to round decimal to 0.733 and then convert that to 7.3%. I did try and convert to a float but had no joy there. It seems once with a Decimal we're stuck with it.
Questions I have :
I wrote this code mostly by looking at the tests in repo.
Market value of equity (e): 1000000 Market value of debt (d): 2000000 Cost of equity (rE): 0.15 Cost of debt (rD): 0.05 Tax rate (t): 0.3
proc wacc(e: DecimalType, d: DecimalType, rE: DecimalType, rD: DecimalType, t:DecimalType ): DecimalType =
let v = e + d
let eV = e / v
let dV = d / v
let adjRD = rD * (1 - t)
return eV * rE + dV * adjRD
let e = newDecimal(1000000)
let d = newDecimal(2000000)
let rE = newDecimal("0.15")
let rD = newDecimal("0.05")
let t = newDecimal("0.3")
let w = wacc(e, d, rE, rD, t)
let y = quantize(w,newDecimal("1e-3"))
echo reduce(y * 100),"%"
Thanks in advance
Nelly
Everything else but point 4 is beyond me... but if you want to make it a bit nicer you can define your own literal:
import decimal
proc `'dec`(s: string): DecimalType = newDecimal(s)
echo 1e4'dec
type Dec = DecimalType
proc wacc(e, d, rE, rD, t: Dec ): Dec =
3.5 you can use a single let, var, const, type.. instead of multiple:
let
a = 1
b = 2
If we combine all of techniques, we will get very idiomatic Nim code:
type Dec = DecimalType
template `'dec`(s: string | SomeInteger): DecimalType = newDecimal(s)
proc wacc(e, d, rE, rD, t: Dec ): Dec =
let
v = e + d
eV = e / v
dV = d / v
adjRD = rD * (1 - t)
eV * rE + dV * adjRD
let
e = 1000000'dec
d = 2000000'dec
rE = 0.15'dec
rD = 0.05'dec
t = 0.3'dec
let w = wacc(e, d, rE, rD, t)
let y = quantize(w, newDecimal("1e-3"))
echo reduce(y * 100), '%'