Models


Behavioral-Responses

Partial-equilibrium behavioral-responses module that works with Tax-Calculator

Behavioral-Responses, which is part of the Policy Simulation Library (PSL) collection of USA tax models, estimates partial-equilibrium behavioral responses to changes in the US federal individual income and payroll tax system as simulated by Tax-Calculator. It provides two ways of doing this: (1) the response function, which contains higher-level logic that supports the Tax-Brain "Partial Equilibrium Simulation" capability and requires specification of only the elasticities, and (2) the quantity_response function, which contains lower-level logic that requires specification of the quantity whose response is to be estimated, requires specification of the marginal tax rates and elasticities to be used in the response calculation, and allows the response estimation to be conducted by subgroup with different elasticities for each subgroup.

Maintainers
  • Matt Jensen

Code repository

User documentation

Contributor documentation

Link to webapp

Cost-of-Capital-Calculator

Evaluates the effect of US federal taxes on businesses' investment incentives

Cost-of-Capital-Calculator is a model that can be used to evaluate the effect of US federal taxes on the investment incentives of corporate and non-corporate businesses. Specifically, Cost-of-Capital-Calculator uses data on the business assets and financial policy, as well as microdata on individual tax filers, to compute marginal effective tax rates on new investments. In modeling the effects of changes to the individual income tax code, Cost-of-Capital-Calculator works with Tax-Calculator, another open source model of US federal tax policy. Cost-of-Capital-Calculator is written in Python, an interpreted language that can execute on Windows, Mac, or Linux.

Maintainers

Code repository

User documentation

Link to webapp

microdf

microdf is a Python package for analyzing economic microdata as pandas DataFrames, with special functions for Tax-Calculator.

OG-USA

Overlapping-Generations Model for Evaluating Fiscal Policy in the United States

OG-USA is an overlapping-generations (OG) model of the economy of the United States (USA) that allows for dynamic general equilibrium analysis of federal tax policy. The model output focuses changes in macroeconomic aggregates (GDP, investment, consumption), wages, interest rates, and the stream of tax revenues over time. Regularly updated documentation of the model theory--its output, and solution method--and the Python API is available here.

Maintainers

Code repository

User documentation

Contributor documentation

ParamTools

Library for parameter processing and validation with a focus on computational modeling projects

Define, update, and validate your model's parameters.

Install using pip:

pip install paramtools

Install using conda:

conda install -c conda-forge paramtools

Usage

Subclass paramtools.Parameters and define your model's parameters:

```python import paramtools

class Params(paramtools.Parameters): defaults = { "schema": { "labels": { "date": { "type": "date", "validators": { "range": { "min": "2020-01-01", "max": "2021-01-01", "step": {"months": 1} } } } }, }, "a": { "title": "A", "type": "int", "value": [ {"date": "2020-01-01", "value": 2}, {"date": "2020-10-01", "value": 8}, ], "validators": { "range" : { "min": 0, "max": "b" } } }, "b": { "title": "B", "type": "float", "value": [{"date": "2020-01-01", "value": 10.5}] } } ```

Access parameter values

Access values using .sel:

```python params = Params()

params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 2},   {'date': datetime.date(2020, 10, 1), 'value': 8}, ]) 

Look up parameter values using a pandas-like api:

```python from datetime import date

result = params.sel["a"]["date"] == date(2020, 1, 1) result ```

QueryResult([   {'date': datetime.date(2020, 1, 1), 'value': 2} ]) 

python result.isel[0]["value"]

2 

Adjust and validate parameter values

Add a new value:

```python params.adjust({"a": [{"date": "2020-11-01", "value": 22}]})

params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 2},   {'date': datetime.date(2020, 10, 1), 'value': 8},   {'date': datetime.date(2020, 11, 1), 'value': 22}, ]) 

Update an existing value:

```python params.adjust({"a": [{"date": "2020-01-01", "value": 3}]})

params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 3},   {'date': datetime.date(2020, 10, 1), 'value': 8},   {'date': datetime.date(2020, 11, 1), 'value': 22}, ]) 

Update all values:

```python params.adjust({"a": 7})

params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 7},   {'date': datetime.date(2020, 10, 1), 'value': 7},   {'date': datetime.date(2020, 11, 1), 'value': 7}, ]) 

Errors on values that are out of range:

python params.adjust({"a": -1})

    ---------------------------------------------------------------------------  ValidationError                           Traceback (most recent call last)  <ipython-input-8-f8f1b7f6cd9a> in <module>     ----> 1 params.adjust({"a": -1})   ~/Paramtools/paramtools/parameters.py in adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, clobber)     253             least one existing value item's corresponding label values.     254         """     --> 255         return self._adjust(     256             params_or_path,     257             ignore_warnings=ignore_warnings,   ~/Paramtools/paramtools/parameters.py in _adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, is_deserialized, clobber)     371             not ignore_warnings and has_warnings     372         ):     --> 373             raise self.validation_error     374     375         # Update attrs for params that were adjusted.   ValidationError: {     "errors": {         "a": [             "a -1 < min 0 "         ]     } } 

```python params = Params()

params.adjust({"a": [{"date": "2020-01-01", "value": 11}]}) ```

    ---------------------------------------------------------------------------  ValidationError                           Traceback (most recent call last)  <ipython-input-9-cc8a21f044d8> in <module>       1 params = Params()       2     ----> 3 params.adjust({"a": [{"date": "2020-01-01", "value": 11}]})   ~/Paramtools/paramtools/parameters.py in adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, clobber)     253             least one existing value item's corresponding label values.     254         """     --> 255         return self._adjust(     256             params_or_path,     257             ignore_warnings=ignore_warnings,   ~/Paramtools/paramtools/parameters.py in _adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, is_deserialized, clobber)     371             not ignore_warnings and has_warnings     372         ):     --> 373             raise self.validation_error     374     375         # Update attrs for params that were adjusted.   ValidationError: {     "errors": {         "a": [             "a[date=2020-01-01] 11 > max 10.5 b[date=2020-01-01]"         ]     } } 

Errors on invalid values:

```python params = Params()

params.adjust({"b": "abc"}) ```

    ---------------------------------------------------------------------------  ValidationError                           Traceback (most recent call last)  <ipython-input-10-8373a2715e38> in <module>       1 params = Params()       2     ----> 3 params.adjust({"b": "abc"})   ~/Paramtools/paramtools/parameters.py in adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, clobber)     253             least one existing value item's corresponding label values.     254         """     --> 255         return self._adjust(     256             params_or_path,     257             ignore_warnings=ignore_warnings,   ~/Paramtools/paramtools/parameters.py in _adjust(self, params_or_path, ignore_warnings, raise_errors, extend_adj, is_deserialized, clobber)     371             not ignore_warnings and has_warnings     372         ):     --> 373             raise self.validation_error     374     375         # Update attrs for params that were adjusted.   ValidationError: {     "errors": {         "b": [             "Not a valid number: abc."         ]     } } 

Extend parameter values using label definitions

Extend values using label_to_extend:

python params = Params(label_to_extend="date")

python params.sel["a"]

Values([   {'date': datetime.date(2020, 1, 1), 'value': 2},   {'date': datetime.date(2020, 2, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 3, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 4, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 5, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 6, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 7, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 8, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 9, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 10, 1), 'value': 8},   {'date': datetime.date(2020, 11, 1), 'value': 8, '_auto': True},   {'date': datetime.date(2020, 12, 1), 'value': 8, '_auto': True},   {'date': datetime.date(2021, 1, 1), 'value': 8, '_auto': True}, ]) 

Updates to values are carried through to future dates:

```python params.adjust({"a": [{"date": "2020-4-01", "value": 9}]})

params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 2},   {'date': datetime.date(2020, 2, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 3, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 4, 1), 'value': 9},   {'date': datetime.date(2020, 5, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 6, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 7, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 8, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 9, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 10, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 11, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 12, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2021, 1, 1), 'value': 9, '_auto': True}, ]) 

Use clobber to only update values that were set automatically:

```python params = Params(label_to_extend="date") params.adjust( {"a": [{"date": "2020-4-01", "value": 9}]}, clobber=False, )

Sort parameter values by date for nicer output

params.sort_values() params.sel["a"] ```

Values([   {'date': datetime.date(2020, 1, 1), 'value': 2},   {'date': datetime.date(2020, 2, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 3, 1), 'value': 2, '_auto': True},   {'date': datetime.date(2020, 4, 1), 'value': 9},   {'date': datetime.date(2020, 5, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 6, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 7, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 8, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 9, 1), 'value': 9, '_auto': True},   {'date': datetime.date(2020, 10, 1), 'value': 8},   {'date': datetime.date(2020, 11, 1), 'value': 8, '_auto': True},   {'date': datetime.date(2020, 12, 1), 'value': 8, '_auto': True},   {'date': datetime.date(2021, 1, 1), 'value': 8, '_auto': True}, ]) 

NumPy integration

Access values as NumPy arrays with array_first:

```python params = Params(label_to_extend="date", array_first=True)

params.a ```

array([2, 2, 2, 2, 2, 2, 2, 2, 2, 8, 8, 8, 8]) 

python params.a * params.b

array([21., 21., 21., 21., 21., 21., 21., 21., 21., 84., 84., 84., 84.]) 

Only get the values that you want:

python arr = params.to_array("a", date=["2020-01-01", "2020-11-01"]) arr

array([2, 8]) 

Go back to a list of dictionaries:

python params.from_array("a", arr, date=["2020-01-01", "2020-11-01"])

[{'date': datetime.date(2020, 1, 1), 'value': 2},  {'date': datetime.date(2020, 11, 1), 'value': 8}] 
Documentation

Full documentation available at paramtools.dev.

Contributing

Contributions are welcome! Checkout CONTRIBUTING.md to get started.

Credits

ParamTools is built on top of the excellent marshmallow JSON schema and validation framework. I encourage everyone to check out their repo and documentation. ParamTools was modeled off of Tax-Calculator's parameter processing and validation engine due to its maturity and sophisticated capabilities.

Maintainers
  • Hank Doupe

Code repository

User documentation

Contributor documentation

Recent changes

PCI-China

A machine learning project that analyzes state-run media to predict policy changes.

China's industrialization process has long been a product of government direction, be it coercive central planning or ambitious industrial policy. For the first time in the literature, we develop a quantitative indicator of China's policy priorities over a long period of time, which we call the Policy Change Index for China (PCI-China). The PCI-China is a leading indicator that runs from 1951 to the most recent quarter and can be updated in the future. In other words, the PCI-China not only helps us understand the past of China's industrialization but also allows us to make short-term predictions about its future directions.

The design of the PCI-China has two building blocks: (1) it takes as input data the full text of the People's Daily --- the official newspaper of the Communist Party of China --- since it was founded in 1946; (2) it employs a set of machine learning techniques to "read" the articles and detect changes in the way the newspaper prioritizes policy issues.

The source of the PCI-China's predictive power rests on the fact that the People's Daily is at the nerve center of China's propaganda system and that propaganda changes often precede policy changes. Before the great transformation from the central planning under Mao to the economic reform program after Mao, for example, considerable efforts were made by the Chinese government to promote the idea of reform, move public opinion, and mobilize resources toward the new agenda. Therefore, by detecting (real-time) changes in propaganda, the PCI-China is, effectively, predicting (future) changes in policy.

For details about the methodology and findings of this project, please see the following research paper:

Maintainers
  • Julian TszKin Chan
  • Weifeng Zhong

Code repository

User documentation

Contributor documentation

Tax-Brain

Integrator package for multiple open source tax models

Tax-Brain makes it easy for users to simulate the US tax system by providing a single interface for multiple tax models. Currently, Tax-Brain interfaces with Tax-Calculator and Behavioral-Responses. Additional models will be added in the near future to expand Tax-Brain's capabilities to include modeling business taxation and running dynamic general equilibrium simulations.

To learn more about how Tax-Brain works, see this document.

Maintainers
  • Anderson Frailey

Code repository

User documentation

Contributor documentation

Recent changes

Link to webapp

Tax-Calculator

Tax-Calculator is an open-source microsimulation model for static analysis of USA federal income and payroll taxes.

What is Tax-Calculator?

Maintainers
  • Martin Holmer
    • email: first and last names separated by a period at gmail dot com
    • phone: 526-0406 prefaced by area code two zero two
  • Matt Jensen

Code repository

User documentation

Contributor documentation

Recent changes

Tax-Cruncher

Calculates federal tax liabilities from individual data under different policy proposals

Tax-Cruncher calculates federal tax liabilities from individual data under different policy scenarios.

Tax-Cruncher accepts inputs similar to NBER's TAXSIM Version 27, converts those inputs to a format usable by Tax-Calculator, and uses Tax-Calculator capabilities to analyze the user-provided data under various tax policy proposals.

Tax-Cruncher's web application is hosted on Compute Studio. The code that powers the web application can be found in this repository in the cs-config directory.

Maintainers
  • Peter Metz

Code repository

User documentation

Recent changes

Link to webapp