diff --git a/src/app/components/FireCalculatorForm.tsx b/src/app/components/FireCalculatorForm.tsx
index e183f6c..a7b8332 100644
--- a/src/app/components/FireCalculatorForm.tsx
+++ b/src/app/components/FireCalculatorForm.tsx
@@ -73,12 +73,16 @@ interface YearlyData {
age: number;
year: number;
balance: number;
+ untouchedBalance: number;
phase: "accumulation" | "retirement";
monthlyAllowance: number;
+ untouchedMonthlyAllowance: number;
}
interface CalculationResult {
fireNumber: number | null;
+ fireNumber4percent: number | null;
+ retirementAge4percent: number | null;
yearlyData: YearlyData[];
error?: string;
}
@@ -101,8 +105,8 @@ const tooltipRenderer = ({
return (
{`Year: ${data.year.toString()} (Age: ${data.age.toString()})`}
-
{`Balance: ${formatNumber(data.balance)}`}
-
{`Monthly allowance: ${formatNumber(data.monthlyAllowance)}`}
+
{`Balance: ${formatNumber(data.balance)}`}
+
{`Monthly allowance: ${formatNumber(data.monthlyAllowance)}`}
{`Phase: ${data.phase === "accumulation" ? "Accumulation" : "Retirement"}`}
);
@@ -113,6 +117,7 @@ const tooltipRenderer = ({
export default function FireCalculatorForm() {
const [result, setResult] = useState(null);
const irlYear = new Date().getFullYear();
+ const [showing4percent, setShowing4percent] = useState(false);
// Initialize form with default values
const form = useForm({
@@ -149,8 +154,10 @@ export default function FireCalculatorForm() {
age: age,
year: irlYear,
balance: startingCapital,
+ untouchedBalance: startingCapital,
phase: "accumulation",
- monthlyAllowance: initialMonthlyAllowance,
+ monthlyAllowance: 0,
+ untouchedMonthlyAllowance: initialMonthlyAllowance,
});
// Calculate accumulation phase (before retirement)
@@ -175,13 +182,18 @@ export default function FireCalculatorForm() {
newBalance =
previousYearData.balance * annualGrowthRate - inflatedAllowance * 12;
}
-
+ const untouchedBalance =
+ previousYearData.untouchedBalance * annualGrowthRate +
+ monthlySavings * 12;
+ const allowance = phase === "retirement" ? inflatedAllowance : 0;
yearlyData.push({
age: currentAge,
year: year,
balance: newBalance,
+ untouchedBalance: untouchedBalance,
phase: phase,
- monthlyAllowance: inflatedAllowance,
+ monthlyAllowance: allowance,
+ untouchedMonthlyAllowance: inflatedAllowance,
});
}
@@ -192,9 +204,23 @@ export default function FireCalculatorForm() {
);
const retirementData = yearlyData[retirementIndex];
+ const [fireNumber4percent, retirementAge4percent] = (() => {
+ for (const yearData of yearlyData) {
+ if (
+ yearData.untouchedBalance >
+ (yearData.untouchedMonthlyAllowance * 12) / 0.04
+ ) {
+ return [yearData.untouchedBalance, yearData.age];
+ }
+ }
+ return [0, 0];
+ })();
+
if (retirementIndex === -1 || !retirementData) {
setResult({
fireNumber: null,
+ fireNumber4percent: null,
+ retirementAge4percent: null,
error: "Could not calculate retirement data",
yearlyData: yearlyData,
});
@@ -202,6 +228,8 @@ export default function FireCalculatorForm() {
// Set the result
setResult({
fireNumber: retirementData.balance,
+ fireNumber4percent: fireNumber4percent,
+ retirementAge4percent: retirementAge4percent,
yearlyData: yearlyData,
});
}
@@ -430,10 +458,10 @@ export default function FireCalculatorForm() {
offset: -10,
}}
/>
- {/* Left Y axis */}
+ {/* Right Y axis */}
{
if (value >= 1000000) {
return `${(value / 1000000).toPrecision(3)}M`;
@@ -448,10 +476,10 @@ export default function FireCalculatorForm() {
}}
width={30}
/>
- {/* Right Y axis */}
+ {/* Left Y axis */}
{
if (value >= 1000000) {
return `${(value / 1000000).toPrecision(3)}M`;
@@ -473,12 +501,12 @@ export default function FireCalculatorForm() {
>
@@ -487,34 +515,46 @@ export default function FireCalculatorForm() {
type="monotone"
dataKey="balance"
name="balance"
- stroke="var(--chart-1)"
+ stroke="var(--color-orange-500)"
fill="url(#fillBalance)"
fillOpacity={0.9}
activeDot={{ r: 6 }}
- yAxisId={"left"}
+ yAxisId={"right"}
stackId={"a"}
/>
{result.fireNumber && (
+ )}
+ {result.fireNumber4percent && showing4percent && (
+
)}
+ {result.retirementAge4percent && showing4percent && (
+
+ )}
)}
+ {result && (
+
+ )}
@@ -579,6 +644,40 @@ export default function FireCalculatorForm() {
+ {showing4percent && (
+ <>
+
+
+ 4%-Rule FIRE Number
+
+ Capital needed for 4% of it to be greater than your
+ yearly allowance
+
+
+
+
+ {formatNumber(result.fireNumber4percent)}
+
+
+
+
+
+
+ 4%-Rule Retirement Duration
+
+ Years to enjoy your financial independence if you follow
+ the 4% rule
+
+
+
+
+ {form.getValues("lifeExpectancy") -
+ (result.retirementAge4percent ?? 0)}
+
+
+
+ >
+ )}
>
)}