Created
March 6, 2026 02:18
-
-
Save MaxGhenis/36bb820e621a3b77d9389c9a83df78e9 to your computer and use it in GitHub Desktop.
WATCA zero-tax threshold correction: divide by 2.333 not 1.333
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| { | |
| "cells": [ | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "# WATCA zero-tax thresholds: corrected calculation\n", | |
| "\n", | |
| "The Working Americans' Tax Cut Act creates a cost-of-living exemption that phases out between the exemption amount and 175% of the exemption amount. This means the phase-out range is 75% of the exemption, giving an implicit phase-out rate of 1/0.75 = **133%** per dollar of AGI.\n", | |
| "\n", | |
| "But when computing the AGI at which taxable income first becomes positive, we need to account for **both** effects of each additional dollar of AGI above the phase-out start:\n", | |
| "1. **+$1.00** directly to AGI (increases taxable income)\n", | |
| "2. **-$1.333** reduction in exemption (also increases taxable income)\n", | |
| "\n", | |
| "Combined: each $1 of AGI increases taxable income by **$2.333**, not $1.333.\n", | |
| "\n", | |
| "So the correct formula is:\n", | |
| "\n", | |
| "$$\\text{zero\\_tax\\_threshold} = \\text{phaseout\\_start} + \\frac{\\text{standard\\_deduction}}{1 + 1.333} = \\text{phaseout\\_start} + \\frac{\\text{standard\\_deduction}}{2.333}$$" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2026-03-06T01:34:09.226412Z", | |
| "iopub.status.busy": "2026-03-06T01:34:09.226338Z", | |
| "iopub.status.idle": "2026-03-06T01:34:09.501481Z", | |
| "shell.execute_reply": "2026-03-06T01:34:09.501096Z" | |
| } | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>Filing status</th>\n", | |
| " <th>Exemption amount</th>\n", | |
| " <th>Standard deduction</th>\n", | |
| " <th>Wrong threshold (/ 1.333)</th>\n", | |
| " <th>Correct threshold (/ 2.333)</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>Single</td>\n", | |
| " <td>$46,000</td>\n", | |
| " <td>$16,100</td>\n", | |
| " <td>$58,075</td>\n", | |
| " <td>$52,900</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>Head of household</td>\n", | |
| " <td>$64,400</td>\n", | |
| " <td>$24,150</td>\n", | |
| " <td>$82,512</td>\n", | |
| " <td>$74,750</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>Joint</td>\n", | |
| " <td>$92,000</td>\n", | |
| " <td>$32,200</td>\n", | |
| " <td>$116,150</td>\n", | |
| " <td>$105,800</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " Filing status Exemption amount Standard deduction \\\n", | |
| "0 Single $46,000 $16,100 \n", | |
| "1 Head of household $64,400 $24,150 \n", | |
| "2 Joint $92,000 $32,200 \n", | |
| "\n", | |
| " Wrong threshold (/ 1.333) Correct threshold (/ 2.333) \n", | |
| "0 $58,075 $52,900 \n", | |
| "1 $82,512 $74,750 \n", | |
| "2 $116,150 $105,800 " | |
| ] | |
| }, | |
| "execution_count": 1, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "import pandas as pd\n", | |
| "import numpy as np\n", | |
| "\n", | |
| "# WATCA parameters\n", | |
| "amounts = {\"Single\": 46_000, \"Head of household\": 64_400, \"Joint\": 92_000}\n", | |
| "phase_out_multiple = 1.75\n", | |
| "\n", | |
| "# 2026 projected standard deductions (TCJA extended under OBBBA)\n", | |
| "std_ded = {\"Single\": 16_100, \"Head of household\": 24_150, \"Joint\": 32_200}\n", | |
| "\n", | |
| "rows = []\n", | |
| "for fs in amounts:\n", | |
| " amt = amounts[fs]\n", | |
| " sd = std_ded[fs]\n", | |
| " po_range = amt * 0.75\n", | |
| " po_rate = amt / po_range # 1.333\n", | |
| " combined_rate = 1 + po_rate # 2.333\n", | |
| "\n", | |
| " # Incorrect formula (divides by phase-out rate only)\n", | |
| " wrong = amt + sd / po_rate\n", | |
| " # Correct formula (divides by combined rate)\n", | |
| " correct = amt + sd / combined_rate\n", | |
| "\n", | |
| " rows.append({\n", | |
| " \"Filing status\": fs,\n", | |
| " \"Exemption amount\": f\"${amt:,.0f}\",\n", | |
| " \"Standard deduction\": f\"${sd:,.0f}\",\n", | |
| " \"Wrong threshold (/ 1.333)\": f\"${wrong:,.0f}\",\n", | |
| " \"Correct threshold (/ 2.333)\": f\"${correct:,.0f}\",\n", | |
| " })\n", | |
| "\n", | |
| "pd.DataFrame(rows)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "## Verification\n", | |
| "\n", | |
| "At the correct threshold, taxable income should be exactly zero. At the wrong threshold, it's positive (meaning the filer already owes tax)." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2026-03-06T01:34:09.514629Z", | |
| "iopub.status.busy": "2026-03-06T01:34:09.514523Z", | |
| "iopub.status.idle": "2026-03-06T01:34:09.518456Z", | |
| "shell.execute_reply": "2026-03-06T01:34:09.518130Z" | |
| } | |
| }, | |
| "outputs": [ | |
| { | |
| "data": { | |
| "text/html": [ | |
| "<div>\n", | |
| "<style scoped>\n", | |
| " .dataframe tbody tr th:only-of-type {\n", | |
| " vertical-align: middle;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe tbody tr th {\n", | |
| " vertical-align: top;\n", | |
| " }\n", | |
| "\n", | |
| " .dataframe thead th {\n", | |
| " text-align: right;\n", | |
| " }\n", | |
| "</style>\n", | |
| "<table border=\"1\" class=\"dataframe\">\n", | |
| " <thead>\n", | |
| " <tr style=\"text-align: right;\">\n", | |
| " <th></th>\n", | |
| " <th>Filing status</th>\n", | |
| " <th>AGI at wrong threshold</th>\n", | |
| " <th>TI at wrong threshold</th>\n", | |
| " <th>AGI at correct threshold</th>\n", | |
| " <th>TI at correct threshold</th>\n", | |
| " </tr>\n", | |
| " </thead>\n", | |
| " <tbody>\n", | |
| " <tr>\n", | |
| " <th>0</th>\n", | |
| " <td>Single</td>\n", | |
| " <td>$58,075</td>\n", | |
| " <td>$12,075</td>\n", | |
| " <td>$52,900</td>\n", | |
| " <td>$0</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>1</th>\n", | |
| " <td>Head of household</td>\n", | |
| " <td>$82,512</td>\n", | |
| " <td>$18,112</td>\n", | |
| " <td>$74,750</td>\n", | |
| " <td>$0</td>\n", | |
| " </tr>\n", | |
| " <tr>\n", | |
| " <th>2</th>\n", | |
| " <td>Joint</td>\n", | |
| " <td>$116,150</td>\n", | |
| " <td>$24,150</td>\n", | |
| " <td>$105,800</td>\n", | |
| " <td>$0</td>\n", | |
| " </tr>\n", | |
| " </tbody>\n", | |
| "</table>\n", | |
| "</div>" | |
| ], | |
| "text/plain": [ | |
| " Filing status AGI at wrong threshold TI at wrong threshold \\\n", | |
| "0 Single $58,075 $12,075 \n", | |
| "1 Head of household $82,512 $18,112 \n", | |
| "2 Joint $116,150 $24,150 \n", | |
| "\n", | |
| " AGI at correct threshold TI at correct threshold \n", | |
| "0 $52,900 $0 \n", | |
| "1 $74,750 $0 \n", | |
| "2 $105,800 $0 " | |
| ] | |
| }, | |
| "execution_count": 2, | |
| "metadata": {}, | |
| "output_type": "execute_result" | |
| } | |
| ], | |
| "source": [ | |
| "def taxable_income(agi, exemption_amount, standard_deduction):\n", | |
| " \"\"\"Compute taxable income under WATCA.\"\"\"\n", | |
| " po_end = exemption_amount * phase_out_multiple\n", | |
| " po_range = po_end - exemption_amount\n", | |
| " fraction = np.clip((po_end - agi) / po_range, 0, 1)\n", | |
| " exemption = exemption_amount * fraction\n", | |
| " return max(0, agi - standard_deduction - exemption)\n", | |
| "\n", | |
| "\n", | |
| "rows = []\n", | |
| "for fs in amounts:\n", | |
| " amt = amounts[fs]\n", | |
| " sd = std_ded[fs]\n", | |
| " po_rate = amt / (amt * 0.75)\n", | |
| " wrong = amt + sd / po_rate\n", | |
| " correct = amt + sd / (1 + po_rate)\n", | |
| "\n", | |
| " rows.append({\n", | |
| " \"Filing status\": fs,\n", | |
| " \"AGI at wrong threshold\": f\"${wrong:,.0f}\",\n", | |
| " \"TI at wrong threshold\": f\"${taxable_income(wrong, amt, sd):,.0f}\",\n", | |
| " \"AGI at correct threshold\": f\"${correct:,.0f}\",\n", | |
| " \"TI at correct threshold\": f\"${taxable_income(correct, amt, sd):,.0f}\",\n", | |
| " })\n", | |
| "\n", | |
| "pd.DataFrame(rows)" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "metadata": {}, | |
| "source": [ | |
| "The wrong thresholds produce **positive** taxable income (the filer already owes tax at that AGI), while the correct thresholds produce exactly $0.\n", | |
| "\n", | |
| "## Intuition\n", | |
| "\n", | |
| "The error comes from only considering the exemption shrinkage ($1.333/dollar) while forgetting that the additional AGI itself adds to taxable income ($1.00/dollar). The standard deduction buffer erodes at the **sum** of these rates: $2.333 per dollar, so it runs out ~43% sooner than the incorrect formula predicts." | |
| ] | |
| } | |
| ], | |
| "metadata": { | |
| "kernelspec": { | |
| "display_name": "Python 3", | |
| "language": "python", | |
| "name": "python3" | |
| }, | |
| "language_info": { | |
| "codemirror_mode": { | |
| "name": "ipython", | |
| "version": 3 | |
| }, | |
| "file_extension": ".py", | |
| "mimetype": "text/x-python", | |
| "name": "python", | |
| "nbconvert_exporter": "python", | |
| "pygments_lexer": "ipython3", | |
| "version": "3.14.0" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 4 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment