Logo

SQL Server Balloon Function

Updated 2024-02-14 15:22:12.780000

Description

Use the table-valued function Balloon to return the cash flow schedule for a loan with periodic payments of interest (only) and with the principal paid at maturity.

The interest payment period is entered in Balloon as the number of months between interest payments. For example, a loan with monthly interest payments would have a frequency of 1. A loan with quarterly interest payments would have frequency of 3. A loan with annual principal payments would have a frequency of 12.

Balloon supports both an initial grace period and an additional grace period during the life of the loan. All payments and their associated dates are calculated with respect to a reference date supplied to the function (which should not be confused with the start date). If an initial grace period is entered in Balloon and it is greater than the reference date, then it becomes the first interest payment date and subsequent interest payments are calculated from that date forward.

If any payments would otherwise occur in the specified grace period, then that payment is moved to the end of the grace period and all remaining payments are calculated from the end of the grace period.

If no initial grace period is specified then the first payment date is calculated using the interest payment frequency. If the start date has been entered and the number of months between the start date and the reference date is less than the frequency, then the first payment date is calculated by adding the frequency (as a number of months) to the start date.

If no start date has been entered but a previous payment date has been entered and the number of months between the previous payment date and the reference date is less than the frequency, then the first payment date is calculated by adding the frequency (as a number of months) to the previous payment date.

If there is not start date and previous payment dates or the number of months between those dates and the reference date is greater than the frequency, then the first payment date is calculated by adding the frequency (as a number of months) to the reference date.

All payments in the resultant table are moved to the end of the month and interest is calculated using these end-of-month dates.

The interest payment is calculated as:

I=P\times\left[\left(\left(1+\frac{R\times{F}}{12}\right)^{12\slash{F}}\right)^T\right]-1

Where:

column 1column 2column 3
I=InterestPayment
P=@OutstandingAmount
R=@InterestRate
F=@Frequency
T=Time, in years, from PaymentDate ( Period -1) to PaymentDate

If an interest payment occurs at the end of the initial grace period or at the end of the interim grace period and the length of the period (in months) if greater than the frequency, then Balloon calculates a 'grace' interest amount and a regular periodic interest amount.

Syntax

SELECT * FROM [westclintech].[wct].[Balloon](
  <@OutstandingAmount, float,>
 ,<@InterestBasis, nvarchar(4000),>
 ,<@InterestRate, float,>
 ,<@PaymentFrequency, int,>
 ,<@MaturityDate, datetime,>
 ,<@ReferenceDate, datetime,>
 ,<@PrevPayDate, datetime,>
 ,<@StartDate, datetime,>
 ,<@FirstPayDate, datetime,>
 ,<@GracePeriodStartDate, datetime,>
 ,<@GracePeriodEndDate, datetime,>)

Arguments

@OutstandingAmount

the principal amount of the loan. @OutstandingAmount is an expression of type float or of a type that can be implicitly converted to float.

@InterestBasis

the day count convention used to calculate the interest amount. @InterestBasis can be 30/360, Actual/360, Actual/365, or Actual/Actual. @InterestBasis is an expression of the character string data type category.

@InterestRate

the annual rate of interest for the loan. @InterestRate is an expression of type float or of a type that can be implicitly converted to float.

@PaymentFrequency

the number of months in a regular interest payment. @PaymentFrequency is an expression of type int or of a type that can be implicitly converted to int.

@MaturityDate

the maturity date of the loan. @MaturityDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@ReferenceDate

the starting date for the number of months with respect to all other dates. @ReferenceDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@PrevPayDate

the last interest payment date prior to the reference date. @PrevPayDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@StartDate

the start date of the loan. @StartDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@FirstPayDate

the first payment date of the loan if other than a regular periodic payment. @FirstPayDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@GracePeriodStartDate

the date on which the (interim) grace period commences. @GracePeriodStratDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

@GracePeriodEndDate

the date on which the (interim) grace period concludes. @GracePeriodEndDate is an expression that returns a datetime or smalldatetime value, or a character string in date format.

Return Type

table

colNamecolDatatypecolDesc
PeriodintA reference number uniquely identifying a row in the resultant table.
PrincipalPaymentfloatThe amount of the principal payment. The only principal payment is on the maturity date of the loan.
InterestPaymentfloatThe amount of the regular interest payment.
CashFlowfloatPrincipalPayment + InterestPayment + GraceInterest.
OutstandingExposurefloatWhen Period = 0 then @OutstandingAmount. For Period > 0 then OutstandingExposure(Period-1) + InterestPayment.
CapitalAmountInDebtfloatWhen Period = 0, @OutstandingAmount. For Period > 0 then CapitalAmountinDebt(Period-1) - PrincipalPayment
TotalExposurefloatWhen Period = 0, @OutstandingAmount. For Period > 0 then CapitalAmountinDebt(Period-1) + InterestPayment
NumberOfMonthfloatThe number of months between the @ReferenceDate and the PaymentDate.
PaymentDatedatetimeThe end-of-month date of the payment.
GraceInterestfloatThe amount of the grace interest
InterestRatefloatThe interest rate from the @ReferenceDate to the @MaturityDate. See formula above.

Remarks

The PaymentDate for all rows is generated as the last day of the month.

For Period = 0, PrincipalPayment, InterestPayment, CashFlow, NumberOfMonth, GraceInterest, and InterestRate are set to 0.

The time value (see formula above) is calculated based on @InterestBasis:

    For Actual/360 it is the number of days between the 2 PaymentDate values divided by 360.

    For Actual/365 it is the number of days between the 2 PaymentDate values divided by 365.

    For Actual/Actual it is the number of days between the 2 PaymentDate values divided by the number of days in the year of the later PaymentDate.

    For 30/360 is the number of months between the 2 PaymentDate values divided by 12.

If @InterestBasis is NULL then @InterestBasis = 30/360.

If @InterestBasis is not 30/360, ACTUAL/360, ACTUAL/365, or ACTUAL/ACTUAL then an error message will be generated.

If @Frequency is NULL then @Frequency = 1.

If @InterestRate is NULL then @InterestRate = 0.

If @ReferenceDate is NULL then @ReferenceDate = GETDATE().

If @MaturityDate is NULL then @MaturityDate = GETDATE().

GraceInterest is only calculated on @FirstPayDate and @GracePeriodEndDate.

GraceInterest is only calculated if NumberOfMonth – NumberOfMonth(Period-1) > @PaymentFrequency.

GraceInterest is the difference between the interest for the period from the previous row to the current row minus interest that would have been calculated for a period with length equal to @PaymentFrequency.

The last row returned will always be for the maturity date and may be shorter than a regular period depending on the combination of dates and @PaymentFrequency.

Examples

This is a simple 5-year loan with quarterly payments of interest.

SELECT *
FROM wct.Balloon(   100000,       --@OutstandingAmount
                    'Actual/365', --@InterestBasis
                    .04,          --@InterestRate
                    3,            --@PaymentFrequency
                    '2019-09-15', --@MaturityDate
                    '2014-09-15', --@ReferenceDate
                    NULL,         --@PrevPayDate
                    NULL,         --@StartDate
                    NULL,         --@FirstPayDate
                    NULL,         --@GracePeriodStartDate
                    NULL          --@GracePeriodEndDate
                );

This produces the following result.

PeriodPrincipalPaymentInterestPaymentCashFlowOutstandingExposureCapitalAmountInDebtTotalExposureNumberOfMonthPaymentDateGraceInterestInterestRate
000010000010000010000002014-09-30 00:00:00.00000
101008.260475448021008.26047544802101008.260475448100000101008.26047544832014-12-31 00:00:00.00000.0100826047544802
20986.234042100054986.234042100054101994.494517548100000100986.234042162015-03-31 00:00:00.00000.00986234042100054
30997.246658307449997.246658307449102991.741175856100000100997.24665830792015-06-30 00:00:00.00000.00997246658307449
401008.260475448021008.26047544802104000.001651304100000101008.260475448122015-09-30 00:00:00.00000.0100826047544802
501008.260475448021008.26047544802105008.262126752100000101008.260475448152015-12-31 00:00:00.00000.0100826047544802
60997.246658307449997.246658307449106005.508785059100000100997.246658307182016-03-31 00:00:00.00000.00997246658307449
70997.246658307449997.246658307449107002.755443366100000100997.246658307212016-06-30 00:00:00.00000.00997246658307449
801008.260475448021008.26047544802108011.015918814100000101008.260475448242016-09-30 00:00:00.00000.0100826047544802
901008.260475448021008.26047544802109019.276394262100000101008.260475448272016-12-31 00:00:00.00000.0100826047544802
100986.234042100054986.234042100054110005.510436363100000100986.2340421302017-03-31 00:00:00.00000.00986234042100054
110997.246658307449997.246658307449111002.75709467100000100997.246658307332017-06-30 00:00:00.00000.00997246658307449
1201008.260475448021008.26047544802112011.017570118100000101008.260475448362017-09-30 00:00:00.00000.0100826047544802
1301008.260475448021008.26047544802113019.278045566100000101008.260475448392017-12-31 00:00:00.00000.0100826047544802
140986.234042100054986.234042100054114005.512087666100000100986.2340421422018-03-31 00:00:00.00000.00986234042100054
150997.246658307449997.246658307449115002.758745973100000100997.246658307452018-06-30 00:00:00.00000.00997246658307449
1601008.260475448021008.26047544802116011.019221421100000101008.260475448482018-09-30 00:00:00.00000.0100826047544802
1701008.260475448021008.26047544802117019.279696869100000101008.260475448512018-12-31 00:00:00.00000.0100826047544802
180986.234042100054986.234042100054118005.51373897100000100986.2340421542019-03-31 00:00:00.00000.00986234042100054
190997.246658307449997.246658307449119002.760397277100000100997.246658307572019-06-30 00:00:00.00000.00997246658307449
201000001008.26047544802101008.260475448120011.0208727250101008.260475448602019-09-30 00:00:00.00000.0100826047544802

In this example, we modify the SQL by adding a first payment date so that the interest will not be paid until 31-Mar-2015.

SELECT *
FROM wct.Balloon(   100000,       --@OutstandingAmount
                    'Actual/365', --@InterestBasis
                    .04,          --@InterestRate
                    3,            --@PaymentFrequency
                    '2019-09-15', --@MaturityDate
                    '2014-09-15', --@ReferenceDate
                    NULL,         --@PrevPayDate
                    NULL,         --@StartDate
                    '2015-03-15', --@FirstPayDate
                    NULL,         --@GracePeriodStartDate
                    NULL          --@GracePeriodEndDate
                );

This produces the following result.

PeriodPrincipalPaymentInterestPaymentCashFlowOutstandingExposureCapitalAmountInDebtTotalExposureNumberOfMonthPaymentDateGraceInterestInterestRate
000010000010000010000002014-09-30 00:00:00.00000
10986.2340421000542004.43832558996100986.2340421100000100986.234042162015-03-31 00:00:00.0001018.204283489910.0200443832558996
20997.246658307449997.246658307449101983.480700407100000100997.24665830792015-06-30 00:00:00.00000.00997246658307449
301008.260475448021008.26047544802102991.741175856100000101008.260475448122015-09-30 00:00:00.00000.0100826047544802
401008.260475448021008.26047544802104000.001651304100000101008.260475448152015-12-31 00:00:00.00000.0100826047544802
50997.246658307449997.246658307449104997.248309611100000100997.246658307182016-03-31 00:00:00.00000.00997246658307449
60997.246658307449997.246658307449105994.494967918100000100997.246658307212016-06-30 00:00:00.00000.00997246658307449
701008.260475448021008.26047544802107002.755443366100000101008.260475448242016-09-30 00:00:00.00000.0100826047544802
801008.260475448021008.26047544802108011.015918814100000101008.260475448272016-12-31 00:00:00.00000.0100826047544802
90986.234042100054986.234042100054108997.249960914100000100986.2340421302017-03-31 00:00:00.00000.00986234042100054
100997.246658307449997.246658307449109994.496619222100000100997.246658307332017-06-30 00:00:00.00000.00997246658307449
1101008.260475448021008.26047544802111002.75709467100000101008.260475448362017-09-30 00:00:00.00000.0100826047544802
1201008.260475448021008.26047544802112011.017570118100000101008.260475448392017-12-31 00:00:00.00000.0100826047544802
130986.234042100054986.234042100054112997.251612218100000100986.2340421422018-03-31 00:00:00.00000.00986234042100054
140997.246658307449997.246658307449113994.498270525100000100997.246658307452018-06-30 00:00:00.00000.00997246658307449
1501008.260475448021008.26047544802115002.758745973100000101008.260475448482018-09-30 00:00:00.00000.0100826047544802
1601008.260475448021008.26047544802116011.019221421100000101008.260475448512018-12-31 00:00:00.00000.0100826047544802
170986.234042100054986.234042100054116997.253263522100000100986.2340421542019-03-31 00:00:00.00000.00986234042100054
180997.246658307449997.246658307449117994.499921829100000100997.246658307572019-06-30 00:00:00.00000.00997246658307449
191000001008.26047544802101008.260475448119002.7603972770101008.260475448602019-09-30 00:00:00.00000.0100826047544802

We modify the SQL so that there are no interest payments in 2018.

SELECT *
FROM wct.Balloon(   100000,       --@OutstandingAmount
                    'Actual/365', --@InterestBasis
                    .04,          --@InterestRate
                    3,            --@PaymentFrequency
                    '2019-09-15', --@MaturityDate
                    '2014-09-15', --@ReferenceDate
                    NULL,         --@PrevPayDate
                    NULL,         --@StartDate
                    '2015-03-15', --@FirstPayDate
                    '2018-01-01', --@GracePeriodStartDate
                    '2019-01-01'  --@GracePeriodEndDate
                );

This produces the following result.

PeriodPrincipalPaymentInterestPaymentCashFlowOutstandingExposureCapitalAmountInDebtTotalExposureNumberOfMonthPaymentDateGraceInterestInterestRate
000010000010000010000002014-09-30 00:00:00.00000
10986.2340421000542004.43832558996100986.2340421100000100986.234042162015-03-31 00:00:00.0001018.204283489910.0200443832558996
20997.246658307449997.246658307449101983.480700407100000100997.24665830792015-06-30 00:00:00.00000.00997246658307449
301008.260475448021008.26047544802102991.741175856100000101008.260475448122015-09-30 00:00:00.00000.0100826047544802
401008.260475448021008.26047544802104000.001651304100000101008.260475448152015-12-31 00:00:00.00000.0100826047544802
50997.246658307449997.246658307449104997.248309611100000100997.246658307182016-03-31 00:00:00.00000.00997246658307449
60997.246658307449997.246658307449105994.494967918100000100997.246658307212016-06-30 00:00:00.00000.00997246658307449
701008.260475448021008.26047544802107002.755443366100000101008.260475448242016-09-30 00:00:00.00000.0100826047544802
801008.260475448021008.26047544802108011.015918814100000101008.260475448272016-12-31 00:00:00.00000.0100826047544802
90986.234042100054986.234042100054108997.249960914100000100986.2340421302017-03-31 00:00:00.00000.00986234042100054
100997.246658307449997.246658307449109994.496619222100000100997.246658307332017-06-30 00:00:00.00000.00997246658307449
1101008.260475448021008.26047544802111002.75709467100000101008.260475448362017-09-30 00:00:00.00000.0100826047544802
1201008.260475448021008.26047544802112011.017570118100000101008.260475448392017-12-31 00:00:00.00000.0100826047544802
1301008.260475448024412.76058163813113019.278045566100000101008.260475448522019-01-31 00:00:00.0003404.500106190110.0441276058163813
140975.222626694849975.222626694849113994.500672261100000100975.222626695552019-04-30 00:00:00.00000.00975222626694849
1501008.260475448021008.26047544802115002.761147709100000101008.260475448582019-07-31 00:00:00.00000.0100826047544802
16100000667.389989840128100667.38998984115670.1511375490100667.38998984602019-09-30 00:00:00.00000.00667389989840128

In this example we modify the SQL to get rid of the first payment date and calculate the first interest payment using the previous payment date.

SELECT *
FROM wct.Balloon(   100000,       --@OutstandingAmount
                    'Actual/365', --@InterestBasis
                    .04,          --@InterestRate
                    3,            --@PaymentFrequency
                    '2019-09-15', --@MaturityDate
                    '2014-09-15', --@ReferenceDate
                    '2014-08-15', --@PrevPayDate
                    NULL,         --@StartDate
                    NULL,         --@FirstPayDate
                    '2018-01-01', --@GracePeriodStartDate
                    '2019-01-01'  --@GracePeriodEndDate
                );

This produces the following result.

PeriodPrincipalPaymentInterestPaymentCashFlowOutstandingExposureCapitalAmountInDebtTotalExposureNumberOfMonthPaymentDateGraceInterestInterestRate
000010000010000010000002014-09-30 00:00:00.00000
10667.389989840128667.389989840128100667.38998984100000100667.3899898422014-11-30 00:00:00.00000.00667389989840128
20986.234042100054986.234042100054101653.62403194100000100986.234042152015-02-28 00:00:00.00000.00986234042100054
301008.260475448021008.26047544802102661.884507388100000101008.26047544882015-05-31 00:00:00.00000.0100826047544802
401008.260475448021008.26047544802103670.144982836100000101008.260475448112015-08-31 00:00:00.00000.0100826047544802
50997.246658307449997.246658307449104667.391641144100000100997.246658307142015-11-30 00:00:00.00000.00997246658307449
60997.246658307449997.246658307449105664.638299451100000100997.246658307172016-02-29 00:00:00.00000.00997246658307449
701008.260475448021008.26047544802106672.898774899100000101008.260475448202016-05-31 00:00:00.00000.0100826047544802
801008.260475448021008.26047544802107681.159250347100000101008.260475448232016-08-31 00:00:00.00000.0100826047544802
90997.246658307449997.246658307449108678.405908655100000100997.246658307262016-11-30 00:00:00.00000.00997246658307449
100986.234042100054986.234042100054109664.639950755100000100986.2340421292017-02-28 00:00:00.00000.00986234042100054
1101008.260475448021008.26047544802110672.900426203100000101008.260475448322017-05-31 00:00:00.00000.0100826047544802
1201008.260475448021008.26047544802111681.160901651100000101008.260475448352017-08-31 00:00:00.00000.0100826047544802
130997.246658307449997.246658307449112678.407559958100000100997.246658307382017-11-30 00:00:00.00000.00997246658307449
1401008.260475448024766.31329028307113686.668035406100000101008.260475448522019-01-31 00:00:00.0003758.052814835060.0476631329028308
150975.222626694849975.222626694849114661.890662101100000100975.222626695552019-04-30 00:00:00.00000.00975222626694849
1601008.260475448021008.26047544802115670.151137549100000101008.260475448582019-07-31 00:00:00.00000.0100826047544802
17100000667.389989840128100667.38998984116337.5411273890100667.38998984602019-09-30 00:00:00.00000.00667389989840128

In this example we modify the SQL to eliminate the grace period and the previous payment date and add a start date.

SELECT *
FROM wct.Balloon(   100000,       --@OutstandingAmount
                    'Actual/365', --@InterestBasis
                    .04,          --@InterestRate
                    3,            --@PaymentFrequency
                    '2019-09-15', --@MaturityDate
                    '2014-09-15', --@ReferenceDate
                    NULL,         --@PrevPayDate
                    '2011-09-15', --@StartDate
                    NULL,         --@FirstPayDate
                    NULL,         --@GracePeriodStartDate
                    NULL          --@GracePeriodEndDate
                );

This produces the following result.

PeriodPrincipalPaymentInterestPaymentCashFlowOutstandingExposureCapitalAmountInDebtTotalExposureNumberOfMonthPaymentDateGraceInterestInterestRate
000010000010000010000002014-09-30 00:00:00.00000
101008.260475448021008.26047544802101008.260475448100000101008.26047544832014-12-31 00:00:00.00000.0100826047544802
20986.234042100054986.234042100054101994.494517548100000100986.234042162015-03-31 00:00:00.00000.00986234042100054
30997.246658307449997.246658307449102991.741175856100000100997.24665830792015-06-30 00:00:00.00000.00997246658307449
401008.260475448021008.26047544802104000.001651304100000101008.260475448122015-09-30 00:00:00.00000.0100826047544802
501008.260475448021008.26047544802105008.262126752100000101008.260475448152015-12-31 00:00:00.00000.0100826047544802
60997.246658307449997.246658307449106005.508785059100000100997.246658307182016-03-31 00:00:00.00000.00997246658307449
70997.246658307449997.246658307449107002.755443366100000100997.246658307212016-06-30 00:00:00.00000.00997246658307449
801008.260475448021008.26047544802108011.015918814100000101008.260475448242016-09-30 00:00:00.00000.0100826047544802
901008.260475448021008.26047544802109019.276394262100000101008.260475448272016-12-31 00:00:00.00000.0100826047544802
100986.234042100054986.234042100054110005.510436363100000100986.2340421302017-03-31 00:00:00.00000.00986234042100054
110997.246658307449997.246658307449111002.75709467100000100997.246658307332017-06-30 00:00:00.00000.00997246658307449
1201008.260475448021008.26047544802112011.017570118100000101008.260475448362017-09-30 00:00:00.00000.0100826047544802
1301008.260475448021008.26047544802113019.278045566100000101008.260475448392017-12-31 00:00:00.00000.0100826047544802
140986.234042100054986.234042100054114005.512087666100000100986.2340421422018-03-31 00:00:00.00000.00986234042100054
150997.246658307449997.246658307449115002.758745973100000100997.246658307452018-06-30 00:00:00.00000.00997246658307449
1601008.260475448021008.26047544802116011.019221421100000101008.260475448482018-09-30 00:00:00.00000.0100826047544802
1701008.260475448021008.26047544802117019.279696869100000101008.260475448512018-12-31 00:00:00.00000.0100826047544802
180986.234042100054986.234042100054118005.51373897100000100986.2340421542019-03-31 00:00:00.00000.00986234042100054
190997.246658307449997.246658307449119002.760397277100000100997.246658307572019-06-30 00:00:00.00000.00997246658307449
201000001008.26047544802101008.260475448120011.0208727250101008.260475448602019-09-30 00:00:00.00000.0100826047544802

See Also

BULLET - Schedule with single interest and principal payment at maturity

CONSTANTCASHFLOW - Schedule with equal periodic cash flows

CONSTANTPAYMENTAMOUNT - Schedule with no maturity with fixed periodic payment amount

CONSTANTPRINCIPAL - Schedule with fixed maturity date where the periodic principal payment is calculated on a straight-line basis

CONSTANTPRINCIPALAMOUNT - Schedule with no fixed maturity with a fixed periodic principal payment

CONSTANTPRINCIPALRATE - Schedule with no fixed maturity where a fixed percentage principal payment

PAYMENTPERIODS - Number of months until first payment date, start of grace period, end of grace period, and total number payments for a loan