Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,7 @@ Company Data

<img src="store-sales/screenshot.png" width="49%"></img>
<img src="corporate-travel/screenshot.png" width="49%"></img>

Inflation Adjusting

`inflation-adjusting/main.py` sketches CPI-adjusted comparisons for policy limits like FDIC deposit insurance coverage and retirement contribution caps.
24 changes: 24 additions & 0 deletions inflation-adjusting/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Inflation Adjusting

Small starter dataset and script for comparing nominal policy limits in current dollars. This covers the two examples from issue #24:

- FDIC standard maximum deposit insurance limits
- 401(k) elective deferral and IRA contribution limits

The script uses the `cpi` package from `palewire/cpi`, which adjusts U.S. dollars with CPI-U data.

## Sources

- FDIC, `Options for Deposit Insurance Reform`, Section 3, Table 3.1: standard maximum deposit insurance amount history.
- IRS retirement topics and COLA pages for 2023-2026 401(k), 457(b), SIMPLE, and IRA limits.
- `palewire/cpi` documentation for `cpi.inflate(amount, year, to=...)`.

## Usage

```console
python -m pip install cpi
python -m cpi update
python inflation-adjusting/main.py --to-year 2026
```

Use `--category fdic` or `--category retirement` to print one group.
113 changes: 113 additions & 0 deletions inflation-adjusting/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
"""Print nominal policy limits and CPI-adjusted comparisons."""

from __future__ import annotations

import argparse
import csv
import sys
from dataclasses import dataclass
from typing import Iterable


@dataclass(frozen=True)
class Limit:
category: str
name: str
year: int
amount: int
note: str


# FDIC source: Options for Deposit Insurance Reform, Section 3, Table 3.1.
FDIC_LIMITS = (
Limit("fdic", "temporary deposit insurance limit", 1934, 2500, "temporary 1934 limit"),
Limit("fdic", "standard deposit insurance limit", 1934, 5000, "permanent 1934 limit"),
Limit("fdic", "standard deposit insurance limit", 1950, 10000, ""),
Limit("fdic", "standard deposit insurance limit", 1966, 15000, ""),
Limit("fdic", "standard deposit insurance limit", 1969, 20000, ""),
Limit("fdic", "standard deposit insurance limit", 1974, 40000, ""),
Limit("fdic", "standard deposit insurance limit", 1980, 100000, ""),
Limit("fdic", "standard deposit insurance limit", 2008, 250000, ""),
)


# IRS retirement topics/COLA pages for recent contribution limits.
RETIREMENT_LIMITS = (
Limit("retirement", "401(k), 403(b), and 457(b) elective deferral", 2023, 22500, ""),
Limit("retirement", "401(k), 403(b), and 457(b) elective deferral", 2024, 23000, ""),
Limit("retirement", "401(k), 403(b), and 457(b) elective deferral", 2025, 23500, ""),
Limit("retirement", "401(k), 403(b), and 457(b) elective deferral", 2026, 24500, ""),
Limit("retirement", "traditional and Roth IRA contribution", 2023, 6500, ""),
Limit("retirement", "traditional and Roth IRA contribution", 2024, 7000, ""),
Limit("retirement", "traditional and Roth IRA contribution", 2025, 7000, ""),
Limit("retirement", "traditional and Roth IRA contribution", 2026, 7500, ""),
Limit("retirement", "SIMPLE plan elective deferral", 2023, 15500, ""),
Limit("retirement", "SIMPLE plan elective deferral", 2024, 16000, ""),
Limit("retirement", "SIMPLE plan elective deferral", 2025, 16500, ""),
Limit("retirement", "SIMPLE plan elective deferral", 2026, 17000, ""),
)


def selected_limits(category: str) -> Iterable[Limit]:
if category == "fdic":
return FDIC_LIMITS
if category == "retirement":
return RETIREMENT_LIMITS
return (*FDIC_LIMITS, *RETIREMENT_LIMITS)


def inflate(amount: int, year: int, to_year: int | None) -> float:
try:
import cpi
except ImportError as exc:
raise SystemExit(
"Install CPI data support first: python -m pip install cpi"
) from exc

if to_year is None:
return cpi.inflate(amount, year)
return cpi.inflate(amount, year, to=to_year)


def parse_args(argv: list[str] | None = None) -> argparse.Namespace:
parser = argparse.ArgumentParser(
description="Print CPI-adjusted FDIC and retirement policy limits."
)
parser.add_argument(
"--category",
choices=("all", "fdic", "retirement"),
default="all",
help="Limit output to one dataset.",
)
parser.add_argument(
"--to-year",
type=int,
default=None,
help="Adjustment year. Defaults to the latest CPI year available.",
)
return parser.parse_args(argv)


def main(argv: list[str] | None = None) -> int:
args = parse_args(argv)
writer = csv.writer(sys.stdout)
writer.writerow(
("category", "name", "year", "nominal_amount", "to_year", "adjusted_amount", "note")
)
for item in selected_limits(args.category):
writer.writerow(
(
item.category,
item.name,
item.year,
item.amount,
args.to_year or "latest",
round(inflate(item.amount, item.year, args.to_year), 2),
item.note,
)
)
return 0


if __name__ == "__main__":
raise SystemExit(main())