From d7028f5b7407b58b1be718b3008a2280ab450988 Mon Sep 17 00:00:00 2001 From: zzhhaa Date: Fri, 30 Aug 2024 15:37:16 +0100 Subject: [PATCH 1/4] chore: passed forecastParameters to tenure classes --- app/models/tenure/FairholdLandPurchase.ts | 8 ++++---- app/models/tenure/FairholdLandRent.ts | 11 ++++------- app/models/tenure/MarketPurchase.ts | 17 +++++++++++------ app/models/tenure/MarketRent.ts | 20 +++++++++++--------- 4 files changed, 30 insertions(+), 26 deletions(-) diff --git a/app/models/tenure/FairholdLandPurchase.ts b/app/models/tenure/FairholdLandPurchase.ts index 011a95cb..44ffce48 100644 --- a/app/models/tenure/FairholdLandPurchase.ts +++ b/app/models/tenure/FairholdLandPurchase.ts @@ -1,23 +1,23 @@ import { Fairhold } from "../Fairhold"; import { Mortgage } from "../Mortgage"; +import { ForecastParameters } from '../ForecastParameters'; interface FairholdLandPurchaseParams { newBuildPrice: number; depreciatedBuildPrice: number; - constructionPriceGrowthPerYear: number; - yearsForecast: number; - maintenanceCostPercentage: number; - incomeGrowthPerYear: number; affordability: number; fairhold: Fairhold; + forecastParameters: ForecastParameters; } export class FairholdLandPurchase { + params: FairholdLandPurchaseParams; discountedLandPrice: number; discountedLandMortgage: Mortgage; depreciatedHouseMortgage: Mortgage; constructor(params: FairholdLandPurchaseParams) { + this.params = params; this.discountedLandPrice = params.fairhold.discountedLandPriceOrRent; this.discountedLandMortgage = new Mortgage({ diff --git a/app/models/tenure/FairholdLandRent.ts b/app/models/tenure/FairholdLandRent.ts index b5faaa95..6fd05837 100644 --- a/app/models/tenure/FairholdLandRent.ts +++ b/app/models/tenure/FairholdLandRent.ts @@ -1,6 +1,7 @@ import { MONTHS_PER_YEAR } from "../constants"; import { Fairhold } from "../Fairhold"; import { Mortgage } from "../Mortgage"; +import { ForecastParameters } from '../ForecastParameters'; interface FairholdLandRentParams { averageRentYearly: number; @@ -9,23 +10,19 @@ interface FairholdLandRentParams { depreciatedBuildPrice: number; landPrice: number; incomeYearly: number; - affordabilityThresholdIncomePercentage: number; - propertyPriceGrowthPerYear: number; - constructionPriceGrowthPerYear: number; - yearsForecast: number; - maintenanceCostPercentage: number; - incomeGrowthPerYear: number; - rentGrowthPerYear: number; fairhold: Fairhold; + forecastParameters: ForecastParameters; } export class FairholdLandRent { + params: FairholdLandRentParams; /** Mortgage on the depreciated value of the house */ depreciatedHouseMortgage: Mortgage; /** discounted value of the monthly land rent according to fairhold */ discountedLandRentMonthly: number; constructor(params: FairholdLandRentParams) { + this.params = params; this.depreciatedHouseMortgage = new Mortgage({ propertyValue: params.depreciatedBuildPrice, }); diff --git a/app/models/tenure/MarketPurchase.ts b/app/models/tenure/MarketPurchase.ts index b8004966..6332a55f 100644 --- a/app/models/tenure/MarketPurchase.ts +++ b/app/models/tenure/MarketPurchase.ts @@ -1,24 +1,29 @@ import { Mortgage } from "../Mortgage"; import { MONTHS_PER_YEAR } from "../constants"; +import { ForecastParameters, DEFAULT_FORECAST_PARAMETERS } from '../ForecastParameters'; -interface ConstructorParams { +interface MarketPurchaseParams { averagePrice: number; newBuildPrice: number; depreciatedBuildPrice: number; landPrice: number; incomeYearly: number; - propertyPriceGrowthPerYear: number; - constructionPriceGrowthPerYear: number; - yearsForecast: number; maintenanceCostPercentage: number; + forecastParameters: ForecastParameters; } export class MarketPurchase { + params: MarketPurchaseParams; public affordability: number; public houseMortgage: Mortgage; public landMortgage: Mortgage; - constructor(params: ConstructorParams) { + constructor(params: MarketPurchaseParams) { + this.params = params; + this.params.forecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, + ...params.forecastParameters + }; this.houseMortgage = new Mortgage({ propertyValue: params.newBuildPrice, }); @@ -30,7 +35,7 @@ export class MarketPurchase { this.affordability = this.calculateAffordability(params); } - private calculateAffordability({ incomeYearly }: ConstructorParams) { + private calculateAffordability({ incomeYearly }: MarketPurchaseParams) { const affordability = (this.landMortgage.monthlyPayment * MONTHS_PER_YEAR + this.houseMortgage.monthlyPayment * MONTHS_PER_YEAR) / diff --git a/app/models/tenure/MarketRent.ts b/app/models/tenure/MarketRent.ts index c20b75b9..64e963d1 100644 --- a/app/models/tenure/MarketRent.ts +++ b/app/models/tenure/MarketRent.ts @@ -1,26 +1,28 @@ import { MONTHS_PER_YEAR } from "../constants"; - -interface ConstructorParams { +import { ForecastParameters, DEFAULT_FORECAST_PARAMETERS } from '../ForecastParameters'; +interface MarketRentParams { averageRentYearly: number; averagePrice: number; newBuildPrice: number; depreciatedBuildPrice: number; landPrice: number; incomeYearly: number; - propertyPriceGrowthPerYear: number; - constructionPriceGrowthPerYear: number; - yearsForecast: number; - maintenanceCostPercentage: number; - rentGrowthPerYear: number; + forecastParameters: ForecastParameters; } export class MarketRent { + params: MarketRentParams; public affordability: number; public averageRentMonthly: number; public averageRentLandMonthly: number; public averageRentHouseMonthly: number; - constructor(params: ConstructorParams) { + constructor(params: MarketRentParams) { + this.params = params; + this.params.forecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, + ...params.forecastParameters + }; const { averageRentMonthly, averageRentLandMonthly, @@ -39,7 +41,7 @@ export class MarketRent { averagePrice, incomeYearly, averageRentYearly, - }: ConstructorParams) { + }: MarketRentParams) { const averageRentMonthly = averageRentYearly / MONTHS_PER_YEAR; const landToTotalRatio = landPrice / averagePrice; const averageRentLandMonthly = averageRentMonthly * landToTotalRatio; From 2ce245a9afa9d016f131b70234cacd025aa496aa Mon Sep 17 00:00:00 2001 From: zzhhaa Date: Fri, 30 Aug 2024 15:46:59 +0100 Subject: [PATCH 2/4] fix: removed extra property MarketPurchaseParam property --- app/models/tenure/MarketPurchase.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/app/models/tenure/MarketPurchase.ts b/app/models/tenure/MarketPurchase.ts index 6332a55f..e5a0864c 100644 --- a/app/models/tenure/MarketPurchase.ts +++ b/app/models/tenure/MarketPurchase.ts @@ -8,7 +8,6 @@ interface MarketPurchaseParams { depreciatedBuildPrice: number; landPrice: number; incomeYearly: number; - maintenanceCostPercentage: number; forecastParameters: ForecastParameters; } From e30e4c37b2d1fe276278d795a16ed0b193314d58 Mon Sep 17 00:00:00 2001 From: zzhhaa Date: Fri, 30 Aug 2024 15:57:36 +0100 Subject: [PATCH 3/4] feat: pass forecastParameters to tenure tests --- app/models/tenure/FairholdLandPurchase.test.ts | 8 ++++++-- app/models/tenure/FairholdLandRent.test.ts | 7 ++++++- app/models/tenure/MarketPurchase.test.ts | 17 ++++------------- app/models/tenure/MarketRent.test.ts | 18 ++++-------------- 4 files changed, 20 insertions(+), 30 deletions(-) diff --git a/app/models/tenure/FairholdLandPurchase.test.ts b/app/models/tenure/FairholdLandPurchase.test.ts index ec72dd2e..58372edc 100644 --- a/app/models/tenure/FairholdLandPurchase.test.ts +++ b/app/models/tenure/FairholdLandPurchase.test.ts @@ -1,22 +1,26 @@ import { Fairhold } from "../Fairhold"; -import { DEFAULT_FORECAST_PARAMETERS } from "../ForecastParameters"; +import { DEFAULT_FORECAST_PARAMETERS, ForecastParameters } from "../ForecastParameters"; import { FairholdLandPurchase } from "./FairholdLandPurchase"; let tenureFairholdLandPurchase: FairholdLandPurchase; beforeEach(() => { + const forecastParameters: ForecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, + }; + tenureFairholdLandPurchase = new FairholdLandPurchase({ //incomeYearly: 45816, //averagePrice: 218091.58, newBuildPrice: 186560, depreciatedBuildPrice: 110717.45, //landPrice: 31531.579, - ...DEFAULT_FORECAST_PARAMETERS, affordability: 0.2, fairhold: new Fairhold({ affordability: 0.2, landPriceOrRent: 31531.579, }), + forecastParameters: forecastParameters, }); }); diff --git a/app/models/tenure/FairholdLandRent.test.ts b/app/models/tenure/FairholdLandRent.test.ts index ef152896..be335eee 100644 --- a/app/models/tenure/FairholdLandRent.test.ts +++ b/app/models/tenure/FairholdLandRent.test.ts @@ -1,10 +1,14 @@ import { Fairhold } from "../Fairhold"; -import { DEFAULT_FORECAST_PARAMETERS } from "../ForecastParameters"; +import { DEFAULT_FORECAST_PARAMETERS, ForecastParameters } from "../ForecastParameters"; import { FairholdLandRent } from "./FairholdLandRent"; let tenureFairholdLandRent: FairholdLandRent; beforeEach(() => { + const forecastParameters: ForecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, + }; + tenureFairholdLandRent = new FairholdLandRent({ averageRentYearly: 20000, incomeYearly: 45816, @@ -17,6 +21,7 @@ beforeEach(() => { affordability: 0.2, landPriceOrRent: 20000, }), + forecastParameters: forecastParameters, }); }); diff --git a/app/models/tenure/MarketPurchase.test.ts b/app/models/tenure/MarketPurchase.test.ts index f1e5885f..f01121b6 100644 --- a/app/models/tenure/MarketPurchase.test.ts +++ b/app/models/tenure/MarketPurchase.test.ts @@ -1,16 +1,11 @@ import { MarketPurchase } from "./MarketPurchase"; +import { DEFAULT_FORECAST_PARAMETERS, ForecastParameters } from "../ForecastParameters"; let tenureMarketPurchase: MarketPurchase; beforeEach(() => { - const forecastParameters = { - maintenanceCostPercentage: 0.0125, // percentage maintenance cost - incomeGrowthPerYear: 0.04, // 4% income growth per year - constructionPriceGrowthPerYear: 0.025, // 2.5% - rentGrowthPerYear: 0.03, // 3% - propertyPriceGrowthPerYear: 0.05, // 5% - yearsForecast: 40, // 40 years - affordabilityThresholdIncomePercentage: 0.35, // percentage of imcome to afford rent or purchase + const forecastParameters: ForecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, }; tenureMarketPurchase = new MarketPurchase({ @@ -19,11 +14,7 @@ beforeEach(() => { newBuildPrice: 186560, depreciatedBuildPrice: 110717.45, landPrice: 31531.579, - propertyPriceGrowthPerYear: forecastParameters.propertyPriceGrowthPerYear, - constructionPriceGrowthPerYear: - forecastParameters.constructionPriceGrowthPerYear, - yearsForecast: forecastParameters.yearsForecast, - maintenanceCostPercentage: forecastParameters.maintenanceCostPercentage, + forecastParameters: forecastParameters, }); }); diff --git a/app/models/tenure/MarketRent.test.ts b/app/models/tenure/MarketRent.test.ts index b77bad18..41869a9d 100644 --- a/app/models/tenure/MarketRent.test.ts +++ b/app/models/tenure/MarketRent.test.ts @@ -1,16 +1,11 @@ import { MarketRent } from "./MarketRent"; +import { DEFAULT_FORECAST_PARAMETERS, ForecastParameters } from "../ForecastParameters"; let tenureMarketRent: MarketRent; beforeEach(() => { - const forecastParameters = { - maintenanceCostPercentage: 0.0125, // percentage maintenance cost - incomeGrowthPerYear: 0.04, // 4% income growth per year - constructionPriceGrowthPerYear: 0.025, // 2.5% - rentGrowthPerYear: 0.03, // 3% - propertyPriceGrowthPerYear: 0.05, // 5% - yearsForecast: 40, // 40 years - affordabilityThresholdIncomePercentage: 0.35, // percentage of imcome to afford rent or purchase + const forecastParameters: ForecastParameters = { + ...DEFAULT_FORECAST_PARAMETERS, }; tenureMarketRent = new MarketRent({ @@ -20,12 +15,7 @@ beforeEach(() => { newBuildPrice: 186560, depreciatedBuildPrice: 110717.45, landPrice: 31531.579, - propertyPriceGrowthPerYear: forecastParameters.propertyPriceGrowthPerYear, - constructionPriceGrowthPerYear: - forecastParameters.constructionPriceGrowthPerYear, - yearsForecast: forecastParameters.yearsForecast, - maintenanceCostPercentage: forecastParameters.maintenanceCostPercentage, - rentGrowthPerYear: forecastParameters.rentGrowthPerYear, + forecastParameters: forecastParameters, }); }); From 660e4353fe9e749758a96f556dbffac6deba3239 Mon Sep 17 00:00:00 2001 From: zzhhaa Date: Fri, 30 Aug 2024 15:58:11 +0100 Subject: [PATCH 4/4] feat: passed forecastParameters to Household too --- app/models/Household.ts | 36 ++++-------------------------------- 1 file changed, 4 insertions(+), 32 deletions(-) diff --git a/app/models/Household.ts b/app/models/Household.ts index 8c4ce7d7..f91f50fb 100644 --- a/app/models/Household.ts +++ b/app/models/Household.ts @@ -58,13 +58,7 @@ export class Household { newBuildPrice: this.property.newBuildPrice, depreciatedBuildPrice: this.property.depreciatedBuildPrice, landPrice: this.property.landPrice, - propertyPriceGrowthPerYear: - this.forecastParameters.propertyPriceGrowthPerYear, - constructionPriceGrowthPerYear: - this.forecastParameters.constructionPriceGrowthPerYear, - yearsForecast: this.forecastParameters.yearsForecast, - maintenanceCostPercentage: - this.forecastParameters.maintenanceCostPercentage, + forecastParameters: this.forecastParameters, }); const marketRent = new MarketRent({ @@ -74,14 +68,7 @@ export class Household { depreciatedBuildPrice: this.property.depreciatedBuildPrice, landPrice: this.property.landPrice, incomeYearly: this.incomeYearly, - propertyPriceGrowthPerYear: - this.forecastParameters.propertyPriceGrowthPerYear, - constructionPriceGrowthPerYear: - this.forecastParameters.constructionPriceGrowthPerYear, - yearsForecast: this.forecastParameters.yearsForecast, - maintenanceCostPercentage: - this.forecastParameters.maintenanceCostPercentage, - rentGrowthPerYear: this.forecastParameters.rentGrowthPerYear, + forecastParameters: this.forecastParameters, }); const socialRent = new SocialRent({ @@ -95,12 +82,7 @@ export class Household { const fairholdLandPurchase = new FairholdLandPurchase({ newBuildPrice: this.property.newBuildPrice, depreciatedBuildPrice: this.property.depreciatedBuildPrice, - constructionPriceGrowthPerYear: - this.forecastParameters.constructionPriceGrowthPerYear, - yearsForecast: this.forecastParameters.yearsForecast, - maintenanceCostPercentage: - this.forecastParameters.maintenanceCostPercentage, - incomeGrowthPerYear: this.forecastParameters.incomeGrowthPerYear, + forecastParameters: this.forecastParameters, affordability: marketPurchase.affordability, fairhold: new Fairhold({ affordability: marketPurchase.affordability, @@ -115,17 +97,7 @@ export class Household { depreciatedBuildPrice: this.property.depreciatedBuildPrice, // depreciated building price landPrice: this.property.landPrice, // land price incomeYearly: this.incomeYearly, // income - affordabilityThresholdIncomePercentage: - this.forecastParameters.affordabilityThresholdIncomePercentage, // affordability threshold percentage - propertyPriceGrowthPerYear: - this.forecastParameters.propertyPriceGrowthPerYear, // property price growth per year - constructionPriceGrowthPerYear: - this.forecastParameters.constructionPriceGrowthPerYear, // construction price growth per year - yearsForecast: this.forecastParameters.yearsForecast, // years forecast - maintenanceCostPercentage: - this.forecastParameters.maintenanceCostPercentage, // maintenance cost percentage - incomeGrowthPerYear: this.forecastParameters.incomeGrowthPerYear, // income growth per year - rentGrowthPerYear: this.forecastParameters.rentGrowthPerYear, // rent growth per year + forecastParameters: this.forecastParameters, fairhold: new Fairhold({ affordability: marketRent.affordability,