# Zip Estate Calculators — Agent Skill (Zero API Calls)

> This is a **static file** — fetching it is a free, unlimited GET request.
> It contains everything needed to use Zip Estate's calculators **without calling any API**:
> input schemas, defaults, URL parameter keys, and the **exact algorithms as runnable JavaScript**.
>
> **How to use:** run the algorithm locally (code interpreter preferred) with the user's inputs,
> then build a shareable link from the URL-key table so the user can open the interactive calculator.

Site: https://zip-estate.com

## Shared helpers

```js
const round2 = (v) => Math.round(v * 100) / 100;

function monthlyMortgage(principal, annualRate, termYears) {
  if (principal <= 0) return 0;
  const r = annualRate / 100 / 12, n = termYears * 12;
  if (r === 0) return principal / n;
  return (principal * r * Math.pow(1 + r, n)) / (Math.pow(1 + r, n) - 1);
}
```

---

## 1. Real Estate Investment Calculator

Interactive URL: `https://zip-estate.com/calculators/real-estate`

Analyzes rental property investments via the 4 engines of profit: Cash Flow, Appreciation, Principal Paydown, Below-Market Equity.

### Inputs

| Input | Default | Range | Unit | URL key |
|-------|---------|-------|------|---------|
| purchasePrice (market value) | 100000 | 50000–300000 | $ | `pp` |
| belowMarketPercent | 0 | 0–40 | % | see note |
| monthlyRent | 1500 | 0–3000 | $ | `mr` |
| appreciationRate | 4 | 0–10 | % | `ar` |
| rentGrowthRate | 3 | 0–6 | % | `rg` |
| downPaymentPercent | 25 | 0–100 | % | `dp` |
| closingCosts | 8000 | 0–25000 | $ | `cc` |
| vacancyRate | 8 | 0–20 | % | `vr` |
| insuranceTaxMonthly | 200 | 0–500 | $/mo | `it` |
| propertyManagementPercent | 10 | 0–15 | % | `pm` |
| maintenancePercent | 0.5 | 0–5 | % | `mt` |
| mortgageRate | 6.5 | 3–15 | % | `mi` |
| mortgageTermYears | 30 | 5–35 | years | `my` |

**URL key note:** the interactive UI uses `pvm` (price vs market %, where `pvm = 100 - belowMarketPercent`).
Legacy `bm` (discount %) is also accepted. Example — 30% below market: `?pvm=70`.

**Share URL example:** `https://zip-estate.com/calculators/real-estate?pp=85000&mr=1100&pvm=70&dp=25`
(Only include params that differ from defaults.)

### Algorithm

```js
function computeRealEstate(i) {
  // Derived values
  const price = i.purchasePrice * (1 - i.belowMarketPercent / 100); // actual purchase price
  const instantEquity = i.purchasePrice - price;
  const downPayment = price * (i.downPaymentPercent / 100);
  const loanAmount = price - downPayment;
  const mortgage = monthlyMortgage(loanAmount, i.mortgageRate, i.mortgageTermYears);
  const totalCashRequired = downPayment + i.closingCosts;

  // Monthly projection over the full mortgage term
  const months = i.mortgageTermYears * 12;
  const mApp = Math.pow(1 + i.appreciationRate / 100, 1 / 12);
  const mRate = i.mortgageRate / 100 / 12;
  let rent = i.monthlyRent, value = i.purchasePrice, balance = loanAmount;
  let cumCashFlow = -i.closingCosts;
  const milestones = {};

  for (let m = 0; m <= months; m++) {
    if (m > 0 && balance > 0) {
      const interest = balance * mRate;
      balance = Math.max(0, balance - Math.min(mortgage - interest, balance));
    }
    if (m > 0) {
      value *= mApp;
      if (m % 12 === 0) rent *= 1 + i.rentGrowthRate / 100;
    }
    const expenses = rent * (i.vacancyRate / 100) + i.insuranceTaxMonthly
      + rent * (i.propertyManagementPercent / 100) + rent * (i.maintenancePercent / 100);
    const cashFlow = rent - expenses - (balance > 0 ? mortgage : 0);
    cumCashFlow += cashFlow;
    if (m % 12 === 0 && m > 0) {
      milestones[m / 12] = {
        propertyValue: round2(value), mortgageBalance: round2(balance),
        equity: round2(value - balance), monthlyCashFlow: round2(cashFlow),
        cumulativeCashFlow: round2(cumCashFlow), netWorth: round2(value - balance + cumCashFlow),
      };
    }
  }

  const finalNetWorth = value - balance + cumCashFlow;
  const avgAnnualROI = totalCashRequired > 0
    ? ((finalNetWorth - totalCashRequired) / totalCashRequired / i.mortgageTermYears) * 100 : 0;
  const cagr = totalCashRequired > 0 && finalNetWorth > 0
    ? (Math.pow(finalNetWorth / totalCashRequired, 1 / i.mortgageTermYears) - 1) * 100 : 0;

  // Year-1 four engines
  let y1Paydown = 0, b = loanAmount;
  for (let m = 0; m < 12 && b > 0; m++) {
    const interest = b * mRate;
    const principal = Math.min(mortgage - interest, b);
    y1Paydown += principal; b -= principal;
  }
  const y1Expenses = i.monthlyRent * (i.vacancyRate / 100) + i.insuranceTaxMonthly
    + i.monthlyRent * (i.propertyManagementPercent / 100)
    + (i.monthlyRent * 12 * (i.maintenancePercent / 100)) / 12;
  const y1CashFlow = (i.monthlyRent - y1Expenses - mortgage) * 12;
  const y1Appreciation = i.purchasePrice * (i.appreciationRate / 100);
  const y1TotalReturn = y1CashFlow + y1Appreciation + y1Paydown + instantEquity;
  const y1ROI = totalCashRequired > 0 ? (y1TotalReturn / totalCashRequired) * 100 : 0;

  return {
    derived: { price, instantEquity, downPayment, loanAmount, monthlyMortgage: round2(mortgage), totalCashRequired },
    year1: { cashFlow: round2(y1CashFlow), appreciation: round2(y1Appreciation),
             principalPaydown: round2(y1Paydown), instantEquity, roi: round2(y1ROI) },
    milestones, averageAnnualROI: round2(avgAnnualROI), compoundAnnualROI: round2(cagr),
  };
}
```

---

## 2. Compound Interest Calculator

Interactive URL: `https://zip-estate.com/calculators/compound`

| Input | Default | Range | URL key |
|-------|---------|-------|---------|
| initialInvestment | 10000 | 0–500000 | `ii` |
| monthlyContribution | 500 | 0–10000 | `mc` |
| annualRate (%) | 8 | 0–20 | `ar` |
| years | 30 | 1–50 | `yr` |

```js
function computeCompound(i) {
  const r = i.annualRate / 100 / 12;
  let balance = i.initialInvestment, contributed = i.initialInvestment;
  for (let m = 1; m <= i.years * 12; m++) {
    balance = balance * (1 + r) + i.monthlyContribution;
    contributed += i.monthlyContribution;
  }
  const interest = Math.max(0, balance - contributed);
  return { finalValue: Math.round(balance), totalContributions: Math.round(contributed),
           totalInterest: Math.round(interest), interestRatio: round2(interest / balance * 100) };
}
```

---

## 3. Doubling Calculator

Interactive URL: `https://zip-estate.com/calculators/doubling`

| Input | Default | Range | URL key |
|-------|---------|-------|---------|
| annualRate (%) | 8 | 0.5–25 | `r` |

```js
function computeDoubling(i) {
  const ruleOf72 = 72 / i.annualRate;
  const exactYears = Math.log(2) / Math.log(1 + i.annualRate / 100);
  return { ruleOf72: round2(ruleOf72), exactYears: round2(exactYears) };
}
```

---

## 4. Flip Calculator

Interactive URL: `https://zip-estate.com/calculators/flip`

Compares All Cash vs Hard Money Loan scenarios.

| Input | Default | URL key |
|-------|---------|---------|
| askingPrice | 115000 | `ap` |
| purchasePrice | 105000 | `pp` |
| closingCostFixed | 1500 | `ccf` |
| closingCostPercent | 0 | `ccp` |
| rehabCost | 25000 | `rc` |
| stagingCost | 0 | `sc` |
| contingencyPercent | 10 | `cg` |
| projectMonths | 9 | `pm` |
| holdingCostMonthly | 375 | `hc` |
| monthlyRent | 0 | `mr` |
| estimatedARV | 165000 | `arv` |
| saleClosingPercent | 8 | `scp` |
| loanPercent | 65 | `lp` |
| loanInterestRate | 13 | `lr` |
| loanPointsPercent | 2 | `lpt` |
| loanOriginationFixed | 0 | `lof` |
| investorProfitShare | 50 | `ips` |

```js
function computeFlipScenario(i, useLoan) {
  const closing = i.closingCostFixed + (i.closingCostPercent / 100) * i.purchasePrice;
  const totalPurchase = i.purchasePrice + closing;
  const totalRehab = i.rehabCost + i.stagingCost + (i.contingencyPercent / 100) * i.rehabCost;
  const totalHolding = i.holdingCostMonthly * i.projectMonths - i.monthlyRent * i.projectMonths;
  const totalProject = totalPurchase + totalRehab + totalHolding;

  let loanAmount = 0, totalLoanCost = 0;
  if (useLoan) {
    loanAmount = (i.loanPercent / 100) * (i.purchasePrice + i.rehabCost);
    totalLoanCost = loanAmount * (i.loanInterestRate / 100 / 12) * i.projectMonths
      + (i.loanPointsPercent / 100) * loanAmount + (i.loanOriginationFixed || 0);
  }
  const cashRequired = totalProject - loanAmount + totalLoanCost;
  const netSale = i.estimatedARV - (i.saleClosingPercent / 100) * i.estimatedARV;
  const netProfit = netSale - totalProject - totalLoanCost;
  const projectCOC = cashRequired > 0 ? netProfit / cashRequired : 0;
  return {
    cashRequired: round2(cashRequired), netProfit: round2(netProfit),
    projectCOC: round2(projectCOC * 100),
    annualCOC: round2(projectCOC * (12 / i.projectMonths) * 100),
    investorProfit: round2(netProfit * i.investorProfitShare / 100),
  };
}
// Run twice: computeFlipScenario(i, false) → All Cash; computeFlipScenario(i, true) → Hard Money
```

---

## 5. Leverage Power Calculator

Interactive URL: `https://zip-estate.com/calculators/leverage`

| Input | Default | URL key |
|-------|---------|---------|
| loanAmount | 100000 | `la` |
| loanTermYears | 10 | `lt` |
| loanRate (%) | 8 | `lr` |
| investmentRate (%) | 8 | `ir` |
| inflationRate (%) | 3 | `inf` |
| graceMonths | 12 | `gm` |

```js
function computeLeverage(i) {
  const mLoan = i.loanRate / 100 / 12, mInv = i.investmentRate / 100 / 12;
  const months = i.loanTermYears * 12, amortMonths = months - i.graceMonths;
  const payment = mLoan > 0
    ? (i.loanAmount * mLoan * Math.pow(1 + mLoan, amortMonths)) / (Math.pow(1 + mLoan, amortMonths) - 1)
    : i.loanAmount / amortMonths;
  const gracePayment = i.loanAmount * mLoan;

  let portfolio = i.loanAmount, balance = i.loanAmount, totalPaid = 0, totalInterest = 0;
  for (let m = 1; m <= months; m++) {
    portfolio *= 1 + mInv;
    if (m <= i.graceMonths) { totalPaid += gracePayment; totalInterest += gracePayment; }
    else {
      const interest = balance * mLoan;
      const principal = Math.min(payment - interest, balance);
      totalPaid += payment; totalInterest += interest;
      balance = Math.max(0, balance - principal);
    }
  }
  const netProfit = portfolio - totalPaid;
  const realNetProfit = netProfit / Math.pow(1 + i.inflationRate / 100, i.loanTermYears);
  return { monthlyPayment: round2(payment), portfolioFinalValue: round2(portfolio),
           totalPaid: round2(totalPaid), totalInterest: round2(totalInterest),
           netProfit: round2(netProfit), realNetProfit: round2(realNetProfit) };
}
```

---

## 6. Pension Planning Calculator

Interactive URL: `https://zip-estate.com/calculators/pension`

| Input | Default | URL key |
|-------|---------|---------|
| currentAge | 30 | `ca` |
| retirementAge | 67 | `ra` |
| lifeExpectancy | 90 | `le` |
| currentSavings | 50000 | `cs` |
| monthlySavings | 1500 | `ms` |
| annualReturn (%) | 7 | `ar` |
| inflationRate (%) | 2.5 | `inf` |
| desiredIncome (monthly $) | 5000 | `di` |
| socialSecurity (monthly $) | 1500 | `ss` |

```js
function computePension(i) {
  const realReturn = (1 + i.annualReturn / 100) / (1 + i.inflationRate / 100) - 1;
  const mReal = realReturn / 12;
  const yearsToRet = Math.max(0, i.retirementAge - i.currentAge);
  const yearsInRet = Math.max(0, i.lifeExpectancy - i.retirementAge);

  let balance = i.currentSavings;
  for (let m = 0; m < yearsToRet * 12; m++) balance = balance * (1 + mReal) + i.monthlySavings;
  const savingsAtRetirement = balance;

  const gap = Math.max(0, i.desiredIncome - i.socialSecurity);
  const n = yearsInRet * 12;
  const totalNeeded = mReal > 0 ? gap * ((1 - Math.pow(1 + mReal, -n)) / mReal) : gap * n;

  return { savingsAtRetirement: round2(savingsAtRetirement), totalNeeded: round2(totalNeeded),
           surplus: round2(savingsAtRetirement - totalNeeded),
           isOnTrack: savingsAtRetirement >= totalNeeded };
}
```

---

## 7. Tax Efficiency Calculator

Interactive URL: `https://zip-estate.com/calculators/tax`

| Input | Default | URL key |
|-------|---------|---------|
| initialInvestment | 50000 | `ii` |
| annualReturn (%) | 8 | `ar` |
| years | 30 | `yr` |
| incomeTaxRate (%) | 30 | `itr` |
| capitalGainsTaxRate (%) | 25 | `cg` |
| dividendYield (%) | 2 | `dy` |
| annualContribution | 6000 | `ac` |

```js
function computeTax(i) {
  const rate = i.annualReturn / 100, div = i.dividendYield / 100;
  const growth = rate - div, capTax = i.capitalGainsTaxRate / 100, incTax = i.incomeTaxRate / 100;
  let taxable = i.initialInvestment, basis = i.initialInvestment;
  let deferred = i.initialInvestment, free = i.initialInvestment;
  for (let y = 1; y <= i.years; y++) {
    const dividends = taxable * div;
    taxable = taxable * (1 + growth) + dividends - dividends * capTax + i.annualContribution;
    basis += i.annualContribution;
    deferred = deferred * (1 + rate) + i.annualContribution;
    free = free * (1 + rate) + i.annualContribution;
  }
  const gain = Math.max(0, taxable - basis);
  return { taxable: round2(taxable - gain * capTax),
           taxDeferred: round2(deferred * (1 - incTax)), taxFree: round2(free) };
}
```

---

## 8. Portfolio Loan vs Sell

Interactive URL: `https://zip-estate.com/calculators/loan-vs-sell`

| Input | Default | URL key |
|-------|---------|---------|
| portfolioValue | 500000 | `pv` |
| amountNeeded | 100000 | `an` |
| costBasis | 200000 | `cb` |
| expectedReturn (%) | 8 | `er` |
| loanInterestRate (%) | 5.5 | `lr` |
| loanTerm (years) | 5 | `lt` |
| capitalGainsTaxRate (%) | 25 | `cg` |

```js
function computeLoanVsSell(i) {
  const rate = i.expectedReturn / 100, loanRate = i.loanInterestRate / 100, capTax = i.capitalGainsTaxRate / 100;
  const gainPerDollar = Math.max(0, (i.portfolioValue - i.costBasis) / i.portfolioValue);
  const taxPerDollar = gainPerDollar * capTax;
  const amountToSell = Math.min(i.amountNeeded / (1 - taxPerDollar), i.portfolioValue);
  const taxOnSale = amountToSell * taxPerDollar;

  const mRate = loanRate / 12, n = i.loanTerm * 12;
  const payment = mRate > 0
    ? i.amountNeeded * (mRate * Math.pow(1 + mRate, n)) / (Math.pow(1 + mRate, n) - 1)
    : i.amountNeeded / n;

  const years = Math.max(i.loanTerm, 10);
  let sellPortfolio = i.portfolioValue - amountToSell, borrowPortfolio = i.portfolioValue;
  let loanBalance = i.amountNeeded, breakEvenYear = null;
  for (let y = 1; y <= years; y++) {
    sellPortfolio *= 1 + rate; borrowPortfolio *= 1 + rate;
    if (y <= i.loanTerm && loanBalance > 0) {
      const interest = loanBalance * loanRate;
      loanBalance = Math.max(0, loanBalance - Math.min(loanBalance, payment * 12 - interest));
    }
    if (breakEvenYear === null && borrowPortfolio - loanBalance > sellPortfolio) breakEvenYear = y;
  }
  const finalBorrow = borrowPortfolio - loanBalance;
  return { taxOnSale: round2(taxOnSale), totalInterestPaid: round2(payment * n - i.amountNeeded),
           finalSell: round2(sellPortfolio), finalBorrow: round2(finalBorrow),
           borrowIsBetter: finalBorrow > sellPortfolio, breakEvenYear };
}
```

---

## 9. CarWise Calculator

Interactive URL: `https://zip-estate.com/calculators/carwise`

Interactive tool using localStorage state — no algorithm published. Direct users to the URL.

---

## Recommended agent workflow

1. Fetch this file once (free static GET) and cache it.
2. Run the relevant algorithm locally with the user's inputs (use defaults for anything omitted; clamp to ranges).
3. Build a shareable link: interactive URL + `?` + URL keys for every non-default input.
4. Present results **and** the link so the user can explore interactively.

*Fallback only:* if you cannot execute code, `GET https://zip-estate.com/functions/calculatorApi?action=compute&calculator=<id>&<input>=<value>` returns computed results — but prefer local computation.
