Logo

SQL Server AIFACTOR_OFC Function

Updated 2023-10-06 11:55:35.177000

Description

Use the scalar-valued function AIFACTOR_OFC to calculate the Accrued Interest Factor for a bond during its odd first coupon period. AIFACTOR_OCF returns a decimal value which can then be multiplied by the face amount of the bond to return the monetary value of the accrued interest for the odd first period.

Syntax

SELECT [westclintech].[wct].[AIFACTOR_OFC] (
  <@Basis, nvarchar(4000),>
 ,<@Rate, float,>
 ,<@IssueDate, datetime,>
 ,<@Settlement, datetime,>
 ,<@FirstInterestDate, datetime,>
 ,<@Frequency, int,>
 ,<@Holidays, nvarchar(max),>);

Arguments

@Basis

the day-count convention used in the calculation of the accrued coupon interest. @Basis is an expression of the character string data type category.

@BasisDay count basis
0 or omittedUS (NASD) 30/360
1Actual/Actual
2Actual/360
3Actual/365
4European 30/360
530/360 ISDA
6NL/ACT
7NL/365
8NL/360
9A/364
10US (NASD) 30/360 non-end-of-month
11Actual/Actual non-end-of-month
12Actual/360 non-end-of-month
13Actual/365 non-end-of-month
14European 30/360 non-end-of-month
1530/360 ISDA non-end-of-month
16NL/ACT non-end-of-month
17NL/365 non-end-of-month
18NL/360 non-end-of-month
19A/364 non-end-of-month
20BUS/252
21Actual/ISDA
22Actual/ISMA
23Actual/365L
24Actual/AFB
30BUS/252 non-end-of-month

@IssueDate

the first accrual date for the bond. @IssueDate is an expression of type datetime or of a type that can be implicitly converted to datetime.

@Settlement

the settlement date of the transaction. @Settlement is an expression of type datetime or of a type that can be implicitly converted to datetime.

@FirstInterestDate

the first interest payment date for the bond. When the settlement date occurs on the first interest date, the factor returned will be for the entire first coupon period. @FirstInterestDate is an expression of type datetime or of a type that can be implicitly converted to datetime.

@Frequency

the number of coupon payments per year. For annual payments, @Frequency = 1; for semi-annual, @Frequency = 2; for quarterly, @Frequency = 4; for monthly, @Frequency = 12. @Frequency is an expression of type float or of a type that can be implicitly converted to float.

@Holidays

a comma separated string containing the holiday (non-business) dates to be used in the calculation of the number of business days. You can use the aggregate function NBD to create an appropriately formatted string.

Return Type

float

Remarks

@Settlement must be less than or equal to @FirstInterestDate.

@Settlement must be greater than or equal to @IssueDate.

If @Settlement = @IssueDate then the function returns zero.

For bonds where the settlement date is after the first interest date, use AIFACTOR or AIFACTOR_RPI.

For bonds where the settlement date is in an odd last coupon period, use AIFACTOR or AIFACOR_OLC.

For more information on accrual calculations, go to AIFACTOR.

Examples

In this example, we show the calculation of the accrued interest factor for the entire coupon period for all the supported day-count conventions. To keep the SELECT statement simple, we have put the holidays into a scalar variable up front. The holidays are only required for BUS/252 and BUS/252 NON-EOM day-count conventions.

DECLARE @h as varchar(max);
SET @h
    = '20110101,20110307,20110308,20110421,20110422,20110501,20110623,20110907,
              20111012,20111102,20111115,20111225,20120101,20120220,20120221,
              20120406,20120421,20120501,20120607,20120907,20121012,20121102,
              20121115,20121225';
SELECT n.Description,
       wct.AIFACTOR_OFC(   n.basis,      --Basis
                           .10,          --Rate
                           '2011-07-15', --Issue Date
                           '2012-06-30', --Settlement Date
                           '2012-06-30', --First Interest Date
                           2,            --Frequency
                           @h            --Holidays
                       ) * 10000 as [Interest]
FROM
(
    SELECT 0,
           'BOND'
    UNION ALL
    SELECT 1,
           'Actual / Actual'
    UNION ALL
    SELECT 2,
           'Actual / 360'
    UNION ALL
    SELECT 3,
           'Actual / 365'
    UNION ALL
    SELECT 4,
           '30E / 360'
    UNION ALL
    SELECT 5,
           '30 / 360 ISDA'
    UNION ALL
    SELECT 6,
           'NL / ACT'
    UNION ALL
    SELECT 7,
           'NL / 365'
    UNION ALL
    SELECT 8,
           'NL / 360'
    UNION ALL
    SELECT 9,
           'Actual / 364'
    UNION ALL
    SELECT 10,
           'BOND NON-EOM'
    UNION ALL
    SELECT 11,
           'Actual / Actual NON-EOM'
    UNION ALL
    SELECT 12,
           'Actual / 360 NON-EOM'
    UNION ALL
    SELECT 13,
           'Actual / 365 NON-EOM'
    UNION ALL
    SELECT 14,
           '30E / 360 NON-EOM'
    UNION ALL
    SELECT 15,
           '30 / 360 ISDA NON-EOM'
    UNION ALL
    SELECT 16,
           'NL / ACT NON-EOM'
    UNION ALL
    SELECT 17,
           'NL / 365 NON-EOM'
    UNION ALL
    SELECT 18,
           'NL / 360 NON-EOM'
    UNION ALL
    SELECT 19,
           'Actual / 364 NON-EOM'
    UNION ALL
    SELECT 20,
           'BUS / 252'
    UNION ALL
    SELECT 21,
           'Actual / ISDA'
    UNION ALL
    SELECT 22,
           'Actual / ISMA'
    UNION ALL
    SELECT 23,
           'Actual / 365L'
    UNION ALL
    SELECT 24,
           'Actual / AFB'
    UNION ALL
    SELECT 30,
           'BUS / 252 NON-EOM'
) n(basis, Description);

This produces the following result.

DescriptionInterest
BOND958.333333333333
Actual / Actual959.239130434783
Actual / 360975
Actual / 365961.643835616438
30E / 360958.333333333333
30 / 360 ISDA958.333333333333
NL / ACT959.239130434783
NL / 365958.904109589041
NL / 360972.222222222222
Actual / 364964.285714285714
BOND NON-EOM958.333333333333
Actual / Actual NON-EOM959.016393442623
Actual / 360 NON-EOM975
Actual / 365 NON-EOM961.643835616439
30E / 360 NON-EOM958.333333333333
30 / 360 ISDA NON-EOM958.333333333333
NL / ACT NON-EOM959.016393442623
NL / 365 NON-EOM958.904109589041
NL / 360 NON-EOM972.222222222222
Actual / 364 NON-EOM964.285714285714
BUS / 252934.557015350965
Actual / ISDA960.288943783217
Actual / ISMA959.239130434783
Actual / 365L960.281458192979
Actual / AFB960.27397260274
BUS / 252 NON-EOM934.557015350965

In this example, we show the calculation of the accrued interest factor for each of the day-count conventions for the issue date, the last day of the year within the odd coupon period, and for a date in the following year in the odd coupon period.

DECLARE @h as varchar(max);
SET @h
    = '20110101,20110307,20110308,20110421,20110422,20110501,20110623,20110907,
              20111012,20111102,20111115,20111225,20120101,20120220,20120221,
              20120406,20120421,20120501,20120607,20120907,20121012,20121102,
              20121115,20121225';
SELECT Description,
       [2011-07-15],
       [2011-12-31],
       [2012-04-01]
FROM
(
    SELECT n.Description,
           n.basis,
           m.sd,
           CAST(wct.AIFACTOR_OFC(   n.basis,      --Basis
                                    .10,          --Rate
                                    '2011-07-15', --Issue Date
                                    m.sd,         --Settlement Date
                                    '2012-06-30', --First Interest Date
                                    2,            --Frequency
                                    @h            --Holidays
                                ) * 10000 as money) as [Interest]
    FROM
    (
        SELECT 0,
               'BOND'
        UNION ALL
        SELECT 1,
               'Actual / Actual'
        UNION ALL
        SELECT 2,
               'Actual / 360'
        UNION ALL
        SELECT 3,
               'Actual / 365'
        UNION ALL
        SELECT 4,
               '30E / 360'
        UNION ALL
        SELECT 5,
               '30 / 360 ISDA'
        UNION ALL
        SELECT 6,
               'NL / ACT'
        UNION ALL
        SELECT 7,
               'NL / 365'
        UNION ALL
        SELECT 8,
               'NL / 360'
        UNION ALL
        SELECT 9,
               'Actual / 364'
        UNION ALL
        SELECT 10,
               'BOND NON-EOM'
        UNION ALL
        SELECT 11,
               'Actual / Actual NON-EOM'
        UNION ALL
        SELECT 12,
               'Actual / 360 NON-EOM'
        UNION ALL
        SELECT 13,
               'Actual / 365 NON-EOM'
        UNION ALL
        SELECT 14,
               '30E / 360 NON-EOM'
        UNION ALL
        SELECT 15,
               '30 / 360 ISDA NON-EOM'
        UNION ALL
        SELECT 16,
               'NL / ACT NON-EOM'
        UNION ALL
        SELECT 17,
               'NL / 365 NON-EOM'
        UNION ALL
        SELECT 18,
               'NL / 360 NON-EOM'
        UNION ALL
        SELECT 19,
               'Actual / 364 NON-EOM'
        UNION ALL
        SELECT 20,
               'BUS / 252'
        UNION ALL
        SELECT 21,
               'Actual / ISDA'
        UNION ALL
        SELECT 22,
               'Actual / ISMA'
        UNION ALL
        SELECT 23,
               'Actual / 365L'
        UNION ALL
        SELECT 24,
               'Actual / AFB'
        UNION ALL
        SELECT 30,
               'BUS / 252 NON-EOM'
    ) n(basis, Description)
        CROSS APPLY
    (
        SELECT '2011-07-15'
        UNION ALL
        SELECT '2011-12-31'
        UNION ALL
        SELECT '2012-04-01'
    ) m(sd)
) d
PIVOT
(
    min(INTEREST)
    FOR sd in ([2011-07-15], [2011-12-31], [2012-04-01])
) as P
ORDER by basis;

This produces the following result.

Description2011-07-152011-12-312012-04-01
BOND0.00458.3333711.1111
Actual / Actual0.00459.2391711.9864
Actual / 3600.00469.4444725.00
Actual / 3650.00463.0137715.0685
30E / 3600.00458.3333711.1111
30 / 360 ISDA0.00458.3333711.1111
NL / ACT0.00459.2391710.6203
NL / 3650.00463.0137712.3288
NL / 3600.00469.4444722.2222
Actual / 3640.00464.2857717.033
BOND NON-EOM0.00458.3333711.1111
Actual / Actual NON-EOM0.00461.7486713.1148
Actual / 360 NON-EOM0.00469.4444725.00
Actual / 365 NON-EOM0.00463.0137715.0685
30E / 360 NON-EOM0.00458.3333711.1111
30 / 360 ISDA NON-EOM0.00458.3333711.1111
NL / ACT NON-EOM0.00461.7636711.7636
NL / 365 NON-EOM0.00463.0137712.3288
NL / 360 NON-EOM0.00469.4444722.2222
Actual / 364 NON-EOM0.00464.2857717.033
BUS / 2520.00446.4685690.5128
Actual / ISDA0.00463.0137714.3873
Actual / ISMA0.00459.2391711.9864
Actual / 365L0.00463.0137714.3798
Actual / AFB0.00463.0062714.3723
BUS / 252 NON-EOM0.00446.4685690.5128

See Also

ACCRINT - Calculate the accrued interest for a security that pays periodic interest.

ACCRINTM - Calculate the accrued interest for a security that pays interest at maturity.

AIFACTOR - Calculate the Accrued Interest Factor

AIFACTOR_IAM - Calculate the Accrued Interest Factor for an Interest-at-Maturity security

AIFACTOR_OLC - Calculate the Accrued Interest Factor for a bond during its odd last coupon period

AIFACTOR_RPI - Calculate the Accrued Interest Factor for a Regular Periodic Interest period

BONDINT - Accrued interest on a bond paying regular, periodic interest

COMPINT - Calculate the accrued interest for a security where interest is compounded periodically and paid at maturity

ODDCOMPINT - Calculate the accrued interest in first coupon period for a bond with an odd first coupon and a par value of 100

ODDFINT - Accrued interest for a bond with an odd first coupon

ODDLINT - Accrued interest for a bond with an odd last coupon