UPDATE: Converted to lambda.r.
Here’s a short example of using lambda.r for calculating the DV01 of a bond. The basic idea is to layout the type definitions and then create the functions to do the calculations.
<br />require(lambda.r)<br /><br />Bond(par, coupon, yield, periods, freq) %as% {<br /><%%KEEPWHITESPACE%%> list(par=par, coupon=coupon, yield=yield, periods=periods, freq=freq)<br />}<br /><br /># Inherit from the Bond type<br />SemiBond(par, coupon, yield, periods, freq=2) %as%<br /><%%KEEPWHITESPACE%%> Bond(par, coupon, yield, periods, freq)<br /><br />price(bond) %::% Bond : numeric<br />price(bond) %as% price(bond, bond$yield)<br /><br />price(bond, r) %::% Bond : numeric : numeric<br />price(bond, r) %as%<br />{<br /><%%KEEPWHITESPACE%%> r <- r / bond$freq<br /><%%KEEPWHITESPACE%%> n <- bond$periods<br /><%%KEEPWHITESPACE%%> coupon(bond) * (1 - (1+r)^-n) / r + bond$par * (1+r)^-n<br />}<br /><br />dv01(bond) %::% Bond : numeric<br />dv01(bond) %as%<br />{<br /><%%KEEPWHITESPACE%%> y1 <- bond$yield - 0.0001<br /><%%KEEPWHITESPACE%%> y2 <- bond$yield + 0.0001<br /><%%KEEPWHITESPACE%%> p1 <- price(bond, y1)<br /><%%KEEPWHITESPACE%%> p2 <- price(bond, y2)<br /><%%KEEPWHITESPACE%%> - (p1 - p2) / (y1 - y2) / 100<br />}<br />The helper functions below show some of the power of guards. Depending on the value of a field, a different function variant can be called for the coupon calculation. (Note that this is used for illustrative purposes and would break down in the current ZIRP world.)
<br /># When coupon is in percentage terms<br />coupon(bond) %::% Bond : numeric<br />coupon(bond) %when% {<br /><%%KEEPWHITESPACE%%> bond$coupon < 1<br />} %as% {<br /><%%KEEPWHITESPACE%%> bond$par * bond$coupon / bond$freq<br />}<br /><br />coupon(bond) %::% Bond : numeric<br />coupon(bond) %as% { bond$coupon / bond$freq }<br />The code can be run by executing the below snippet.
<br />> b <- SemiBond(100,3.5, 0.035, 10)<br />> dv01(b)<br />[1] 4.550612<br />