diff --git a/src/Runner.jl b/src/Runner.jl index 83a4d626..3447ce96 100644 --- a/src/Runner.jl +++ b/src/Runner.jl @@ -92,7 +92,13 @@ module Runner observer[] =Progress( settings.uuid, "starting",0, 0, 0, settings.num_households ) @time @threads for thread in 1:num_threads for hno in start[thread]:stop[thread] + hh = FRSHouseholdGetter.get_household( hno ) + #= + if hno < 20 + println( "getting hh $hno hid=$(hh.hid) datayear=$(hh.data_year)") + end + =# nation = nation_from_region( hh.region ) # println( "nation = $nation; included nations=$(settings.included_nations)") if nation in settings.included_nations @@ -123,7 +129,7 @@ module Runner # println( "wage set back to $(pers.income[wages]) metr is $(pres.metr)") end # working age end # people - end + end # mrs if settings.do_replacement_rates for (pid,pers) in hh.people if ( ! pers.is_standard_child ) && ( pers.age <= settings.mr_rr_upper_age ) diff --git a/src/STBOutput.jl b/src/STBOutput.jl index 09130587..88771263 100644 --- a/src/STBOutput.jl +++ b/src/STBOutput.jl @@ -47,7 +47,7 @@ export irdiff # count of the aggregates added to the income_frame - total benefits and so on, plus 8 indirect fields -const EXTRA_INC_COLS = 17 +const EXTRA_INC_COLS = 18 #= @@ -143,7 +143,9 @@ const EXTRA_INC_COLS = 17 frame.excise_cider = zeros(n) frame.excise_wine = zeros(n) frame.excise_tobacco = zeros(n) + frame.total_indirect = zeros(n) frame.net_cost = zeros( n ) + frame.net_inc_indirect = zeros( n ) # add some crosstab fields ... frame.id = fill( id, n ) frame.data_year = zeros( Int, n ) @@ -394,7 +396,7 @@ const EXTRA_INC_COLS = 17 for em in instances( Tenure_Type ) selected = incd.tenure .== em out[row,col] =sum( WEEKS_PER_YEAR .* incd[selected,col] .* incd[selected,:weight] ) # £mn - row += 1 + row += 1 out[row,col] = sum((incd[selected,col] .> 0) .* incd[selected,:weight]) # Counts row += 1 end @@ -404,9 +406,12 @@ const EXTRA_INC_COLS = 17 row += 1 out[row,col] = sum((incd[selected,col] .> 0) .* incd[selected,:weight]) # Counts row += 1 - end - - end + end + end + # note that the Count field for the next two is meaningless + out.total_indirect = out.VED + out.fuel_duty + out.VAT + out.excise_beer + out.excise_cider + out.excise_wine + + out.excise_tobacco + out.net_inc_indirect = out.net_cost - out.total_indirect # select!(out, Not([:pid,:hid,:weight])) # clear out pids return out end @@ -500,15 +505,27 @@ const EXTRA_INC_COLS = 17 sysno :: Integer, num_systems :: Integer ) hfno = get_slot_for_household( hh.hid, hh.data_year ) + #= + if hh.hid < 20 + println( "adding hh $(hh.hid) sysno=$sysno") + end + =# fill_hh_frame_row!( frames.hh[sysno][hfno, :], hh, hres) nbus = length(hres.bus) np = length( hh.people ) bus = get_benefit_units( hh ) - pfbu = 0 + npp = 0 for buno in 1:nbus for( pid, pers ) in bus[buno].people + npp += 1 pfno = get_slot_for_person( pid, hh.data_year ) + #= + if hh.hid < 0 + println( "pid=$pid data_year=$(hh.data_year) pfno=$pfno sysno=$sysno") + end + =# + @assert pfno > 0 "pfno non-positive for pid=$pid data_year=$(hh.data_year) pfno=$pnfo" # pfbu += 1 from_child_record = pid in bus[buno].children incrow = frames.income[sysno][pfno,:] @@ -532,10 +549,10 @@ const EXTRA_INC_COLS = 17 incrow.excise_cider = hres.indirect.excise_cider incrow.excise_wine = hres.indirect.excise_wine incrow.excise_tobacco = hres.indirect.excise_tobacco - end - + end end # person loop end # bu loop + @assert np == npp "not all people allocated; actual people=$np allocated people $npp" end """ diff --git a/src/TheEqualiser.jl b/src/TheEqualiser.jl index 6411c08d..613e42c7 100644 --- a/src/TheEqualiser.jl +++ b/src/TheEqualiser.jl @@ -62,6 +62,7 @@ mutable struct RunParameters{T<:AbstractFloat} params :: TaxBenefitSystem{T} settings :: Settings base_cost :: T + iterations :: Int target :: EqTargets obs :: Observable end @@ -138,8 +139,11 @@ function run( x :: T, rparams :: RunParameters{T} ) where T <: AbstractFloat rparams.params.loctax.ct.house_values = hvals rparams.params.othertaxes = othvals rparams.params.indirect.vat = vat + rparams.iterations += 1 summary = summarise_frames!(results, rparams.settings) - nc = summary.income_summary[1][1,:net_cost] + nc = summary.income_summary[1][1,:net_inc_indirect] + println( "nc = $nc rparams.base_cost=$(rparams.base_cost) iterations=$(rparams.iterations) delta=$x target=$(rparams.target)") + rparams.obs[]=Progress( rparams.settings.uuid, "equalising", rparams.iterations, 0, 0, 0 ) return round( nc - rparams.base_cost, digits=0 ) end @@ -154,7 +158,7 @@ function equalise( base_cost :: T, observer :: Observable ) :: T where T<:AbstractFloat zerorun = ZeroProblem( run, 0.0 ) # fixme guess at 0.0 ? - rparams = RunParameters( sys, settings, base_cost, target, observer ) + rparams = RunParameters( sys, settings, base_cost, 0, target, observer ) incch = solve( zerorun, rparams ) # # TODO test incch is sensible diff --git a/test/all_uk_runner_tests.jl b/test/all_uk_runner_tests.jl index 0816f935..29b733b3 100644 --- a/test/all_uk_runner_tests.jl +++ b/test/all_uk_runner_tests.jl @@ -35,16 +35,6 @@ of = on(obs) do p println(tot) end -function make_default_settings() :: Settings - # settings = Settings() - settings = get_all_uk_settings_2023() - settings.do_marginal_rates = false - settings.requested_threads = 4 - settings.means_tested_routing = uc_full - settings.do_health_esimates = true - return settings - end - const targets = [ :label, :income_tax, :national_insurance, :local_taxes, :social_fund_loan_repayment, :student_loan_repayments, :care_insurance, :child_benefit, :state_pension, @@ -61,9 +51,9 @@ const targets = [ :label, :housing_benefit, :free_school_meals, :universal_credit, :other_benefits] function do_basic_uk_run() - settings = make_default_settings() + settings = get_all_uk_settings_2023() settings.run_name="all-uk-run-$(date_string())" - sys = [get_system(year=2023, scotland=false), get_system(year=2023, scotland=true)] + sys = [get_system(year=2023, scotland=false), get_system(year=2023, scotland=false)] println( sys[1].ni) tot = 0 # force reset of data to use UK dataset diff --git a/test/equaliser_tests.jl b/test/equaliser_tests.jl index 7cb32c1f..dcbbac6a 100644 --- a/test/equaliser_tests.jl +++ b/test/equaliser_tests.jl @@ -10,6 +10,7 @@ using .STBParameters using .STBIncomes using .ExampleHelpers using .Monitor: Progress +using .RunSettings using .TheEqualiser using .STBOutput using PrettyTables @@ -17,20 +18,7 @@ using CSV using .GeneralTaxComponents: WEEKS_PER_YEAR -function load_system()::TaxBenefitSystem - sys = load_file( joinpath( Definitions.MODEL_PARAMS_DIR, "sys_2021_22.jl" )) - # - # Note that as of Budget21 removing these doesn't actually happen till May 2022. - # - load_file!( sys, joinpath( Definitions.MODEL_PARAMS_DIR, "sys_2021-uplift-removed.jl")) - # uc taper to 55 - load_file!( sys, joinpath( Definitions.MODEL_PARAMS_DIR, "budget_2021_uc_changes.jl")) - weeklyise!( sys ) - return sys -end - - -settings = Settings() +settings = get_all_uk_settings_2023() settings.do_marginal_rates = false settings.poverty_line=100.0 # arbit @@ -42,24 +30,24 @@ of = on(obs) do p println(p) tot += p.step - println(tot) + # println(tot) end -@testset "Eq UBI Tests" begin - base = load_system() - sys = load_system() +@testset "Eq UBI with income tax Tests" begin + base = get_system(year=2023, scotland=false ) + sys = get_system(year=2023, scotland=false ) sys.ubi.abolished = false sys.it.personal_allowance = 0.0 settings.num_households, settings.num_people, nhh2 = - FRSHouseholdGetter.initialise( settings; reset=true ) + FRSHouseholdGetter.initialise( settings; reset=true ) make_ubi_pre_adjustments!( sys ) base_res = do_one_run( settings, [base], obs ) summary = summarise_frames!(base_res,settings) - base_cost = summary.income_summary[1][1,:net_cost] - + base_cost = summary.income_summary[1][1,:net_inc_indirect] + println( "base cost is $base_cost") eq = equalise( eq_it, sys, @@ -67,12 +55,13 @@ end base_cost, obs ) sys.it.non_savings_rates .+= eq + println( "got it rate change of $eq") ubi_res = do_one_run( settings, [sys], obs ) ubi_summary = summarise_frames!(ubi_res,settings) - ubi_cost = ubi_summary.income_summary[1][1,:net_cost] + ubi_cost = ubi_summary.income_summary[1][1,:net_inc_indirect] println( "needs tax rise of $eq") net_cost = ubi_cost - base_cost println( "net_cost=$net_cost" ) @@ -84,8 +73,8 @@ end end @testset "Eq UBI With Wealth Tests" begin - base = load_system() - sys = load_system() + base = get_system(year=2023, scotland=false ) + sys = get_system(year=2023, scotland=false ) sys.ubi.abolished = false sys.it.personal_allowance = 0.0 make_ubi_pre_adjustments!( sys ) @@ -94,7 +83,7 @@ end [base], obs ) summary = summarise_frames!(base_res,settings) - base_cost = summary.income_summary[1][1,:net_cost] + base_cost = summary.income_summary[1][1,:net_inc_indirect] eq = equalise( eq_wealth_tax, @@ -103,12 +92,15 @@ end base_cost, obs ) sys.othertaxes.wealth_tax = eq + println( "VAT change is $eq") ubi_res = do_one_run( settings, [sys], obs ) + + ubi_summary = summarise_frames!(ubi_res,settings) - ubi_cost = ubi_summary.income_summary[1][1,:net_cost] + ubi_cost = ubi_summary.income_summary[1][1,:net_inc_indirect] println( "needs tax rise of $eq") net_cost = ubi_cost - base_cost @@ -119,3 +111,40 @@ end # pretty_table( ubi_summary.income_summary[1][1,:] ) end + +@testset "Eq UBI With VAT" begin + base = get_system(year=2023, scotland=false ) + sys = get_system(year=2023, scotland=false ) + sys.ubi.abolished = false + sys.it.personal_allowance = 0.0 + make_ubi_pre_adjustments!( sys ) + base_res = do_one_run( + settings, + [base], + obs ) + summary = summarise_frames!(base_res,settings) + base_cost = summary.income_summary[1][1,:net_inc_indirect] + + eq = equalise( + eq_all_vat, + sys, + settings, + base_cost, + obs ) + sys.indirect.vat.standard_rate += eq + sys.indirect.vat.reduced_rate += eq + sys.indirect.vat.assumed_exempt_rate += eq*0.5 + ubi_res = do_one_run( + settings, + [sys], + obs ) + ubi_summary = summarise_frames!(ubi_res,settings) + ubi_cost = ubi_summary.income_summary[1][1,:net_inc_indirect] + + net_cost = ubi_cost - base_cost + println( "net_cost=$net_cost" ) + println( "taxrates $(sys.indirect.vat.standard_rate*100.0)%") + println("ubi summary") + CSV.write( "ubi_summary.income_summary_wealth.csv", ubi_summary.income_summary[1] ) + # pretty_table( ubi_summary.income_summary[1][1,:] ) +end diff --git a/test/expenditure_tests.jl b/test/expenditure_tests.jl index 355ebf77..44a70753 100644 --- a/test/expenditure_tests.jl +++ b/test/expenditure_tests.jl @@ -26,7 +26,7 @@ using .STBOutput: make_poverty_line, summarise_inc_frame, using .Expenditure using StatsBase -settings = Settings() +settings = Settings() # get_all_uk_settings_2023() BenchmarkTools.DEFAULT_PARAMETERS.seconds = 120 BenchmarkTools.DEFAULT_PARAMETERS.samples = 2 @@ -51,10 +51,13 @@ end settings.do_marginal_rates = false settings.dump_frames = false sys = [get_system(year=2022, scotland=true), get_system( year=2022,scotland=true )] - nhhs,npeople = init_data() - share = zeros( nhhs,2 ) - for hno in 1:nhhs + settings.num_households, settings.num_people, nhh2 = + FRSHouseholdGetter.initialise( settings; reset=true ) + println(sys[1]) + share = zeros( nhh2,2 ) + for hno in 1:nhh2 hh = get_household(hno) + # println(hh) # dup but can't be helped intermed = make_intermediate( hh,