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.
Files changed (258) hide show
  1. policyengine_uk/__init__.py +5 -3
  2. policyengine_uk/data/__init__.py +1 -0
  3. policyengine_uk/data/dataset_schema.py +70 -18
  4. policyengine_uk/data/economic_assumptions.py +36 -10
  5. policyengine_uk/data/filter_dataset.py +52 -0
  6. policyengine_uk/dynamics/labour_supply.py +343 -0
  7. policyengine_uk/dynamics/participation.py +629 -0
  8. policyengine_uk/dynamics/progression.py +384 -0
  9. policyengine_uk/microsimulation.py +105 -0
  10. policyengine_uk/model_api.py +1 -0
  11. policyengine_uk/parameters/gov/boe/base_rate.yaml +34 -0
  12. policyengine_uk/parameters/gov/boe/index.yaml +2 -0
  13. policyengine_uk/parameters/gov/contrib/behavioral_responses/employee_salary_sacrifice_reduction_rate.yaml +14 -0
  14. policyengine_uk/parameters/gov/contrib/behavioral_responses/salary_sacrifice_broad_base_haircut_rate.yaml +22 -0
  15. policyengine_uk/parameters/gov/contrib/cec/state_pension_increase.yaml +1 -1
  16. policyengine_uk/parameters/gov/contrib/ubi_center/carbon_tax.yaml +2 -2
  17. policyengine_uk/parameters/gov/contrib/ubi_center/land_value_tax.yaml +3 -3
  18. policyengine_uk/parameters/gov/dcms/bbc/tv_licence/colour.yaml +5 -5
  19. policyengine_uk/parameters/gov/dfe/education_spending.yaml +1 -1
  20. policyengine_uk/parameters/gov/dft/rail/fare_index.yaml +32 -0
  21. policyengine_uk/parameters/gov/dft/rail/prior_law_fare_index.yaml +32 -0
  22. policyengine_uk/parameters/gov/dft/rail/ridership_index.yaml +30 -0
  23. policyengine_uk/parameters/gov/dft/spending.yaml +2 -2
  24. policyengine_uk/parameters/gov/dwp/ESA/income/earn_disregard.yaml +1 -1
  25. policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_couple.yaml +1 -1
  26. policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_lone_parent.yaml +1 -1
  27. policyengine_uk/parameters/gov/dwp/ESA/income/income_disregard_single.yaml +1 -1
  28. policyengine_uk/parameters/gov/dwp/ESA/income/pension_disregard.yaml +1 -1
  29. policyengine_uk/parameters/gov/dwp/IIDB/maximum.yaml +1 -1
  30. policyengine_uk/parameters/gov/dwp/JSA/contrib/amount_over_25.yaml +1 -1
  31. policyengine_uk/parameters/gov/dwp/JSA/contrib/earn_disregard.yaml +1 -1
  32. policyengine_uk/parameters/gov/dwp/JSA/contrib/pension_disregard.yaml +1 -1
  33. policyengine_uk/parameters/gov/dwp/JSA/income/amount_18_24.yaml +7 -7
  34. policyengine_uk/parameters/gov/dwp/JSA/income/amount_over_25.yaml +7 -7
  35. policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_couple.yaml +1 -1
  36. policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_lone_parent.yaml +1 -1
  37. policyengine_uk/parameters/gov/dwp/JSA/income/income_disregard_single.yaml +1 -1
  38. policyengine_uk/parameters/gov/dwp/LHA/shared_accommodation_age_threshold.yaml +12 -0
  39. policyengine_uk/parameters/gov/dwp/attendance_allowance/higher.yaml +7 -7
  40. policyengine_uk/parameters/gov/dwp/attendance_allowance/lower.yaml +7 -7
  41. policyengine_uk/parameters/gov/dwp/benefit_cap.yaml +3 -3
  42. policyengine_uk/parameters/gov/dwp/carer_premium/couple.yaml +2 -2
  43. policyengine_uk/parameters/gov/dwp/carer_premium/single.yaml +6 -6
  44. policyengine_uk/parameters/gov/dwp/carers_allowance/rate.yaml +7 -7
  45. policyengine_uk/parameters/gov/dwp/disability_premia/disability_couple.yaml +1 -1
  46. policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_couple.yaml +1 -1
  47. policyengine_uk/parameters/gov/dwp/disability_premia/enhanced_single.yaml +1 -1
  48. policyengine_uk/parameters/gov/dwp/disability_premia/severe_couple.yaml +1 -1
  49. policyengine_uk/parameters/gov/dwp/dla/mobility/higher.yaml +4 -4
  50. policyengine_uk/parameters/gov/dwp/dla/mobility/lower.yaml +8 -8
  51. policyengine_uk/parameters/gov/dwp/dla/self_care/higher.yaml +7 -7
  52. policyengine_uk/parameters/gov/dwp/dla/self_care/lower.yaml +8 -8
  53. policyengine_uk/parameters/gov/dwp/dla/self_care/middle.yaml +7 -7
  54. policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/lone_parent/aged.yaml +1 -1
  55. policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/lone_parent/older.yaml +3 -3
  56. policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/single/aged.yaml +1 -1
  57. policyengine_uk/parameters/gov/dwp/housing_benefit/allowances/single/older.yaml +3 -3
  58. policyengine_uk/parameters/gov/dwp/housing_benefit/means_test/income_disregard/worker.yaml +1 -1
  59. policyengine_uk/parameters/gov/dwp/housing_benefit/non_dep_deduction/amount.yaml +1 -1
  60. policyengine_uk/parameters/gov/dwp/housing_benefit/takeup.yaml +7 -7
  61. policyengine_uk/parameters/gov/dwp/income_support/amounts/amount_16_24.yaml +1 -1
  62. policyengine_uk/parameters/gov/dwp/income_support/amounts/amount_couples_over_18.yaml +1 -1
  63. policyengine_uk/parameters/gov/dwp/income_support/means_test/earn_disregard.yaml +1 -1
  64. policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_couple.yaml +1 -1
  65. policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_lone_parent.yaml +1 -1
  66. policyengine_uk/parameters/gov/dwp/income_support/means_test/income_disregard_single.yaml +1 -1
  67. policyengine_uk/parameters/gov/dwp/income_support/means_test/pension_disregard.yaml +1 -1
  68. policyengine_uk/parameters/gov/dwp/income_support/takeup.yaml +7 -7
  69. policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/carer/addition.yaml +4 -4
  70. policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/minimum_guarantee.yaml +9 -9
  71. policyengine_uk/parameters/gov/dwp/pension_credit/guarantee_credit/severe_disability/addition.yaml +3 -3
  72. policyengine_uk/parameters/gov/dwp/pension_credit/savings_credit/threshold.yaml +5 -5
  73. policyengine_uk/parameters/gov/dwp/pip/daily_living/enhanced.yaml +7 -7
  74. policyengine_uk/parameters/gov/dwp/pip/daily_living/standard.yaml +8 -8
  75. policyengine_uk/parameters/gov/dwp/pip/mobility/enhanced.yaml +4 -4
  76. policyengine_uk/parameters/gov/dwp/pip/mobility/standard.yaml +9 -9
  77. policyengine_uk/parameters/gov/dwp/sda/maximum.yaml +7 -7
  78. policyengine_uk/parameters/gov/dwp/state_pension/basic_state_pension/amount.yaml +11 -11
  79. policyengine_uk/parameters/gov/dwp/state_pension/new_state_pension/amount.yaml +4 -4
  80. policyengine_uk/parameters/gov/dwp/tax_credits/child_tax_credit/limit/child_count.yaml +10 -1
  81. policyengine_uk/parameters/gov/dwp/tax_credits/child_tax_credit/takeup.yaml +7 -7
  82. policyengine_uk/parameters/gov/dwp/tax_credits/working_tax_credit/takeup.yaml +7 -7
  83. policyengine_uk/parameters/gov/dwp/universal_credit/elements/carer/amount.yaml +3 -3
  84. policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/amount.yaml +2 -4
  85. policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/disabled/amount.yaml +2 -4
  86. policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/first/higher_amount.yaml +6 -8
  87. policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/limit/child_count.yaml +6 -1
  88. policyengine_uk/parameters/gov/dwp/universal_credit/elements/child/severely_disabled/amount.yaml +3 -5
  89. policyengine_uk/parameters/gov/dwp/universal_credit/elements/childcare/cap.yaml +2 -6
  90. policyengine_uk/parameters/gov/dwp/universal_credit/elements/disabled/amount.yaml +4 -6
  91. policyengine_uk/parameters/gov/dwp/universal_credit/elements/housing/non_dep_deduction/amount.yaml +4 -1
  92. policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/active.yaml +9 -0
  93. policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/new_claimant_health_element.yaml +9 -0
  94. policyengine_uk/parameters/gov/dwp/universal_credit/rebalancing/standard_allowance_uplift.yaml +13 -0
  95. policyengine_uk/parameters/gov/dwp/universal_credit/standard_allowance/amount.yaml +5 -5
  96. policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/maximum_taxable_income.yaml +2 -1
  97. policyengine_uk/parameters/gov/dwp/winter_fuel_payment/eligibility/taxable_income_test/use_maximum_taxable_income.yaml +1 -0
  98. policyengine_uk/parameters/gov/dynamic/obr_labour_supply_assumptions.yaml +9 -0
  99. policyengine_uk/parameters/gov/economic_assumptions/create_economic_assumption_indices.py +1 -1
  100. policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml +522 -153
  101. policyengine_uk/parameters/gov/hmrc/cgt/additional_rate.yaml +5 -0
  102. policyengine_uk/parameters/gov/hmrc/cgt/basic_rate.yaml +5 -0
  103. policyengine_uk/parameters/gov/hmrc/cgt/higher_rate.yaml +4 -0
  104. policyengine_uk/parameters/gov/hmrc/child_benefit/amount/additional.yaml +6 -6
  105. policyengine_uk/parameters/gov/hmrc/child_benefit/amount/eldest.yaml +8 -8
  106. policyengine_uk/parameters/gov/hmrc/child_benefit/takeup/by_age.yaml +1 -1
  107. policyengine_uk/parameters/gov/hmrc/fuel_duty/calculate_fuel_duty_rates.py +464 -0
  108. policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml +86 -10
  109. policyengine_uk/parameters/gov/hmrc/income_tax/allowances/personal_allowance/amount.yaml +6 -0
  110. policyengine_uk/parameters/gov/hmrc/income_tax/earned_taxable_income_exclusions.yaml +2 -1
  111. policyengine_uk/parameters/gov/hmrc/income_tax/income_tax_additions.yaml +1 -0
  112. policyengine_uk/parameters/gov/hmrc/income_tax/rates/dividends.yaml +12 -0
  113. policyengine_uk/parameters/gov/hmrc/income_tax/rates/property.yaml +46 -0
  114. policyengine_uk/parameters/gov/hmrc/income_tax/rates/savings.yaml +46 -0
  115. policyengine_uk/parameters/gov/hmrc/income_tax/rates/scotland/rates.yaml +2 -2
  116. policyengine_uk/parameters/gov/hmrc/income_tax/rates/uk.yaml +14 -2
  117. policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employee/additional.yaml +4 -6
  118. policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/rates/employer.yaml +3 -3
  119. policyengine_uk/parameters/gov/hmrc/national_insurance/class_1/thresholds/secondary_threshold.yaml +14 -4
  120. policyengine_uk/parameters/gov/hmrc/national_insurance/class_2/flat_rate.yaml +2 -2
  121. policyengine_uk/parameters/gov/hmrc/national_insurance/salary_sacrifice_pension_cap.yaml +16 -0
  122. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/index.yaml +12 -0
  123. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_1/boe_margin.yaml +11 -0
  124. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/additional_rate.yaml +27 -0
  125. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/index.yaml +16 -0
  126. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/plan_2/upper_threshold.yaml +48 -0
  127. policyengine_uk/parameters/gov/hmrc/student_loans/interest_rates/postgraduate_additional_rate.yaml +11 -0
  128. policyengine_uk/parameters/gov/hmrc/student_loans/postgraduate_repayment_rate.yaml +9 -0
  129. policyengine_uk/parameters/gov/hmrc/student_loans/repayment_rate.yaml +9 -0
  130. policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_1.yaml +25 -0
  131. policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_2.yaml +58 -0
  132. policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_4.yaml +19 -0
  133. policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/plan_5.yaml +16 -0
  134. policyengine_uk/parameters/gov/hmrc/student_loans/thresholds/postgraduate.yaml +21 -0
  135. policyengine_uk/parameters/gov/hmrc/vat/reduced_rate_share.yaml +3 -3
  136. policyengine_uk/parameters/gov/indices/private_rent_index.yaml +9 -9
  137. policyengine_uk/parameters/gov/revenue_scotland/lbtt/non_residential.yaml +2 -2
  138. policyengine_uk/parameters/gov/revenue_scotland/lbtt/rent.yaml +2 -2
  139. policyengine_uk/parameters/gov/revenue_scotland/lbtt/residential/first_time_buyer_rate.yaml +2 -2
  140. policyengine_uk/parameters/gov/revenue_scotland/lbtt/residential/rate.yaml +2 -2
  141. policyengine_uk/parameters/gov/wra/land_transaction_tax/non_residential.yaml +2 -2
  142. policyengine_uk/parameters/gov/wra/land_transaction_tax/rent.yaml +2 -2
  143. policyengine_uk/parameters/gov/wra/land_transaction_tax/residential/higher_rate.yaml +1 -1
  144. policyengine_uk/parameters/gov/wra/land_transaction_tax/residential/primary.yaml +2 -2
  145. policyengine_uk/parameters/household/consumption/carbon/consumption.yaml +8 -6
  146. policyengine_uk/parameters/household/consumption/carbon/intensity.yaml +4 -1
  147. policyengine_uk/parameters/household/consumption/carbon/production.yaml +12 -7
  148. policyengine_uk/parameters/household/consumption/carbon/production_by_source.yaml +76 -41
  149. policyengine_uk/parameters/household/consumption/fuel/prices/petrol.yaml +1 -1
  150. policyengine_uk/parameters/household/poverty/absolute_poverty_threshold_bhc.yaml +1 -1
  151. policyengine_uk/reforms/policyengine/adjust_budgets.py +0 -1
  152. policyengine_uk/scenarios/__init__.py +4 -0
  153. policyengine_uk/scenarios/pip_reform.py +23 -0
  154. policyengine_uk/scenarios/reindex_benefit_cap.py +32 -0
  155. policyengine_uk/scenarios/repeal_two_child_limit.py +10 -0
  156. policyengine_uk/scenarios/uc_reform.py +50 -0
  157. policyengine_uk/simulation.py +619 -0
  158. policyengine_uk/system.py +3 -257
  159. policyengine_uk/tax_benefit_system.py +141 -0
  160. policyengine_uk/tests/behavioral_responses/test_labor_supply_responses.yaml +183 -0
  161. policyengine_uk/tests/microsimulation/reforms_config.yaml +8 -8
  162. policyengine_uk/tests/microsimulation/test_reform_impacts.py +2 -2
  163. policyengine_uk/tests/microsimulation/test_salary_sacrifice_cap_reform.py +401 -0
  164. policyengine_uk/tests/microsimulation/test_validity.py +2 -3
  165. policyengine_uk/tests/microsimulation/update_reform_impacts.py +104 -40
  166. policyengine_uk/tests/policy/baseline/contrib/policyengine/employer_ni/employer_ni_fixed_employer_cost_change.yaml +105 -0
  167. policyengine_uk/tests/policy/baseline/finance/benefit/family/child_benefit.yaml +2 -0
  168. policyengine_uk/tests/policy/baseline/finance/benefit/family/income_support.yaml +0 -23
  169. policyengine_uk/tests/policy/baseline/gov/dcms/bbc/tv-licence/tv_licence.yaml +3 -0
  170. policyengine_uk/tests/policy/baseline/gov/dfe/extended_childcare_entitlement/extended_childcare_entitlement.yaml +17 -17
  171. policyengine_uk/tests/policy/baseline/gov/dwp/basic_state_pension.yaml +44 -0
  172. policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/allowances/gift_aid.yaml +71 -0
  173. policyengine_uk/tests/policy/baseline/gov/hmrc/income_tax/allowances/personal_allowance.yaml +161 -0
  174. policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employee.yaml +107 -0
  175. policyengine_uk/tests/policy/baseline/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employer.yaml +95 -0
  176. policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_interest_rate.yaml +153 -0
  177. policyengine_uk/tests/policy/baseline/gov/hmrc/student_loans/student_loan_repayment.yaml +130 -0
  178. policyengine_uk/tests/policy/baseline/household/wealth/vehicle.yaml +27 -0
  179. policyengine_uk/tests/policy/reforms/nov_2025_budget/income_source_tax_rates.yaml +235 -0
  180. policyengine_uk/tests/policy/reforms/nov_2025_budget/income_tax_freeze.yaml +83 -0
  181. policyengine_uk/tests/policy/reforms/parametric/basic_income/basic_income.yaml +1 -0
  182. policyengine_uk/tests/test_behavioral_responses.py +215 -0
  183. policyengine_uk/tests/test_fiscal_year_parameters.py +131 -0
  184. policyengine_uk/utils/__init__.py +1 -0
  185. policyengine_uk/utils/compare.py +28 -0
  186. policyengine_uk/utils/create_ahc_deflator.py +169 -0
  187. policyengine_uk/utils/create_triple_lock.py +1 -1
  188. policyengine_uk/utils/dependencies.py +259 -0
  189. policyengine_uk/utils/parameters.py +12 -1
  190. policyengine_uk/utils/scenario.py +225 -0
  191. policyengine_uk/utils/solve_private_school_attendance_factor.py +4 -6
  192. policyengine_uk/variables/contrib/policyengine/education_budget_change.py +0 -1
  193. policyengine_uk/variables/contrib/policyengine/employer_ni/baseline_employer_cost.py +5 -1
  194. policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_fixed_employer_cost_change.py +23 -23
  195. policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_capital_incidence.py +1 -1
  196. policyengine_uk/variables/contrib/policyengine/employer_ni/employer_ni_response_consumer_incidence.py +1 -1
  197. policyengine_uk/variables/contrib/policyengine/other_public_spending_budget_change.py +0 -1
  198. policyengine_uk/variables/gov/dfe/targeted_childcare_entitlement/targeted_childcare_entitlement_eligible.py +0 -1
  199. policyengine_uk/variables/gov/dft/rail_subsidy_spending.py +16 -1
  200. policyengine_uk/variables/gov/dft/rail_usage.py +16 -0
  201. policyengine_uk/variables/gov/dwp/BRMA_LHA_rate.py +7 -2
  202. policyengine_uk/variables/gov/dwp/LHA_category.py +4 -2
  203. policyengine_uk/variables/gov/dwp/additional_state_pension.py +4 -2
  204. policyengine_uk/variables/gov/dwp/basic_state_pension.py +26 -8
  205. policyengine_uk/variables/gov/dwp/is_CTC_eligible.py +1 -1
  206. policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt.py +9 -13
  207. policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_earnings.py +66 -0
  208. policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_health_disability.py +75 -0
  209. policyengine_uk/variables/gov/dwp/is_benefit_cap_exempt_other.py +66 -0
  210. policyengine_uk/variables/gov/dwp/winter_fuel_allowance.py +5 -4
  211. policyengine_uk/variables/gov/gov_tax.py +0 -2
  212. policyengine_uk/variables/gov/hmrc/household_tax.py +0 -1
  213. policyengine_uk/variables/gov/hmrc/income_tax/allowances/gift_aid.py +23 -0
  214. policyengine_uk/variables/gov/hmrc/income_tax/allowances/personal_allowance.py +9 -2
  215. policyengine_uk/variables/gov/hmrc/income_tax/income_tax_pre_charges.py +1 -0
  216. policyengine_uk/variables/gov/hmrc/income_tax/liability/property_income_tax.py +75 -0
  217. policyengine_uk/variables/gov/hmrc/income_tax/liability/savings_income_tax.py +4 -4
  218. policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_broad_base_haircut.py +43 -0
  219. policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employee.py +38 -0
  220. policyengine_uk/variables/gov/hmrc/national_insurance/salary_sacrifice_pension_ni_employer.py +27 -0
  221. policyengine_uk/variables/gov/hmrc/pensions/pension_contributions_via_salary_sacrifice_adjusted.py +31 -0
  222. policyengine_uk/variables/gov/hmrc/pensions/salary_sacrifice_returned_to_income.py +41 -0
  223. policyengine_uk/variables/gov/hmrc/student_loans/__init__.py +2 -0
  224. policyengine_uk/variables/gov/hmrc/student_loans/plan_1_interest_rate.py +23 -0
  225. policyengine_uk/variables/gov/hmrc/student_loans/plan_2_interest_rate.py +31 -0
  226. policyengine_uk/variables/gov/hmrc/student_loans/plan_4_interest_rate.py +22 -0
  227. policyengine_uk/variables/gov/hmrc/student_loans/plan_5_interest_rate.py +18 -0
  228. policyengine_uk/variables/gov/hmrc/student_loans/postgraduate_interest_rate.py +23 -0
  229. policyengine_uk/variables/gov/hmrc/student_loans/student_loan_plan.py +27 -0
  230. policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment.py +91 -0
  231. policyengine_uk/variables/gov/hmrc/student_loans/student_loan_repayment_rate.py +31 -0
  232. policyengine_uk/variables/gov/hmrc/would_claim_child_benefit.py +5 -1
  233. policyengine_uk/variables/household/demographic/benunit/benunit_count_adults.py +11 -0
  234. policyengine_uk/variables/household/demographic/is_disabled_for_benefits.py +13 -1
  235. policyengine_uk/variables/household/income/hbai_household_net_income.py +29 -1
  236. policyengine_uk/variables/household/income/hbai_household_net_income_ahc.py +13 -0
  237. policyengine_uk/variables/household/income/household_net_income.py +5 -1
  238. policyengine_uk/variables/household/income/inflation_adjustment.py +24 -0
  239. policyengine_uk/variables/household/post_tax_income.py +12 -0
  240. policyengine_uk/variables/household/wealth/num_vehicles.py +9 -0
  241. policyengine_uk/variables/household/wealth/owns_vehicle.py +17 -0
  242. policyengine_uk/variables/input/consumption/property/council_tax.py +0 -35
  243. policyengine_uk/variables/input/consumption/property/employee_pension_contributions.py +8 -1
  244. policyengine_uk/variables/input/consumption/property/employee_pension_contributions_reported.py +16 -0
  245. policyengine_uk/variables/input/consumption/property/pension_contributions_via_salary_sacrifice.py +16 -0
  246. policyengine_uk/variables/input/employment_income.py +2 -0
  247. policyengine_uk/variables/input/rent.py +0 -40
  248. policyengine_uk/variables/input/savings_interest_income.py +3 -1
  249. {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/METADATA +17 -8
  250. {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/RECORD +252 -173
  251. {policyengine_uk-2.40.1.dist-info → policyengine_uk-2.65.6.dist-info}/WHEEL +1 -1
  252. policyengine_uk/repo.py +0 -3
  253. policyengine_uk/tests/policy/baseline/gov/abolitions/abolition_parameters.yaml +0 -250
  254. policyengine_uk/variables/contrib/policyengine/high_income_incident_tax_change.py +0 -22
  255. policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template/CHANGELOG.md +0 -2285
  256. policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template/README.md +0 -37
  257. policyengine_uk-2.40.1.dist-info/licenses/LICENSE +0 -661
  258. {policyengine_uk-2.40.1.data/data/share/openfisca/openfisca-country-template → policyengine_uk-2.65.6.dist-info/licenses}/LICENSE +0 -0
@@ -1,6 +1,11 @@
1
1
  description: Capital gains tax rate on additional rate taxpayers. This parameter is under active development and reforms including it should not be cited.
2
2
  values:
3
3
  2015-01-01: 0.2
4
+ 2025-04-06: 0.24
4
5
  metadata:
5
6
  unit: /1
6
7
  label: Capital Gains Tax additional rate
8
+ reference:
9
+ - title: Finance Act 2025(7)
10
+ href: https://www.legislation.gov.uk/ukpga/2025/8/section/7
11
+
@@ -1,6 +1,11 @@
1
1
  description: Capital gains tax rate on basic rate taxpayers. This parameter is under active development and reforms including it should not be cited.
2
2
  values:
3
3
  2015-01-01: 0.1
4
+ 2025-04-06: 0.18
4
5
  metadata:
5
6
  unit: /1
6
7
  label: Capital Gains Tax basic rate
8
+ reference:
9
+ - title: Finance Act 2025(7)
10
+ href: https://www.legislation.gov.uk/ukpga/2025/8/section/7
11
+
@@ -1,6 +1,10 @@
1
1
  description: Capital gains tax rate on higher rate taxpayers. This parameter is under active development and reforms including it should not be cited.
2
2
  values:
3
3
  2015-01-01: 0.2
4
+ 2025-04-06: 0.24
4
5
  metadata:
5
6
  unit: /1
6
7
  label: Capital Gains Tax higher rate
8
+ reference:
9
+ - title: Finance Act 2025(7)
10
+ href: https://www.legislation.gov.uk/ukpga/2025/8/section/7
@@ -1,7 +1,7 @@
1
1
  description: Child Benefit amount for each additional child
2
2
  values:
3
3
  2007-04-09:
4
- value: 12.10
4
+ value: 12.1
5
5
  # Legislation.gov.uk amends this amount to £12.55, but
6
6
  # the amendment it references directs that it should be
7
7
  # amended to £12.10. We use the original amendment.
@@ -9,12 +9,12 @@ values:
9
9
  - title: The Child Benefit Up-rating Order 2007(2)(b)
10
10
  href: https://www.legislation.gov.uk/uksi/2007/1053/article/2/made
11
11
  2009-01-05:
12
- value: 13.20
12
+ value: 13.2
13
13
  reference:
14
14
  - title: The Child Benefit (Rates) (Amendment) Regulations 2008(3)(b)
15
15
  href: https://www.legislation.gov.uk/uksi/2008/3246/regulation/3/made
16
16
  2010-04-12:
17
- value: 13.40
17
+ value: 13.4
18
18
  reference:
19
19
  - title: The Child Benefit Up-rating Order 2010(2)(b)
20
20
  href: https://www.legislation.gov.uk/uksi/2010/982/article/2/made
@@ -24,7 +24,7 @@ values:
24
24
  - title: The Child Benefit and Tax Credits Up-rating Order 2014(2)(b)
25
25
  href: https://www.legislation.gov.uk/uksi/2014/384/article/2/made
26
26
  2015-04-06:
27
- value: 13.70
27
+ value: 13.7
28
28
  reference:
29
29
  - title: The Child Benefit and Tax Credits Up-rating Order 2015(2)(b)
30
30
  href: https://www.legislation.gov.uk/uksi/2015/567/article/2/made
@@ -34,12 +34,12 @@ values:
34
34
  - title: The Tax Credits, Child Benefit and Guardian’s Allowance Up-rating Regulations 2020(5)(b)
35
35
  href: https://www.legislation.gov.uk/uksi/2020/298/regulation/5/made
36
36
  2021-04-12:
37
- value: 14.00
37
+ value: 14
38
38
  reference:
39
39
  - title: The Tax Credits, Child Benefit and Guardian’s Allowance Up-rating Regulations 2021(5)(b)
40
40
  href: https://www.legislation.gov.uk/uksi/2021/156/regulation/5/made
41
41
  2022-04-01: 14.45
42
- 2023-04-01: 15.90
42
+ 2023-04-01: 15.9
43
43
  2024-04-01:
44
44
  value: 16.95
45
45
  reference:
@@ -1,27 +1,27 @@
1
1
  description: Child Benefit amount for the eldest or only child
2
2
  values:
3
3
  2007-04-09:
4
- value: 18.80
4
+ value: 18.8
5
5
  reference:
6
6
  - title: The Child Benefit Up-rating Order 2007(2)(a)
7
7
  href: https://www.legislation.gov.uk/uksi/2007/1053/article/2/made
8
8
  2009-01-05:
9
- value: 20.00
9
+ value: 20
10
10
  reference:
11
11
  - title: The Child Benefit (Rates) (Amendment) Regulations 2008(3)(a)
12
12
  href: https://www.legislation.gov.uk/uksi/2008/3246/regulation/3/made
13
13
  2010-04-12:
14
- value: 20.30
14
+ value: 20.3
15
15
  reference:
16
16
  - title: The Child Benefit Up-rating Order 2010(2)(a)
17
17
  href: https://www.legislation.gov.uk/uksi/2010/982/article/2/made
18
18
  2014-04-07:
19
- value: 20.50
19
+ value: 20.5
20
20
  reference:
21
21
  - title: The Child Benefit and Tax Credits Up-rating Order 2014(2)(a)
22
22
  href: https://www.legislation.gov.uk/uksi/2014/384/article/2/made
23
23
  2015-04-06:
24
- value: 20.70
24
+ value: 20.7
25
25
  reference:
26
26
  - title: The Child Benefit and Tax Credits Up-rating Order 2015(2)(a)
27
27
  href: https://www.legislation.gov.uk/uksi/2015/567/article/2/made
@@ -35,10 +35,10 @@ values:
35
35
  reference:
36
36
  - title: The Tax Credits, Child Benefit and Guardian’s Allowance Up-rating Regulations 2021(5)(a)
37
37
  href: https://www.legislation.gov.uk/uksi/2021/156/regulation/5/made
38
- 2022-04-01: 21.80
39
- 2023-04-01: 24.00
38
+ 2022-04-01: 21.8
39
+ 2023-04-01: 24
40
40
  2024-04-01:
41
- value: 25.60
41
+ value: 25.6
42
42
  reference:
43
43
  - title: Benefits Uprating 2024/25 | Commons Library Briefing
44
44
  href: https://researchbriefings.files.parliament.uk/documents/CBP-9872/CBP-9872.pdf
@@ -7,7 +7,7 @@ brackets:
7
7
  - threshold:
8
8
  2022-01-01: 1
9
9
  amount:
10
- 2022-01-01: 0.80
10
+ 2022-01-01: 0.8
11
11
  - threshold:
12
12
  2022-01-01: 2
13
13
  amount:
@@ -0,0 +1,464 @@
1
+ """
2
+ Calculates calendar year average fuel duty rates and updates petrol_and_diesel.yaml.
3
+
4
+ Reads base rates from petrol_and_diesel.yaml and RPI forecasts from yoy_growth.yaml,
5
+ then computes weighted averages accounting for the staggered 5p cut reversal and
6
+ RPI uprating from April 2027.
7
+
8
+ Usage:
9
+ python calculate_fuel_duty_rates.py # Print calculations only
10
+ python calculate_fuel_duty_rates.py --update # Update the YAML file
11
+ """
12
+
13
+ import argparse
14
+ import re
15
+ from datetime import date
16
+ from calendar import isleap
17
+ from pathlib import Path
18
+
19
+ import yaml
20
+
21
+
22
+ # Years to calculate rates for
23
+ CALCULATION_YEARS = range(2026, 2031)
24
+
25
+
26
+ def get_repo_root() -> Path:
27
+ """Find the repository root by looking for policyengine_uk directory."""
28
+ current = Path(__file__).resolve()
29
+ while current != current.parent:
30
+ if (current / "policyengine_uk").is_dir():
31
+ return current
32
+ current = current.parent
33
+ raise RuntimeError("Could not find repository root")
34
+
35
+
36
+ def get_fuel_duty_yaml_path() -> Path:
37
+ """Get the path to the fuel duty YAML file."""
38
+ repo_root = get_repo_root()
39
+ return (
40
+ repo_root
41
+ / "policyengine_uk/parameters/gov/hmrc/fuel_duty/petrol_and_diesel.yaml"
42
+ )
43
+
44
+
45
+ def load_fuel_duty_rates() -> dict:
46
+ """Load fuel duty rates from the YAML parameter file."""
47
+ yaml_path = get_fuel_duty_yaml_path()
48
+ with open(yaml_path) as f:
49
+ return yaml.safe_load(f)
50
+
51
+
52
+ def load_rpi_forecasts() -> dict:
53
+ """Load RPI year-on-year growth forecasts from economic assumptions."""
54
+ repo_root = get_repo_root()
55
+ yaml_path = (
56
+ repo_root
57
+ / "policyengine_uk/parameters/gov/economic_assumptions/yoy_growth.yaml"
58
+ )
59
+ with open(yaml_path) as f:
60
+ data = yaml.safe_load(f)
61
+
62
+ # Extract RPI values and convert to percentage format
63
+ rpi_values = data["obr"]["rpi"]["values"]
64
+ rpi_forecasts = {}
65
+ for date_key, value in rpi_values.items():
66
+ # Handle both string and datetime.date keys from YAML
67
+ if hasattr(date_key, "year"):
68
+ year = date_key.year
69
+ else:
70
+ year = int(str(date_key).split("-")[0])
71
+ # Convert from decimal (0.0371) to percentage (3.71)
72
+ rpi_forecasts[year] = value * 100
73
+ return rpi_forecasts
74
+
75
+
76
+ def get_value_for_date(values: dict, target_date: str) -> float:
77
+ """
78
+ Get the value for a specific date from a YAML values dict.
79
+ Handles both string and datetime.date keys.
80
+ """
81
+ for date_key, value in values.items():
82
+ # Normalize date key to string for comparison
83
+ if hasattr(date_key, "strftime"):
84
+ key_str = date_key.strftime("%Y-%m-%d")
85
+ else:
86
+ key_str = str(date_key)
87
+
88
+ if key_str == target_date:
89
+ # Value might be a dict with 'value' key or a direct number
90
+ if isinstance(value, dict):
91
+ return value["value"]
92
+ return value
93
+ return None
94
+
95
+
96
+ def get_base_rate_with_cut(fuel_duty_data: dict) -> float:
97
+ """
98
+ Get the base fuel duty rate with the 5p cut still in place.
99
+ This is the rate at 2022-03-23 (when the 5p cut was introduced).
100
+ Returns rate in pence.
101
+ """
102
+ values = fuel_duty_data["values"]
103
+ # The 5p cut rate is at 2022-03-23
104
+ rate = get_value_for_date(values, "2022-03-23")
105
+ if rate is None:
106
+ raise ValueError("Could not find 2022-03-23 fuel duty rate")
107
+ # Convert from GBP to pence
108
+ return rate * 100
109
+
110
+
111
+ def get_pre_cut_rate(fuel_duty_data: dict) -> float:
112
+ """
113
+ Get the fuel duty rate before the 5p cut (the rate to restore to).
114
+ This is the rate at 2021-01-01 (57.95p).
115
+ Returns rate in pence.
116
+ """
117
+ values = fuel_duty_data["values"]
118
+ rate = get_value_for_date(values, "2021-01-01")
119
+ if rate is None:
120
+ raise ValueError("Could not find 2021-01-01 fuel duty rate")
121
+ return rate * 100
122
+
123
+
124
+ # Staggered reversal schedule (date, cumulative increase in pence)
125
+ REVERSAL_SCHEDULE = [
126
+ (date(2026, 9, 1), 1.0), # +1p
127
+ (date(2026, 12, 1), 3.0), # +2p more (total +3p)
128
+ (date(2027, 3, 1), 5.0), # +2p more (total +5p, full reversal)
129
+ ]
130
+
131
+
132
+ def get_rate_on_date(
133
+ d: date,
134
+ base_rate_with_cut: float,
135
+ pre_cut_rate: float,
136
+ rpi_forecasts: dict,
137
+ ) -> float:
138
+ """Get the fuel duty rate (in pence) on a specific date."""
139
+ # Start with the base rate (with 5p cut still in place)
140
+ rate = base_rate_with_cut
141
+
142
+ # Apply staggered reversal
143
+ for reversal_date, increase in REVERSAL_SCHEDULE:
144
+ if d >= reversal_date:
145
+ rate = base_rate_with_cut + increase
146
+
147
+ # Apply RPI uprating from April 2027
148
+ if d >= date(2027, 4, 1):
149
+ # Rate after full reversal (pre-cut rate)
150
+ rate = pre_cut_rate
151
+
152
+ # Apply cumulative RPI uprating
153
+ for year in sorted(rpi_forecasts.keys()):
154
+ if year < 2026:
155
+ continue # Only apply forecasts from 2026 onwards
156
+ uprating_date = date(year + 1, 4, 1)
157
+ if d >= uprating_date:
158
+ rpi = rpi_forecasts[year]
159
+ rate = rate * (1 + rpi / 100)
160
+
161
+ return round(rate, 2)
162
+
163
+
164
+ def days_in_year(year: int) -> int:
165
+ """Return number of days in a year."""
166
+ return 366 if isleap(year) else 365
167
+
168
+
169
+ def calculate_annual_average(
170
+ year: int,
171
+ base_rate_with_cut: float,
172
+ pre_cut_rate: float,
173
+ rpi_forecasts: dict,
174
+ ) -> float:
175
+ """Calculate the weighted average fuel duty rate for a calendar year."""
176
+ total_days = days_in_year(year)
177
+
178
+ # Calculate daily rates and sum them
179
+ total_rate = 0.0
180
+ for month in range(1, 13):
181
+ for day in range(1, 32):
182
+ try:
183
+ d = date(year, month, day)
184
+ total_rate += get_rate_on_date(
185
+ d, base_rate_with_cut, pre_cut_rate, rpi_forecasts
186
+ )
187
+ except ValueError:
188
+ # Invalid date (e.g., Feb 30)
189
+ continue
190
+
191
+ average = total_rate / total_days
192
+ return round(average, 2)
193
+
194
+
195
+ def format_as_pounds(pence: float) -> str:
196
+ """Convert pence to pounds string format for YAML."""
197
+ return f"{pence / 100:.4f}"
198
+
199
+
200
+ def generate_year_breakdown(
201
+ year: int,
202
+ base_rate_with_cut: float,
203
+ pre_cut_rate: float,
204
+ rpi_forecasts: dict,
205
+ ) -> list:
206
+ """Generate period breakdown for a year, returns list of (start, end, rate, days)."""
207
+ current_rate = None
208
+ period_start = None
209
+ periods = []
210
+
211
+ for month in range(1, 13):
212
+ for day in range(1, 32):
213
+ try:
214
+ d = date(year, month, day)
215
+ rate = get_rate_on_date(
216
+ d, base_rate_with_cut, pre_cut_rate, rpi_forecasts
217
+ )
218
+
219
+ if rate != current_rate:
220
+ if current_rate is not None:
221
+ days = (prev_date - period_start).days + 1
222
+ periods.append(
223
+ (period_start, prev_date, current_rate, days)
224
+ )
225
+ current_rate = rate
226
+ period_start = d
227
+ prev_date = d
228
+ except ValueError:
229
+ continue
230
+
231
+ # Add final period
232
+ if current_rate is not None:
233
+ days = (prev_date - period_start).days + 1
234
+ periods.append((period_start, prev_date, current_rate, days))
235
+
236
+ return periods
237
+
238
+
239
+ def generate_note_for_year(
240
+ year: int,
241
+ avg_pence: float,
242
+ base_rate_with_cut: float,
243
+ pre_cut_rate: float,
244
+ rpi_forecasts: dict,
245
+ ) -> str:
246
+ """Generate the note text for a year's YAML entry."""
247
+ periods = generate_year_breakdown(
248
+ year, base_rate_with_cut, pre_cut_rate, rpi_forecasts
249
+ )
250
+ total_days = days_in_year(year)
251
+ year_type = "leap year" if isleap(year) else ""
252
+
253
+ lines = []
254
+ if year_type:
255
+ lines.append(f"Calendar year {year} average ({year_type}):")
256
+ else:
257
+ lines.append(f"Calendar year {year} average:")
258
+
259
+ for start, end, rate, days in periods:
260
+ lines.append(
261
+ f"- {start.strftime('%b %d')} - {end.strftime('%b %d')} "
262
+ f"({days} days): {rate:.2f}p"
263
+ )
264
+
265
+ # Add formula
266
+ formula_parts = [f"{rate:.2f}p * {days}" for _, _, rate, days in periods]
267
+ lines.append(
268
+ f"({' + '.join(formula_parts)}) / {total_days} = {avg_pence:.2f}p"
269
+ )
270
+ lines.append("Generated by calculate_fuel_duty_rates.py")
271
+
272
+ return "\n".join(lines)
273
+
274
+
275
+ def update_yaml_file(
276
+ calculated_rates: dict,
277
+ rpi_forecasts: dict,
278
+ base_rate_with_cut: float,
279
+ pre_cut_rate: float,
280
+ ) -> None:
281
+ """Update the petrol_and_diesel.yaml file with calculated rates."""
282
+ yaml_path = get_fuel_duty_yaml_path()
283
+
284
+ # Read the current file content
285
+ with open(yaml_path, "r") as f:
286
+ content = f.read()
287
+
288
+ # For each year, update or add the entry
289
+ for year, avg_pence in calculated_rates.items():
290
+ date_str = f"{year}-01-01"
291
+ value_pounds = avg_pence / 100
292
+
293
+ # Generate the note
294
+ note = generate_note_for_year(
295
+ year, avg_pence, base_rate_with_cut, pre_cut_rate, rpi_forecasts
296
+ )
297
+ # Indent note lines for YAML
298
+ note_yaml = note.replace("\n", "\n ")
299
+
300
+ # Pattern to match existing entry for this year
301
+ # Matches from the date line until the next date or metadata section
302
+ pattern = (
303
+ rf"( {date_str}:.*?)(?=\n \d{{4}}-\d{{2}}-\d{{2}}:|\nmetadata:)"
304
+ )
305
+
306
+ # New entry text
307
+ new_entry = f""" {date_str}:
308
+ value: {value_pounds:.4f}
309
+ metadata:
310
+ reference:
311
+ - title: OBR Economic and Fiscal Outlook November 2025
312
+ href: https://obr.uk/efo/economic-and-fiscal-outlook-november-2025/
313
+ note: |
314
+ {note_yaml}"""
315
+
316
+ # Try to replace existing entry
317
+ if re.search(pattern, content, re.DOTALL):
318
+ content = re.sub(pattern, new_entry, content, flags=re.DOTALL)
319
+ else:
320
+ # Entry doesn't exist, need to add it before metadata section
321
+ # Find the metadata section and insert before it
322
+ metadata_match = re.search(r"\nmetadata:", content)
323
+ if metadata_match:
324
+ insert_pos = metadata_match.start()
325
+ content = (
326
+ content[:insert_pos]
327
+ + "\n"
328
+ + new_entry
329
+ + content[insert_pos:]
330
+ )
331
+
332
+ # Write the updated content back
333
+ with open(yaml_path, "w") as f:
334
+ f.write(content)
335
+
336
+ print(f"Updated {yaml_path}")
337
+
338
+
339
+ def print_calculations(
340
+ base_rate_with_cut: float,
341
+ pre_cut_rate: float,
342
+ rpi_forecasts: dict,
343
+ calculated_rates: dict,
344
+ ) -> None:
345
+ """Print calculation details to stdout."""
346
+ print("Loading data from repository files...")
347
+ print(f" Base rate with 5p cut (2022-03-23): {base_rate_with_cut:.2f}p")
348
+ print(f" Pre-cut rate (2021-01-01): {pre_cut_rate:.2f}p")
349
+ print()
350
+
351
+ print(
352
+ "RPI forecasts from yoy_growth.yaml (applied in April of next year):"
353
+ )
354
+ for year in CALCULATION_YEARS:
355
+ rpi = rpi_forecasts.get(year, 0)
356
+ print(f" {year}: {rpi:.2f}%")
357
+ print()
358
+
359
+ print("=" * 60)
360
+ print("Fuel Duty Rate Calculations")
361
+ print("=" * 60)
362
+ print()
363
+
364
+ # Show the rate schedule
365
+ print("Rate Schedule (actual policy dates):")
366
+ print("-" * 40)
367
+ key_dates = [
368
+ date(2026, 1, 1),
369
+ date(2026, 9, 1),
370
+ date(2026, 12, 1),
371
+ date(2027, 3, 1),
372
+ date(2027, 4, 1),
373
+ date(2028, 4, 1),
374
+ date(2029, 4, 1),
375
+ date(2030, 4, 1),
376
+ ]
377
+ for d in key_dates:
378
+ rate = get_rate_on_date(
379
+ d, base_rate_with_cut, pre_cut_rate, rpi_forecasts
380
+ )
381
+ print(f" {d}: {rate:.2f}p ({format_as_pounds(rate)} GBP)")
382
+
383
+ print()
384
+ print("Calendar Year Averages (for YAML parameter file):")
385
+ print("-" * 40)
386
+
387
+ for year in CALCULATION_YEARS:
388
+ avg = calculated_rates[year]
389
+ print(f" {year}-01-01:")
390
+ print(f" value: {format_as_pounds(avg)}")
391
+ print(f" # Average rate: {avg:.2f}p")
392
+ print()
393
+
394
+ # Show detailed breakdown for each year
395
+ print()
396
+ print("Detailed Breakdown:")
397
+ print("=" * 60)
398
+
399
+ for year in CALCULATION_YEARS:
400
+ year_type = "leap year" if isleap(year) else "regular year"
401
+ print(f"\n{year} ({year_type}):")
402
+ print("-" * 40)
403
+
404
+ periods = generate_year_breakdown(
405
+ year, base_rate_with_cut, pre_cut_rate, rpi_forecasts
406
+ )
407
+ total_days = days_in_year(year)
408
+ weighted_sum = 0.0
409
+
410
+ for start, end, rate, days in periods:
411
+ weighted_sum += rate * days
412
+ print(
413
+ f" {start.strftime('%b %d')} - {end.strftime('%b %d')}: "
414
+ f"{days:3d} days @ {rate:.2f}p"
415
+ )
416
+
417
+ avg = weighted_sum / total_days
418
+ print(f" Average: {avg:.2f}p ({format_as_pounds(avg)} GBP)")
419
+
420
+
421
+ def main():
422
+ parser = argparse.ArgumentParser(
423
+ description="Calculate fuel duty rates based on Autumn Budget 2025 policy."
424
+ )
425
+ parser.add_argument(
426
+ "--update",
427
+ action="store_true",
428
+ help="Update the petrol_and_diesel.yaml file with calculated rates",
429
+ )
430
+ args = parser.parse_args()
431
+
432
+ # Load data from repository files
433
+ fuel_duty_data = load_fuel_duty_rates()
434
+ rpi_forecasts = load_rpi_forecasts()
435
+
436
+ base_rate_with_cut = get_base_rate_with_cut(fuel_duty_data)
437
+ pre_cut_rate = get_pre_cut_rate(fuel_duty_data)
438
+
439
+ # Calculate rates for each year
440
+ calculated_rates = {}
441
+ for year in CALCULATION_YEARS:
442
+ avg = calculate_annual_average(
443
+ year, base_rate_with_cut, pre_cut_rate, rpi_forecasts
444
+ )
445
+ calculated_rates[year] = avg
446
+
447
+ # Print calculations
448
+ print_calculations(
449
+ base_rate_with_cut, pre_cut_rate, rpi_forecasts, calculated_rates
450
+ )
451
+
452
+ # Update YAML file if requested
453
+ if args.update:
454
+ print()
455
+ print("=" * 60)
456
+ print("Updating YAML file...")
457
+ print("=" * 60)
458
+ update_yaml_file(
459
+ calculated_rates, rpi_forecasts, base_rate_with_cut, pre_cut_rate
460
+ )
461
+
462
+
463
+ if __name__ == "__main__":
464
+ main()