Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BankingProductLendingRate - move properties Rate & ComparisonRate to RateTier #184

Closed
markt-amp opened this issue Apr 9, 2020 · 6 comments
Labels
Banking Banking domain APIs

Comments

@markt-amp
Copy link

markt-amp commented Apr 9, 2020

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

  • BankingProductLendingRate
  • BankingProductRateTier

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 #48 is adopted

This change would:

  • Allow for flexible implementations at various dollar or LVR cut-offs without repeating data
  • Removes any ambiguity regarding the rate that applies to a tier
  • Reduce returned data payload size

Change details

BankingProductLendingRate

  • Make property 'tier' mandatory
  • Remove properties 'rate' and 'comparisonRate'

BankingProductRateTier

  • Add property 'rate' - mandatory
  • Add property 'comparisionRate' - optional (assuming that the change applies to RateTier - this would cater for line of credit loans and deposits too)

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
Copy link

perlboy commented Apr 21, 2020

This looks related to #94.

@anzbankau
Copy link

@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
Copy link
Author

markt-amp commented Apr 21, 2020

Thanks for your constructive feedback @anzbankau - where the standards are now in v3 have already incorporated a repaymentType and 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
Copy link

@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
Copy link
Member

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:

  • Tiers are optional in the current standards because they are merely to qualify for the rate, not to specify the rate
  • just to emphasise the point about a sub-product > rate structure versus a rate > sub-product structure
  • The rate can't be at the tier level because it doesn't apply to one tier

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.

  • A tier name of "Loan amount" may be appropriate as a key for any equivalent tiers providing DOLLAR-based loan amount ranges for identifying the rates applicable to a certain loan amount.
  • A tier name of "Loan-to-Value Ratio" may be appropriate as a key for any equivalent tiers providing PERCENT-based LVR ranges for identifying the rates applicable to a certain Loan-to-Value Ratio (LVR).

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%

@github-project-automation github-project-automation bot moved this from Full Backlog to Done in Data Standards Maintenance Jun 30, 2023
@anzbankau
Copy link

@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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Banking Banking domain APIs
Projects
Status: Done
Development

No branches or pull requests

5 participants