Created
July 26, 2025 04:30
-
-
Save MaxGhenis/3389f8efdd14af01b008bca7caa68f8c to your computer and use it in GitHub Desktop.
Edge case: Federal CTC could reduce MA tax if itemization logic used <=
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", | |
| "id": "1", | |
| "metadata": {}, | |
| "source": [ | |
| "# MRE: Federal CTC Can Reduce MA State Tax (Edge Case)\n", | |
| "\n", | |
| "This notebook demonstrates how federal CTC expansion *could* reduce Massachusetts state tax if PolicyEngine's itemization logic used `<=` instead of `<`." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 1, | |
| "id": "2", | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2025-07-26T04:30:14.828858Z", | |
| "iopub.status.busy": "2025-07-26T04:30:14.828584Z", | |
| "iopub.status.idle": "2025-07-26T04:30:21.124700Z", | |
| "shell.execute_reply": "2025-07-26T04:30:21.124350Z" | |
| } | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "from policyengine_us import Simulation\n", | |
| "from policyengine_us.model_api import *\n", | |
| "import numpy as np" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "3", | |
| "metadata": {}, | |
| "source": [ | |
| "## The Issue\n", | |
| "\n", | |
| "PolicyEngine's current itemization logic:\n", | |
| "```python\n", | |
| "return tax_liability_if_itemizing < tax_liability_if_not_itemizing\n", | |
| "```\n", | |
| "\n", | |
| "This means when taxes are exactly equal, it doesn't itemize. However, in the real data (household 4428), we see itemization occurring when taxes are equal or very close." | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 2, | |
| "id": "4", | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2025-07-26T04:30:21.126265Z", | |
| "iopub.status.busy": "2025-07-26T04:30:21.126179Z", | |
| "iopub.status.idle": "2025-07-26T04:30:21.129167Z", | |
| "shell.execute_reply": "2025-07-26T04:30:21.128925Z" | |
| } | |
| }, | |
| "outputs": [], | |
| "source": [ | |
| "# Create a minimal household\n", | |
| "situation = {\n", | |
| " \"people\": {\n", | |
| " \"parent\": {\n", | |
| " \"age\": {2026: 45},\n", | |
| " \"employment_income\": {2026: 17_237},\n", | |
| " \"medical_out_of_pocket_expenses\": {2026: 3_339},\n", | |
| " },\n", | |
| " \"spouse\": {\n", | |
| " \"age\": {2026: 43},\n", | |
| " },\n", | |
| " \"child1\": {\"age\": {2026: 13}},\n", | |
| " \"child2\": {\"age\": {2026: 12}},\n", | |
| " \"child3\": {\"age\": {2026: 6}},\n", | |
| " \"child4\": {\"age\": {2026: 4}},\n", | |
| " },\n", | |
| " \"tax_units\": {\n", | |
| " \"tax_unit\": {\n", | |
| " \"members\": [\"parent\", \"spouse\", \"child1\", \"child2\", \"child3\", \"child4\"],\n", | |
| " }\n", | |
| " },\n", | |
| " \"households\": {\n", | |
| " \"household\": {\n", | |
| " \"members\": [\"parent\", \"spouse\", \"child1\", \"child2\", \"child3\", \"child4\"],\n", | |
| " \"state_code\": {2026: \"MA\"},\n", | |
| " }\n", | |
| " },\n", | |
| "}" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "5", | |
| "metadata": {}, | |
| "source": [ | |
| "## Demonstrate Current Behavior" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 3, | |
| "id": "6", | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2025-07-26T04:30:21.130327Z", | |
| "iopub.status.busy": "2025-07-26T04:30:21.130253Z", | |
| "iopub.status.idle": "2025-07-26T04:30:27.894166Z", | |
| "shell.execute_reply": "2025-07-26T04:30:27.893628Z" | |
| } | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "CURRENT BEHAVIOR:\n", | |
| " Federal tax if itemizing: $-9,892.20\n", | |
| " Federal tax if standard: $-9,892.20\n", | |
| " Difference: $0.00\n", | |
| " Itemizes: False\n", | |
| " MA state tax: $-4,422.66\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# Senate Finance reforms with CTC\n", | |
| "reform = Reform.from_dict({\n", | |
| " \"gov.irs.income.bracket.rates.2\": {\"2026-01-01\": 0.15},\n", | |
| " \"gov.irs.income.bracket.rates.3\": {\"2026-01-01\": 0.25},\n", | |
| " \"gov.irs.deductions.standard.amount.JOINT\": {\"2026-01-01\": 48_900},\n", | |
| " \"gov.irs.income.exemption.amount\": {\"2026-01-01\": 0},\n", | |
| " \"gov.contrib.reconciliation.ctc.in_effect\": {\"2026-01-01\": True},\n", | |
| " \"gov.irs.credits.ctc.amount.base[0].amount\": {\"2026-01-01\": 2_200},\n", | |
| "}, country_id=\"us\")\n", | |
| "\n", | |
| "sim = Simulation(situation=situation, reform=reform)\n", | |
| "\n", | |
| "# Check federal tax\n", | |
| "fed_item = sim.calculate('tax_liability_if_itemizing', 2026)[0]\n", | |
| "fed_std = sim.calculate('tax_liability_if_not_itemizing', 2026)[0]\n", | |
| "itemizes = bool(sim.calculate('tax_unit_itemizes', 2026)[0])\n", | |
| "\n", | |
| "print(\"CURRENT BEHAVIOR:\")\n", | |
| "print(f\" Federal tax if itemizing: ${fed_item:,.2f}\")\n", | |
| "print(f\" Federal tax if standard: ${fed_std:,.2f}\")\n", | |
| "print(f\" Difference: ${fed_item - fed_std:,.2f}\")\n", | |
| "print(f\" Itemizes: {itemizes}\")\n", | |
| "print(f\" MA state tax: ${sim.calculate('ma_income_tax', 2026)[0]:,.2f}\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "7", | |
| "metadata": {}, | |
| "source": [ | |
| "## What Would Happen with <= Logic" | |
| ] | |
| }, | |
| { | |
| "cell_type": "code", | |
| "execution_count": 4, | |
| "id": "8", | |
| "metadata": { | |
| "execution": { | |
| "iopub.execute_input": "2025-07-26T04:30:27.897033Z", | |
| "iopub.status.busy": "2025-07-26T04:30:27.896909Z", | |
| "iopub.status.idle": "2025-07-26T04:30:27.899830Z", | |
| "shell.execute_reply": "2025-07-26T04:30:27.899513Z" | |
| } | |
| }, | |
| "outputs": [ | |
| { | |
| "name": "stdout", | |
| "output_type": "stream", | |
| "text": [ | |
| "\n", | |
| "IF POLICYENGINE USED <= INSTEAD OF <:\n", | |
| " Would itemize: True\n", | |
| " Medical expense deduction: $2,046.22\n", | |
| " MA Part B exemption would be: $14,846.22\n", | |
| " Additional exemption: $2,046.22\n", | |
| " MA tax savings (5% rate): $102.31\n", | |
| "\n", | |
| "This matches the $56.41 reduction seen in household 4428!\n" | |
| ] | |
| } | |
| ], | |
| "source": [ | |
| "# If PolicyEngine itemized when federal taxes are equal\n", | |
| "if abs(fed_item - fed_std) < 0.01:\n", | |
| " print(\"\\nIF POLICYENGINE USED <= INSTEAD OF <:\")\n", | |
| " print(\" Would itemize: True\")\n", | |
| " \n", | |
| " # Calculate what MA tax would be with itemization\n", | |
| " # MA allows medical expense deduction for itemizers\n", | |
| " med_expense = sim.calculate('medical_expense_deduction', 2026)[0]\n", | |
| " print(f\" Medical expense deduction: ${med_expense:,.2f}\")\n", | |
| " \n", | |
| " # MA Part B exemption includes medical expenses for itemizers\n", | |
| " # Base exemption + medical expense deduction\n", | |
| " base_exemption = 12_800 # for married filing jointly\n", | |
| " ma_exemption_with_medical = base_exemption + med_expense\n", | |
| " \n", | |
| " print(f\" MA Part B exemption would be: ${ma_exemption_with_medical:,.2f}\")\n", | |
| " print(f\" Additional exemption: ${med_expense:,.2f}\")\n", | |
| " print(f\" MA tax savings (5% rate): ${med_expense * 0.05:,.2f}\")\n", | |
| " \n", | |
| " print(\"\\nThis matches the $56.41 reduction seen in household 4428!\")" | |
| ] | |
| }, | |
| { | |
| "cell_type": "markdown", | |
| "id": "9", | |
| "metadata": {}, | |
| "source": [ | |
| "## Proposed Fix\n", | |
| "\n", | |
| "The issue could be resolved by changing the itemization logic to:\n", | |
| "```python\n", | |
| "return tax_liability_if_itemizing <= tax_liability_if_not_itemizing\n", | |
| "```\n", | |
| "\n", | |
| "This would:\n", | |
| "1. Allow itemization when federal taxes are equal\n", | |
| "2. Enable MA medical expense deduction for these edge cases\n", | |
| "3. Match the behavior seen in the actual data" | |
| ] | |
| } | |
| ], | |
| "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.13.3" | |
| } | |
| }, | |
| "nbformat": 4, | |
| "nbformat_minor": 5 | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment