-
-
Notifications
You must be signed in to change notification settings - Fork 132
Add tax_filer parameter to model income tax non-filers
#1084
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
This commit implements a new tax_filer parameter that enables modeling of income tax non-filers in OG-Core. Non-filers pay zero income tax and face zero marginal tax rates on labor and capital income, while still paying payroll taxes. Implementation: - Add tax_filer parameter to default_parameters.json (J-vector, 0-1) - Modify income_tax_liab() to scale income tax by tax_filer[j] - Modify MTR_income() to scale marginal tax rates by tax_filer[j] - Update FOC_labor() and FOC_savings() to pass j parameter Features: - Backward compatible (default: all groups file) - Handles scalar j and vector cases with proper broadcasting - Maintains consistency between ATR and MTR for non-filers - No kinks in numerical optimization (smooth within j-groups) Testing: - All 85 existing tests pass with no regressions - Full model run validates correct economic behavior - Tax revenue increases 7.98% when non-filers become filers - GDP decreases 2.54% due to tax distortions Documentation: - Add run_ogcore_nonfiler_example.py example script - Add TAX_FILER_README.md user guide - Add TAX_FILER_IMPLEMENTATION_SUMMARY.md technical summary 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
|
This PR addresses Issue #1078. |
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #1084 +/- ##
==========================================
+ Coverage 73.20% 73.23% +0.02%
==========================================
Files 21 21
Lines 5143 5178 +35
==========================================
+ Hits 3765 3792 +27
- Misses 1378 1386 +8
Flags with carried forward coverage won't be shown. Click here to find out more.
🚀 New features to boost your workflow:
|
|
I've updated this PR to:
In doing (1), I noted that the case of non-filers could be handled by setting the non-compliance rate to that group to 100%. But there may be value in carrying the two parameters because (i) one could think about non-compliance still affecting incentives (e.g., it might only apply to the ETR and not the MTR), (ii) we may want to be able to separately compare revenue lost from non-filing vs from non-compliance, and (iii) there might be better optics for certain users to avoid using the non-compliance parameter. In doing (2), it occurred to me that one might want different parameters to specify non-filing with respect to income and wealth taxes. In future commits to this branch, I'll create these two parameters. |
|
Now two parameters are added All local tests are passing with the exception of one test in The one test failure with Nothing changed with respect to this module in this PR and we've seen this happen before, so I suggest we ignore it in this case. @rickecon This PR is ready for your review. |
|
@jdebacker. This looks great. Thanks for this PR. Merging. |
Summary
This PR implements a new tax_filer parameter that enables modeling of income tax non-filers in OG-Core. This feature allows researchers to analyze filing thresholds, tax compliance policies, and the economic effects of requiring low-income households to file taxes.
Motivation
In reality, many low-income households are not required to file income tax returns due to filing thresholds (e.g., standard deduction). This PR provides the capability to model this important feature of the tax system.
Implementation Approach
After evaluating two approaches:
We selected Approach 2 because it avoids numerical kinks within j-group optimization and aligns with existing J-differentiated parameters.
Changes
Core Implementation (3 files)
ogcore/default_parameters.json(lines 4251-4278)tax_filerparameter: J-length vector of floats (0.0 to 1.0)[1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0](all groups file)tax_filer[j]= 0.0 → non-filer (no income tax, zero MTRs)tax_filer[j]= 1.0 → full filer (normal tax treatment)tax_filer[j]= 0.5 → partial filer (50% of group files)ogcore/tax.pyincome_tax_liab()(lines 378-396): Scales income tax bytax_filer[j], payroll tax unaffectedMTR_income()(lines 113-190): Added optionaljparameter, scales MTR bytax_filer[j]ogcore/household.pyFOC_labor()(line 718): PassjtoMTR_income()FOC_savings()(line 529): PassjtoMTR_income()Documentation (3 files)
examples/run_ogcore_nonfiler_example.pyj=0non-filers) vs reform (all filers)examples/TAX_FILER_README.mdTAX_FILER_IMPLEMENTATION_SUMMARY.mdKey Features
✅ Economically consistent: Both ATR and MTR are zero for non-filers
✅ Numerically robust: No kinks within j-group optimization
✅ Backward compatible: Default behavior unchanged (all groups file)
✅ Well-tested: All 85 existing tests pass with no regressions
✅ Validated: Full model runs confirm correct behavior
✅ Documented: Examples and README provided
Testing
Existing Tests
tests/test_tax.py)tests/test_household.py)Model Run Validation
Baseline:
tax_filer = [0.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0](j=0non-filers)Reform:
tax_filer = [1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0](all filers)Results when
j=0transitions from non-filer to filer:These results confirm the implementation is working correctly.
Usage Example
See
examples/run_ogcore_nonfiler_example.pyfor a complete example.Economic Interpretation
Non-filers (
tax_filer[j] = 0.0):Policy Applications:
Backward Compatibility
✅ Fully backward compatible
tax_filer = [1.0, 1.0, ...]preserves original behaviorMTR_income()defaults to NoneChecklist
🤖 Generated with https://claude.com/claude-code
Co-Authored-By: Claude Sonnet 4.5 noreply@anthropic.com