ConsumerDataStandardsAustralia / standards-maintenance

This repository houses the interactions, consultations and work management to support the maintenance of baselined components of the Consumer Data Right API Standards and Information Security profile.
41 stars 9 forks source link

BankingProductLendingRate - move properties Rate & ComparisonRate to RateTier #184

Closed markt-amp closed 1 year ago

markt-amp commented 4 years ago

Description

Mortgage products often use LVR based pricing with specific rates being applied to particular tiers of LVR. The current version of the standards results in repetition of data unnecessarily for the same product and leaves the API ambiguous by the presence/absence of BankingProductRateTier. For mortgages this fundamentally means the creation of a rate and rate tier tier for each LVR level.

This same change could be adopted to DepositRates to support term deposits, but isn't being suggested in this change request.

Area Affected

Change Proposed

At the moment the standards represent the rate as applicable to LendingRate at the object level, we feel the rates would be better represented within the tier itself. This change proposal assumes that https://github.com/ConsumerDataStandardsAustralia/standards-maintenance/issues/48 is adopted

This change would:

Change details

BankingProductLendingRate

BankingProductRateTier

JSON tree

Current: sample_current

Proposed: sample_proposed

Payload samples

Current

{
    "productId": "AMP_ESSENTIAL_HL",
    "effectiveFrom": "2010-07-14T14:00:00Z",
    "effectiveTo": "9999-12-30T13:00:00Z",
    "lastUpdated": "2019-05-29T16:16:12.630613Z",
    "productCategory": "RESIDENTIAL_MORTGAGES",
    "name": "AMP Essential Home Loan",
    "description": "AMP Essential Home Loan",
    "brand": "AMP",
    "brandName": "AMP",
    "isTailored": false,
    "additionalInformation": {
        "overviewUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan",
        "termsUri": "https://www.amp.com.au/bankterms",
        "feesAndPricingUri": "https://www.amp.com.au/content/dam/amp/digitalhub/common/Documents/HomeLoans/Forms/308006_Home_Loan_Fees_and_Charges_Guide.pdf"
    },
    "features": [{
            "featureType": "REDRAW",
            "additionalValue": "Redraw extra funds you deposit whenever you like, with no withdrawal fees. You can redraw your extra funds using online banking, our mobile apps, BankPhone and BankAssist.",
            "additionalInfo": "Redraw applies to variable rate loans only"
        }
    ],
    "eligibility": [{
            "eligibilityType": "NATURAL_PERSON"
        }
    ],

    "lendingRates": [{
            "lendingRateType": "variable",
            "rate": "0.0459",
            "comparisonRate": "0.0462",
            "repaymentType": "PRINCIPAL_AND_INTEREST",
            "loanPurpose": "INVESTMENT",
            "calculationFrequency": "P1D",
            "applicationFrequency": "P1M",
            "interestPaymentDue": "IN_ARREARS",
            "tiers": [{
                    "name": "investor_lvr_0_100",
                    "unitOfMeasure": "DOLLAR",
                    "minimumValue": 0,
                    "maximumValue": 99999999,
                    "rateApplicationMethod": "WHOLE_BALANCE",
                    "applicabilityConditions": {
                        "additionalInfo": "Max LVR 90% + LMI",
                        "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                    }
                }
            ]
        }, {
            "lendingRateType": "variable",
            "rate": "0.02770",
            "comparisonRate": "0.0280",
            "repaymentType": "PRINCIPAL_AND_INTEREST",
            "loanPurpose": "OWNER_OCCUPIED",
            "calculationFrequency": "P1D",
            "applicationFrequency": "P1M",
            "interestPaymentDue": "IN_ARREARS",
            "tiers": [{
                    "name": "OO_lvr_0_80",
                    "unitOfMeasure": "PERCENT",
                    "minimumValue": 0,
                    "maximumValue": 80,
                    "rateApplicationMethod": "PER_TIER",
                    "applicabilityConditions": {
                        "additionalInfo": "Max LVR 80%, $100,000 and above",
                        "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                    }
                }
            ]
        }, {
            "lendingRateType": "variable",
            "rate": "0.00334",
            "comparisonRate": "0.0337",
            "repaymentType": "PRINCIPAL_AND_INTEREST",
            "loanPurpose": "OWNER_OCCUPIED",
            "calculationFrequency": "P1D",
            "applicationFrequency": "P1M",
            "interestPaymentDue": "IN_ARREARS",
            "tiers": [{
                    "name": "OO_lvr_81_100",
                    "unitOfMeasure": "PERCENT",
                    "minimumValue": 81,
                    "maximumValue": 100,
                    "rateApplicationMethod": "PER_TIER",
                    "applicabilityConditions": {
                        "additionalInfo": "Max LVR 80%, $100,000 and above",
                        "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                    }
                }
            ]
        }
    ]
}

Proposed

{
    "productId": "AMP_ESSENTIAL_HL",
    "effectiveFrom": "2010-07-14T14:00:00Z",
    "effectiveTo": "9999-12-30T13:00:00Z",
    "lastUpdated": "2019-05-29T16:16:12.630613Z",
    "productCategory": "RESIDENTIAL_MORTGAGES",
    "name": "AMP Essential Home Loan",
    "description": "AMP Essential Home Loan",
    "brand": "AMP",
    "brandName": "AMP",
    "isTailored": false,
    "additionalInformation": {
        "overviewUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan",
        "termsUri": "https://www.amp.com.au/bankterms",
        "feesAndPricingUri": "https://www.amp.com.au/content/dam/amp/digitalhub/common/Documents/HomeLoans/Forms/308006_Home_Loan_Fees_and_Charges_Guide.pdf"
    },
    "features": [{
        "featureType": "REDRAW",
        "additionalValue": "Redraw extra funds you deposit whenever you like, with no withdrawal fees. You can redraw your extra funds using online banking, our mobile apps, BankPhone and BankAssist.",
        "additionalInfo": "Redraw applies to variable rate loans only"
    }],
    "eligibility": [{
        "eligibilityType": "NATURAL_PERSON"
    }],
    "lendingRates": [{
            "lendingRateType": "variable",
            "repaymentType": "PRINCIPAL_AND_INTEREST",
            "loanPurpose": "INVESTMENT",
            "calculationFrequency": "P1D",
            "applicationFrequency": "P1M",
            "interestPaymentDue": "IN_ARREARS",
            "tiers": [{
                "rate": "0.0459",
                "comparisonRate": "0.0462",
                "name": "investor_lvr_0_100",
                "unitOfMeasure": "DOLLAR",
                "minimumValue": 0,
                "maximumValue": 99999999,
                "rateApplicationMethod": "WHOLE_BALANCE",
                "applicabilityConditions": {
                    "additionalInfo": "Max LVR 90% + LMI",
                    "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                }
            }]
        },
        {
            "lendingRateType": "variable",
            "repaymentType": "PRINCIPAL_AND_INTEREST",
            "loanPurpose": "OWNER_OCCUPIED",
            "calculationFrequency": "P1D",
            "applicationFrequency": "P1M",
            "interestPaymentDue": "IN_ARREARS",
            "tiers": [{
                "name": "OO_lvr_0_80",
                "unitOfMeasure": "PERCENT",
                "minimumValue": 0,
                "maximumValue": 80,
                "rate": "0.02770",
                "comparisonRate": "0.0280",
                "rateApplicationMethod": "PER_TIER",
                "applicabilityConditions": {
                    "additionalInfo": "Max LVR 80%, $100,000 and above",
                    "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                }
            }, {
                "name": "OO_lvr_81_100",
                "unitOfMeasure": "PERCENT",
                "minimumValue": 81,
                "maximumValue": 100,
                "rate": "0.00334",
                "comparisonRate": "0.0337",
                "rateApplicationMethod": "PER_TIER",
                "applicabilityConditions": {
                    "additionalInfo": "Max LVR 80%, $100,000 and above",
                    "additionalInfoUri": "https://www.amp.com.au/home-loans/loans/amp-essential-home-loan"
                }
            }]
        }
    ]
}
perlboy commented 4 years ago

This looks related to #94.

anzbankau commented 4 years ago

@markt-amp , the original standards had lendingRates and depositRate arrays to hold rates with additional properties providing the context of the rate or criteria or applicability by which the rate could be selected. The flexibility of this approach is demonstrated by the 'dimensional model' where the rate is a measure/fact and the other descriptive properties are 'dimensional' - from which the consumer can infer their own structures including custom hierarchies. The addition of tiers followed that pattern, with a generic discrete/ranged value schema but also a tier array to allow the criteria/applicability to be multi-dimensional/combinatorial.

This proposal seems to include product sub-types (e.g. variable + P&I + investor, variable + P&I + owner-occupier) as the primary objects in the array with rates and tiers within them. This imposes a schema-based structure 'above' the rates and tiers rather than allow the data consumer to interpret the structure as they prefer based upon properties 'beneath' the rate. The proposal either forces a single tier object for simple rates or would require properties that have been 'pushed down' into the tier to be repeated at the sub-product level to allow the tier to be optional. Tiers are optional in the current standards because they are merely to qualify for the rate, not to specify the rate. Additional properties that may be required for lendingRate or depositRate in future do not need to be added to the generic ProductRateTier schema. Pushing properties down into ProductRateTier would require separate ProductLendingRateTier and ProductDepositRateTier schema as the new properties may apply only to one product class e.g. comparisonRate only applies to lendingRate.

markt-amp commented 4 years ago

Thanks for your constructive feedback @anzbankau - where the standards are now in v3 have already incorporated a repaymentTypeand loandPurpose at the 'ProductLendingRate' level.

With regards to this:

Allow the data consumer to interpret the structure as they prefer based upon properties 'beneath' the rate.

And this:

Pushing properties down into ProductRateTier would require separate ProductLendingRateTier and ProductDepositRateTier schema as the new properties may apply only to one product class e.g. comparisonRate only applies to lendingRate

In practice, you'd no doubt agree that leaving lending rates subject to interpretation by a consumer for a mortgage are far more risky than deposit rates. Sure you could capture more information in additionalValue and additionalInfo fields. Further - comparison rates where they're currently placed now don't cater for line of credit style products. Given that the standards have evolved to differentiate between a Lending Rate and Deposit rate, suitable applicable tiers to cater for those schemas I feel should exist to provide clarity and a good positive consumer experience, possibly even conditional rather than optional. Thoughts?

anzbankau commented 4 years ago

@markt-amp,

In practice, you'd no doubt agree that leaving lending rates subject to interpretation by a consumer for a mortgage are far more risky than deposit rates. Sure you could capture more information in additionalValue and additionalInfo fields.

The current standards are for flexibility and extensibility and shouldn't cause misinterpretation. The proposal is a structural change, 'inverting' the structure, but doesn't really change the content or reduce the risk of misinterpretation - especially with the example provided with a single tier for a single sub-product. It just has the potential to impose a data holder's product structure (e.g. a Variable Rate Home Loan) into sub-products on the data consumer. The objects in the proposed `lendingRate' array are sub-products represented by a combination of attributes values rather than rates. It's not obvious in the home loan example because they are one-to-one so data consumers can treat each sub-product with rates as a single object. In principle, if a three-level sub-product hierarchy was required (e.g. Variable > P&I|IO > Investment|Owner Occupied), the schema above the rate would require an additional level whereas the current standards allow data consumers to create a hierarchy from a 'flat' list of properties as they need it (e.g. Variable > Investment|Owner Occupied > P&I|IO). I'm using this just to emphasise the point about a sub-product > rate structure versus a rate > sub-product structure.

Perhaps the more concrete problem with the proposal is that it doesn't support rates that apply to a combination of properties - the purpose of the tiers array property. The rate can't be at the tier level because it doesn't apply to one tier e.g.:

{
    "rate": "0.0419",
    "comparisonRate": "0.0459",
    "lendingRateType": "VARIABLE",
    "repaymentType": "PRINCIPAL_AND_INTEREST",
    "loanPurpose": "INVESTMENT",
    "calculationFrequency": "P1D",
    "applicationFrequency": "P1M",
    "interestPaymentDue": "IN_ARREARS"
    "additionalInfo": "Principal & Interest (Residential Investment  Loan $250,000 - $499,999) : Borrowing 80% or less of the property value",
    "tiers": [
        {
            "name": "Amount",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": 250000,
            "maximumValue": 499999,
            "rateApplicationMethod": "WHOLE_BALANCE"
            "applicabilityConditions": {
                "additionalInfo": "Total mortgage lending of between $250,000 and $499,999"
            },
        },
        {
            "name": "Loan-to-Value Ratio",
            "unitOfMeasure": "PERCENT",
            "minimumValue": 0,
            "maximumValue": 80,
            "rateApplicationMethod": "WHOLE_BALANCE"
            "applicabilityConditions": {
                "additionalInfo": "Borrowing up to 80% of the property value"
            },
        }
    ],
},

Further - comparison rates where they're currently placed now don't cater for line of credit style products.

Could you please expand on this? How does the proposal solve this?

Given that the standards have evolved to differentiate between a Lending Rate and Deposit rate, suitable applicable tiers to cater for those schemas I feel should exist to provide clarity and a good positive consumer experience, possibly even conditional rather than optional. Thoughts?

The LendingRate and DepositRate schema were different from the start in recognition of the different properties that determine the rates. The RateTier schema was designed to be generic for flexibility and extensibility. As mentioned above, the structural change proposed shouldn't change clarity and consumer experience.

nils-work commented 1 year ago

As this issue hasn't been proposed for consideration in maintenance iterations or had any further comments for three years, a summary and general guidance is provided below to foster any further feedback. If there are no further comments this issue will be regarded as a query with an answer provided and closed on 30 June 2023.

The original issue suggests moving rate values from the top of the rate object, into the tiers array so each rate is at the same level as the tier, as described in the diff below.

{
    "productId": "string",
    "lastUpdated": "string",
    "productCategory": "RESIDENTIAL_MORTGAGES",
    "name": "string",
    "description": "string",
    "brand": "string",
    "isTailored": true,
    "lendingRates": [{
        "lendingRateType": "variable",
-       "rate": "0.0459",
-       "comparisonRate": "0.0462",
        "repaymentType": "PRINCIPAL_AND_INTEREST",
        "loanPurpose": "INVESTMENT",
        "calculationFrequency": "P1D",
        "applicationFrequency": "P1M",
        "interestPaymentDue": "IN_ARREARS",
        "tiers": [{
            "name": "investor_lvr_0_100",
            "unitOfMeasure": "DOLLAR",
            "minimumValue": 0,
            "maximumValue": 99999999,
+           "rate": "0.0459",
+           "comparisonRate": "0.0462",
            "rateApplicationMethod": "WHOLE_BALANCE",
            "applicabilityConditions": {
                "additionalInfo": "Max LVR 90% + LMI",
                "additionalInfoUri": "string"
            }
        }]
    }

There was feedback against this proposal, suggesting it changes the 'rate' (parent) -> 'tier' (child / details to qualify for the rate) relationship, noted in this comment:

As further demonstrated in the sample in the above comment, the purpose of tiers is to allow the querying and display of details to 'qualify' for, or applicable to, the respective rate which the tier is a property of.

Also as shown in that comment, a holder may specify multiple dimensions that a rate may be qualified against, using their own familiar naming convention to provide the labels (or 'keys') for a set of common unitOfMeasure values.

This convention is expected to enable the consolidation of the tier values matching the common key, to provide an interpretation like below:

  • These are the rates available by "Loan amount":
    • $200,000 - $400,000: 3.5%
    • $400,000 - $600,000: 4.5%
    • $600,000 - $800,000: 5.5%
  • These are the rates available by "Loan-to-Value Ratio":
    • 40% - 60%: 3.5%
    • 60% - 80%: 4.5%
    • 80% - 90%: 5.5%

The name of a tier may be any value, but it is expected to be most useful as a common key for all equivalent tiers based on the same dimension.

In contrast, tier objects provided with unique names such as loan_amt_200_400 or lvr_40_60 would not be as useful as they may appear as different dimensions of qualifying criteria, and the associated values (provided by unitOfMeasure, minimumValue and maximumValue) would only correspond to a single rate when consolidated.

That approach may result in a more complex and repetitive interpretation of the rate detail, such as:

  • These are the rates available by "loan_amt_200_400":
    • $200,000 - $400,000: 3.5%
  • These are the rates available by "loan_amt_400_600":
    • $400,000 - $600,000: 4.5%
  • These are the rates available by "loan_amt_600_800":
    • $600,000 - $800,000: 5.5%
  • These are the rates available by "lvr_40_60":
    • 40% - 60%: 3.5%
  • These are the rates available by "lvr_60_80":
    • 60% - 80%: 4.5%
  • These are the rates available by "lvr_80_90":
    • 80% - 90%: 5.5%
anzbankau commented 1 year ago

@nils-work,

We appreciate your excellent guidance on the use of tiers, with good examples. Since the first version of the schema we considered proposing an additional tierSet level (i.e., array and object with tierSetName property) to enforce the collection abstraction, but we were concerned about the impact on the community structure so soon after v1.0.0. We recognised that common practice would demonstrate how consistent naming (i.e., using tiers[].{}.name) can allow data consumers to interpret/collate the tier set. Your guidance and examples will help with this and should be a good reference.