# FpML 4.5 Validation Rules - Rules for Loan Messages

This is the Loan part of the validation rule set accompanying the FpML 4.5 Working Draft. The introductory section in the validation section of the specifications contains background information and documentation for this page.

The rules contained on this page contain links to cut down versions of valid and invalid test cases. The cut down test cases are non-normative and are provided for the purpose of documentation only.

## Content

- Namespace
- Functions
- Rules
- Rules with comments
  - ln-2
  - ln-7
  - ln-8
  - ln-9

## Namespace

default element namespace = http://www.fpml.org/2008/FpML-4-5

## Functions

The following shared functions are used in the rules.

- same-currency

## Rules

#### Unique contexts:

- LoanContract (complex type): ln-1
- DrawdownNotice (complex type): ln-2 ln-13 ln-14 ln-15 ln-16 ln-17 ln-18 ln-19
- InterestRatePeriod (complex type): ln-3 ln-4 ln-5
- InterestAccrualSchedule (complex type): ln-6 ln-7 ln-8 ln-9
- FacilityNotice (complex type): ln-10 ln-11 ln-12 ln-30 ln-31
- InterestPaymentNotice (complex type): ln-20 ln-21
- LoanContractRepayment (complex type): ln-22
- Repayment (complex type): ln-23 ln-25 ln-26
- RepaymentNotice (complex type): ln-24
- OneOffFeeNotice (complex type): ln-27 ln-28
- OneOffFeePayment (complex type): ln-29
- Deprecated rules
- Removed rules

ln-1 (Mandatory)
Context: LoanContract (complex type)
currentInterestRatePeriod/startDate >= effectiveDate.
Test cases: [Valid] [Invalid]
ln-2 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(loanContract)] [loanContract/currentInterestRatePeriod/floatingRateIndex = normalizedString("PRIME")]
loanContract/currentInterestRatePeriod/rateFixingDate = loanContract/effectiveDate.
Comment: For a LoanContract the fixing date for the rate is always the effective date of the contract.
Test cases: [Invalid]
ln-3 (Mandatory)
Context: InterestRatePeriod (complex type)
endDate >= startDate >= rateFixingDate.
Test cases: [Invalid]
ln-4 (Mandatory)
Context: InterestRatePeriod (complex type)
[not(exists(mandatoryCostRate))] [exists(interestRate)] [exists(margin)] [exists(allInRate)]
allInRate = margin + interestRate.
Test cases: [Invalid]
ln-5 (Mandatory)
Context: InterestRatePeriod (complex type)
[exists(mandatoryCostRate)] [exists(interestRate)] [exists(margin)] [exists(allInRate)]
allInRate = margin + interestRate + mandatoryCostRate.
Test cases: [Invalid]
ln-6 (Mandatory)
Context: InterestAccrualSchedule (complex type)
interestRatePeriod/startDate,lenderLoanContractPeriod/startDate, interestAccrualPeriod/startDate must be equal in each period.
Test cases: [Invalid]
ln-7 (Mandatory)
Context: InterestAccrualSchedule (complex type)
[count(interestRatePeriod)>1]
Every $startDate in $interestAccrualSchedule/interestRatePeriod[startDate > min($interestAccrualSchedule/interestRatePeriod/startDate)]/startDate satisfies $startDate - xs:dayTimeDuration("P1D") = $interestAccrualSchedule/interestRatePeriod/endDate.
Comment: Each interestRatePeriod except the first, starts 1 day after any other interestRatePeriod
Test cases: [Invalid]
ln-8 (Mandatory)
Context: InterestAccrualSchedule (complex type)
[count(lenderLoanContractPeriod)>1]
Every $startDate in $interestAccrualSchedule/lenderLoanContractPeriod[startDate > min($interestAccrualSchedule/lenderLoanContractPeriod/startDate)]/startDate satisfies $startDate - xs:dayTimeDuration("P1D") = $interestAccrualSchedule/lenderLoanContractPeriod/endDate.
Comment: Each lenderLoanContractPeriod except the first, starts 1 day after any other lenderLoanContractPeriod
Test cases: [Invalid]
ln-9 (Mandatory)
Context: InterestAccrualSchedule (complex type)
[count(interestAccrualPeriod)>1]
Every $startDate in $interestAccrualSchedule/interestAccrualPeriod[startDate > min($interestAccrualSchedule/interestAccrualPeriod/startDate)]/startDate satisfies $startDate - xs:dayTimeDuration("P1D") = $interestAccrualSchedule/interestAccrualPeriod/endDate.
Comment: Each interestAccrualPeriod except the first, starts 1 day after any other interestAccrualPeriod
Test cases: [Invalid]
ln-10 (Mandatory)
Context: FacilityNotice (complex type)
[exists(facilityIdentifier/originalCommitmentAmount)] [exists(facilityCommitmentPosition/loanContractPosition/loanContractSummary/originalAmount)] [same-currency((facilityIdentifier/originalCommitmentAmount,facilityCommitmentPosition/loanContractPosition/loanContractSummary/originalAmount))]
facilityIdentifier/originalCommitmentAmount/amount >= facilityCommitmentPosition/loanContractPosition/loanContractSummary/originalAmount/amount.
Test cases: [Invalid]
ln-11 (Mandatory)
Context: FacilityNotice (complex type)
[exists(facilityCommitmentPosition/loanContractPosition)] [same-currency((facilityCommitmentPosition/currentAmount/shareAmount/amount,//facilityCommitmentPosition/loanContractPosition/currentAmount/shareAmount/amount))]
facilityCommitmentPosition/currentAmount/shareAmount/amount >= the sum of all facilityCommitmentPosition/loanContractPosition/currentAmount/shareAmount/amount.
Test cases: [Invalid]
ln-12 (Mandatory)
Context: FacilityNotice (complex type)
[exists(facilityCommitmentPosition/loanContractPosition)] [same-currency((facilityCommitmentPosition/priorAmount/shareAmount/amount,//facilityCommitmentPosition/loanContractPosition/priorAmount/shareAmount/amount))]
facilityCommitmentPosition/priorAmount/shareAmount/amount >= the sum of all facilityCommitmentPosition/loanContractPosition/priorAmount/shareAmount/amount.
Test cases: [Invalid]
ln-13 (Mandatory)
Context: DrawdownNotice (complex type)
noticeDate <= drawdownPayment/paymentDate.
Test cases: [Invalid]
ln-14 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(loanContract)]
drawdownPayment/paymentDate >= loanContract/effectiveDate.
Test cases: [Invalid]
ln-15 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(dealIdentifier/creditAgreementDate)]
loanContract/effectiveDate and drawdownPayment/paymentDate >= dealIdentifier/creditAgreementDate.
Test cases: [Invalid]
ln-16 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(facilityCommitmentPosition/priorAmount/shareAmount)] [same-currency((facilityCommitmentPosition/priorAmount/shareAmount,drawdownPayment/shareLoanContractAmount))]
drawdownPayment/shareLoanContractAmount <= facilityCommitmentPosition/priorAmount/shareAmount.
Test cases: [Invalid]
ln-17 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(loanContract)] [same-currency((loanContract/amount/amount,drawdownPayment/shareLoanContractAmount/amount))]
loanContract/amount/amount >= drawdownPayment/shareLoanContractAmount/amount.
Test cases: [Invalid]
ln-18 (Mandatory)
Context: DrawdownNotice (complex type)
[exists(loanContractSummary)] [same-currency((loanContractSummary/originalAmount/amount,drawdownPayment/shareLoanContractAmount/amount))]
loanContractSummary/originalAmount/amount >= drawdownPayment/shareLoanContractAmount/amount.
Test cases: [Invalid]
ln-19 (Mandatory)
Context: DrawdownNotice (complex type)
[drawdownEventType = RateSetEvent] [exists(loanContract)]
loanContract/currentInterestRatePeriod/interestRate and loanContract/currentInterestRatePeriod/margin and loanContract/currentInterestRatePeriod/allInRate and loanContract/currentInterestRatePeriod/interestDayBasis and loanContract/currentInterestRatePeriod/indexTenor must exist.
Test cases: [Invalid]
ln-20 (Mandatory)
Context: InterestPaymentNotice (complex type)
[same-currency((interestPayment/amount/shareAmount/amount,//interestAccrualSchedule/interestAccrualPeriod/shareInterestAccrualAmount/amount))]
interestPayment/amount/shareAmount/amount = the sum of all interestAccrualSchedule/interestAccrualPeriod/shareInterestAccrualAmount/amount.
Test cases: [Invalid]
ln-21 (Mandatory)
Context: InterestPaymentNotice (complex type)
interestAccrualSchedule/interestRatePeriod/interestRate and interestAccrualSchedule/interestRatePeriod/margin and interestAccrualSchedule/interestRatePeriod/allInRate and interestAccrualSchedule/interestRatePeriod/interestDayBasis and interestAccrualSchedule/interestRatePeriod/indexTenor must exist.
Test cases: [Invalid]
ln-22 (Mandatory)
Context: LoanContractRepayment (complex type)
[exists(loanContractSummary/originalAmount)] [same-currency((loanContractSummary/originalAmount/amount,amount/globalAmount/amount))]
loanContractSummary/originalAmount/amount >= amount/globalAmount/amount.
Test cases: [Invalid]
ln-23 (Mandatory)
Context: Repayment (complex type)
[same-currency((facilityRepayment/amount/globalAmount/amount,//loanContractRepayment/loanContractSummary/originalAmount/amount))]
facilityRepayment/amount/globalAmount/amount >= the sum of all loanContractRepayment/loanContractSummary/originalAmount/amount.
Test cases: [Invalid]
ln-24 (Mandatory)
Context: RepaymentNotice (complex type)
[exists(facilityCommitmentPosition)] [same-currency((facilityCommitmentPosition/priorAmount/shareAmount/amount,repayment/facilityRepayment/amount/shareAmount/amount))]
facilityCommitmentPosition/priorAmount/shareAmount/amount >= repayment/facilityRepayment/amount/shareAmount/amount.
Test cases: [Invalid]
ln-25 (Mandatory)
Context: Repayment (complex type)
[same-currency((facilityRepayment/amount/shareAmount/amount,//loanContractRepayment/amount/shareAmount/amount))]
facilityRepayment/amount/shareAmount/amount >= the sum of all loanContractRepayment/amount/shareAmount/amount.
Test cases: [Invalid]
ln-26 (Mandatory)
Context: Repayment (complex type)
[exists(loanContractRepayment/amount/globalAmount)] [same-currency((facilityRepayment/amount/globalAmount/amount,//loanContractRepayment/amount/globalAmount/amount))]
facilityRepayment/amount/globalAmount/amount >= the sum of all loanContractRepayment/amount/globalAmount/amount.
Test cases: [Invalid]
ln-27 (Mandatory)
Context: OneOffFeeNotice (complex type)
[feePayment/feeType = BreakageFee]
loanContractSummary must exist.
Test cases: [Invalid]
ln-28 (Mandatory)
Context: OneOffFeeNotice (complex type)
[feePayment/feeType = AssignmentFee]
loanContractSummary must not exist.
Test cases: [Invalid]
ln-29 (Mandatory)
Context: OneOffFeePayment (complex type)
paymentDate >= effectiveDate.
Test cases: [Invalid]
ln-30 (Mandatory)
Context: FacilityNotice (complex type)
[exists(facilityCommitmentPosition/loanContractPosition/currentAmount/globalAmount)] [exists(facilityCommitmentPosition/currentAmount/globalAmount)] [same-currency((facilityCommitmentPosition/currentAmount/globalAmount/amount,//facilityCommitmentPosition/loanContractPosition/currentAmount/globalAmount))]
facilityCommitmentPosition/currentAmount/globalAmount/amount >= the sum of all facilityCommitmentPosition/loanContractPosition/currentAmount/globalAmount/amount.
Test cases: [Invalid]
ln-31 (Mandatory)
Context: FacilityNotice (complex type)
[exists(facilityCommitmentPosition/loanContractPosition/priorAmount/globalAmount)] [exists(facilityCommitmentPosition/priorAmount/globalAmount)] [same-currency((facilityCommitmentPosition/priorAmount/globalAmount/amount,//facilityCommitmentPosition/loanContractPosition/priorAmount/globalAmount/amount))]
facilityCommitmentPosition/priorAmount/globalAmount/amount >= the sum of all facilityCommitmentPosition/loanContractPosition/priorAmount/globalAmount/amount.
Test cases: [Invalid]

#### Deprecated rules

#### Removed rules