Skip to content

Commit

Permalink
indirect taxes - VAT in output and equalising
Browse files Browse the repository at this point in the history
  • Loading branch information
grahamstark committed Aug 29, 2023
1 parent eccee02 commit 41e3c61
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 53 deletions.
8 changes: 7 additions & 1 deletion src/Runner.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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 )
Expand Down
33 changes: 25 additions & 8 deletions src/STBOutput.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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


#=
Expand Down Expand Up @@ -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 )
Expand Down Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -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,:]
Expand All @@ -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

"""
Expand Down
8 changes: 6 additions & 2 deletions src/TheEqualiser.jl
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ mutable struct RunParameters{T<:AbstractFloat}
params :: TaxBenefitSystem{T}
settings :: Settings
base_cost :: T
iterations :: Int
target :: EqTargets
obs :: Observable
end
Expand Down Expand Up @@ -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

Expand All @@ -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
Expand Down
14 changes: 2 additions & 12 deletions test/all_uk_runner_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand All @@ -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
Expand Down
81 changes: 55 additions & 26 deletions test/equaliser_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -10,27 +10,15 @@ using .STBParameters
using .STBIncomes
using .ExampleHelpers
using .Monitor: Progress
using .RunSettings
using .TheEqualiser
using .STBOutput
using PrettyTables
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

Expand All @@ -42,37 +30,38 @@ 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,
settings,
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" )
Expand All @@ -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 )
Expand All @@ -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,
Expand All @@ -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
Expand All @@ -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
11 changes: 7 additions & 4 deletions test/expenditure_tests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand Down

0 comments on commit 41e3c61

Please sign in to comment.