Prepare the Files

Model background

A vanilla interest rate swap is a contractual agreement to exchange fixed interest payments for floating interest payments on a specified notional.

The price of a vanilla interest rate swap is computed by taking the difference between discounted fixed and floating legs:

\[\begin{equation} PV_{IRS} = \sum_{i=\alpha}^{n}N\left(L(t, T_{i-1}, T_i) - K \right)\tau_i P(t, T_i) \tag{1} \end{equation}\]

where:

\(L(t, T_{i-1}, T_i)\) is the forward rate between \(T_{i-1}\) and \(T_i\) at time \(t\).
\(K\) is the fixed rate.
\(\tau_i\) is the year fraction between \(T_{i-1}\) and \(T_i\).
\(N\) is the notional amount.
\(\alpha\) is such that for \(\alpha \leq i \leq n\), \(T_i > t\).
\(P(t,T_i)\) is the discount factor between \(t\) and \(T_i\).

To prepare the files for running the model
  1. Create a script file: IRS.psl, and enter the following code.
    • You use the following script to price a vanilla interest rate swap.
    • The functions, provided by the FPP library, that you use to design this payoff, in a module, are the following:
      • discountFactorFromCurve() from the InterestRate.module: returns the discount factor computed at date and based on the input curve.
      • forwardRate() from the ForwardRate.module: returns a forward rate from startDate to endDate computed at calculationDate() according to a basis and based on the input curve.
      • yearFraction() from YearFraction.module: returns the year fraction from startDate to endDate according to a basis.
/**
 * Returns the price of an interest rate swap 
 */
def npv = 0
// List of fixed and variable legs
for (def leg in legs) {
    
    // List of cash flows
    for (def scheduleLine in leg.schedule) {
               
    // Discount factor
        def df = discountFactorFromCurve(leg.discountCurve, scheduleLine.endDate)
        // Year fraction
        def dcf = yearFraction(scheduleLine.startDate, scheduleLine.endDate, leg.basis, YearFractionParameters())
       
        // Fixed cash flow
        if (leg.indexationType == "fixed") {
                    
            if (leg.payOrRec == "receiving")
                npv += leg.notional * leg.fixedRate * dcf * df
            else
                npv -= leg.notional * leg.fixedRate * dcf * df
                
        }
        // Variable cash flow
        else {

            def rate = forwardRate(scheduleLine.startDate, scheduleLine.endDate, leg.basis, YearFractionParameters(), leg.projectionCurve)
                        
            if (leg.payOrRec == "receiving")
                npv += leg.notional * rate * dcf * df
            else
                npv -= leg.notional * rate * dcf * df
        
        }
    }
}
// Net present value
return npv
  1. Create a document file: IRS.json, and enter the following code.
    • Within the code, you define the structure of the document file.
    • You define the legs and schedules required for pricing an interest rate swap.
    • You also define the discount and projection curves, the legs as fixed or floating and the schedules with the start and end dates of the cash-flows.
{
  "dealStamp": "IRS",
  "legs": [
    {
      "basis": "ACT/365.FIXED",
      "discountCurve": "discount_Libor_3M",
      "fixedRate": 0.0175,
      "indexationType": "fixed",
      "notional": 100000,
      "payOrRec": "paying",
      "schedule": [
        {
          "endDate": "2017-06-01",
          "startDate": "2017-03-01"
        },
        {
          "endDate": "2017-09-01",
          "startDate": "2017-06-01"
        },
        {
          "endDate": "2017-12-01",
          "startDate": "2017-09-01"
        },
        {
          "endDate": "2018-03-01",
          "startDate": "2017-12-01"
        }
      ]
    },
    {
      "basis": "ACT/365.FIXED",
      "discountCurve": "discount_Libor_3M",
      "indexationType": "floating",
      "notional": 100000,
      "payOrRec": "receiving",
      "projectionCurve": "projection_Libor_3M",
      "schedule": [
        {
          "endDate": "2017-06-01",
          "startDate": "2017-03-01"
        },
        {
          "endDate": "2017-09-01",
          "startDate": "2017-06-01"
        },
        {
          "endDate": "2017-12-01",
          "startDate": "2017-09-01"
        },
        {
          "endDate": "2018-03-01",
          "startDate": "2017-12-01"
        }
      ]
    }
  ]
}
  1. Create a pricing file: IRS.scn, and enter the following code.
    • Within the code, you define the structure of the pricing data file.
    • You describe the discount and projection curves that are required for pricing an interest rate swap that are used to compute the discount factors and the forward rates.
{
  "dates": [
    "2017-04-13"
  ],
  "historicalData": [
  ],
  "scenarioData": [
    {
      "id": {
        "parameters": [
          "discount_Libor_3M",
          "discountFactor"
        ],
        "type": "YIELD_CURVE"
      },
      "metaData": {
        "currency": "USD",
        "interpolationMethods": [
          "flat"
        ],
        "interpolationVariables": [
          "discountFactor"
        ],
        "switchDates": [
        ],
        "zeroCouponBasis": "ACT/365.FIXED",
        "zeroCouponFormula": "exponential"
      },
      "points": {
        "2017-04-13": [
          {
            "values": [
              1
            ],
            "x": 17269
          },
          {
            "values": [
              0.99976
            ],
            "x": 17294
          },
          {
            "values": [
              0.99952
            ],
            "x": 17319
          },
          {
            "values": [
              0.99928
            ],
            "x": 17344
          },
          {
            "values": [
              0.99904
            ],
            "x": 17369
          },
          {
            "values": [
              0.9988
            ],
            "x": 17394
          },
          {
            "values": [
              0.99856
            ],
            "x": 17419
          },
          {
            "values": [
              0.99799
            ],
            "x": 17444
          },
          {
            "values": [
              0.99742
            ],
            "x": 17469
          },
          {
            "values": [
              0.99685
            ],
            "x": 17494
          },
          {
            "values": [
              0.99628
            ],
            "x": 17519
          },
          {
            "values": [
              0.99572
            ],
            "x": 17544
          },
          {
            "values": [
              0.99515
            ],
            "x": 17569
          },
          {
            "values": [
              0.99458
            ],
            "x": 17594
          },
          {
            "values": [
              0.99424
            ],
            "x": 17619
          },
          {
            "values": [
              0.99391
            ],
            "x": 17644
          },
          {
            "values": [
              0.99357
            ],
            "x": 17669
          },
          {
            "values": [
              0.99323
            ],
            "x": 17694
          },
          {
            "values": [
              0.9929
            ],
            "x": 17719
          },
          {
            "values": [
              0.99256
            ],
            "x": 17787
          }
        ]
      }
    },
    {
      "id": {
        "parameters": [
          "projection_Libor_3M",
          "discountFactor"
        ],
        "type": "YIELD_CURVE"
      },
      "metaData": {
        "currency": "USD",
        "interpolationMethods": [
          "flat"
        ],
        "interpolationVariables": [
          "discountFactor"
        ],
        "switchDates": [
        ],
        "zeroCouponBasis": "ACT/365.FIXED",
        "zeroCouponFormula": "exponential"
      },
      "points": {
        "2017-04-13": [
          {
            "values": [
              1
            ],
            "x": 17269
          },
          {
            "values": [
              0.99943
            ],
            "x": 17294
          },
          {
            "values": [
              0.99886
            ],
            "x": 17319
          },
          {
            "values": [
              0.99829
            ],
            "x": 17344
          },
          {
            "values": [
              0.99772
            ],
            "x": 17369
          },
          {
            "values": [
              0.99715
            ],
            "x": 17394
          },
          {
            "values": [
              0.99658
            ],
            "x": 17419
          },
          {
            "values": [
              0.99629
            ],
            "x": 17444
          },
          {
            "values": [
              0.99601
            ],
            "x": 17469
          },
          {
            "values": [
              0.99572
            ],
            "x": 17494
          },
          {
            "values": [
              0.99544
            ],
            "x": 17519
          },
          {
            "values": [
              0.99515
            ],
            "x": 17544
          },
          {
            "values": [
              0.99486
            ],
            "x": 17569
          },
          {
            "values": [
              0.99458
            ],
            "x": 17594
          },
          {
            "values": [
              0.99403
            ],
            "x": 17619
          },
          {
            "values": [
              0.99347
            ],
            "x": 17644
          },
          {
            "values": [
              0.99292
            ],
            "x": 17669
          },
          {
            "values": [
              0.99236
            ],
            "x": 17694
          },
          {
            "values": [
              0.99181
            ],
            "x": 17719
          },
          {
            "values": [
              0.99125
            ],
            "x": 17787
          }
        ]
      }
    }
  ]
}