diff --git a/changelog.d/2586.added.md b/changelog.d/2586.added.md new file mode 100644 index 0000000000..65e7cb0796 --- /dev/null +++ b/changelog.d/2586.added.md @@ -0,0 +1 @@ +- Added seven input-driven gambling duty families from 2024/25 to household and government taxes, including a documented casino incidence proxy. diff --git a/docs/engineering/excise-duties.md b/docs/engineering/excise-duties.md index 2151b427ae..2e353c04a9 100644 --- a/docs/engineering/excise-duties.md +++ b/docs/engineering/excise-duties.md @@ -6,6 +6,11 @@ and duty on LPG and natural road fuel gas from supplied household inputs. diesel duty. These totals combine the different annual bases described below. The incidence assumption is full pass-through to consumers. +The model also includes seven gambling duty families from supplied attributed +household bases. [Household gambling duties](gambling-duties.md) documents the +rates, casino incidence proxy, period conventions and outstanding population +data, machine-premises and VAT work. + ## Coverage and periods Alcohol, tobacco and car duty calculations cover 2024/25 to 2026/27. The alcohol diff --git a/docs/engineering/gambling-duties.md b/docs/engineering/gambling-duties.md new file mode 100644 index 0000000000..ba66d26751 --- /dev/null +++ b/docs/engineering/gambling-duties.md @@ -0,0 +1,274 @@ +# Household gambling duties + +The model calculates General Betting Duty, Pool Betting Duty, Remote Gaming +Duty, Machine Games Duty, casino Gaming Duty incidence, Bingo Duty and Lottery +Duty from supplied annual household bases. The `gambling_duty` output adds +these seven components and enters `household_tax` and `gov_tax` once. The +incidence assumption passes all duty to consumers. These inputs support +household calculations; they do not establish population revenue estimates or +repair existing survey data. + +## Periods and attribution + +Coverage starts in 2024/25. Model period `2024` covers 6 April 2024 to 5 April +2025. The six statutory duty formulas apply dated rates within each interval +of that fiscal year and weight each interval by its share of the year, using +`utils.excise.fiscal_year_segments`. They assume each supplied annual base +accrues uniformly. For example, Finance Act 2026 raises Remote Gaming Duty on +1 April 2026: FY2025 contains 360 days at 21% and five at 40%. The remote +betting change on 1 April 2027 similarly affects five days of FY2026. A reform +dated within a fiscal year is split the same way. The casino incidence proxy +takes one value per model year instead, as described below. + +Each input supplies a nonnegative, already-attributed dutiable base in pounds. +All inputs default to zero. A data provider must allocate operator liabilities +to households, preserving statutory netting, adjustments and exemptions before +supplying these bases. A household's raw signed stakes minus winnings do not +satisfy this contract. The formulas do not reproduce operator accounting +periods or loss carry-forward. They floor each input at zero, so a negative +input gives no duty and does not offset another base. +Positive inputs before 2024 produce default zero because those model years +remain outside the implemented coverage. + +The full pass-through assumption follows the issue's household-incidence +proposal. The OBR's November 2025 forecast assumed around 90% pass-through of +the Budget 2025 increases; that behavioural assumption about changes is not a +baseline incidence fraction in this implementation. This implementation does +not reproduce the OBR's demand or substitution costing. Government receipts +and household incidence use the same attributed base here. + +Source: [OBR November 2025 Economic and Fiscal Outlook, paragraph 3.40](https://obr.uk/docs/dlm_uploads/OBR_Economic_and_fiscal_outlook_November_2025.pdf#page=85). + +## General Betting Duty + +Supply these separate, non-overlapping inputs: + +| Annual household input | Dutiable base | +| --- | --- | +| `remote_uk_horseracing_betting_net_losses` | Remote fixed-odds bets wholly related to horse racing in the United Kingdom. | +| `remote_other_betting_net_losses` | Other qualifying remote fixed-odds bets, excluding all pool and spread bets, exchange commission, on-course bets and qualifying licensed-premises self-service betting terminals. | +| `land_based_fixed_odds_betting_net_losses` | Dutiable off-course land-based fixed-odds bets, including qualifying self-service betting terminals in licensed premises. Exclude on-course bets, pools, spread bets and exchange commission. | +| `horse_and_dog_pool_betting_net_losses` | Dutiable pool or totalisator bets wholly related to horse or dog racing. | +| `financial_spread_betting_net_losses` | Dutiable financial spread betting net receipts of UK bookmakers. | +| `other_spread_betting_net_losses` | Dutiable nonfinancial spread betting net receipts of UK bookmakers. | +| `betting_exchange_commission` | Chargeable exchange commission charged to UK persons. Exchange stakes must not enter another input. | + +The rate is 15% for fixed odds, racing pools and exchange commission, 3% for +financial spreads and 10% for other spreads. Qualifying other remote +fixed-odds bets use 25% from 1 April 2027. Bets wholly on UK horse racing, +qualifying licensed-premises self-service terminals and pool bets retain their +existing treatment. On-course bets are exempt and must not enter a dutiable +input. A terminal used to bet on future real events differs from a gaming +machine subject to Machine Games Duty. + +Sources: [Finance Act 2014, Chapter 1](https://www.legislation.gov.uk/ukpga/2014/26/part/3/chapter/1), +[Finance Act 2026, section 87](https://www.legislation.gov.uk/ukpga/2026/11/section/87) +and [HMRC gambling duty guidance](https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty). + +## Pool Betting Duty + +Supply `pool_betting_net_receipts`, the household's attributed dutiable pool +betting base, including statutory additions and excluding qualifying +community-benefit bets. The rate is 15%. Exclude fixed-odds bets and pools +wholly related to horse or dog racing; those racing pools enter General Betting +Duty. A mixed pool does not become exempt from Pool Betting Duty merely +because one leg concerns horse or dog racing. + +Source: [Finance Act 2014, Chapter 2](https://www.legislation.gov.uk/ukpga/2014/26/part/3/chapter/2). + +## Remote Gaming Duty + +Supply `remote_gaming_net_losses`, the household's attributed chargeable, +non-exempt remote gaming profits base. The rate is 21% in the starting +coverage, rising to 40% on 1 April 2026. The input excludes gaming already +charged with another gambling tax and other exemptions in section 161. Remote +bingo enters this base only where chargeable: section 161 also exempts UK +licensed bingo and specified unlicensed bingo with mixed remote and in-person +participation. Do not allocate the same gaming to another duty base. + +Sources: [Finance Act 2014, sections 154 to 162](https://www.legislation.gov.uk/ukpga/2014/26/part/3/chapter/3), +[Finance Act 2026, section 86](https://www.legislation.gov.uk/ukpga/2026/11/section/86) +and [HMRC historical rates](https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates). + +## Machine Games Duty + +Supply attributed dutiable net takings separately: + +| Input | Rate | Statutory machine class | +| --- | --- | --- | +| `machine_games_lower_rate_net_takings` | 5% | Every dutiable game costs at most 20p and has a maximum cash prize of at most £10. | +| `machine_games_standard_rate_net_takings` | 20% | The machine does not qualify for the lower rate, and every dutiable game costs at most £5. | +| `machine_games_higher_rate_net_takings` | 25% | Other dutiable machines. | + +Classify the entire machine using all dutiable games it offers. Exactly £5 per +play remains within the standard-rate limit. A gambling category, one selected +game or a premises type does not identify the tax class. The model introduces +no average rate, machine-count weighting or premises allocation. A reform +targeting betting shops needs a separate evidenced allocation of each tax +class's net takings by premises. + +Sources: [Finance Act 2012, Schedule 24](https://www.legislation.gov.uk/ukpga/2012/14/schedule/24) +and [HMRC Notice 452](https://www.gov.uk/guidance/machine-games-duty-excise-notice-452). + +## Bingo Duty + +Supply `bingo_net_receipts`, the household's nonnegative share of dutiable +bingo promotion profits after statutory adjustments and exemptions. Bingo Duty +charged 10% before abolition on 1 April 2026. FY2025 therefore charges +£3,600 on a uniform £36,500 attributed base: £100 per day × 360 days × 10%. +FY2026 charges zero. The operator's exemption where duty would be less than +£1 does not create a household threshold. The supplied base must already +reflect the operator's treatment. + +Exclude bingo exempt under the pre-repeal law, including wholly remote +unlicensed bingo under section 17(2A). Chargeable remote gaming uses the +separate Remote Gaming Duty contract, including its section 161 exemptions. + +Sources: [Betting and Gaming Duties Act 1981, section 17, as at 6 April 2024](https://www.legislation.gov.uk/ukpga/1981/63/section/17/2024-04-06) +and [Finance Act 2026, section 88](https://www.legislation.gov.uk/ukpga/2026/11/section/88). + +## Lottery Duty + +Supply `national_lottery_ticket_spending`, the chargeable consideration for +National Lottery tickets and scratchcards. The rate is 12%, with no deduction +for winnings or expenses. Section 25 includes amounts paid, given or debited +in connection with the ticket. Where consideration falls below a shown ticket +price, or no consideration is given, use the deemed shown price. Exempt +lotteries and bingo are outside this input. The model's initial parameter +entry marks verified 2024/25 coverage and makes no earlier commencement claim. + +Sources: [Finance Act 1993, section 24](https://www.legislation.gov.uk/ukpga/1993/34/section/24/2024-04-06), +[section 25](https://www.legislation.gov.uk/ukpga/1993/34/section/25/2024-04-06) +and [HMRC Notice 458](https://www.gov.uk/guidance/lottery-duty-excise-notice-458). + +## Casino Gaming Duty incidence + +Supply `land_based_casino_net_losses`, the household's nonnegative attributed +dutiable casino gross gaming yield. The attribution includes applicable gaming +charges, such as participation charges for equal-chance games, alongside +stakes less prizes where the operator acts as banker. Exclude admission-only +charges, machine games and gaming taxed or exempt under the other duties. + +The household formula multiplies this base by the empirical assumption +`household.consumption.gambling.casino_effective_rate`, initially **0.235487** +(23.5487%). It holds that fraction constant from model year 2024 onwards. +Like the other household consumption assumptions, the proxy takes one value +per model year: the value in force on 1 January of the year in which the model +year starts. Unlike a change to a statutory rate, a change to the proxy dated +within a fiscal year is not split by day; it applies to a whole model year +when it is in force on that 1 January. The proxy sits outside `gov`, where the +reform routes read a bare year such as `"2027"` as a calendar year, so a day +split would spread such a reform over two model years. + +The approved proxy divides these official observations: + +| Observation, April 2024 to March 2025 | Amount | Source location | +| --- | ---: | --- | +| HMRC UK Gaming Duty cash receipts | £165.397 million | July 2026 Betting and Gaming tables, `Table_1_BG_receipts!E45`, reported in £000. | +| Gambling Commission GB casino **game** gross gaming yield | £702.36095883367 million | 2024/25 industry statistics, `8a!B94`, also `8!H49`; provisional. | + +The exact division gives 0.2354871778104747736771859341. Rounding to six +fractional decimals changes the arithmetic on that denominator by £124.89, +below HMRC's £1,000 source reporting unit. Casino **machine** yield of +£231.47255869591993 million is excluded; machines use Machine Games Duty. +The original HMRC ODS SHA-256 is +`3979df37c0611cce371f80950bacac6bc5e9dad499c726f6138f838c882914e8`; +the original Gambling Commission workbook SHA-256 is +`ea5335233cc728f9c500d4ed3233bd996b60acb2cff11f271e0fcf002c8e1b6b`. + +The observations have different coverage. HMRC reports UK cash receipts with +payment and accounting lags; the Gambling Commission reports GB licensed +operator yield and marks the 2024/25 row provisional. Both source periods run +1 April to 31 March, while the model uses 6 April to 5 April. The division +therefore supplies a documented incidence approximation, without establishing +matched geography, taxpayers or accrual periods. Its numerical precision does +not resolve those differences. [Issue 2587](https://github.com/PolicyEngine/policyengine-uk/issues/2587) +tracks review and refresh of the proxy. + +Statutory Gaming Duty applies progressive bands to casino premises for an +operator accounting period. The separate +`gov.hmrc.gambling_duty.gaming.normal_six_month_bands` catalogue records the +registered-premises, normal six-month schedule: 15% on the first £2,686,000, +20% on the next £1,852,000, 30% on the next £3,243,000, 40% on the next +£6,845,000 and 50% thereafter. It excludes unregistered-gaming treatment and +alternative accounting-period adjustments. Household annual losses never +enter those bands. + +The bands have not changed since 1 April 2022: +[HMRC's rates page](https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates) +gives the same bands for accounting periods beginning on or after 1 April +2026. The government froze them for 2026-27, "with the usual RPI uprating +thereafter" ([OBR November 2025 Economic and Fiscal Outlook, paragraph 3.39](https://obr.uk/docs/dlm_uploads/OBR_Economic_and_fiscal_outlook_November_2025.pdf#page=85)). +Bands for accounting periods from 1 April 2027 are therefore expected to +change but are not yet law, and the catalogue does not anticipate them. The +programme registry's `verified_end_year: 2027` is deliberate: household +outputs use the proxy, not the bands. + +Changing the operator catalogue alone leaves the household proxy unchanged. +Scoring a casino band reform requires operator yield distributions and an +incidence mapping, or an explicitly supplied alternative effective fraction. +The fixed proxy does not model behaviour, predict later effective rates or +certify national receipts. + +Sources: [Finance Act 1997, sections 10 and 11](https://www.legislation.gov.uk/ukpga/1997/16/section/11/2024-04-06), +[HMRC Notice 453](https://www.gov.uk/guidance/gaming-duty-excise-notice-453), +[HMRC July 2026 tables](https://assets.publishing.service.gov.uk/media/6ab54fd9fe72ed1e2b02f06b/2026_Jul_Bet_and_Gam_Tab.ods) +and [Gambling Commission 2024/25 industry statistics](https://www.gamblingcommission.gov.uk/statistics-and-research/publication/industry-statistics-annual-report-financial-year-april-2024-to-march-2025). + +## Tax totals and fiscal classification + +The seven component duties enter `gambling_duty`, which enters household and +government taxes once. The fiscal partition assigns that head to **Other HMRC +taxes**. OBR's November 2025 Economic and Fiscal Outlook, Table A.5 footnote 5, +places betting and gaming duties in that row. The model measures only the +gambling part from supplied bases; residual Other HMRC taxes remain +unmodelled. No Table 3.1 allocation is asserted. Removing the row from the +partition's list of rows with no household measure does not claim complete +coverage of the row. + +Source: [OBR November 2025 Economic and Fiscal Outlook, Table A.5](https://obr.uk/docs/dlm_uploads/OBR_Economic_and_fiscal_outlook_November_2025.pdf#page=195). + +## Data and coverage follow-ups + +Released data need a separate mapping from gambling stakes and winnings to +these dutiable bases. The mapping must distinguish remote and land-based +products, avoid overlap, address survey under-recording and reconcile weighted +totals with HMRC receipts using compatible periods and population coverage. +The formulas make no allocation from `recreation_consumption`. Default-zero +inputs do not demonstrate upstream data adoption or population coverage. + +The reconciliation target is HMRC's UK receipts for April 2024 to March 2025, +the year of the casino proxy: + +| Duty | 2024-25 receipts | Cell | +| --- | ---: | --- | +| General Betting Duty | £713.858 million | `B45` | +| Pool Betting Duty | £8.125 million | `C45` | +| Remote Gaming Duty | £1,162.539 million | `F45` | +| Machine Games Duty | £609.245 million | `I45` | +| Gaming Duty | £165.397 million | `E45` | +| Bingo Duty | £25.233 million | `H45` | +| Lottery Duty | £931.887 million | `J45` | +| Total | £3,616.284 million | `K45` | + +The cells are in `Table_1_BG_receipts` of the +[HMRC July 2026 tables](https://assets.publishing.service.gov.uk/media/6ab54fd9fe72ed1e2b02f06b/2026_Jul_Bet_and_Gam_Tab.ods), +the file the casino proxy cites, reported in £000. The commentary on HMRC's +[statistics page](https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics) +gives the same General Betting Duty, Pool Betting Duty and Lottery Duty +figures, rounded. These are cash receipts for a 1 April to 31 March year, so a +reconciliation must handle the timing, period and coverage differences +described for the casino proxy. + +The three machine tax-class bases cannot score a betting-shop-only reform +without joint tax-class-by-premises yield data. Premises shares alone do not +identify that allocation, and machine counts do not provide yield weights. +No assumption of independence between premises and tax class enters the +model. [Issue 2586](https://github.com/PolicyEngine/policyengine-uk/issues/2586) +remains open for that contract and data work, alongside Microcosm 1359 and +Chronos 381. The separate casino review remains under issue 2587. + +Gambling removal from the VAT base also requires a comparable expenditure +contract: subtracting net gambling losses from a gross-stakes consumption +aggregate would mix bases. Data adoption, calibrated population receipts and +VAT-base repair remain separate from this seven-family engine foundation. diff --git a/policyengine_uk/data/fiscal_partition.yaml b/policyengine_uk/data/fiscal_partition.yaml index 3ae9f9fef0..c5f169450f 100644 --- a/policyengine_uk/data/fiscal_partition.yaml +++ b/policyengine_uk/data/fiscal_partition.yaml @@ -100,6 +100,12 @@ sources: the employer NI response incidence and the two unallocated tax changes) as exclusions from a total of levels; here they are heads of the totals that use them, zero at current law. + gambling_duties: >- + OBR, Economic and fiscal outlook, November 2025, Table A.5, footnote 5, + includes betting and gaming duties within Other HMRC taxes. This head + measures only supplied household gambling bases; the other components + of that receipts row remain unmodelled. No Table 3.1 allocation is + claimed. https://obr.uk/docs/dlm_uploads/OBR_Economic_and_fiscal_outlook_November_2025.pdf#page=195 totals: gov_tax: @@ -338,6 +344,26 @@ tax_heads: Zero for every household on policyengine-uk-data 1.58.0 (enhanced_frs_2024_25) in every year from 2025 to 2030, measured 2026-10-11. Issue 1874. + - id: gambling_duty + label: Betting and gaming duties + variable: gambling_duty + entity: household + obr_line: Other HMRC taxes + obr_line_note: >- + Betting and gaming duties belong to this row under November 2025 Table + A.5 footnote 5. This head provides partial row coverage only; other + Other HMRC taxes remain unmodelled. + obr_table_3_1: null + report_group: excise_duties + payer: household + totals: [gov_tax, household_tax] + sign: nonnegative + data_note: >- + Calculated from supplied nonnegative attributed dutiable bases only. + Missing inputs default to zero; this does not establish population + data adoption or calibrated receipts. Casino incidence uses a fixed + UK cash receipts/GB game yield proxy reviewed under issue 2587. + This head does not measure the residual Other HMRC taxes components. - id: tv_licence label: TV licence fee variable: tv_licence @@ -604,6 +630,13 @@ exclusions: - {variable: wine_duty, kind: component, head: alcohol_duty} - {variable: spirits_duty, kind: component, head: alcohol_duty} - {variable: other_fermented_duty, kind: component, head: alcohol_duty} + - {variable: general_betting_duty, kind: component, head: gambling_duty} + - {variable: pool_betting_duty, kind: component, head: gambling_duty} + - {variable: remote_gaming_duty, kind: component, head: gambling_duty} + - {variable: machine_games_duty, kind: component, head: gambling_duty} + - {variable: gaming_duty, kind: component, head: gambling_duty} + - {variable: bingo_duty, kind: component, head: gambling_duty} + - {variable: lottery_duty, kind: component, head: gambling_duty} - {variable: car_vehicle_excise_duty, kind: component, head: vehicle_excise_duty} # Council tax net of a benefit - {variable: council_tax_less_benefit, kind: composite, spans: [council_tax], note: "Council tax net of Council Tax Reduction (the OBR's basis). The totals count gross council tax and credit the reduction as spending, so adding this would count council tax twice."} @@ -695,7 +728,6 @@ uncovered_receipts: - {obr_line: Bank surcharge} - {obr_line: Apprenticeship levy} - {obr_line: Digital services tax} - - {obr_line: Other HMRC taxes} - {obr_line: Environmental levies} - {obr_line: Emissions Trading Scheme} - {obr_line: Energy profits levy} diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/bingo/rate.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/bingo/rate.yaml new file mode 100644 index 0000000000..2fd52c9e06 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/bingo/rate.yaml @@ -0,0 +1,16 @@ +description: The UK levies Bingo Duty at this rate on dutiable bingo promotion profits, until its abolition on 1 April 2026. +values: + '2014-07-01': 0.1 + '2026-04-01': 0 +metadata: + unit: /1 + period: year + label: bingo duty rate + preserve_calendar_dates: true + reference: + - title: Betting and Gaming Duties Act 1981, section 17, as at 6 April 2024 + href: https://www.legislation.gov.uk/ukpga/1981/63/section/17/2024-04-06 + - title: Finance Act 2026, section 88 + href: https://www.legislation.gov.uk/ukpga/2026/11/section/88 + - title: HMRC historical gambling duty rates + href: https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/gaming/normal_six_month_bands.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/gaming/normal_six_month_bands.yaml new file mode 100644 index 0000000000..c97ddaf56e --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/gaming/normal_six_month_bands.yaml @@ -0,0 +1,34 @@ +description: The UK applies these marginal Gaming Duty rates to gross gaming yield from registered casino premises in a normal six-month accounting period, with thresholds measured over that six-month period. This operator catalogue excludes unregistered gaming and alternative-period adjustments. Household calculations do not use it, so changing these bands leaves household casino duty unchanged; see household.consumption.gambling.casino_effective_rate. +brackets: +- threshold: + '2022-04-01': 0 + rate: + '2022-04-01': 0.15 +- threshold: + '2022-04-01': 2_686_000 + rate: + '2022-04-01': 0.2 +- threshold: + '2022-04-01': 4_538_000 + rate: + '2022-04-01': 0.3 +- threshold: + '2022-04-01': 7_781_000 + rate: + '2022-04-01': 0.4 +- threshold: + '2022-04-01': 14_626_000 + rate: + '2022-04-01': 0.5 +metadata: + type: marginal_rate + unit: /1 + threshold_unit: currency-GBP + label: normal six-month casino gaming duty bands + reference: + - title: Finance Act 1997, section 11(2), as at 6 April 2024 + href: https://www.legislation.gov.uk/ukpga/1997/16/section/11/2024-04-06 + - title: HMRC Gaming Duty Notice 453 + href: https://www.gov.uk/guidance/gaming-duty-excise-notice-453 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/exchange_commission.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/exchange_commission.yaml new file mode 100644 index 0000000000..abd5b9a0de --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/exchange_commission.yaml @@ -0,0 +1,15 @@ +description: The UK levies General Betting Duty at this rate on chargeable betting exchange commission. +values: + '2014-12-01': 0.15 +metadata: + unit: /1 + period: year + label: general betting duty exchange commission rate + reference: + - title: Finance Act 2014, section 141(2) to (4) + href: https://www.legislation.gov.uk/ukpga/2014/26/section/141 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates + - title: HMRC General Betting Duty guidance + href: https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/financial_spread.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/financial_spread.yaml new file mode 100644 index 0000000000..e905872ac1 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/financial_spread.yaml @@ -0,0 +1,15 @@ +description: The UK levies General Betting Duty at this rate on financial spread betting. +values: + '2014-12-01': 0.03 +metadata: + unit: /1 + period: year + label: general betting duty financial spread rate + reference: + - title: Finance Act 2014, section 129(2) + href: https://www.legislation.gov.uk/ukpga/2014/26/section/129 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates + - title: HMRC General Betting Duty guidance + href: https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/fixed_odds.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/fixed_odds.yaml new file mode 100644 index 0000000000..8242a0f702 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/fixed_odds.yaml @@ -0,0 +1,17 @@ +description: The UK levies General Betting Duty at this rate on fixed-odds and wholly horse or dog racing pool betting. +values: + '2014-12-01': 0.15 +metadata: + unit: /1 + period: year + label: general betting duty fixed odds rate + reference: + - title: Finance Act 2014, section 127 + href: https://www.legislation.gov.uk/ukpga/2014/26/section/127 + - title: Finance Act 2014, section 135(2) + href: https://www.legislation.gov.uk/ukpga/2014/26/section/135 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates + - title: HMRC General Betting Duty guidance + href: https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/other_spread.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/other_spread.yaml new file mode 100644 index 0000000000..f8738f79bd --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/other_spread.yaml @@ -0,0 +1,15 @@ +description: The UK levies General Betting Duty at this rate on other spread betting. +values: + '2014-12-01': 0.1 +metadata: + unit: /1 + period: year + label: general betting duty other spread rate + reference: + - title: Finance Act 2014, section 130(2) + href: https://www.legislation.gov.uk/ukpga/2014/26/section/130 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates + - title: HMRC General Betting Duty guidance + href: https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/remote.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/remote.yaml new file mode 100644 index 0000000000..e2039ab95e --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/general_betting/rates/remote.yaml @@ -0,0 +1,16 @@ +description: The UK levies General Betting Duty at this rate on qualifying remote fixed-odds bets other than bets wholly related to UK horse racing. The new remote rate excludes pool, spread and on-course bets and qualifying licensed-premises self-service betting terminals. +values: + '2014-12-01': 0.15 + '2027-04-01': 0.25 +metadata: + unit: /1 + period: year + label: general betting duty qualifying remote rate + reference: + - title: Finance Act 2014, section 127 + href: https://www.legislation.gov.uk/ukpga/2014/26/section/127 + - title: Finance Act 2026, section 87 + href: https://www.legislation.gov.uk/ukpga/2026/11/section/87 + - title: HMRC gambling duty rates + href: https://www.gov.uk/government/publications/rates-and-allowance-excise-duty-gambling-duty/excise-duty-gambling-duty-rates + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/lottery/rate.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/lottery/rate.yaml new file mode 100644 index 0000000000..1c7b65606d --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/lottery/rate.yaml @@ -0,0 +1,15 @@ +description: The UK levies Lottery Duty at this rate on chargeable ticket consideration, including deemed ticket price. The initial entry marks this model's 2024/25 coverage, rather than legislative commencement. +values: + '2024-04-06': 0.12 +metadata: + unit: /1 + period: year + label: lottery duty rate + reference: + - title: Finance Act 1993, section 25, as at 6 April 2024 + href: https://www.legislation.gov.uk/ukpga/1993/34/section/25/2024-04-06 + - title: Finance Act 1993, section 24, as at 6 April 2024 + href: https://www.legislation.gov.uk/ukpga/1993/34/section/24/2024-04-06 + - title: HMRC Lottery Duty Notice 458 + href: https://www.gov.uk/guidance/lottery-duty-excise-notice-458 + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/higher.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/higher.yaml new file mode 100644 index 0000000000..dab76291c3 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/higher.yaml @@ -0,0 +1,15 @@ +description: The UK levies Machine Games Duty at this rate on dutiable net takings from machines outside the lower- and standard-rate classes. +values: + '2015-03-01': 0.25 +metadata: + unit: /1 + period: year + label: machine games duty higher rate + reference: + - title: Finance Act 2012, Schedule 24, paragraph 9 + href: https://www.legislation.gov.uk/ukpga/2012/14/schedule/24/paragraph/9 + - title: HMRC Machine Games Duty Notice 452 + href: https://www.gov.uk/guidance/machine-games-duty-excise-notice-452 + - title: HMRC historical gambling duty rates + href: https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/lower.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/lower.yaml new file mode 100644 index 0000000000..f20b5a0465 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/lower.yaml @@ -0,0 +1,15 @@ +description: The UK levies Machine Games Duty at this rate on dutiable net takings from machines on which every dutiable game costs at most 20p and has a maximum cash prize of at most GBP 10. +values: + '2013-02-01': 0.05 +metadata: + unit: /1 + period: year + label: machine games duty lower rate + reference: + - title: Finance Act 2012, Schedule 24, paragraph 9 + href: https://www.legislation.gov.uk/ukpga/2012/14/schedule/24/paragraph/9 + - title: HMRC Machine Games Duty Notice 452 + href: https://www.gov.uk/guidance/machine-games-duty-excise-notice-452 + - title: HMRC historical gambling duty rates + href: https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/standard.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/standard.yaml new file mode 100644 index 0000000000..71d5b1d668 --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/machine_games/rates/standard.yaml @@ -0,0 +1,15 @@ +description: The UK levies Machine Games Duty at this rate on dutiable net takings from machines outside the lower-rate class on which every dutiable game costs at most GBP 5. +values: + '2013-02-01': 0.2 +metadata: + unit: /1 + period: year + label: machine games duty standard rate + reference: + - title: Finance Act 2012, Schedule 24, paragraph 9 + href: https://www.legislation.gov.uk/ukpga/2012/14/schedule/24/paragraph/9 + - title: HMRC Machine Games Duty Notice 452 + href: https://www.gov.uk/guidance/machine-games-duty-excise-notice-452 + - title: HMRC historical gambling duty rates + href: https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/pool_betting/rate.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/pool_betting/rate.yaml new file mode 100644 index 0000000000..d7ab82002c --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/pool_betting/rate.yaml @@ -0,0 +1,13 @@ +description: The UK levies Pool Betting Duty at this rate on chargeable pool betting profits, excluding pools wholly related to horse or dog racing and qualifying community-benefit bets. +values: + '2014-12-01': 0.15 +metadata: + unit: /1 + period: year + label: pool betting duty rate + reference: + - title: Finance Act 2014, sections 143 and 144 + href: https://www.legislation.gov.uk/ukpga/2014/26/section/144 + - title: HMRC General Betting Duty and Pool Betting Duty guidance + href: https://www.gov.uk/guidance/general-betting-duty-pool-betting-duty-and-remote-gaming-duty + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/gov/hmrc/gambling_duty/remote_gaming/rate.yaml b/policyengine_uk/parameters/gov/hmrc/gambling_duty/remote_gaming/rate.yaml new file mode 100644 index 0000000000..d59ed3e27c --- /dev/null +++ b/policyengine_uk/parameters/gov/hmrc/gambling_duty/remote_gaming/rate.yaml @@ -0,0 +1,16 @@ +description: The UK levies Remote Gaming Duty at this rate on chargeable non-exempt remote gaming profits. +values: + '2019-04-01': 0.21 + '2026-04-01': 0.4 +metadata: + unit: /1 + period: year + label: remote gaming duty rate + reference: + - title: Finance Act 2014, section 155 + href: https://www.legislation.gov.uk/ukpga/2014/26/section/155 + - title: Finance Act 2026, section 86 + href: https://www.legislation.gov.uk/ukpga/2026/11/section/86 + - title: HMRC historical gambling duty rates + href: https://www.gov.uk/government/statistics/uk-betting-and-gaming-statistics/historical-uk-betting-and-gaming-duty-rates + preserve_calendar_dates: true diff --git a/policyengine_uk/parameters/household/consumption/gambling/casino_effective_rate.yaml b/policyengine_uk/parameters/household/consumption/gambling/casino_effective_rate.yaml new file mode 100644 index 0000000000..f4403879e5 --- /dev/null +++ b/policyengine_uk/parameters/household/consumption/gambling/casino_effective_rate.yaml @@ -0,0 +1,14 @@ +description: The model attributes household casino Gaming Duty at this empirical fraction of supplied dutiable casino yield. It divides HMRC UK cash Gaming Duty receipts of GBP 165.397 million by provisional Gambling Commission GB casino game yield of GBP 702.36095883367 million for April 2024 to March 2025, rounded to six fractional decimals and held constant after model year 2024. Geography, receipt timing and model-year differences remain unresolved; review and refresh are tracked at https://github.com/PolicyEngine/policyengine-uk/issues/2587. Like the other household consumption assumptions, it takes one value per model year, the value in force on 1 January of the year in which the model year starts; unlike the statutory gambling duty rates, a change dated within a fiscal year is not split by day. +values: + '2024-01-01': 0.235487 +metadata: + unit: /1 + period: year + label: casino gaming duty household incidence fraction + reference: + - title: HMRC July 2026 Betting and Gaming tables, Table_1_BG_receipts E45, GBP 000 + href: https://assets.publishing.service.gov.uk/media/6ab54fd9fe72ed1e2b02f06b/2026_Jul_Bet_and_Gam_Tab.ods + - title: Gambling Commission April 2024 to March 2025 industry statistics, casino game yield, sheet 8a B94 + href: https://www.gamblingcommission.gov.uk/statistics-and-research/publication/industry-statistics-annual-report-financial-year-april-2024-to-march-2025 + - title: Review and refresh the household casino-duty incidence proxy + href: https://github.com/PolicyEngine/policyengine-uk/issues/2587 diff --git a/policyengine_uk/programs.yaml b/policyengine_uk/programs.yaml index 11657e674c..307736433f 100644 --- a/policyengine_uk/programs.yaml +++ b/policyengine_uk/programs.yaml @@ -125,6 +125,19 @@ programs: verified_end_year: 2026 notes: One car per person with supplied vehicle characteristics. Excludes vans, motorcycles, eVED and population imputation. + - id: gambling_duty + name: Gambling duties + full_name: Betting and gaming duties + category: Taxes + agency: HMRC + status: partial + coverage: UK + variable: gambling_duty + parameter_prefix: gov.hmrc.gambling_duty + verified_start_year: 2024 + verified_end_year: 2027 + notes: Seven duty families on supplied attributed bases. Casino incidence uses a fixed FY2024/25 UK receipts/GB game yield proxy under household.consumption.gambling; review issue 2587. Excludes population imputation, verified machine-class-by-premises allocation and VAT-base repair. + - id: student_loans name: Student loan repayments full_name: Student Loan Repayments diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/bingo_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/bingo_duty.yaml new file mode 100644 index 0000000000..bc5e12bb50 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/bingo_duty.yaml @@ -0,0 +1,33 @@ +- name: Case 1, attributed dutiable bingo profits use ten percent in FY2024. + period: 2024 + input: + bingo_net_receipts: 1_000 + output: + bingo_duty: 100 # BGDA 1981 section 17(1)(b). + +- name: Case 2, bingo abolition affects the final five days of FY2025. + period: 2025 + input: + bingo_net_receipts: 36_500 + output: + bingo_duty: 3_600 # FA 2026 section 88: 100 * 360 * .10. + +- name: Case 3, bingo duty is abolished throughout FY2026. + period: 2026 + input: + bingo_net_receipts: 36_500 + output: + bingo_duty: 0 + +- name: Case 4, missing bingo input defaults to zero. + period: 2024 + input: {} + output: + bingo_duty: 0 + +- name: Case 5, a negative bingo base gives no duty. + period: 2024 + input: + bingo_net_receipts: -1_000 + output: + bingo_duty: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/gaming_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/gaming_duty.yaml new file mode 100644 index 0000000000..abe16cd9ec --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/gaming_duty.yaml @@ -0,0 +1,36 @@ +- name: Case 1, household casino incidence uses the approved empirical fraction. + period: 2024 + absolute_error_margin: 0.01 + input: + land_based_casino_net_losses: 1_000 + output: + gaming_duty: 235.487 # 1,000 * .235487; HMRC/GC FY2024/25 ratio, issue 2587. + +- name: Case 2, household casino incidence scales linearly with the supplied base. + period: 2024 + absolute_error_margin: 0.01 + input: + land_based_casino_net_losses: 10_000 + output: + gaming_duty: 2_354.87 # Annual household bases never use operator brackets. + +- name: Case 3, the empirical casino fraction stays constant after its source year. + period: 2027 + absolute_error_margin: 0.01 + input: + land_based_casino_net_losses: 1_000 + output: + gaming_duty: 235.487 + +- name: Case 4, missing casino input defaults to zero. + period: 2024 + input: {} + output: + gaming_duty: 0 + +- name: Case 5, a negative casino base gives no duty. + period: 2024 + input: + land_based_casino_net_losses: -1_000 + output: + gaming_duty: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/general_betting_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/general_betting_duty.yaml new file mode 100644 index 0000000000..54b1741ab2 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/general_betting_duty.yaml @@ -0,0 +1,83 @@ +- name: Case 1, UK horseracing remote fixed odds use the general rate. + period: 2024 + input: + remote_uk_horseracing_betting_net_losses: 1_000 + output: + general_betting_duty: 150 # FA 2014 section 127: 1,000 * 15%. + +- name: Case 2, other remote fixed odds use the general rate before April 2027. + period: 2024 + input: + remote_other_betting_net_losses: 1_000 + output: + general_betting_duty: 150 + +- name: Case 3, licensed-premises self-service terminals use the land-based rate. + period: 2027 + input: + land_based_fixed_odds_betting_net_losses: 1_000 + output: + general_betting_duty: 150 # Excluded from FA 2014 section 127A remote bets. + +- name: Case 4, pools wholly related to horse or dog racing enter general betting duty. + period: 2027 + input: + horse_and_dog_pool_betting_net_losses: 1_000 + output: + general_betting_duty: 150 + pool_betting_duty: 0 + +- name: Case 5, financial spread betting has a separate three percent base. + period: 2024 + input: + financial_spread_betting_net_losses: 1_000 + output: + general_betting_duty: 30 # FA 2014 section 129(2). + +- name: Case 6, other spread betting has a separate ten percent base. + period: 2024 + input: + other_spread_betting_net_losses: 1_000 + output: + general_betting_duty: 100 # FA 2014 section 130(2). + +- name: Case 7, betting exchanges pay duty on commission. + period: 2024 + input: + betting_exchange_commission: 1_000 + output: + general_betting_duty: 150 # FA 2014 section 141(2) to (4), commission rather than stakes. + +- name: Case 8, remote fixed odds change during FY2026 with exclusions retained. + period: 2026 + input: + remote_other_betting_net_losses: 36_500 + remote_uk_horseracing_betting_net_losses: 36_500 + land_based_fixed_odds_betting_net_losses: 36_500 + horse_and_dog_pool_betting_net_losses: 36_500 + output: + # FA 2026 section 87: 360 days at 15%, five at 25%; three excluded bases at 15%. + general_betting_duty: 21_950 # 5,525 + 3 * 5,475. + +- name: Case 9, remote fixed odds use twenty-five percent throughout FY2027. + period: 2027 + input: + remote_other_betting_net_losses: 36_500 + remote_uk_horseracing_betting_net_losses: 36_500 + land_based_fixed_odds_betting_net_losses: 36_500 + horse_and_dog_pool_betting_net_losses: 36_500 + output: + general_betting_duty: 25_550 # 9,125 + 3 * 5,475. + +- name: Case 10, negative bases give no duty and do not offset another base. + period: 2027 + input: + remote_uk_horseracing_betting_net_losses: -1_000 + remote_other_betting_net_losses: -1_000 + land_based_fixed_odds_betting_net_losses: 1_000 + horse_and_dog_pool_betting_net_losses: -1_000 + financial_spread_betting_net_losses: -1_000 + other_spread_betting_net_losses: -1_000 + betting_exchange_commission: -1_000 + output: + general_betting_duty: 150 # Only the land-based base: 1,000 * 15%. diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/integration.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/integration.yaml new file mode 100644 index 0000000000..b037692f88 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/integration.yaml @@ -0,0 +1,364 @@ +# All other tax heads are held at zero to expose an exactly-once integration. +# Oracles: statutory component rates; casino .235487 approved proxy (issue 2587). +- name: Case 1, missing gambling bases preserve zero isolated tax totals. + period: 2024 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + output: + general_betting_duty: 0 + pool_betting_duty: 0 + remote_gaming_duty: 0 + machine_games_duty: 0 + bingo_duty: 0 + lottery_duty: 0 + gaming_duty: 0 + gambling_duty: 0 + household_tax: 0 + gov_tax: 0 +- name: Case 2, all fifteen non-overlapping bases enter both tax totals once. + period: 2024 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_uk_horseracing_betting_net_losses: 1_000 + remote_other_betting_net_losses: 1_000 + land_based_fixed_odds_betting_net_losses: 1_000 + horse_and_dog_pool_betting_net_losses: 1_000 + financial_spread_betting_net_losses: 1_000 + other_spread_betting_net_losses: 1_000 + betting_exchange_commission: 1_000 + pool_betting_net_receipts: 1_000 + remote_gaming_net_losses: 1_000 + machine_games_lower_rate_net_takings: 1_000 + machine_games_standard_rate_net_takings: 1_000 + machine_games_higher_rate_net_takings: 1_000 + bingo_net_receipts: 1_000 + national_lottery_ticket_spending: 1_000 + land_based_casino_net_losses: 1_000 + output: + general_betting_duty: 880 + pool_betting_duty: 150 + remote_gaming_duty: 210 + machine_games_duty: 500 + bingo_duty: 100 + lottery_duty: 120 + gaming_duty: 235.487 + gambling_duty: 2_195.487 + household_tax: 2_195.487 + gov_tax: 2_195.487 +- name: Case 3, coverage before FY2024 remains unmodelled. + period: 2023 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_uk_horseracing_betting_net_losses: 1_000 + remote_other_betting_net_losses: 1_000 + land_based_fixed_odds_betting_net_losses: 1_000 + horse_and_dog_pool_betting_net_losses: 1_000 + financial_spread_betting_net_losses: 1_000 + other_spread_betting_net_losses: 1_000 + betting_exchange_commission: 1_000 + pool_betting_net_receipts: 1_000 + remote_gaming_net_losses: 1_000 + machine_games_lower_rate_net_takings: 1_000 + machine_games_standard_rate_net_takings: 1_000 + machine_games_higher_rate_net_takings: 1_000 + bingo_net_receipts: 1_000 + national_lottery_ticket_spending: 1_000 + land_based_casino_net_losses: 1_000 + output: + general_betting_duty: 0 + pool_betting_duty: 0 + remote_gaming_duty: 0 + machine_games_duty: 0 + bingo_duty: 0 + lottery_duty: 0 + gaming_duty: 0 + gambling_duty: 0 + household_tax: 0 + gov_tax: 0 +- name: Case 4, explicit zero bases preserve zero isolated tax totals. + period: 2027 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_uk_horseracing_betting_net_losses: 0 + remote_other_betting_net_losses: 0 + land_based_fixed_odds_betting_net_losses: 0 + horse_and_dog_pool_betting_net_losses: 0 + financial_spread_betting_net_losses: 0 + other_spread_betting_net_losses: 0 + betting_exchange_commission: 0 + pool_betting_net_receipts: 0 + remote_gaming_net_losses: 0 + machine_games_lower_rate_net_takings: 0 + machine_games_standard_rate_net_takings: 0 + machine_games_higher_rate_net_takings: 0 + bingo_net_receipts: 0 + national_lottery_ticket_spending: 0 + land_based_casino_net_losses: 0 + output: + general_betting_duty: 0 + pool_betting_duty: 0 + remote_gaming_duty: 0 + machine_games_duty: 0 + bingo_duty: 0 + lottery_duty: 0 + gaming_duty: 0 + gambling_duty: 0 + household_tax: 0 + gov_tax: 0 +- name: Case 5, remote gaming and betting keep separate April transitions. + period: 2026 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_other_betting_net_losses: 36_500 + remote_gaming_net_losses: 36_500 + output: + general_betting_duty: 5_525 + pool_betting_duty: 0 + remote_gaming_duty: 14_600 + machine_games_duty: 0 + bingo_duty: 0 + lottery_duty: 0 + gaming_duty: 0 + gambling_duty: 20_125 + household_tax: 20_125 + gov_tax: 20_125 +- name: Case 6, the FY2025 remote gaming increase and bingo abolition are time weighted. + period: 2025 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_gaming_net_losses: 36_500 + bingo_net_receipts: 36_500 + output: + general_betting_duty: 0 + pool_betting_duty: 0 + remote_gaming_duty: 7_760 + machine_games_duty: 0 + bingo_duty: 3_600 + lottery_duty: 0 + gaming_duty: 0 + gambling_duty: 11_360 + household_tax: 11_360 + gov_tax: 11_360 +- name: Case 7, casino gaming machine takings and other products remain distinct. + period: 2024 + absolute_error_margin: 0.01 + input: + LVT: 0 + alcohol_duty: 0 + business_rates: 0 + capital_gains_tax: 0 + carbon_tax: 0 + consumer_incident_tax_revenue_change: 0 + corporate_incident_tax_revenue_change: 0 + corporate_sdlt: 0 + council_tax: 0 + domestic_rates: 0 + employer_ni_response_capital_incidence: 0 + employer_ni_response_consumer_incidence: 0 + expected_lbtt: 0 + expected_ltt: 0 + expected_sdlt: 0 + fuel_duty: 0 + high_value_council_tax_surcharge: 0 + income_tax: 0 + national_insurance: 0 + ni_employer: 0 + non_primary_residence_wealth_tax: 0 + private_school_vat: 0 + student_loan_repayments: 0 + tobacco_duty: 0 + tv_licence: 0 + vat: 0 + vat_change: 0 + vehicle_excise_duty: 0 + wealth_tax: 0 + remote_uk_horseracing_betting_net_losses: 1_000 + machine_games_standard_rate_net_takings: 1_000 + bingo_net_receipts: 1_000 + national_lottery_ticket_spending: 1_000 + land_based_casino_net_losses: 1_000 + output: + general_betting_duty: 150 + pool_betting_duty: 0 + remote_gaming_duty: 0 + machine_games_duty: 200 + bingo_duty: 100 + lottery_duty: 120 + gaming_duty: 235.487 + gambling_duty: 805.487 + household_tax: 805.487 + gov_tax: 805.487 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/lottery_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/lottery_duty.yaml new file mode 100644 index 0000000000..b29dfdfb94 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/lottery_duty.yaml @@ -0,0 +1,26 @@ +- name: Case 1, National Lottery duty uses gross chargeable ticket consideration. + period: 2024 + input: + national_lottery_ticket_spending: 1_000 + output: + lottery_duty: 120 # FA 1993 section 25(1): 12% without winnings deductions. + +- name: Case 2, the same lottery rate applies in FY2027. + period: 2027 + input: + national_lottery_ticket_spending: 1_000 + output: + lottery_duty: 120 + +- name: Case 3, missing National Lottery spending defaults to zero. + period: 2024 + input: {} + output: + lottery_duty: 0 + +- name: Case 4, negative National Lottery spending gives no duty. + period: 2024 + input: + national_lottery_ticket_spending: -1_000 + output: + lottery_duty: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/machine_games_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/machine_games_duty.yaml new file mode 100644 index 0000000000..70d2aa8adc --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/machine_games_duty.yaml @@ -0,0 +1,38 @@ +- name: Case 1, lower-rate machine net takings use five percent. + period: 2024 + input: + machine_games_lower_rate_net_takings: 1_000 + output: + machine_games_duty: 50 # FA 2012 Schedule 24 paragraph 9. + +- name: Case 2, standard-rate machine net takings use twenty percent. + period: 2024 + input: + machine_games_standard_rate_net_takings: 1_000 + output: + machine_games_duty: 200 + +- name: Case 3, higher-rate machine net takings use twenty-five percent. + period: 2024 + input: + machine_games_higher_rate_net_takings: 1_000 + output: + machine_games_duty: 250 + +- name: Case 4, machine classes supply their own bases without a mix assumption. + period: 2024 + input: + machine_games_lower_rate_net_takings: 1_000 + machine_games_standard_rate_net_takings: 2_000 + machine_games_higher_rate_net_takings: 3_000 + output: + machine_games_duty: 1_200 # 50 + 400 + 750. + +- name: Case 5, negative machine bases give no duty and do not offset another class. + period: 2024 + input: + machine_games_lower_rate_net_takings: -1_000 + machine_games_standard_rate_net_takings: -1_000 + machine_games_higher_rate_net_takings: 1_000 + output: + machine_games_duty: 250 # Only the higher-rate base: 1,000 * 25%. diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/pool_betting_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/pool_betting_duty.yaml new file mode 100644 index 0000000000..0125fedfdc --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/pool_betting_duty.yaml @@ -0,0 +1,24 @@ +- name: Case 1, dutiable non-racing pool receipts use fifteen percent. + period: 2024 + input: + pool_betting_net_receipts: 1_000 + output: + pool_betting_duty: 150 # FA 2014 section 144. + general_betting_duty: 0 + +- name: Case 2, general and pool betting bases remain distinct. + period: 2027 + input: + pool_betting_net_receipts: 1_000 + horse_and_dog_pool_betting_net_losses: 2_000 + output: + general_betting_duty: 300 + pool_betting_duty: 150 + gambling_duty: 450 + +- name: Case 3, a negative pool betting base gives no duty. + period: 2024 + input: + pool_betting_net_receipts: -1_000 + output: + pool_betting_duty: 0 diff --git a/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/remote_gaming_duty.yaml b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/remote_gaming_duty.yaml new file mode 100644 index 0000000000..41319194c6 --- /dev/null +++ b/policyengine_uk/tests/policy/baseline/gov/hmrc/gambling_duty/remote_gaming_duty.yaml @@ -0,0 +1,28 @@ +- name: Case 1, remote gaming profits use twenty-one percent in FY2024. + period: 2024 + input: + remote_gaming_net_losses: 36_500 + output: + remote_gaming_duty: 7_665 # HMRC historic rates: 36,500 * 21%. + +- name: Case 2, remote gaming changes on 1 April within FY2025. + period: 2025 + input: + remote_gaming_net_losses: 36_500 + output: + # FA 2026 section 86: 360 days at 21% and five at 40%. + remote_gaming_duty: 7_760 # 100 * (360 * .21 + 5 * .40). + +- name: Case 3, remote gaming uses forty percent throughout FY2026. + period: 2026 + input: + remote_gaming_net_losses: 36_500 + output: + remote_gaming_duty: 14_600 + +- name: Case 4, a negative remote gaming base gives no duty. + period: 2026 + input: + remote_gaming_net_losses: -1_000 + output: + remote_gaming_duty: 0 # Each base is floored at zero, not charged at -40%. diff --git a/policyengine_uk/tests/test_gambling_additional_schedules.py b/policyengine_uk/tests/test_gambling_additional_schedules.py new file mode 100644 index 0000000000..d4a89b4891 --- /dev/null +++ b/policyengine_uk/tests/test_gambling_additional_schedules.py @@ -0,0 +1,84 @@ +"""New duty dates, operator catalogue and the household casino approximation.""" + +import numpy as np +import pytest + +from policyengine_uk import CountryTaxBenefitSystem +from policyengine_uk.tests.test_gambling_schedules import gambling_simulation + + +def test_bingo_rate_preserves_abolition_date(): + """Finance Act 2026 section 88 abolishes bingo duty on 1 April 2026.""" + system = CountryTaxBenefitSystem() + rate = system.parameters.gov.hmrc.gambling_duty.bingo.rate + assert rate("2026-03-31") == 0.1 + assert rate("2026-04-01") == 0 + + +def test_registered_casino_normal_six_month_operator_catalogue(): + """Finance Act 1997 section 11(2): cumulative six-month premises bands.""" + system = CountryTaxBenefitSystem() + scale = system.parameters( + "2024" + ).gov.hmrc.gambling_duty.gaming.normal_six_month_bands + yield_amounts = np.array( + [ + 0, + 2_686_000, + 2_686_001, + 4_538_000, + 4_538_001, + 7_781_000, + 7_781_001, + 14_626_000, + 14_626_001, + ], + dtype=float, + ) + # Successive statutory widths: 2,686,000; 1,852,000; 3,243,000; 6,845,000. + expected = [ + 0, + 402_900, + 402_900.2, + 773_300, + 773_300.3, + 1_746_200, + 1_746_200.4, + 4_484_200, + 4_484_200.5, + ] + assert scale.calc(yield_amounts) == pytest.approx(expected) + + +def test_explicit_casino_incidence_reform_changes_household_duty(): + """An explicit 30% incidence assumption charges GBP 300 on GBP 1,000.""" + sim = gambling_simulation( + 2024, + {"household.consumption.gambling.casino_effective_rate": {"2024": 0.3}}, + {"land_based_casino_net_losses": 1_000}, + ) + assert sim.calculate("gaming_duty", 2024).iloc[0] == pytest.approx(300) + + +def test_casino_proxy_takes_one_value_per_model_year(): + """FY2026 reads the proxy at 1 January 2026, before a change from 2027.""" + sim = gambling_simulation( + 2026, + { + "household.consumption.gambling.casino_effective_rate": { + "2027-01-01.2027-04-05": 0.3 + } + }, + {"land_based_casino_net_losses": 1_000}, + ) + assert sim.calculate("gaming_duty", 2026).iloc[0] == pytest.approx(235.487) + + +def test_operator_band_reform_does_not_automatically_change_household_proxy(): + """The empirical household proxy does not model casino band responses.""" + sim = gambling_simulation( + 2024, + {"gov.hmrc.gambling_duty.gaming.normal_six_month_bands[0].rate": {"2024": 0.3}}, + {"land_based_casino_net_losses": 1_000}, + ) + assert sim.calculate("gaming_duty", 2024).iloc[0] == pytest.approx(235.487) diff --git a/policyengine_uk/tests/test_gambling_schedules.py b/policyengine_uk/tests/test_gambling_schedules.py new file mode 100644 index 0000000000..904834e087 --- /dev/null +++ b/policyengine_uk/tests/test_gambling_schedules.py @@ -0,0 +1,129 @@ +"""Statutory gambling rate dates and fiscal-year reform behaviour.""" + +import pytest + +from policyengine_uk import CountryTaxBenefitSystem, Microsimulation +from policyengine_uk.model_api import Scenario + + +@pytest.mark.parametrize( + "path,before,after,old,new", + [ + ("remote_gaming.rate", "2026-03-31", "2026-04-01", 0.21, 0.4), + ("general_betting.rates.remote", "2027-03-31", "2027-04-01", 0.15, 0.25), + ], +) +def test_gambling_rates_preserve_exact_statutory_dates(path, before, after, old, new): + """Finance Act 2026 sections 86 and 87 change rates on 1 April.""" + system = CountryTaxBenefitSystem() + rate = system.parameters.get_child(f"gov.hmrc.gambling_duty.{path}") + assert rate(before) == old + assert rate(after) == new + + +def gambling_simulation(year, changes, inputs): + return Microsimulation( + situation={ + "people": {"person1": {"age": {year: 40}}}, + "benunits": {"benunit": {"members": ["person1"]}}, + "households": { + "household": { + "members": ["person1"], + **{name: {year: value} for name, value in inputs.items()}, + } + }, + }, + scenario=Scenario(parameter_changes=changes), + ) + + +@pytest.mark.parametrize( + "year,path,inputs,variable,expected", + [ + ( + 2025, + "remote_gaming.rate", + {"remote_gaming_net_losses": 36_500}, + "remote_gaming_duty", + 18_250, + ), + ( + 2026, + "general_betting.rates.remote", + {"remote_other_betting_net_losses": 36_500}, + "general_betting_duty", + 18_250, + ), + ( + 2026, + "machine_games.rates.standard", + {"machine_games_standard_rate_net_takings": 36_500}, + "machine_games_duty", + 18_250, + ), + ( + 2026, + "lottery.rate", + {"national_lottery_ticket_spending": 36_500}, + "lottery_duty", + 18_250, + ), + ], +) +def test_annual_gambling_reform_replaces_the_whole_fiscal_year( + year, path, inputs, variable, expected +): + """A 50% annual reform applies to all GBP 36,500 of the year's base.""" + sim = gambling_simulation( + year, {f"gov.hmrc.gambling_duty.{path}": {str(year): 0.5}}, inputs + ) + assert sim.calculate(variable, year).values[0] == pytest.approx(expected) + + +@pytest.mark.parametrize( + "path,value,inputs,variable,expected", + [ + ( + "lottery.rate", + 0.2, + {"national_lottery_ticket_spending": 1_000}, + "lottery_duty", + 1_000 * (270 * 0.12 + 95 * 0.2) / 365, # 140.82, not 120. + ), + ( + "remote_gaming.rate", + 0.5, + {"remote_gaming_net_losses": 10_000}, + "remote_gaming_duty", + 10_000 * (270 * 0.4 + 95 * 0.5) / 365, # 4,260.27. + ), + ], +) +def test_dated_reform_within_the_fiscal_year_splits_by_day( + path, value, inputs, variable, expected +): + """A reform from 1 January to 5 April 2027 covers 95 of FY2026's 365 days.""" + sim = gambling_simulation( + 2026, + {f"gov.hmrc.gambling_duty.{path}": {"2027-01-01.2027-04-05": value}}, + inputs, + ) + assert sim.calculate(variable, 2026).values[0] == pytest.approx(expected, abs=0.01) + + +def test_explicit_date_reform_keeps_its_dates_and_adjacent_fiscal_year(): + """Five days at 50%, 360 at 15%, then the FY2026 statutory transition.""" + sim = gambling_simulation( + 2025, + { + "gov.hmrc.gambling_duty.general_betting.rates.remote": { + "2026-04-01.2026-04-05": 0.5 + } + }, + {"remote_other_betting_net_losses": 36_500}, + ) + sim.set_input("remote_other_betting_net_losses", 2026, [36_500]) + # Explicit five-day reform: 100 * (360 * .15 + 5 * .50). + assert sim.calculate("general_betting_duty", 2025).values[0] == pytest.approx(5_650) + # Finance Act 2026 section 87: 100 * (360 * .15 + 5 * .25). + assert sim.calculate("general_betting_duty", 2026).values[0] == pytest.approx(5_525) diff --git a/policyengine_uk/variables/gov/gov_tax.py b/policyengine_uk/variables/gov/gov_tax.py index ffbe95bae9..ea1742a789 100644 --- a/policyengine_uk/variables/gov/gov_tax.py +++ b/policyengine_uk/variables/gov/gov_tax.py @@ -13,6 +13,7 @@ "fuel_duty", "alcohol_duty", "tobacco_duty", + "gambling_duty", "vehicle_excise_duty", "tv_licence", "wealth_tax", diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/bingo_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/bingo_duty.py new file mode 100644 index 0000000000..ae6516ebef --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/bingo_duty.py @@ -0,0 +1,23 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class bingo_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Bingo Duty" + reference = ( + "https://www.legislation.gov.uk/ukpga/1981/63/section/17/2024-04-06", + "https://www.legislation.gov.uk/ukpga/2026/11/section/88", + ) + + def formula_2024(household, period, parameters): + receipts = max_(household("bingo_net_receipts", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.bingo, period.start.year + ): + total += receipts * rates.rate * share + return total diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/gambling_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/gambling_duty.py new file mode 100644 index 0000000000..a5fc8b5225 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/gambling_duty.py @@ -0,0 +1,18 @@ +from policyengine_uk.model_api import * + + +class gambling_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Gambling duty" + adds = [ + "general_betting_duty", + "pool_betting_duty", + "remote_gaming_duty", + "machine_games_duty", + "gaming_duty", + "bingo_duty", + "lottery_duty", + ] diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/gaming_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/gaming_duty.py new file mode 100644 index 0000000000..224649e28c --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/gaming_duty.py @@ -0,0 +1,18 @@ +from policyengine_uk.model_api import * + + +class gaming_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Casino Gaming Duty incidence" + reference = ( + "https://www.legislation.gov.uk/ukpga/1997/16/section/11", + "https://github.com/PolicyEngine/policyengine-uk/issues/2587", + ) + + def formula_2024(household, period, parameters): + rate = parameters(period).household.consumption.gambling.casino_effective_rate + losses = max_(household("land_based_casino_net_losses", period), 0) + return losses * rate diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/general_betting_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/general_betting_duty.py new file mode 100644 index 0000000000..a45c5f46a7 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/general_betting_duty.py @@ -0,0 +1,39 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class general_betting_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "General Betting Duty" + reference = ( + "https://www.legislation.gov.uk/ukpga/2014/26/part/3/chapter/1", + "https://www.legislation.gov.uk/ukpga/2026/11/section/87", + ) + + def formula_2024(household, period, parameters): + fixed_odds = ( + max_(household("remote_uk_horseracing_betting_net_losses", period), 0) + + max_(household("land_based_fixed_odds_betting_net_losses", period), 0) + + max_(household("horse_and_dog_pool_betting_net_losses", period), 0) + ) + remote = max_(household("remote_other_betting_net_losses", period), 0) + financial_spread = max_( + household("financial_spread_betting_net_losses", period), 0 + ) + other_spread = max_(household("other_spread_betting_net_losses", period), 0) + exchange = max_(household("betting_exchange_commission", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.general_betting.rates, period.start.year + ): + total += share * ( + fixed_odds * rates.fixed_odds + + remote * rates.remote + + financial_spread * rates.financial_spread + + other_spread * rates.other_spread + + exchange * rates.exchange_commission + ) + return total diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/lottery_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/lottery_duty.py new file mode 100644 index 0000000000..eb442993af --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/lottery_duty.py @@ -0,0 +1,20 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class lottery_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Lottery Duty" + reference = "https://www.legislation.gov.uk/ukpga/1993/34/section/25" + + def formula_2024(household, period, parameters): + spending = max_(household("national_lottery_ticket_spending", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.lottery, period.start.year + ): + total += spending * rates.rate * share + return total diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/machine_games_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/machine_games_duty.py new file mode 100644 index 0000000000..7292d7fc74 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/machine_games_duty.py @@ -0,0 +1,24 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class machine_games_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Machine Games Duty" + reference = "https://www.legislation.gov.uk/ukpga/2012/14/schedule/24" + + def formula_2024(household, period, parameters): + lower = max_(household("machine_games_lower_rate_net_takings", period), 0) + standard = max_(household("machine_games_standard_rate_net_takings", period), 0) + higher = max_(household("machine_games_higher_rate_net_takings", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.machine_games.rates, period.start.year + ): + total += share * ( + lower * rates.lower + standard * rates.standard + higher * rates.higher + ) + return total diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/pool_betting_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/pool_betting_duty.py new file mode 100644 index 0000000000..45cca174b1 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/pool_betting_duty.py @@ -0,0 +1,20 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class pool_betting_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Pool Betting Duty" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/144" + + def formula_2024(household, period, parameters): + receipts = max_(household("pool_betting_net_receipts", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.pool_betting, period.start.year + ): + total += receipts * rates.rate * share + return total diff --git a/policyengine_uk/variables/gov/hmrc/gambling_duty/remote_gaming_duty.py b/policyengine_uk/variables/gov/hmrc/gambling_duty/remote_gaming_duty.py new file mode 100644 index 0000000000..b1ed51d749 --- /dev/null +++ b/policyengine_uk/variables/gov/hmrc/gambling_duty/remote_gaming_duty.py @@ -0,0 +1,23 @@ +from policyengine_uk.model_api import * +from policyengine_uk.utils.excise import fiscal_year_segments + + +class remote_gaming_duty(Variable): + value_type = float + entity = Household + definition_period = YEAR + unit = GBP + label = "Remote Gaming Duty" + reference = ( + "https://www.legislation.gov.uk/ukpga/2014/26/section/155", + "https://www.legislation.gov.uk/ukpga/2026/11/section/86", + ) + + def formula_2024(household, period, parameters): + losses = max_(household("remote_gaming_net_losses", period), 0) + total = 0 + for rates, share in fiscal_year_segments( + parameters.gov.hmrc.gambling_duty.remote_gaming, period.start.year + ): + total += losses * rates.rate * share + return total diff --git a/policyengine_uk/variables/gov/hmrc/household_tax.py b/policyengine_uk/variables/gov/hmrc/household_tax.py index 3404b8ade9..3794ac08b5 100644 --- a/policyengine_uk/variables/gov/hmrc/household_tax.py +++ b/policyengine_uk/variables/gov/hmrc/household_tax.py @@ -13,6 +13,7 @@ "fuel_duty", "alcohol_duty", "tobacco_duty", + "gambling_duty", "vehicle_excise_duty", "tv_licence", "wealth_tax", diff --git a/policyengine_uk/variables/input/consumption/gambling/betting_exchange_commission.py b/policyengine_uk/variables/input/consumption/gambling/betting_exchange_commission.py new file mode 100644 index 0000000000..453f5c85b9 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/betting_exchange_commission.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class betting_exchange_commission(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Chargeable betting exchange commission attributed to the household" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/141" diff --git a/policyengine_uk/variables/input/consumption/gambling/bingo_net_receipts.py b/policyengine_uk/variables/input/consumption/gambling/bingo_net_receipts.py new file mode 100644 index 0000000000..ad67462e6d --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/bingo_net_receipts.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class bingo_net_receipts(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable bingo promotion profits" + reference = "https://www.legislation.gov.uk/ukpga/1981/63/section/17/2024-04-06" diff --git a/policyengine_uk/variables/input/consumption/gambling/financial_spread_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/financial_spread_betting_net_losses.py new file mode 100644 index 0000000000..8aefb4c920 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/financial_spread_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class financial_spread_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable financial spread betting losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/128" diff --git a/policyengine_uk/variables/input/consumption/gambling/horse_and_dog_pool_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/horse_and_dog_pool_betting_net_losses.py new file mode 100644 index 0000000000..f628b80280 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/horse_and_dog_pool_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class horse_and_dog_pool_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable horse and dog racing pool losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/134" diff --git a/policyengine_uk/variables/input/consumption/gambling/land_based_casino_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/land_based_casino_net_losses.py new file mode 100644 index 0000000000..bb19e35e74 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/land_based_casino_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class land_based_casino_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable land-based casino gaming yield" + reference = "https://www.legislation.gov.uk/ukpga/1997/16/section/11" diff --git a/policyengine_uk/variables/input/consumption/gambling/land_based_fixed_odds_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/land_based_fixed_odds_betting_net_losses.py new file mode 100644 index 0000000000..0156162579 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/land_based_fixed_odds_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class land_based_fixed_odds_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable land-based fixed-odds losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/126" diff --git a/policyengine_uk/variables/input/consumption/gambling/machine_games_higher_rate_net_takings.py b/policyengine_uk/variables/input/consumption/gambling/machine_games_higher_rate_net_takings.py new file mode 100644 index 0000000000..5a80acaa9c --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/machine_games_higher_rate_net_takings.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class machine_games_higher_rate_net_takings(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable higher-rate machine games net takings" + reference = "https://www.gov.uk/guidance/machine-games-duty-excise-notice-452" diff --git a/policyengine_uk/variables/input/consumption/gambling/machine_games_lower_rate_net_takings.py b/policyengine_uk/variables/input/consumption/gambling/machine_games_lower_rate_net_takings.py new file mode 100644 index 0000000000..f746d877d6 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/machine_games_lower_rate_net_takings.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class machine_games_lower_rate_net_takings(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable lower-rate machine games net takings" + reference = "https://www.gov.uk/guidance/machine-games-duty-excise-notice-452" diff --git a/policyengine_uk/variables/input/consumption/gambling/machine_games_standard_rate_net_takings.py b/policyengine_uk/variables/input/consumption/gambling/machine_games_standard_rate_net_takings.py new file mode 100644 index 0000000000..c4acb3d525 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/machine_games_standard_rate_net_takings.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class machine_games_standard_rate_net_takings(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable standard-rate machine games net takings" + reference = "https://www.gov.uk/guidance/machine-games-duty-excise-notice-452" diff --git a/policyengine_uk/variables/input/consumption/gambling/national_lottery_ticket_spending.py b/policyengine_uk/variables/input/consumption/gambling/national_lottery_ticket_spending.py new file mode 100644 index 0000000000..e493e2bbbf --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/national_lottery_ticket_spending.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class national_lottery_ticket_spending(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Chargeable National Lottery ticket consideration" + reference = "https://www.legislation.gov.uk/ukpga/1993/34/section/25" diff --git a/policyengine_uk/variables/input/consumption/gambling/other_spread_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/other_spread_betting_net_losses.py new file mode 100644 index 0000000000..075809c3b2 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/other_spread_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class other_spread_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable other spread betting losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/130" diff --git a/policyengine_uk/variables/input/consumption/gambling/pool_betting_net_receipts.py b/policyengine_uk/variables/input/consumption/gambling/pool_betting_net_receipts.py new file mode 100644 index 0000000000..d3f88029c1 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/pool_betting_net_receipts.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class pool_betting_net_receipts(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable non-racing pool betting net receipts" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/143" diff --git a/policyengine_uk/variables/input/consumption/gambling/remote_gaming_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/remote_gaming_net_losses.py new file mode 100644 index 0000000000..ecaae21921 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/remote_gaming_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class remote_gaming_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed chargeable non-exempt remote gaming losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/161" diff --git a/policyengine_uk/variables/input/consumption/gambling/remote_other_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/remote_other_betting_net_losses.py new file mode 100644 index 0000000000..c2ee45223c --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/remote_other_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class remote_other_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable other remote fixed-odds losses" + reference = "https://www.legislation.gov.uk/ukpga/2026/11/section/87" diff --git a/policyengine_uk/variables/input/consumption/gambling/remote_uk_horseracing_betting_net_losses.py b/policyengine_uk/variables/input/consumption/gambling/remote_uk_horseracing_betting_net_losses.py new file mode 100644 index 0000000000..367b3e80e3 --- /dev/null +++ b/policyengine_uk/variables/input/consumption/gambling/remote_uk_horseracing_betting_net_losses.py @@ -0,0 +1,11 @@ +from policyengine_uk.model_api import * + + +class remote_uk_horseracing_betting_net_losses(Variable): + value_type = float + entity = Household + definition_period = YEAR + default_value = 0 + unit = GBP + label = "Attributed dutiable remote UK horseracing fixed-odds losses" + reference = "https://www.legislation.gov.uk/ukpga/2014/26/section/127"