diff --git a/changelog_entry.yaml b/changelog_entry.yaml index e69de29bb2d..9e04a9467e4 100644 --- a/changelog_entry.yaml +++ b/changelog_entry.yaml @@ -0,0 +1,10 @@ +- bump: patch + changes: + changed: + - title: Fix VT capital gains exclusion for financial instruments + description: > + Vermont's 40% capital gains exclusion now correctly excludes financial + instruments (stocks, bonds) from eligibility. Only the flat $5,000 + exclusion applies to these gains. Added new input variable + long_term_capital_gains_on_assets_eligible_for_vt_exclusion for + modeling the 40% exclusion on qualifying assets. diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_capital_gains_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_capital_gains_exclusion.yaml index 6e92a9342fe..435ba557c67 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_capital_gains_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_capital_gains_exclusion.yaml @@ -1,60 +1,86 @@ -- name: VT capital gain exclusion amount unit test 1 +# Vermont capital gains exclusion: +# - Flat $5,000 exclusion applies to ALL capital gains +# - 40% exclusion (capped at $350k) ONLY applies to eligible assets +# (excludes stocks, bonds, financial instruments, real estate) +# - Final exclusion cannot exceed 40% of federal taxable income + +- name: VT exclusion is zero when not in VT period: 2022 input: - state_code: ME # Test state definition other than VT + state_code: ME adjusted_net_capital_gain: 1_000 taxable_income: 1_000 - vt_percentage_capital_gains_exclusion: 1_000 output: - vt_capital_gains_exclusion: 0 + vt_capital_gains_exclusion: 0 -- name: VT capital gain exclusion amount unit test 2 +- name: VT flat exclusion capped by 40% of taxable income period: 2022 input: state_code: VT adjusted_net_capital_gain: 6_000 taxable_income: 1_000 - vt_percentage_capital_gains_exclusion: 1_000 + # No eligible gains, so percentage exclusion is 0 output: - vt_capital_gains_exclusion: 400 # # min(5000,1000*0.4) = 400 + vt_capital_gains_exclusion: 400 # min(5000, 1000*0.4) = 400 -- name: VT capital gain exclusion amount unit test 3 +- name: VT flat exclusion of 5k when no percentage exclusion period: 2022 input: state_code: VT adjusted_net_capital_gain: 6_000 taxable_income: 12_600 - vt_percentage_capital_gains_exclusion: 1_000 + # No eligible gains specified, so only flat exclusion applies output: - vt_capital_gains_exclusion: 5_000 # min(5000,12600*0.4) = 4000 + vt_capital_gains_exclusion: 5_000 # flat $5k, under 40% cap -- name: VT capital gain exclusion amount unit test 4 +- name: VT percentage exclusion beats flat when eligible gains are high period: 2022 input: state_code: VT adjusted_net_capital_gain: 12_600 taxable_income: 12_700 - vt_percentage_capital_gains_exclusion: 5_040 + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 12_600 output: - vt_capital_gains_exclusion: 5_040 # min(5040,5080) = 5040 + # Flat: min(12600, 5000) = 5000 + # Percentage: min(12600 * 0.4, 350000) = 5040 + # Chosen: max(5000, 5040) = 5040 + # Cap: 12700 * 0.4 = 5080 + # Final: min(5040, 5080) = 5040 + vt_capital_gains_exclusion: 5_040 -- name: VT capital gain exclusion amount unit test 5 +- name: VT exclusion capped at 40% of taxable income period: 2022 input: state_code: VT adjusted_net_capital_gain: 12_600 taxable_income: 12_500 - vt_percentage_capital_gains_exclusion: 5_040 + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 12_600 output: - vt_capital_gains_exclusion: 5_000 # min(5040,5000) = 5000 + # Flat: 5000, Percentage: 5040, Chosen: 5040 + # Cap: 12500 * 0.4 = 5000 + # Final: min(5040, 5000) = 5000 + vt_capital_gains_exclusion: 5_000 -- name: Adjusted net capital gain is reduced by the dividend income +- name: Adjusted net capital gain is reduced by dividend income for flat exclusion period: 2022 input: state_code: VT adjusted_net_capital_gain: 6_000 taxable_income: 12_600 - vt_percentage_capital_gains_exclusion: 1_000 qualified_dividend_income: 4_000 + # No eligible gains, so percentage exclusion is 0 output: + # Reduced ANCG: max(6000 - 4000, 0) = 2000 + # Flat: min(2000, 5000) = 2000 vt_capital_gains_exclusion: 2_000 + +- name: Financial instrument gains only get flat exclusion + period: 2024 + input: + state_code: VT + long_term_capital_gains: 137_498 # Financial instruments + taxable_income: 140_418 + # No long_term_capital_gains_on_assets_eligible_for_vt_exclusion + output: + # Only flat $5,000 applies (financial instruments are NOT eligible for 40%) + vt_capital_gains_exclusion: 5_000 diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_percentage_capital_gains_exclusion.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_percentage_capital_gains_exclusion.yaml index 3ef8fefaf26..bd5b9f62e60 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_percentage_capital_gains_exclusion.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/agi/vt_percentage_capital_gains_exclusion.yaml @@ -1,40 +1,45 @@ -- name: VT percentage capital gain exclusion amount unit test 1 +# The 40% percentage exclusion only applies to capital gains from eligible assets. +# Eligible assets EXCLUDE: stocks, bonds, financial instruments, real estate. +# Since standard capital gains inputs represent financial instruments (ineligible), +# users must specify long_term_capital_gains_on_assets_eligible_for_vt_exclusion. + +- name: VT percentage exclusion is zero when not in VT period: 2022 input: - state_code: ME # Test state definition other than VT - adjusted_net_capital_gain: 1_000 + state_code: ME + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 1_000 output: vt_percentage_capital_gains_exclusion: 0 -- name: VT percentage capital gain exclusion amount unit test 2 +- name: VT percentage exclusion is zero when no eligible gains specified period: 2022 input: state_code: VT - adjusted_net_capital_gain: 0 + long_term_capital_gains: 100_000 # Financial instruments - NOT eligible output: - vt_percentage_capital_gains_exclusion: 0 + vt_percentage_capital_gains_exclusion: 0 -- name: VT percentage capital gain exclusion amount unit test 3 +- name: VT percentage exclusion is 40% of eligible gains period: 2022 input: state_code: VT - adjusted_net_capital_gain: 1_000 + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 1_000 output: - vt_percentage_capital_gains_exclusion: 400 + vt_percentage_capital_gains_exclusion: 400 -- name: VT percentage capital gain exclusion amount unit test 4 +- name: VT percentage exclusion is capped at 350k period: 2022 input: state_code: VT - adjusted_net_capital_gain: 900_000 + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 900_000 output: - vt_percentage_capital_gains_exclusion: 350_000 + vt_percentage_capital_gains_exclusion: 350_000 -- name: Adjusted net capital reduced by dividend income +- name: VT percentage exclusion only counts eligible gains, not all LTCG period: 2022 input: state_code: VT - adjusted_net_capital_gain: 900_000 - qualified_dividend_income: 1_000_000 + long_term_capital_gains: 500_000 # Financial instruments - NOT eligible + long_term_capital_gains_on_assets_eligible_for_vt_exclusion: 10_000 output: - vt_percentage_capital_gains_exclusion: 0 + vt_percentage_capital_gains_exclusion: 4_000 # 40% of 10k eligible only diff --git a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/integration.yaml b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/integration.yaml index e36ed8ee715..c91cdd29507 100644 --- a/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/integration.yaml +++ b/policyengine_us/tests/policy/baseline/gov/states/vt/tax/income/integration.yaml @@ -25,3 +25,37 @@ state_fips: 50 output: vt_income_tax: 7_963 + +# From GitHub issue #7291: VT capital gains exclusion incorrectly applies to financial instruments +# Financial instrument gains (stocks/bonds) are NOT eligible for the 40% exclusion. +# Only the flat $5,000 exclusion applies. +- name: VT capital gains exclusion - financial instruments get flat exclusion only + period: 2024 + absolute_error_margin: 10 + input: + people: + person1: + age: 40 + employment_income: 2_576 + taxable_interest_income: 344 + long_term_capital_gains: 137_498 # Financial instruments - NOT eligible for 40% + is_tax_unit_head: true + dependent1: + age: 10 + is_tax_unit_dependent: true + tax_units: + tax_unit: + members: [person1, dependent1] + premium_tax_credit: 0 + spm_units: + spm_unit: + members: [person1, dependent1] + households: + household: + members: [person1, dependent1] + state_fips: 50 # Vermont + output: + # Federal AGI: 2576 + 344 + 137498 = 140418 + # Only $5,000 flat exclusion applies since gains are from financial instruments + # VT AGI: 140418 - 5000 = 135418 + vt_agi: 135_418 diff --git a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_capital_gains_exclusion.py b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_capital_gains_exclusion.py index ba2bc1be278..6f406c81b44 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_capital_gains_exclusion.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_capital_gains_exclusion.py @@ -6,17 +6,21 @@ class vt_capital_gains_exclusion(Variable): entity = TaxUnit label = "Vermont capital gains exclusion" unit = USD - documentation = "Vermont excludes a portion of capital gains, calculated either as a flat amount or as a fraction of adjusted net capital gains, and limited by a fraction of federal taxable income." + documentation = ( + "Vermont offers two capital gains exclusions: a flat $5,000 exclusion for all " + "capital gains, and a 40% exclusion (up to $350,000) only for gains from eligible " + "assets. Stocks, bonds, financial instruments, and real estate are NOT eligible " + "for the 40% exclusion. The exclusion is capped at 40% of federal taxable income." + ) definition_period = YEAR defined_for = StateCode.VT reference = ( - "https://tax.vermont.gov/sites/tax/files/documents/IN-153-2022.pdf#page=1" # 2022 Schedule IN-153 Vermont Capital Gains Exclusion Calculation - "https://legislature.vermont.gov/statutes/section/32/151/05811" # Titl. 32 V.S.A. § 5811(21)(B)(ii) - "https://tax.vermont.gov/sites/tax/files/documents/IN-153%20Instr-2022.pdf" + "https://tax.vermont.gov/sites/tax/files/documents/IN-153-2024.pdf#page=1", + "https://legislature.vermont.gov/statutes/section/32/151/05811", ) def formula(tax_unit, period, parameters): - # Get adjusted net capital gains, which is capped at 0 + # Get adjusted net capital gains (used for flat exclusion) adjusted_net_capital_gain = tax_unit( "adjusted_net_capital_gain", period ) @@ -29,17 +33,20 @@ def formula(tax_unit, period, parameters): p = parameters( period ).gov.states.vt.tax.income.agi.exclusions.capital_gain - # The flat exclusion is the less of a capped amount - # or the actual amount of net adjusted capital gains + + # Flat $5,000 exclusion applies to ALL capital gains (including financial instruments) flat_exclusion = min_(reduced_adjusted_net_capital_gain, p.flat.cap) - # Get percentage exclusion + + # 40% exclusion only applies to explicitly eligible capital gains + # (excludes stocks, bonds, financial instruments, real estate) percentage_exclusion = tax_unit( "vt_percentage_capital_gains_exclusion", period ) - # Filer can choose from flat or percentage exclusion. - # Assume the filer will always choose the larger one + + # Filer chooses the larger exclusion chosen_exclusion = max_(flat_exclusion, percentage_exclusion) - # The chosen exclusion should not exceed 40% of federal taxable income + + # The chosen exclusion cannot exceed 40% of federal taxable income federal_taxable_income = tax_unit("taxable_income", period) cap = federal_taxable_income * p.income_share_cap return min_(chosen_exclusion, cap) diff --git a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_percentage_capital_gains_exclusion.py b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_percentage_capital_gains_exclusion.py index 7de7bcb2ecb..d0d7ca4863f 100644 --- a/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_percentage_capital_gains_exclusion.py +++ b/policyengine_us/variables/gov/states/vt/tax/income/adjusted_gross_income/subtractions/vt_capital_gain_exclusion/vt_percentage_capital_gains_exclusion.py @@ -6,32 +6,33 @@ class vt_percentage_capital_gains_exclusion(Variable): entity = TaxUnit label = "Vermont percentage capital gains exclusion" unit = USD - documentation = "This can be selected to be subtracted from federal adjusted gross income in Vermont as percentage capital gains exclusion." + documentation = ( + "Vermont's 40% capital gains exclusion only applies to gains from qualifying " + "assets held more than 3 years. Stocks, bonds, financial instruments, and real " + "estate are NOT eligible. Only gains from explicitly eligible assets (e.g., farms, " + "businesses) qualify for this exclusion." + ) definition_period = YEAR defined_for = StateCode.VT reference = ( - "https://tax.vermont.gov/sites/tax/files/documents/IN-153-2022.pdf#page=1" # 2022 Schedule IN-153 Vermont Capital Gains Exclusion Calculation - "https://legislature.vermont.gov/statutes/section/32/151/05811" # Titl. 32 V.S.A. § 5811(21)(B)(ii) - "https://tax.vermont.gov/sites/tax/files/documents/IN-153%20Instr-2022.pdf" + "https://tax.vermont.gov/sites/tax/files/documents/IN-153-2024.pdf#page=2", + "https://legislature.vermont.gov/statutes/section/32/151/05811", ) def formula(tax_unit, period, parameters): - # Get adjusted net capital gain, which is capped at 0 - adjusted_net_capital_gain = tax_unit( - "adjusted_net_capital_gain", period - ) - qualified_dividend_income = add( - tax_unit, period, ["qualified_dividend_income"] - ) - reduced_adjusted_net_capital_gain = max_( - adjusted_net_capital_gain - qualified_dividend_income, 0 + # Per VT Schedule IN-153: The 40% exclusion only applies to eligible assets. + # Eligible assets exclude: stocks/bonds traded on exchanges, financial instruments, + # depreciable personal property (except farm property/timber), and real estate. + # Since standard capital gains inputs map to financial instruments (ineligible), + # we only use explicitly designated VT-eligible capital gains. + eligible_gains = add( + tax_unit, + period, + ["long_term_capital_gains_on_assets_eligible_for_vt_exclusion"], ) p = parameters( period ).gov.states.vt.tax.income.agi.exclusions.capital_gain - # The percentage exclusion equals to a percentage of - # the adjusted net capital gain and has a maximum value - percentage_exclusion = ( - reduced_adjusted_net_capital_gain * p.percentage.rate - ) + # The percentage exclusion equals 40% of eligible gains, capped at $350,000 + percentage_exclusion = eligible_gains * p.percentage.rate return min_(percentage_exclusion, p.percentage.cap) diff --git a/policyengine_us/variables/household/income/person/capital_gains/long_term_capital_gains_on_assets_eligible_for_vt_exclusion.py b/policyengine_us/variables/household/income/person/capital_gains/long_term_capital_gains_on_assets_eligible_for_vt_exclusion.py new file mode 100644 index 00000000000..d0686ea4aab --- /dev/null +++ b/policyengine_us/variables/household/income/person/capital_gains/long_term_capital_gains_on_assets_eligible_for_vt_exclusion.py @@ -0,0 +1,20 @@ +from policyengine_us.model_api import * + + +class long_term_capital_gains_on_assets_eligible_for_vt_exclusion(Variable): + value_type = float + entity = Person + label = "Long-term capital gains on assets eligible for Vermont's 40% exclusion" + unit = USD + documentation = ( + "Vermont's 40% capital gains exclusion only applies to gains from qualifying " + "assets held more than 3 years, excluding: stocks and bonds publicly traded or " + "traded on an exchange, any other financial instruments, depreciable personal " + "property (other than farm property and standing timber), and real estate. " + "Qualifying assets typically include: farms, businesses, and certain timber." + ) + definition_period = YEAR + reference = ( + "https://tax.vermont.gov/sites/tax/files/documents/IN-153-2024.pdf#page=2", + "https://legislature.vermont.gov/statutes/section/32/151/05811", + )