174 lines
5.8 KiB
TypeScript
174 lines
5.8 KiB
TypeScript
/**
|
|
* rMortgage Types
|
|
*
|
|
* Models a distributed mortgage where N lenders each hold $1k-$5k tranches
|
|
* of a single property, using TBFF primitives (Flow/Funnel/Outcome).
|
|
*/
|
|
|
|
// ─── Lender ──────────────────────────────────────────────
|
|
|
|
export interface Lender {
|
|
id: string
|
|
name: string
|
|
walletAddress: string
|
|
}
|
|
|
|
// ─── Tranche Transfer (secondary market) ─────────────────
|
|
|
|
export interface TrancheTransfer {
|
|
id: string
|
|
fromLenderId: string
|
|
toLenderId: string
|
|
price: number // what buyer paid
|
|
principalRemaining: number // at time of transfer
|
|
premiumPercent: number // (price - principalRemaining) / principalRemaining * 100
|
|
date: number // timestamp
|
|
}
|
|
|
|
// ─── Mortgage Tranche ────────────────────────────────────
|
|
|
|
export interface MortgageTranche {
|
|
id: string
|
|
lender: Lender
|
|
principal: number // original tranche size (e.g., 5000)
|
|
principalRemaining: number // how much principal is still owed
|
|
interestRate: number // annual rate (e.g., 0.06 for 6%)
|
|
termMonths: number
|
|
monthsElapsed: number
|
|
// Per-payment breakdown (current month)
|
|
monthlyPayment: number
|
|
monthlyPrincipal: number
|
|
monthlyInterest: number
|
|
// Cumulative
|
|
totalInterestPaid: number
|
|
totalPrincipalPaid: number
|
|
// Secondary market
|
|
transferable: boolean
|
|
listedForSale: boolean
|
|
askingPrice?: number
|
|
transferHistory: TrancheTransfer[]
|
|
// Status
|
|
status: 'active' | 'repaid'
|
|
funded: boolean // true if a lender has claimed this tranche
|
|
// Lending tier
|
|
tierLabel: string // e.g., "5yr", "10yr", etc.
|
|
// Reinvestment
|
|
reinvestmentRate?: number // if set, lender reinvests repayments at this rate
|
|
isReinvested: boolean // true if this tranche was created from reinvestment
|
|
parentTrancheId?: string // original tranche this was reinvested from
|
|
reinvestmentPool: number // accumulated returns waiting to be reinvested
|
|
}
|
|
|
|
// ─── Mortgage Simulation State ───────────────────────────
|
|
|
|
export interface MortgageState {
|
|
// Property
|
|
propertyValue: number
|
|
downPayment: number
|
|
totalPrincipal: number // propertyValue - downPayment
|
|
|
|
// Structure
|
|
trancheSize: number // default tranche (e.g., 5000)
|
|
baseInterestRate: number // e.g., 0.06
|
|
termMonths: number // e.g., 360 (30 years)
|
|
|
|
// Borrower
|
|
borrower: {
|
|
id: string
|
|
name: string
|
|
walletAddress: string
|
|
}
|
|
|
|
// All tranches
|
|
tranches: MortgageTranche[]
|
|
|
|
// Simulation
|
|
currentMonth: number
|
|
monthlyPayment: number // total monthly payment (sum of all tranches)
|
|
overpayment: number // extra per month above minimum
|
|
overpaymentTarget: 'extra_principal' | 'community_fund' | 'split'
|
|
|
|
// Aggregates
|
|
totalInterestPaid: number
|
|
totalPrincipalPaid: number
|
|
totalPrincipalRemaining: number
|
|
tranchesRepaid: number
|
|
|
|
// Overflow / Community
|
|
communityFundBalance: number
|
|
|
|
// Comparison
|
|
traditionalTotalInterest: number
|
|
traditionalMonthlyPayment: number
|
|
}
|
|
|
|
// ─── Lending Term Tiers ─────────────────────────────────
|
|
|
|
export interface LendingTier {
|
|
label: string // e.g., "5yr Short"
|
|
termYears: number // e.g., 5
|
|
rate: number // e.g., 0.035
|
|
allocation: number // fraction of total (0-1), all tiers sum to 1
|
|
}
|
|
|
|
export const DEFAULT_TIERS: LendingTier[] = [
|
|
{ label: '2yr', termYears: 2, rate: 0.025, allocation: 0.10 },
|
|
{ label: '5yr', termYears: 5, rate: 0.035, allocation: 0.20 },
|
|
{ label: '10yr', termYears: 10, rate: 0.045, allocation: 0.25 },
|
|
{ label: '15yr', termYears: 15, rate: 0.055, allocation: 0.25 },
|
|
{ label: '30yr', termYears: 30, rate: 0.065, allocation: 0.20 },
|
|
]
|
|
|
|
// ─── Simulator Controls ──────────────────────────────────
|
|
|
|
export interface MortgageSimulatorConfig {
|
|
propertyValue: number
|
|
downPaymentPercent: number
|
|
trancheSize: number
|
|
interestRate: number // as decimal (0.06) — base rate, overridden by tiers
|
|
termYears: number // max term (for the full mortgage)
|
|
overpayment: number
|
|
overpaymentTarget: 'extra_principal' | 'community_fund' | 'split'
|
|
// Rate variation: spread across tranches
|
|
rateVariation: number // e.g., 0.01 means rates vary +/- 1%
|
|
// Reinvestment: % of lenders who reinvest repayments
|
|
reinvestorPercent: number // 0-100 (default 40)
|
|
reinvestmentRates: number[] // rates at which reinvestors lend (e.g., [0.03, 0.05])
|
|
// Funding level: % of tranches that have been claimed by lenders
|
|
fundingPercent: number // 0-100 (default 85)
|
|
// Starting point
|
|
startMonth: number // skip to this month on load (e.g., 60 = 5 years)
|
|
// Lending tiers: different terms & rates
|
|
lendingTiers: LendingTier[]
|
|
useVariableTerms: boolean // false = all same term, true = use tiers
|
|
}
|
|
|
|
export const DEFAULT_CONFIG: MortgageSimulatorConfig = {
|
|
propertyValue: 500_000,
|
|
downPaymentPercent: 20,
|
|
trancheSize: 5_000,
|
|
interestRate: 0.06,
|
|
termYears: 30,
|
|
overpayment: 0,
|
|
overpaymentTarget: 'extra_principal',
|
|
rateVariation: 0,
|
|
fundingPercent: 85,
|
|
reinvestorPercent: 40,
|
|
reinvestmentRates: [0.03, 0.05],
|
|
startMonth: 60,
|
|
lendingTiers: DEFAULT_TIERS,
|
|
useVariableTerms: true,
|
|
}
|
|
|
|
// ─── Amortization Schedule Entry ─────────────────────────
|
|
|
|
export interface AmortizationEntry {
|
|
month: number
|
|
payment: number
|
|
principal: number
|
|
interest: number
|
|
balance: number
|
|
cumulativeInterest: number
|
|
cumulativePrincipal: number
|
|
}
|