PolicyEngine / policyengine-us

The PolicyEngine US Python package contains a rules engine of the US tax-benefit system, and microdata generation for microsimulation analysis.
https://policyengine.org/us
GNU Affero General Public License v3.0
100 stars 174 forks source link

Fix federal non-refundable CTC calculations #4800

Open martinholmer opened 1 month ago

martinholmer commented 1 month ago

The calculation of the federal non-refundable Child Tax Credit (CTC) is incorrect because in some cases it produces an amount that exceeds the income tax before credits amount. This, of course, is a bug by definition: a non-refundable credit can never exceed the income tax liability before credits.

Here is a simple test case that illustrates the problem:

- name: Single Texan with three children and low salary as only income.
  absolute_error_margin: 0.01
  period: 2022
  input:
    people:
      person1:
        age: 39
        employment_income: 30_000
      person2:
        age: 15
      person3:
        age: 14
      person4:
        age: 11
    spm_units:
      spm_unit:
        members: [person1, person2, person3, person4]
    tax_units:
      tax_unit:
        members: [person1, person2, person3, person4]
    households:
      household:
        members: [person1, person2, person3, person4]
        state_code: TX
  output:  # expected values from online TAXSIM-35
    income_tax_before_credits: 1_060
    non_refundable_ctc: 1_060

##############################################################################
# ABOVE TEST IS IN A FILE NAMED ctcbug.yaml
# TEST ENVIRONMENT:
#   % pip list | grep policyengine
#   policyengine-core             2.21.8
#   policyengine-us               1.34.1
# RESULTS FROM RUNNING THIS TEST ARE AS FOLLOWS:
#
#=============================== FAILURES ===================================
#_____________________________ test session _________________________________
#/Users/mrh/work/.../ctcbug.yaml:
#  Test 'Single Texan with three children and low salary as only income.':
#    non_refundable_ctc@2022: [1875.] differs from 1060.0
#                             with an absolute margin [815.] > 0.01
#======================= short test summary info ============================
#FAILED ctcbug.yaml::
#========================== 1 failed in 3.89s ===============================
PavelMakarchuk commented 1 month ago

@MaxGhenis curious your thoughts here - I do not think that this is a bug but more of a structural questions

We do compute a non refundable CTC amount of $1,875 which is then limited in the income_tax_capped_non_refundable_credits - if included in the test above this variable returns a value of $1,060 - and this is ultimately the value that will affect the net income calculation

To get insights into the applicable CTC amount we also have the ctc_limiting_tax_liability variable which also returns $1,060

However since Martin is raising this issue it might be worth discussing if this could be misleading for developers who are looking into individual non refundable credit computation files

martinholmer commented 1 month ago

@PavelMakarchuk said in issue #4800:

I do not think that this is a bug

I don't understand how you can say that when the non_refundable_ctc variable is defined as "The portion of the Child Tax Credit that is not refundable."

https://github.com/PolicyEngine/policyengine-us/blob/6cb1140cd768ad97be2483efdfcca6c3d7bc210f/policyengine_us/variables/gov/irs/credits/ctc/non_refundable_ctc.py#L4-L14

That is an unambiguous definition of the variable. And the value of that variable is not always correct.

PavelMakarchuk commented 1 month ago

@PavelMakarchuk said in issue #4800:

I do not think that this is a bug

I don't understand how you can say that when the non_refundable_ctc variable is defined as "The portion of the Child Tax Credit that is not refundable."

https://github.com/PolicyEngine/policyengine-us/blob/6cb1140cd768ad97be2483efdfcca6c3d7bc210f/policyengine_us/variables/gov/irs/credits/ctc/non_refundable_ctc.py#L4-L14

That is an unambiguous definition of the variable. And the value of that variable is not always correct.

Perhaps changing the variable name to maximum_non_refundable_ctc would be more descriptive but this would lead to a structural change of naming all non refundable credit variables maximum_x as we do not cap any non ref. credits at taxes until later in the computation tree

martinholmer commented 1 month ago

@PavelMakarchuk said in issue #4800:

Perhaps changing the variable name to maximum_non_refundable_ctc would be more descriptive but this would lead to a structural change of naming all non refundable credit variables maximum_x as we do not cap any [nonrefundable] credits at taxes until later in the computation tree.

How is a user of PolicyEngine-US supposed to get the ACTUAL non-refundable CTC amount?

MaxGhenis commented 1 month ago

We can do this for the federal non-refundable CTC, but in general we don't intend to track the sequence of non-refundable credits (as opposed to capping the sum at tax before credits) unless a use case arises.

martinholmer commented 1 month ago

@MaxGhenis said in issue #4800:

We can do this for the federal non-refundable CTC

Good! That will certainly help the developers working in the policyengine-taxsim repository, who seem to be confused in the same way I was about the CTC variables.