diff --git a/app/models/Fairhold.test.ts b/app/models/Fairhold.test.ts index 0a2ead6..79e9f22 100644 --- a/app/models/Fairhold.test.ts +++ b/app/models/Fairhold.test.ts @@ -10,19 +10,18 @@ it("can be instantiated", () => { it("correctly calculates the fairhold formula below the threshold", () => { const fairhold = new Fairhold({ - affordability: 0.05, + affordability: 0.15, landPriceOrRent: 100, }); - expect(fairhold.discountLand).toBeCloseTo(0.6877641290737884); + expect(fairhold.discountLand).toBeCloseTo(0.535); }); it("correctly calculates the fairhold formula above the threshold", () => { const fairhold = new Fairhold({ - affordability: 0.05, + affordability: 0.5, landPriceOrRent: 100, - plateau: 3, }); - expect(fairhold.discountLand).toBeCloseTo(0.68776); + expect(fairhold.discountLand).toBeCloseTo(0.15); }); it("correctly deals with negative values of landPriceOrRent", () => { diff --git a/app/models/Fairhold.ts b/app/models/Fairhold.ts index dda48bd..e137eda 100644 --- a/app/models/Fairhold.ts +++ b/app/models/Fairhold.ts @@ -1,50 +1,27 @@ import * as math from "mathjs"; -const DEFAULT_AMPLITUDE = 0.25; -const DEFAULT_LENGTH = 1; -const DEFAULT_POSITION = 0.45; -const DEFAULT_PLATEAU = 0.15; -const DEFAULT_THRESHOLD = 0.5; +// Fairhold formula constants +const MULTIPLIER = -1.1 +const OFFSET = 0.7 +const PLATEAU = 0.15 -type ConstructorParams = Pick & - Partial< - Pick< - Fairhold, - "amplitude" | "length" | "position" | "plateau" | "threshold" - > - >; +type ConstructorParams = Pick; export class Fairhold { public affordability: number; public landPriceOrRent: number; - public amplitude: number; - public length: number; - public position: number; - public plateau: number; - public threshold: number; public discountLand: number; public discountedLandPriceOrRent: number; constructor(params: ConstructorParams) { this.affordability = params.affordability; this.landPriceOrRent = params.landPriceOrRent; - this.amplitude = params.amplitude || DEFAULT_AMPLITUDE; - this.length = params.length || DEFAULT_LENGTH; - this.position = params.position || DEFAULT_POSITION; - this.plateau = params.plateau || DEFAULT_PLATEAU; - this.threshold = params.threshold || DEFAULT_THRESHOLD; this.discountLand = this.calculateFairholdDiscount(); this.discountedLandPriceOrRent = this.calculateDiscountedPriceOrRent(); } private calculateFairholdDiscount() { - if (this.affordability > this.threshold) return this.plateau; - - const discountLand = - this.amplitude * - math.cos((2 * math.pi * this.affordability) / this.length) + - this.position; - + const discountLand = math.max(MULTIPLIER * this.affordability + OFFSET, PLATEAU) return discountLand; }