Skip to content

TaxSolver/TaxSolver

Repository files navigation

TaxSolver: A Design Tool for Optimal Income Tax Reform

Python 3.11+ License: MIT arXiv DOI

TaxSolver is a constrained optimization-based tool that enables policymakers to design optimal income tax reforms by focusing on the desired outcomes of a reform in conjunction with fiscal guarantees that a reform has to abide by rather than ad-hoc rule adjustments. Read our accompanying paper Implementing Optimal Taxation: A Constrained Optimization Framework for Tax Reform.

Abstract

While optimal taxation theory provides clear prescriptions for tax design, translating these insights into actual tax codes remains difficult. Existing work largely offers theoretical characterizations of optimal systems, while practical implementation methods are scarce. Bridging this gap involves designing tax rules that meet theoretical goals, while accommodating administrative, distributional, and other practical constraints that arise in real-world reform. We develop a method casting tax reform as a constrained optimization problem by parametrizing the entire income tax code as a set of piecewise linear functions mapping tax-relevant inputs into liabilities and marginal rates. This allows users to impose constraints on marginal rate schedules, limits on income swings, and objectives like revenue neutrality, efficiency, simplicity, or distributional fairness that reflect both theoretical and practical considerations. The framework is computationally tractable for complex tax codes and flexible enough to accommodate diverse constraints, welfare objectives and behavioral responses. Whereas existing tools are typically used for ex-post `what-if' analysis of specific reforms, our framework explicitly incorporates real-world reform constraints and jointly optimizes across the full tax code. We illustrate the framework in several simulated settings, including a detailed reconstruction of the Dutch income tax system. For the Dutch case, we generate a family of reforms that smooth existing spikes in marginal tax rates to any desired cap, reduce the number of rules, and impose hard caps on income losses households can experience from the reform. We also introduce \texttt{TaxSolver}, an open-source package, allowing policymakers and researchers to implement and extend the framework.

Key Features & Evidence for Practice

  1. Mathematical Foundation: Most tax codes can be defined as a simple system of equations that make it possible to solve tax reform as (linear) optimization problem.

  2. Policy-Aligned Design: Linear optimization allows policymakers to formulate both hard guarantees that the reform has to adhere to, as well as objectives that are maximized within these set constraints. This makes optimization a practical tool that is aligned with the reality of policy work.

  3. Systematic Approach: Our approach allows for a tax reform process that does not consist of ad-hoc tweaking of existing rules but reasons over the entire system and returns an optimal solution.

  4. Real-World Application: We illustrate our approach by reforming various example systems, as well as a system representing the complexity and scale of a real-world income tax code.

Installation

Prerequisites

  • Python 3.11 or higher
  • pip package manager

Install from source

pip install git+https://github.com/Tax-Lab/TaxSolver.git

Install for development

git clone https://github.com/Tax-Lab/TaxSolver.git
cd TaxSolver
pip install -e .

Quick Start

import os
import TaxSolver as tx
from TaxSolver.constraints.income_constraint import IncomeConstraint
from TaxSolver.constraints.budget_constraint import BudgetConstraint
from TaxSolver.data_wrangling.data_loader import DataLoader
from TaxSolver.data_wrangling.bracket_input import BracketInput
from TaxSolver.objective import BudgetObjective

# Load taxpayer data from a system with 6 brackets into TaxSolver format.
# In the bundled example file the after-tax income column is named "outcome_1".
dl = DataLoader(path=os.path.join("data", "example", "simple_simul_1000.xlsx"), 
                income_before_tax="income_before_tax", 
                income_after_tax="outcome_1")

# Initialize the solver
tax_solver = tx.TaxSolver(dl.households)

# Split input along inflection points to construct brackets
BracketInput.add_split_variables_to_solver(
    tx=tax_solver,
    target_var="income_before_tax",
    inflection_points=[0, 25_000, 50_000, 75_000, 100_000, 125_000, 150_000],
    group_vars=["k_everybody"]
)

# Define solver variables for the optimization
income_tax = tx.BracketRule(
    name="income_before_tax_k_everybody",
    var_name="income_before_tax",
    k_group_var="k_everybody",
    ub=1,
    lb=0,
)

# Add solver variables to the solver
tax_solver.add_rules([income_tax])

# Define constraints for the optimization
income_constraint = IncomeConstraint(0.0001, dl.households.values()) # No one can experience income shocks of more than 0.01%
budget_constraint = BudgetConstraint(
    "All_households", dl.households.values(), 0, 0 # The total tax revenue cannot decrease or increase
)

# Add constraints to the solver
tax_solver.add_constraints([income_constraint, budget_constraint])

# Add an objective to the optimization (required before solving)
tax_solver.add_objective(BudgetObjective(budget_constraint))

# Solve the optimization problem
tax_solver.solve()

# View results
print(tax_solver.rules_and_rates_table())

Documentation

  • Tutorial: See notebooks/example_notebook.ipynb and notebooks/readme_notebook.ipynb for walkthroughs.
  • Methods: See paper/methods.md for the methodology underlying TaxSolver.

Project Structure

TaxSolver/
├── src/TaxSolver/           # Main package
│   ├── tax_solver.py        # Core solver orchestration
│   ├── rule.py              # Tax/benefit rule definitions
│   ├── objective.py         # Optimization objectives
│   ├── backend/             # Solver backends (CVXPY/HiGHS, Gurobi)
│   ├── constraints/         # Constraint definitions
│   ├── data_wrangling/      # Data loading and bracket inputs
│   └── population/          # Household and person models
├── paper/                   # Academic paper and examples
├── tests/                   # Test suite
├── notebooks/               # Notebooks
└── data/                    # Example datasets

Core Concepts

  • Tax Rules: Define how income is taxed (flat, progressive, benefits)
  • Constraints: Hard limits the reform must satisfy (budget neutrality, income bounds)
  • Objectives: Goals to optimize (redistribution, efficiency, simplicity)
  • Households: Units of analysis with income, demographics, and tax liabilities

Citation

If you use TaxSolver in your research, please cite:

@article{taxsolver2025,
  title={Implementing Optimal Taxation: A Constrained Optimization Framework for Tax Reform},
  author={Verhagen, M.D. and Schellekens, M. and Garstka, M.},
  year={2025},
  eprint={2508.03708},
  archivePrefix={arXiv},
  note={Software available at: https://github.com/Tax-Lab/TaxSolver.git}
}

License

This project is licensed under the MIT License - see the LICENSE file for details.

Contributing

We welcome contributions! Please see our Contributing Guidelines for details on how to submit pull requests, report issues, and suggest improvements.

Support

  • Issues: Report bugs and request features on GitHub Issues
  • Documentation: Full documentation available at [project website] TODO
  • Academic Paper: [Link to published paper] TODO

Authors

Mark Verhagen Menno Schellekens Michael Garstka

About

A methodology to design optimal income tax reform

Resources

License

Contributing

Stars

4 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors