Skip to content

QST: help with understanding how income splitting works in gettsim #693

@ghost

Description

hey there,
i wanted to check against gettsim that an income tax calculator i wrote isnt producing complete nonsense / that i am using it correctly. i am writing a paper on income splitting and wanted to simulate a system with income splitting and one without it.
however i am confused how to work with gettsim here. from my understanding:

  • whether to apply income splitting to a household is done via the household being in the same tax unit and then internally anz_erwachsene_tu is used to implement income splitting in src/_gettsim/taxes/eink_st.py:26.

i did the basic thing with creating the params, functions and datasets calculating them once and i got the income tax 4998.0.
then i went to:

  1. update tu_id for p_id == 0 (so the husband)
  2. saw that multiple tu_ids in a household are not supported so i updated that as wel

however calling calculate on that gave me this:

hh_id tu_id p_id hh_typ weiblich bruttolohn_m eink_st_tu lohnst_m sonstig_eink_m sonstig_eink_m eink_vermietung_m eink_selbst_m alleinerz
0 1 1 0 single_1_children False 2000 2376 434.116 0 0 0 0 False
1 0 0 1 single_1_children True 1000 37 102.725 0 0 0 0 False
2 0 0 2 single_1_children False 0 37 0 0 0 0 0 False

this shows that while all relevant input is the same the couple pays more through joint taxation (i also checked things in debug the both adults have practically no diff by default as i am sure you are aware)

from my understanding of income splitting this just cannot be the case, as the effect of income splitting is a perfect maximization of the total household income tax progression and usage of their tax exempt amounts.

My Question

could you please help me understand where i am going wrong as in what parts of gettsim or income splitting?

best regards!

My Code

policy_params, policy_functions = set_up_policy_environment(2016)
                                                                            
data = create_synthetic_data(
    n_adults=2,
    n_children=1,
    specs_constant_over_households={"bruttolohn_m": [2000.0, 1000.0, 0.0]},
)
                                                                            
print(data.columns)
                                                                            
targets = [ "eink_st_tu", "anz_erwachsene_tu", "lohnst_m" ]
debug = True
                                                                            
result = compute_taxes_and_transfers(
    data=data,
    functions=policy_functions,
    params=policy_params,
    targets=targets,
    debug=debug
)
result.round(2)
print(result)
                                                                            
data.loc[data["p_id"] == 0, ["tu_id", "hh_id"]] = 1
data["hh_typ"] = "single_1_children"
                                                                            
result = compute_taxes_and_transfers(
    data=data,
    functions=policy_functions,
    params=policy_params,
    targets=targets,
    debug=debug
)
result.round(2)
print(result)
print(result[[
    "hh_id", "tu_id", "p_id", "hh_typ",
    "weiblich", "bruttolohn_m", "eink_st_tu",
    "lohnst_m", "sonstig_eink_m", "sonstig_eink_m",
    "eink_vermietung_m", "eink_selbst_m", "alleinerz"
    ]].to_markdown())

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions