policyengine-uk 2.40.1__py3-none-any.whl → 2.65.6__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- policyengine_uk/__init__.py +5 -3
- policyengine_uk/data/__init__.py +1 -0
- policyengine_uk/data/dataset_schema.py +70 -18
- policyengine_uk/data/economic_assumptions.py +36 -10
- policyengine_uk/data/filter_dataset.py +52 -0
- policyengine_uk/dynamics/labour_supply.py +343 -0
- policyengine_uk/dynamics/participation.py +629 -0
- policyengine_uk/dynamics/progression.py +384 -0
- policyengine_uk/microsimulation.py +105 -0
- policyengine_uk/model_api.py +1 -0
- policyengine_uk/parameters/gov/boe/base_rate.yaml +34 -0
- policyengine_uk/parameters/gov/boe/index.yaml +2 -0
- policyengine_uk/parameters/gov/contrib/behavioral_responses/employee_salary_sacrifice_reduction_rate.yaml +14 -0
- policyengine_uk/parameters/gov/contrib/behavioral_responses/salary_sacrifice_broad_base_haircut_rate.yaml +22 -0
- policyengine_uk/parameters/gov/contrib/cec/state_pension_increase.yaml +1 -1
- policyengine_uk/parameters/gov/contrib/ubi_center/carbon_tax.yaml +2 -2
- policyengine_uk/parameters/gov/contrib/ubi_center/land_value_tax.yaml +3 -3
- policyengine_uk/parameters/gov/dcms/bbc/tv_licence/colour.yaml +5 -5
- policyengine_uk/parameters/gov/dfe/education_spending.yaml +1 -1
- policyengine_uk/parameters/gov/dft/rail/fare_index.yaml +32 -0
- policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml +32 -0
- policyengine_uk/parameters/gov/dft/rail/ridership_index.yaml +30 -0
- policyengine_uk/parameters/gov/dft/spending.yaml +2 -2
- policyengine_uk/parameters/gov/dwp/ESA/income/earn_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_lone_parent.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_single.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/ESA/income/pension_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/IIDB/maximum.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/contrib/amount_over_25.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/contrib/earn_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/contrib/pension_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/income/amount_18_24.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/JSA/income/amount_over_25.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_lone_parent.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_single.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/LHA/shared_accommodation_age_threshold.yaml +12 -0
- policyengine_uk/parameters/gov/dwp/attendance_allowance/higher.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/attendance_allowance/lower.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/benefit_cap.yaml +3 -3
- policyengine_uk/parameters/gov/dwp/carer_premium/couple.yaml +2 -2
- policyengine_uk/parameters/gov/dwp/carer_premium/single.yaml +6 -6
- policyengine_uk/parameters/gov/dwp/carers_allowance/rate.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/disability_premia/disability_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_single.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/disability_premia/severe_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/dla/mobility/higher.yaml +4 -4
- policyengine_uk/parameters/gov/dwp/dla/mobility/lower.yaml +8 -8
- policyengine_uk/parameters/gov/dwp/dla/self_care/higher.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/dla/self_care/lower.yaml +8 -8
- policyengine_uk/parameters/gov/dwp/dla/self_care/middle.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/lone_parent/aged.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/lone_parent/older.yaml +3 -3
- policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/single/aged.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/single/older.yaml +3 -3
- policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/income_disregard/worker.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/housing_benefit/non_dep_deduction/amount.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/housing_benefit/takeup.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/income_support/amounts/amount_16_24.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/amounts/amount_couples_over_18.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/means_test/earn_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_couple.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_lone_parent.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_single.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/means_test/pension_disregard.yaml +1 -1
- policyengine_uk/parameters/gov/dwp/income_support/takeup.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/carer/addition.yaml +4 -4
- policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee.yaml +9 -9
- policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/severe_disability/addition.yaml +3 -3
- policyengine_uk/parameters/gov/dwp/pension_credit/savings_credit/threshold.yaml +5 -5
- policyengine_uk/parameters/gov/dwp/pip/daily_living/enhanced.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/pip/daily_living/standard.yaml +8 -8
- policyengine_uk/parameters/gov/dwp/pip/mobility/enhanced.yaml +4 -4
- policyengine_uk/parameters/gov/dwp/pip/mobility/standard.yaml +9 -9
- policyengine_uk/parameters/gov/dwp/sda/maximum.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/state_pension/basic_state_pension/amount.yaml +11 -11
- policyengine_uk/parameters/gov/dwp/state_pension/new_state_pension/amount.yaml +4 -4
- policyengine_uk/parameters/gov/dwp/tax_credits/child_tax_credit/limit/child_count.yaml +10 -1
- policyengine_uk/parameters/gov/dwp/tax_credits/child_tax_credit/takeup.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/tax_credits/working_tax_credit/takeup.yaml +7 -7
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/carer/amount.yaml +3 -3
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/amount.yaml +2 -4
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/disabled/amount.yaml +2 -4
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/first/higher_amount.yaml +6 -8
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/limit/child_count.yaml +6 -1
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/severely_disabled/amount.yaml +3 -5
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/childcare/cap.yaml +2 -6
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/disabled/amount.yaml +4 -6
- policyengine_uk/parameters/gov/dwp/universal_credit/elements/housing/non_dep_deduction/amount.yaml +4 -1
- policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/active.yaml +9 -0
- policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/new_claimant_health_element.yaml +9 -0
- policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/standard_allowance_uplift.yaml +13 -0
- policyengine_uk/parameters/gov/dwp/universal_credit/standard_allowance/amount.yaml +5 -5
- policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/maximum_taxable_income.yaml +2 -1
- policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/use_maximum_taxable_income.yaml +1 -0
- policyengine_uk/parameters/gov/dynamic/obr_labour_supply_assumptions.yaml +9 -0
- policyengine_uk/parameters/gov/economic_assumptions/create_economic_assumption_indices.py +1 -1
- policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +522 -153
- policyengine_uk/parameters/gov/hmrc/cgt/additional_rate.yaml +5 -0
- policyengine_uk/parameters/gov/hmrc/cgt/basic_rate.yaml +5 -0
- policyengine_uk/parameters/gov/hmrc/cgt/higher_rate.yaml +4 -0
- policyengine_uk/parameters/gov/hmrc/child_benefit/amount/additional.yaml +6 -6
- policyengine_uk/parameters/gov/hmrc/child_benefit/amount/eldest.yaml +8 -8
- policyengine_uk/parameters/gov/hmrc/child_benefit/takeup/by_age.yaml +1 -1
- policyengine_uk/parameters/gov/hmrc/fuel_duty/calculate_fuel_duty_rates.py +464 -0
- policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml +86 -10
- policyengine_uk/parameters/gov/hmrc/income_tax/allowances/personal_allowance/amount.yaml +6 -0
- policyengine_uk/parameters/gov/hmrc/income_tax/earned_taxable_income_exclusions.yaml +2 -1
- policyengine_uk/parameters/gov/hmrc/income_tax/income_tax_additions.yaml +1 -0
- policyengine_uk/parameters/gov/hmrc/income_tax/rates/dividends.yaml +12 -0
- policyengine_uk/parameters/gov/hmrc/income_tax/rates/property.yaml +46 -0
- policyengine_uk/parameters/gov/hmrc/income_tax/rates/savings.yaml +46 -0
- policyengine_uk/parameters/gov/hmrc/income_tax/rates/scotland/rates.yaml +2 -2
- policyengine_uk/parameters/gov/hmrc/income_tax/rates/uk.yaml +14 -2
- policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employee/additional.yaml +4 -6
- policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employer.yaml +3 -3
- policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/thresholds/secondary_threshold.yaml +14 -4
- policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml +2 -2
- policyengine_uk/parameters/gov/hmrc/national_insurance/salary_sacrifice_pension_cap.yaml +16 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/index.yaml +12 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_1/boe_margin.yaml +11 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/additional_rate.yaml +27 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/index.yaml +16 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/upper_threshold.yaml +48 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/postgraduate_additional_rate.yaml +11 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/postgraduate_repayment_rate.yaml +9 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/repayment_rate.yaml +9 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_1.yaml +25 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_2.yaml +58 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_4.yaml +19 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_5.yaml +16 -0
- policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/postgraduate.yaml +21 -0
- policyengine_uk/parameters/gov/hmrc/vat/reduced_rate_share.yaml +3 -3
- policyengine_uk/parameters/gov/indices/private_rent_index.yaml +9 -9
- policyengine_uk/parameters/gov/revenue_scotland/lbtt/non_residential.yaml +2 -2
- policyengine_uk/parameters/gov/revenue_scotland/lbtt/rent.yaml +2 -2
- policyengine_uk/parameters/gov/revenue_scotland/lbtt/residential/first_time_buyer_rate.yaml +2 -2
- policyengine_uk/parameters/gov/revenue_scotland/lbtt/residential/rate.yaml +2 -2
- policyengine_uk/parameters/gov/wra/land_transaction_tax/non_residential.yaml +2 -2
- policyengine_uk/parameters/gov/wra/land_transaction_tax/rent.yaml +2 -2
- policyengine_uk/parameters/gov/wra/land_transaction_tax/residential/higher_rate.yaml +1 -1
- policyengine_uk/parameters/gov/wra/land_transaction_tax/residential/primary.yaml +2 -2
- policyengine_uk/parameters/household/consumption/carbon/consumption.yaml +8 -6
- policyengine_uk/parameters/household/consumption/carbon/intensity.yaml +4 -1
- policyengine_uk/parameters/household/consumption/carbon/production.yaml +12 -7
- policyengine_uk/parameters/household/consumption/carbon/production_by_source.yaml +76 -41
- policyengine_uk/parameters/household/consumption/fuel/prices/petrol.yaml +1 -1
- policyengine_uk/parameters/household/poverty/absolute_poverty_threshold_bhc.yaml +1 -1
- policyengine_uk/reforms/policyengine/adjust_budgets.py +0 -1
- policyengine_uk/scenarios/__init__.py +4 -0
- policyengine_uk/scenarios/pip_reform.py +23 -0
- policyengine_uk/scenarios/reindex_benefit_cap.py +32 -0
- policyengine_uk/scenarios/repeal_two_child_limit.py +10 -0
- policyengine_uk/scenarios/uc_reform.py +50 -0
- policyengine_uk/simulation.py +619 -0
- policyengine_uk/system.py +3 -257
- policyengine_uk/tax_benefit_system.py +141 -0
- policyengine_uk/tests/behavioral_responses/test_labor_supply_responses.yaml +183 -0
- policyengine_uk/tests/microsimulation/reforms_config.yaml +8 -8
- policyengine_uk/tests/microsimulation/test_reform_impacts.py +2 -2
- policyengine_uk/tests/microsimulation/test_salary_sacrifice_cap_reform.py +401 -0
- policyengine_uk/tests/microsimulation/test_validity.py +2 -3
- policyengine_uk/tests/microsimulation/update_reform_impacts.py +104 -40
- policyengine_uk/tests/policy/baseline/contrib/policyengine/employer_ni/employer_ni_fixed_employer_cost_change.yaml +105 -0
- policyengine_uk/tests/policy/baseline/finance/benefit/family/child_benefit.yaml +2 -0
- policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support.yaml +0 -23
- policyengine_uk/tests/policy/baseline/gov/dcms/bbc/tv-licence/tv_licence.yaml +3 -0
- policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml +17 -17
- policyengine_uk/tests/policy/baseline/gov/dwp/basic_state_pension.yaml +44 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/allowances/gift_aid.yaml +71 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/allowances/personal_allowance.yaml +161 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employee.yaml +107 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employer.yaml +95 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_interest_rate.yaml +153 -0
- policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml +130 -0
- policyengine_uk/tests/policy/baseline/household/wealth/vehicle.yaml +27 -0
- policyengine_uk/tests/policy/reforms/nov_2025_budget/income_source_tax_rates.yaml +235 -0
- policyengine_uk/tests/policy/reforms/nov_2025_budget/income_tax_freeze.yaml +83 -0
- policyengine_uk/tests/policy/reforms/parametric/basic_income/basic_income.yaml +1 -0
- policyengine_uk/tests/test_behavioral_responses.py +215 -0
- policyengine_uk/tests/test_fiscal_year_parameters.py +131 -0
- policyengine_uk/utils/__init__.py +1 -0
- policyengine_uk/utils/compare.py +28 -0
- policyengine_uk/utils/create_ahc_deflator.py +169 -0
- policyengine_uk/utils/create_triple_lock.py +1 -1
- policyengine_uk/utils/dependencies.py +259 -0
- policyengine_uk/utils/parameters.py +12 -1
- policyengine_uk/utils/scenario.py +225 -0
- policyengine_uk/utils/solve_private_school_attendance_factor.py +4 -6
- policyengine_uk/variables/contrib/policyengine/education_budget_change.py +0 -1
- policyengine_uk/variables/contrib/policyengine/employer_ni/baseline_employer_cost.py +5 -1
- policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_fixed_employer_cost_change.py +23 -23
- policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py +1 -1
- policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_consumer_incidence.py +1 -1
- policyengine_uk/variables/contrib/policyengine/other_public_spending_budget_change.py +0 -1
- policyengine_uk/variables/gov/dfe/targeted_childcare_entitlement/targeted_childcare_entitlement_eligible.py +0 -1
- policyengine_uk/variables/gov/dft/rail_subsidy_spending.py +16 -1
- policyengine_uk/variables/gov/dft/rail_usage.py +16 -0
- policyengine_uk/variables/gov/dwp/BRMA_LHA_rate.py +7 -2
- policyengine_uk/variables/gov/dwp/LHA_category.py +4 -2
- policyengine_uk/variables/gov/dwp/additional_state_pension.py +4 -2
- policyengine_uk/variables/gov/dwp/basic_state_pension.py +26 -8
- policyengine_uk/variables/gov/dwp/is_CTC_eligible.py +1 -1
- policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt.py +9 -13
- policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_earnings.py +66 -0
- policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_health_disability.py +75 -0
- policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_other.py +66 -0
- policyengine_uk/variables/gov/dwp/winter_fuel_allowance.py +5 -4
- policyengine_uk/variables/gov/gov_tax.py +0 -2
- policyengine_uk/variables/gov/hmrc/household_tax.py +0 -1
- policyengine_uk/variables/gov/hmrc/income_tax/allowances/gift_aid.py +23 -0
- policyengine_uk/variables/gov/hmrc/income_tax/allowances/personal_allowance.py +9 -2
- policyengine_uk/variables/gov/hmrc/income_tax/income_tax_pre_charges.py +1 -0
- policyengine_uk/variables/gov/hmrc/income_tax/liability/property_income_tax.py +75 -0
- policyengine_uk/variables/gov/hmrc/income_tax/liability/savings_income_tax.py +4 -4
- policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_broad_base_haircut.py +43 -0
- policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employee.py +38 -0
- policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employer.py +27 -0
- policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_via_salary_sacrifice_adjusted.py +31 -0
- policyengine_uk/variables/gov/hmrc/pensions/salary_sacrifice_returned_to_income.py +41 -0
- policyengine_uk/variables/gov/hmrc/student_loans/__init__.py +2 -0
- policyengine_uk/variables/gov/hmrc/student_loans/plan_1_interest_rate.py +23 -0
- policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py +31 -0
- policyengine_uk/variables/gov/hmrc/student_loans/plan_4_interest_rate.py +22 -0
- policyengine_uk/variables/gov/hmrc/student_loans/plan_5_interest_rate.py +18 -0
- policyengine_uk/variables/gov/hmrc/student_loans/postgraduate_interest_rate.py +23 -0
- policyengine_uk/variables/gov/hmrc/student_loans/student_loan_plan.py +27 -0
- policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py +91 -0
- policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment_rate.py +31 -0
- policyengine_uk/variables/gov/hmrc/would_claim_child_benefit.py +5 -1
- policyengine_uk/variables/household/demographic/benunit/benunit_count_adults.py +11 -0
- policyengine_uk/variables/household/demographic/is_disabled_for_benefits.py +13 -1
- policyengine_uk/variables/household/income/hbai_household_net_income.py +29 -1
- policyengine_uk/variables/household/income/hbai_household_net_income_ahc.py +13 -0
- policyengine_uk/variables/household/income/household_net_income.py +5 -1
- policyengine_uk/variables/household/income/inflation_adjustment.py +24 -0
- policyengine_uk/variables/household/post_tax_income.py +12 -0
- policyengine_uk/variables/household/wealth/num_vehicles.py +9 -0
- policyengine_uk/variables/household/wealth/owns_vehicle.py +17 -0
- policyengine_uk/variables/input/consumption/property/council_tax.py +0 -35
- policyengine_uk/variables/input/consumption/property/employee_pension_contributions.py +8 -1
- policyengine_uk/variables/input/consumption/property/employee_pension_contributions_reported.py +16 -0
- policyengine_uk/variables/input/consumption/property/pension_contributions_via_salary_sacrifice.py +16 -0
- policyengine_uk/variables/input/employment_income.py +2 -0
- policyengine_uk/variables/input/rent.py +0 -40
- policyengine_uk/variables/input/savings_interest_income.py +3 -1
- {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/METADATA +17 -8
- {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/RECORD +252 -173
- {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/WHEEL +1 -1
- policyengine_uk/repo.py +0 -3
- policyengine_uk/tests/policy/baseline/gov/abolitions/abolition_parameters.yaml +0 -250
- policyengine_uk/variables/contrib/policyengine/high_income_incident_tax_change.py +0 -22
- policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template/CHANGELOG.md +0 -2285
- policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template/README.md +0 -37
- policyengine_uk-2.40.1.dist-info/licenses/LICENSE +0 -661
- {policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template → policyengine_uk-2.65.6.dist-info/licenses}/LICENSE +0 -0
policyengine_uk/system.py
CHANGED
|
@@ -1,257 +1,3 @@
|
|
|
1
|
-
from
|
|
2
|
-
from
|
|
3
|
-
from
|
|
4
|
-
from policyengine_core.taxbenefitsystems import TaxBenefitSystem
|
|
5
|
-
from policyengine_core.simulations import (
|
|
6
|
-
Simulation as CoreSimulation,
|
|
7
|
-
Microsimulation as CoreMicrosimulation,
|
|
8
|
-
)
|
|
9
|
-
from policyengine_uk.data.dataset_schema import (
|
|
10
|
-
UKSingleYearDataset,
|
|
11
|
-
UKMultiYearDataset,
|
|
12
|
-
)
|
|
13
|
-
from policyengine_core.tools.hugging_face import download_huggingface_dataset
|
|
14
|
-
|
|
15
|
-
import pandas as pd
|
|
16
|
-
from policyengine_uk.utils.parameters import (
|
|
17
|
-
backdate_parameters,
|
|
18
|
-
convert_to_fiscal_year_parameters,
|
|
19
|
-
)
|
|
20
|
-
from policyengine_uk.parameters.gov.economic_assumptions.create_economic_assumption_indices import (
|
|
21
|
-
create_economic_assumption_indices,
|
|
22
|
-
)
|
|
23
|
-
from policyengine_uk.parameters.gov.economic_assumptions.lag_average_earnings import (
|
|
24
|
-
add_lagged_earnings,
|
|
25
|
-
)
|
|
26
|
-
from policyengine_uk.parameters.gov.economic_assumptions.lag_cpi import (
|
|
27
|
-
add_lagged_cpi,
|
|
28
|
-
)
|
|
29
|
-
from policyengine_core.reforms import Reform
|
|
30
|
-
from policyengine_uk.reforms import create_structural_reforms_from_parameters
|
|
31
|
-
|
|
32
|
-
from policyengine_uk.parameters.gov.contrib.create_private_pension_uprating import (
|
|
33
|
-
add_private_pension_uprating_factor,
|
|
34
|
-
)
|
|
35
|
-
from policyengine_uk.parameters.gov.dwp.state_pension.triple_lock.create_triple_lock import (
|
|
36
|
-
add_triple_lock,
|
|
37
|
-
)
|
|
38
|
-
from policyengine_core.parameters.operations.homogenize_parameters import (
|
|
39
|
-
homogenize_parameter_structures,
|
|
40
|
-
)
|
|
41
|
-
from policyengine_core.parameters.operations.interpolate_parameters import (
|
|
42
|
-
interpolate_parameters,
|
|
43
|
-
)
|
|
44
|
-
from policyengine_core.parameters.operations.propagate_parameter_metadata import (
|
|
45
|
-
propagate_parameter_metadata,
|
|
46
|
-
)
|
|
47
|
-
from policyengine_core.parameters.operations.uprate_parameters import (
|
|
48
|
-
uprate_parameters,
|
|
49
|
-
)
|
|
50
|
-
from policyengine_core.reforms import Reform
|
|
51
|
-
|
|
52
|
-
COUNTRY_DIR = Path(__file__).parent
|
|
53
|
-
|
|
54
|
-
ENHANCED_FRS = "hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
class CountryTaxBenefitSystem(TaxBenefitSystem):
|
|
58
|
-
variables_dir = COUNTRY_DIR / "variables"
|
|
59
|
-
auto_carry_over_input_variables = True
|
|
60
|
-
basic_inputs = [
|
|
61
|
-
"brma",
|
|
62
|
-
"local_authority",
|
|
63
|
-
"region",
|
|
64
|
-
"employment_income",
|
|
65
|
-
"age",
|
|
66
|
-
]
|
|
67
|
-
modelled_policies = COUNTRY_DIR / "modelled_policies.yaml"
|
|
68
|
-
|
|
69
|
-
def process_parameters(self, reform=None):
|
|
70
|
-
if reform:
|
|
71
|
-
self.apply_reform_set(reform)
|
|
72
|
-
self.parameters = add_private_pension_uprating_factor(self.parameters)
|
|
73
|
-
self.parameters = add_lagged_earnings(self.parameters)
|
|
74
|
-
self.parameters = add_lagged_cpi(self.parameters)
|
|
75
|
-
self.parameters = add_triple_lock(self.parameters)
|
|
76
|
-
self.parameters = create_economic_assumption_indices(self.parameters)
|
|
77
|
-
self.parameters.add_child("baseline", self.parameters.clone())
|
|
78
|
-
self.parameters = homogenize_parameter_structures(
|
|
79
|
-
self.parameters, self.variables
|
|
80
|
-
)
|
|
81
|
-
self.parameters = propagate_parameter_metadata(self.parameters)
|
|
82
|
-
self.parameters = interpolate_parameters(self.parameters)
|
|
83
|
-
self.parameters = uprate_parameters(self.parameters)
|
|
84
|
-
self.parameters = propagate_parameter_metadata(self.parameters)
|
|
85
|
-
self.add_abolition_parameters()
|
|
86
|
-
self.parameters = backdate_parameters(self.parameters, "2015-01-01")
|
|
87
|
-
|
|
88
|
-
self.parameters.gov = convert_to_fiscal_year_parameters(
|
|
89
|
-
self.parameters.gov
|
|
90
|
-
)
|
|
91
|
-
|
|
92
|
-
def __init__(self, reform=None):
|
|
93
|
-
super().__init__(entities, reform=reform)
|
|
94
|
-
|
|
95
|
-
self.parameters_dir = COUNTRY_DIR / "parameters"
|
|
96
|
-
|
|
97
|
-
self.load_parameters(self.parameters_dir)
|
|
98
|
-
|
|
99
|
-
self.process_parameters(reform=reform)
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
system = CountryTaxBenefitSystem()
|
|
103
|
-
|
|
104
|
-
parameters = system.parameters
|
|
105
|
-
variables = system.variables
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
class Simulation(CoreSimulation):
|
|
109
|
-
default_tax_benefit_system = CountryTaxBenefitSystem
|
|
110
|
-
default_tax_benefit_system_instance = system
|
|
111
|
-
default_calculation_period = 2023
|
|
112
|
-
default_input_period = 2023
|
|
113
|
-
default_role = "member"
|
|
114
|
-
max_spiral_loops = 10
|
|
115
|
-
|
|
116
|
-
def __init__(self, *args, **kwargs):
|
|
117
|
-
super().__init__(*args, **kwargs)
|
|
118
|
-
|
|
119
|
-
reform = create_structural_reforms_from_parameters(
|
|
120
|
-
self.tax_benefit_system.parameters, "2023-01-01"
|
|
121
|
-
)
|
|
122
|
-
if reform is not None:
|
|
123
|
-
self.apply_reform(reform)
|
|
124
|
-
|
|
125
|
-
reform_dict = kwargs.get("reform")
|
|
126
|
-
if reform_dict is not None:
|
|
127
|
-
if isinstance(reform_dict, type):
|
|
128
|
-
try:
|
|
129
|
-
reform_dict = reform_dict.parameter_values
|
|
130
|
-
except:
|
|
131
|
-
reform_dict = None
|
|
132
|
-
|
|
133
|
-
if reform_dict is not None:
|
|
134
|
-
if any(["obr" in param for param in reform_dict]):
|
|
135
|
-
self.tax_benefit_system.load_parameters(
|
|
136
|
-
self.tax_benefit_system.parameters_dir
|
|
137
|
-
)
|
|
138
|
-
Reform.from_dict(reform_dict).apply(self.tax_benefit_system)
|
|
139
|
-
self.tax_benefit_system.process_parameters()
|
|
140
|
-
|
|
141
|
-
# Labor supply responses
|
|
142
|
-
|
|
143
|
-
employment_income = self.get_holder("employment_income")
|
|
144
|
-
for known_period in employment_income.get_known_periods():
|
|
145
|
-
array = employment_income.get_array(known_period)
|
|
146
|
-
self.set_input("employment_income_before_lsr", known_period, array)
|
|
147
|
-
employment_income.delete_arrays(known_period)
|
|
148
|
-
|
|
149
|
-
# Capital gains responses
|
|
150
|
-
|
|
151
|
-
cg_holder = self.get_holder("capital_gains")
|
|
152
|
-
for known_period in cg_holder.get_known_periods():
|
|
153
|
-
array = cg_holder.get_array(known_period)
|
|
154
|
-
self.set_input(
|
|
155
|
-
"capital_gains_before_response", known_period, array
|
|
156
|
-
)
|
|
157
|
-
employment_income.delete_arrays(known_period)
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
class Microsimulation(CoreMicrosimulation):
|
|
161
|
-
default_tax_benefit_system = CountryTaxBenefitSystem
|
|
162
|
-
default_dataset = ENHANCED_FRS
|
|
163
|
-
default_dataset_year = 2022
|
|
164
|
-
default_tax_benefit_system_instance = system
|
|
165
|
-
default_calculation_period = 2025
|
|
166
|
-
default_input_period = 2025
|
|
167
|
-
default_role = "member"
|
|
168
|
-
max_spiral_loops = 10
|
|
169
|
-
|
|
170
|
-
def __init__(self, *args, dataset=ENHANCED_FRS, **kwargs):
|
|
171
|
-
if dataset is not None:
|
|
172
|
-
if isinstance(dataset, str):
|
|
173
|
-
if "hf://" in dataset:
|
|
174
|
-
owner, repo, filename = dataset.split("/")[-3:]
|
|
175
|
-
if "@" in filename:
|
|
176
|
-
version = filename.split("@")[-1]
|
|
177
|
-
filename = filename.split("@")[0]
|
|
178
|
-
else:
|
|
179
|
-
version = None
|
|
180
|
-
dataset_file_path = download_huggingface_dataset(
|
|
181
|
-
repo=f"{owner}/{repo}",
|
|
182
|
-
repo_filename=filename,
|
|
183
|
-
version=version,
|
|
184
|
-
)
|
|
185
|
-
|
|
186
|
-
if Path(dataset_file_path).exists():
|
|
187
|
-
if dataset_file_path.endswith(".h5"):
|
|
188
|
-
try:
|
|
189
|
-
UKSingleYearDataset.validate_file_path(
|
|
190
|
-
dataset_file_path
|
|
191
|
-
)
|
|
192
|
-
dataset = UKSingleYearDataset(
|
|
193
|
-
file_path=dataset_file_path
|
|
194
|
-
)
|
|
195
|
-
except:
|
|
196
|
-
pass
|
|
197
|
-
|
|
198
|
-
try:
|
|
199
|
-
UKMultiYearDataset.validate_file_path(
|
|
200
|
-
dataset_file_path
|
|
201
|
-
)
|
|
202
|
-
dataset = UKMultiYearDataset(
|
|
203
|
-
file_path=dataset_file_path
|
|
204
|
-
)
|
|
205
|
-
except Exception as e:
|
|
206
|
-
pass
|
|
207
|
-
|
|
208
|
-
if not isinstance(
|
|
209
|
-
dataset, (UKSingleYearDataset, UKMultiYearDataset)
|
|
210
|
-
):
|
|
211
|
-
dataset = Dataset.from_file(dataset_file_path)
|
|
212
|
-
|
|
213
|
-
super().__init__(*args, dataset=dataset, **kwargs)
|
|
214
|
-
|
|
215
|
-
reform = create_structural_reforms_from_parameters(
|
|
216
|
-
self.tax_benefit_system.parameters, "2023-01-01"
|
|
217
|
-
)
|
|
218
|
-
if reform is not None:
|
|
219
|
-
self.apply_reform(reform)
|
|
220
|
-
|
|
221
|
-
reform_dict = kwargs.get("reform")
|
|
222
|
-
if reform_dict is not None:
|
|
223
|
-
if isinstance(reform_dict, type):
|
|
224
|
-
try:
|
|
225
|
-
reform_dict = reform_dict.parameter_values
|
|
226
|
-
except:
|
|
227
|
-
reform_dict = None
|
|
228
|
-
|
|
229
|
-
if reform_dict is not None:
|
|
230
|
-
if any(["obr" in param for param in reform_dict]):
|
|
231
|
-
self.tax_benefit_system.load_parameters(
|
|
232
|
-
self.tax_benefit_system.parameters_dir
|
|
233
|
-
)
|
|
234
|
-
Reform.from_dict(reform_dict).apply(self.tax_benefit_system)
|
|
235
|
-
self.tax_benefit_system.process_parameters()
|
|
236
|
-
|
|
237
|
-
# Labor supply responses
|
|
238
|
-
|
|
239
|
-
for simulation in list(self.branches.values()) + [self]:
|
|
240
|
-
employment_income = simulation.get_holder("employment_income")
|
|
241
|
-
for known_period in employment_income.get_known_periods():
|
|
242
|
-
array = employment_income.get_array(known_period)
|
|
243
|
-
simulation.set_input(
|
|
244
|
-
"employment_income_before_lsr", known_period, array
|
|
245
|
-
)
|
|
246
|
-
employment_income.delete_arrays(known_period)
|
|
247
|
-
|
|
248
|
-
# Capital gains responses
|
|
249
|
-
|
|
250
|
-
for simulation in list(self.branches.values()) + [self]:
|
|
251
|
-
cg_holder = self.get_holder("capital_gains")
|
|
252
|
-
for known_period in cg_holder.get_known_periods():
|
|
253
|
-
array = cg_holder.get_array(known_period)
|
|
254
|
-
self.set_input(
|
|
255
|
-
"capital_gains_before_response", known_period, array
|
|
256
|
-
)
|
|
257
|
-
employment_income.delete_arrays(known_period)
|
|
1
|
+
from .tax_benefit_system import *
|
|
2
|
+
from .simulation import *
|
|
3
|
+
from .microsimulation import *
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Standard library imports
|
|
2
|
+
import copy
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
from typing import Any, Dict, List
|
|
5
|
+
|
|
6
|
+
# PolicyEngine core imports
|
|
7
|
+
from policyengine_core.parameters.operations.propagate_parameter_metadata import (
|
|
8
|
+
propagate_parameter_metadata,
|
|
9
|
+
)
|
|
10
|
+
from policyengine_core.parameters.operations.uprate_parameters import (
|
|
11
|
+
uprate_parameters,
|
|
12
|
+
)
|
|
13
|
+
from policyengine_core.taxbenefitsystems import TaxBenefitSystem
|
|
14
|
+
from policyengine_core.variables import Variable
|
|
15
|
+
|
|
16
|
+
# PolicyEngine UK imports
|
|
17
|
+
from policyengine_uk.entities import BenUnit, Household, Person
|
|
18
|
+
from policyengine_uk.parameters.gov.contrib.create_private_pension_uprating import (
|
|
19
|
+
add_private_pension_uprating_factor,
|
|
20
|
+
)
|
|
21
|
+
from policyengine_uk.parameters.gov.dwp.state_pension.triple_lock.create_triple_lock import (
|
|
22
|
+
add_triple_lock,
|
|
23
|
+
)
|
|
24
|
+
from policyengine_uk.parameters.gov.economic_assumptions.create_economic_assumption_indices import (
|
|
25
|
+
create_economic_assumption_indices,
|
|
26
|
+
)
|
|
27
|
+
from policyengine_uk.parameters.gov.economic_assumptions.lag_average_earnings import (
|
|
28
|
+
add_lagged_earnings,
|
|
29
|
+
)
|
|
30
|
+
from policyengine_uk.parameters.gov.economic_assumptions.lag_cpi import (
|
|
31
|
+
add_lagged_cpi,
|
|
32
|
+
)
|
|
33
|
+
from policyengine_uk.utils.parameters import (
|
|
34
|
+
backdate_parameters,
|
|
35
|
+
convert_to_fiscal_year_parameters,
|
|
36
|
+
)
|
|
37
|
+
|
|
38
|
+
# Module constants
|
|
39
|
+
COUNTRY_DIR = Path(__file__).parent
|
|
40
|
+
ENHANCED_FRS = "hf://policyengine/policyengine-uk-data/enhanced_frs_2023_24.h5"
|
|
41
|
+
|
|
42
|
+
|
|
43
|
+
class CountryTaxBenefitSystem(TaxBenefitSystem):
|
|
44
|
+
"""UK-specific tax and benefit system implementation.
|
|
45
|
+
|
|
46
|
+
This class defines the UK tax-benefit system with all relevant
|
|
47
|
+
variables, parameters, and entities (Person, BenUnit, Household).
|
|
48
|
+
"""
|
|
49
|
+
|
|
50
|
+
basic_inputs: List[str] = [
|
|
51
|
+
"brma",
|
|
52
|
+
"local_authority",
|
|
53
|
+
"region",
|
|
54
|
+
"employment_income",
|
|
55
|
+
"age",
|
|
56
|
+
]
|
|
57
|
+
modelled_policies = COUNTRY_DIR / "modelled_policies.yaml"
|
|
58
|
+
auto_carry_over_input_variables: bool = True
|
|
59
|
+
|
|
60
|
+
variables: Dict[str, Variable]
|
|
61
|
+
|
|
62
|
+
def reset_parameter_caches(self):
|
|
63
|
+
"""Reset all caches in the tax-benefit system."""
|
|
64
|
+
self._parameters_at_instant_cache = {}
|
|
65
|
+
for parameter in self.parameters.get_descendants():
|
|
66
|
+
parameter._at_instant_cache = {}
|
|
67
|
+
self.parameters._at_instant_cache = {}
|
|
68
|
+
|
|
69
|
+
def reset_parameters(self) -> None:
|
|
70
|
+
"""Reset parameters by reloading from the parameters directory."""
|
|
71
|
+
self._parameters_at_instant_cache = {}
|
|
72
|
+
self.load_parameters(self.parameters_dir)
|
|
73
|
+
|
|
74
|
+
def process_parameters(self) -> None:
|
|
75
|
+
"""Process and transform parameters with UK-specific adjustments.
|
|
76
|
+
|
|
77
|
+
Applies various parameter transformations including:
|
|
78
|
+
- Private pension uprating factors
|
|
79
|
+
- Lagged earnings and CPI indices
|
|
80
|
+
- Triple lock calculations for state pensions
|
|
81
|
+
- Economic assumption indices
|
|
82
|
+
- Parameter uprating and backdating
|
|
83
|
+
- Conversion to fiscal year parameters
|
|
84
|
+
"""
|
|
85
|
+
self._parameters_at_instant_cache = {}
|
|
86
|
+
# Add various UK-specific parameter adjustments
|
|
87
|
+
self.parameters = add_private_pension_uprating_factor(self.parameters)
|
|
88
|
+
self.parameters = add_lagged_earnings(self.parameters)
|
|
89
|
+
self.parameters = add_lagged_cpi(self.parameters)
|
|
90
|
+
self.parameters = add_triple_lock(self.parameters)
|
|
91
|
+
self.parameters = create_economic_assumption_indices(self.parameters)
|
|
92
|
+
|
|
93
|
+
# Create baseline parameters for reform comparisons
|
|
94
|
+
self.parameters.add_child("baseline", self.parameters.clone())
|
|
95
|
+
|
|
96
|
+
# Apply general parameter operations
|
|
97
|
+
self.parameters = propagate_parameter_metadata(self.parameters)
|
|
98
|
+
self.parameters = uprate_parameters(self.parameters)
|
|
99
|
+
self.parameters = backdate_parameters(self.parameters, "2015-01-01")
|
|
100
|
+
self.parameters.gov = convert_to_fiscal_year_parameters(
|
|
101
|
+
self.parameters.gov
|
|
102
|
+
)
|
|
103
|
+
self.reset_parameter_caches()
|
|
104
|
+
|
|
105
|
+
def __init__(self):
|
|
106
|
+
"""Initialize the UK tax-benefit system with entities and parameters."""
|
|
107
|
+
self._parameters_at_instant_cache: Dict[str, Any] = {}
|
|
108
|
+
self.variables = {}
|
|
109
|
+
|
|
110
|
+
# Create copies of entity classes to avoid modifying originals
|
|
111
|
+
person, benunit, household = (
|
|
112
|
+
copy.copy(Person),
|
|
113
|
+
copy.copy(BenUnit),
|
|
114
|
+
copy.copy(Household),
|
|
115
|
+
)
|
|
116
|
+
|
|
117
|
+
# Set up entities
|
|
118
|
+
self.entities = [person, benunit, household]
|
|
119
|
+
self.person_entity = person
|
|
120
|
+
self.group_entities = [benunit, household]
|
|
121
|
+
self.group_entity_keys = [entity.key for entity in self.group_entities]
|
|
122
|
+
|
|
123
|
+
# Link entities to this tax-benefit system
|
|
124
|
+
for entity in self.entities:
|
|
125
|
+
entity.set_tax_benefit_system(self)
|
|
126
|
+
|
|
127
|
+
self.variable_module_metadata = {}
|
|
128
|
+
|
|
129
|
+
# Load all variables from the variables directory
|
|
130
|
+
self.add_variables_from_directory(COUNTRY_DIR / "variables")
|
|
131
|
+
|
|
132
|
+
# Set up and process parameters
|
|
133
|
+
self.parameters_dir = COUNTRY_DIR / "parameters"
|
|
134
|
+
self.reset_parameters()
|
|
135
|
+
self.process_parameters()
|
|
136
|
+
|
|
137
|
+
|
|
138
|
+
# Create system instance for module-level access
|
|
139
|
+
system = CountryTaxBenefitSystem()
|
|
140
|
+
parameters = system.parameters
|
|
141
|
+
variables = system.variables
|
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
# Test 1: OBR parameter enabled - Verifies behavioral response system can be activated
|
|
2
|
+
# This test ensures that:
|
|
3
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
4
|
+
# - Income changes are calculated before any state modifications
|
|
5
|
+
# - The system correctly returns 0 FTE responses when there's no actual policy reform
|
|
6
|
+
# - Proper NaN handling prevents calculation errors
|
|
7
|
+
- name: Test basic behavioral response mechanism works
|
|
8
|
+
period: 2025
|
|
9
|
+
input:
|
|
10
|
+
people:
|
|
11
|
+
parent:
|
|
12
|
+
age: 30
|
|
13
|
+
employment_income: 20_000
|
|
14
|
+
hours_worked: 1500
|
|
15
|
+
child1:
|
|
16
|
+
age: 5
|
|
17
|
+
child2:
|
|
18
|
+
age: 3
|
|
19
|
+
benunits:
|
|
20
|
+
benunit:
|
|
21
|
+
members: [parent, child1, child2]
|
|
22
|
+
households:
|
|
23
|
+
household:
|
|
24
|
+
members: [parent, child1, child2]
|
|
25
|
+
reforms:
|
|
26
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
27
|
+
"2025": true
|
|
28
|
+
output:
|
|
29
|
+
employment_income:
|
|
30
|
+
parent: 20_000 # Should have behavioral response capability
|
|
31
|
+
|
|
32
|
+
# Test 2: OBR parameter enabled with married couple - Verifies different gender behavioral responses
|
|
33
|
+
# This test ensures that:
|
|
34
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
35
|
+
# - Income changes are calculated before any state modifications
|
|
36
|
+
# - The system correctly returns 0 FTE responses when there's no actual policy reform
|
|
37
|
+
# - Proper NaN handling prevents calculation errors
|
|
38
|
+
- name: Test married couple behavioral response
|
|
39
|
+
period: 2025
|
|
40
|
+
input:
|
|
41
|
+
people:
|
|
42
|
+
adult1:
|
|
43
|
+
age: 35
|
|
44
|
+
employment_income: 25_000
|
|
45
|
+
hours_worked: 1800
|
|
46
|
+
gender: MALE
|
|
47
|
+
adult2:
|
|
48
|
+
age: 33
|
|
49
|
+
employment_income: 18_000
|
|
50
|
+
hours_worked: 1200
|
|
51
|
+
gender: FEMALE
|
|
52
|
+
child1:
|
|
53
|
+
age: 6
|
|
54
|
+
child2:
|
|
55
|
+
age: 4
|
|
56
|
+
benunits:
|
|
57
|
+
benunit:
|
|
58
|
+
members: [adult1, adult2, child1, child2]
|
|
59
|
+
is_married: true
|
|
60
|
+
households:
|
|
61
|
+
household:
|
|
62
|
+
members: [adult1, adult2, child1, child2]
|
|
63
|
+
reforms:
|
|
64
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
65
|
+
"2025": true
|
|
66
|
+
output:
|
|
67
|
+
employment_income:
|
|
68
|
+
adult1: 25_000 # Should have minimal response
|
|
69
|
+
adult2: 18_000 # Should have behavioral response capability
|
|
70
|
+
|
|
71
|
+
# Test 3: OBR parameter enabled with lone parent - Verifies single parent behavioral responses
|
|
72
|
+
# This test ensures that:
|
|
73
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
74
|
+
# - Income changes are calculated before any state modifications
|
|
75
|
+
# - The system correctly returns 0 FTE responses when there's no actual policy reform
|
|
76
|
+
# - Proper NaN handling prevents calculation errors
|
|
77
|
+
- name: Test lone parent behavioral response
|
|
78
|
+
period: 2025
|
|
79
|
+
input:
|
|
80
|
+
people:
|
|
81
|
+
parent:
|
|
82
|
+
age: 28
|
|
83
|
+
employment_income: 12_000
|
|
84
|
+
hours_worked: 800
|
|
85
|
+
gender: FEMALE
|
|
86
|
+
child1:
|
|
87
|
+
age: 7
|
|
88
|
+
child2:
|
|
89
|
+
age: 4
|
|
90
|
+
benunits:
|
|
91
|
+
benunit:
|
|
92
|
+
members: [parent, child1, child2]
|
|
93
|
+
is_married: false
|
|
94
|
+
households:
|
|
95
|
+
household:
|
|
96
|
+
members: [parent, child1, child2]
|
|
97
|
+
reforms:
|
|
98
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
99
|
+
"2025": true
|
|
100
|
+
output:
|
|
101
|
+
employment_income:
|
|
102
|
+
parent: 12_000 # Should have behavioral response capability
|
|
103
|
+
|
|
104
|
+
# Test 4: OBR parameter disabled - Verifies system correctly handles disabled behavioral responses
|
|
105
|
+
# This test ensures that:
|
|
106
|
+
# - The system correctly returns no dynamics when OBR is disabled
|
|
107
|
+
# - No calculation errors occur when behavioral responses are turned off
|
|
108
|
+
# - Proper NaN handling prevents calculation errors even when disabled
|
|
109
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
110
|
+
- name: Test behavioral responses are zero when OBR disabled
|
|
111
|
+
period: 2025
|
|
112
|
+
input:
|
|
113
|
+
people:
|
|
114
|
+
parent:
|
|
115
|
+
age: 32
|
|
116
|
+
employment_income: 15_000
|
|
117
|
+
hours_worked: 1040
|
|
118
|
+
benunits:
|
|
119
|
+
benunit:
|
|
120
|
+
members: [parent]
|
|
121
|
+
households:
|
|
122
|
+
household:
|
|
123
|
+
members: [parent]
|
|
124
|
+
reforms:
|
|
125
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
126
|
+
"2025": false # Disabled
|
|
127
|
+
output:
|
|
128
|
+
employment_income:
|
|
129
|
+
parent: 15_000 # Should be unchanged (no behavioral response)
|
|
130
|
+
|
|
131
|
+
# Test 5: OBR parameter enabled with high earner - Verifies minimal response for high income
|
|
132
|
+
# This test ensures that:
|
|
133
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
134
|
+
# - Income changes are calculated before any state modifications
|
|
135
|
+
# - The system correctly returns 0 FTE responses when there's no actual policy reform
|
|
136
|
+
# - Proper NaN handling prevents calculation errors
|
|
137
|
+
- name: Test high earner has minimal behavioral response
|
|
138
|
+
period: 2025
|
|
139
|
+
input:
|
|
140
|
+
people:
|
|
141
|
+
person:
|
|
142
|
+
age: 50
|
|
143
|
+
employment_income: 100_000
|
|
144
|
+
hours_worked: 2200
|
|
145
|
+
benunits:
|
|
146
|
+
benunit:
|
|
147
|
+
members: [person]
|
|
148
|
+
households:
|
|
149
|
+
household:
|
|
150
|
+
members: [person]
|
|
151
|
+
reforms:
|
|
152
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
153
|
+
"2025": true
|
|
154
|
+
output:
|
|
155
|
+
employment_income:
|
|
156
|
+
person: 100_000 # Should be unchanged (minimal behavioral response)
|
|
157
|
+
|
|
158
|
+
# Test 6: Zero income handling - Ensures no NaN values with zero employment income
|
|
159
|
+
# This test ensures that:
|
|
160
|
+
# - Proper NaN handling prevents calculation errors with zero/division by zero cases
|
|
161
|
+
# - Income changes are calculated before any state modifications to avoid corruption
|
|
162
|
+
# - The system handles edge cases (zero income, zero hours) without breaking
|
|
163
|
+
# - No more simulation state corruption from sim.reset_calculations()
|
|
164
|
+
- name: Test zero income handles behavioral response properly
|
|
165
|
+
period: 2025
|
|
166
|
+
input:
|
|
167
|
+
people:
|
|
168
|
+
person:
|
|
169
|
+
age: 30
|
|
170
|
+
employment_income: 0
|
|
171
|
+
hours_worked: 0
|
|
172
|
+
benunits:
|
|
173
|
+
benunit:
|
|
174
|
+
members: [person]
|
|
175
|
+
households:
|
|
176
|
+
household:
|
|
177
|
+
members: [person]
|
|
178
|
+
reforms:
|
|
179
|
+
gov.dynamic.obr_labour_supply_assumptions:
|
|
180
|
+
"2025": true
|
|
181
|
+
output:
|
|
182
|
+
employment_income:
|
|
183
|
+
person: 0 # Should remain 0, not NaN
|
|
@@ -1,33 +1,33 @@
|
|
|
1
1
|
reforms:
|
|
2
2
|
- name: Raise basic rate by 1pp
|
|
3
|
-
expected_impact: 7.
|
|
3
|
+
expected_impact: 7.9
|
|
4
4
|
parameters:
|
|
5
5
|
gov.hmrc.income_tax.rates.uk[0].rate: 0.21
|
|
6
6
|
- name: Raise higher rate by 1pp
|
|
7
|
-
expected_impact:
|
|
7
|
+
expected_impact: 5.1
|
|
8
8
|
parameters:
|
|
9
9
|
gov.hmrc.income_tax.rates.uk[1].rate: 0.42
|
|
10
10
|
- name: Raise personal allowance by ~800GBP/year
|
|
11
|
-
expected_impact:
|
|
11
|
+
expected_impact: -4.1
|
|
12
12
|
parameters:
|
|
13
13
|
gov.hmrc.income_tax.allowances.personal_allowance.amount: 13000
|
|
14
14
|
- name: Raise child benefit by 25GBP/week per additional child
|
|
15
|
-
expected_impact: -1.
|
|
15
|
+
expected_impact: -1.2
|
|
16
16
|
parameters:
|
|
17
17
|
gov.hmrc.child_benefit.amount.additional: 25
|
|
18
18
|
- name: Reduce Universal Credit taper rate to 20%
|
|
19
|
-
expected_impact: -
|
|
19
|
+
expected_impact: -29.4
|
|
20
20
|
parameters:
|
|
21
21
|
gov.dwp.universal_credit.means_test.reduction_rate: 0.2
|
|
22
22
|
- name: Raise Class 1 main employee NICs rate to 10%
|
|
23
|
-
expected_impact:
|
|
23
|
+
expected_impact: 13.3
|
|
24
24
|
parameters:
|
|
25
25
|
gov.hmrc.national_insurance.class_1.rates.employee.main: 0.1
|
|
26
26
|
- name: Raise VAT standard rate by 2pp
|
|
27
|
-
expected_impact:
|
|
27
|
+
expected_impact: 20.9
|
|
28
28
|
parameters:
|
|
29
29
|
gov.hmrc.vat.standard_rate: 0.22
|
|
30
30
|
- name: Raise additional rate by 3pp
|
|
31
|
-
expected_impact:
|
|
31
|
+
expected_impact: 4.4
|
|
32
32
|
parameters:
|
|
33
33
|
gov.hmrc.income_tax.rates.uk[2].rate: 0.48
|
|
@@ -54,9 +54,9 @@ def test_reform_fiscal_impacts(reform, reform_name, expected_impact):
|
|
|
54
54
|
"""Test that each reform produces the expected fiscal impact."""
|
|
55
55
|
impact = get_fiscal_impact(reform)
|
|
56
56
|
|
|
57
|
-
# Allow for small numerical differences (
|
|
57
|
+
# Allow for small numerical differences (1 billion tolerance)
|
|
58
58
|
assert (
|
|
59
|
-
abs(impact - expected_impact) < 0
|
|
59
|
+
abs(impact - expected_impact) < 1.0
|
|
60
60
|
), f"Impact for {reform_name} is {impact:.1f} billion, expected {expected_impact:.1f} billion"
|
|
61
61
|
|
|
62
62
|
|