Forward Rate Agreement (FRA) valuation

Got asked the other day, how to value a FRA in transparent and simple way.
Then we can use the feature of creating instruments directly from the library, without any use of the underlying Quantlab instrument database.

The pattern here is roughly:

  1. create an instrument template (here using the ones provided in the code as examples)
  2. create an instrument def(inition). which is the completed instrument without trade details.
  3. create the actual FRA that we need to value, with size, trade price, dates etc.
  4. create a forward curve to use for valuation. here we just hard code some values. this would regularly be take from the market in Quantlab.
  5. use the curve to value the deal.
  6. done.

Adding both code and the sample workspace.

option(null: hard); // Throw an error if a null value is used in a non-nullable context
out number test_fra(date trade_date) {
	
	//first create a FRA contract we assume to be holding and want to price
	//we use a ready made template FRA (here a NOK 3M) 
	instr_def myfra_def = instr_def_fra(INSTR_TMPL_FRA.fra_nok_3m);

	//the instrument def is a complete FRA without trade specifics.
	//we need to add a settle date and maturity of underlying interest rate.
	date settle_date = date_code("BD3;IMM0").apply_fwd(trade_date, calendar("NORWAY"));
	date mat_date = date_code("IMM1").apply_fwd(settle_date, calendar("NORWAY"));

	//we can now complete the postion with dates and the purchase price/rate and the position size.
	fra myfra = fra(myfra_def, "NOK FRA IMM0", trade_date, settle_date, mat_date, null, 4.07/100, 1000000);

	//we now need a market to price from. for that we simply create a fwd_func object with dummy 3M rates.
	//input are periods in years, fwd rates for 3M Nibor and a choice of interpolation in fwd space. 
	fwd_func fwd3m = fwd_func_interp([1,2,3,4],[3.1,3.0,2.9,3.0]/100,ip_spline());

	//we can now extract the relevant forward rate from the curve and price the FRA.
	number curr_rate = fwd3m.fwd( (settle_date - trade_date) / 365 );
	//note the false flag, that only sets the market rate and not a new par FRA with PV=0.
	//trade date is already known from before.
	myfra = myfra.set_rate(curr_rate, null, false);

	//this present value will be non-discounted. For a discounted version med also need a disccount curve.
	return myfra.present_value();
}

fra example.qlw (7.0 KB)

1 Like