Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: Maximum monthly GIS when spouse/partner receives full OAS pension
values:
2022-01-01: 619.99
2023-01-01: 641.80
2024-01-01: 652.96
2025-01-01: 660.78
metadata:
unit: currency-CAD
period: month
label: GIS maximum amount for couples (both receive OAS)
reference:
- title: Old Age Security payment amounts
href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/old-age-security/payments.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: Maximum monthly Guaranteed Income Supplement for single seniors
values:
2022-01-01: 1_028.96
2023-01-01: 1_065.47
2024-01-01: 1_083.68
2025-01-01: 1_097.75
metadata:
unit: currency-CAD
period: month
label: GIS maximum amount for singles
reference:
- title: Old Age Security payment amounts
href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/old-age-security/payments.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
description: GIS reduction rate per dollar of income
values:
2022-01-01: 0.5
metadata:
unit: /1
label: GIS reduction rate
reference:
- title: Old Age Security Act - Guaranteed Income Supplement
href: https://laws-lois.justice.gc.ca/eng/acts/o-9/page-3.html#h-387820
- title: Government of Canada - GIS Overview
href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/old-age-security/guaranteed-income-supplement/eligibility.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: Combined annual income threshold for GIS when both receive OAS
values:
2022-01-01: 27_552
2023-01-01: 28_560
2024-01-01: 28_800
2025-01-01: 29_424
metadata:
unit: currency-CAD
period: year
label: GIS income threshold for couples (both OAS)
reference:
- title: Old Age Security payment amounts
href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/old-age-security/payments.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
description: Annual income threshold for GIS eligibility for singles
values:
2022-01-01: 20_784
2023-01-01: 21_624
2024-01-01: 21_768
2025-01-01: 22_272
metadata:
unit: currency-CAD
period: year
label: GIS income threshold for singles
reference:
- title: Old Age Security payment amounts
href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/old-age-security/payments.html
125 changes: 125 additions & 0 deletions policyengine_canada/tests/gov/cra/benefits/gis/gis.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
- name: Single senior with no income gets maximum GIS
period: 2024
input:
age: 70
adult_years_in_canada: 50
is_head: true
is_spouse: false
employment_income: 0
self_employment_income: 0
output:
# Maximum monthly for 2024 is $1,083.68
# Annual: $1,083.68 * 12 = $13,004.16
gis: 13_004.16

- name: Single senior with income at threshold gets minimal GIS
period: 2024
input:
age: 70
adult_years_in_canada: 50
is_head: true
is_spouse: false
employment_income: 21_768 # Near threshold for 2024
self_employment_income: 0
output:
# Income: $21,768
# Reduction: $21,768 * 0.5 = $10,884
# GIS: $13,004.16 - $10,884 = $2,120.16
gis: 2_120.16

- name: Single senior with partial income gets reduced GIS
period: 2024
input:
age: 70
adult_years_in_canada: 50
is_head: true
is_spouse: false
employment_income: 10_000
self_employment_income: 0
output:
# Income: $10,000
# Reduction: $10,000 * 0.5 = $5,000
# GIS: $13,004.16 - $5,000 = $8,004.16
gis: 8_004.16

- name: Single senior with income above threshold gets reduced GIS
period: 2024
input:
age: 70
adult_years_in_canada: 50
is_head: true
is_spouse: false
employment_income: 22_000
self_employment_income: 0
output:
# Income: $22,000
# Reduction: $22,000 * 0.5 = $11,000
# GIS: $13,004.16 - $11,000 = $2,004.16
gis: 2_004.16

- name: Not eligible due to age
period: 2024
input:
age: 60
adult_years_in_canada: 40
is_head: true
is_spouse: false
employment_income: 0
self_employment_income: 0
output:
gis: 0

- name: Single senior with high income gets no GIS
period: 2024
input:
age: 70
adult_years_in_canada: 50
is_head: true
is_spouse: false
employment_income: 50_000
self_employment_income: 0
output:
gis: 0

- name: Couple where both receive OAS with no income
period: 2024
input:
people:
head:
age: 70
adult_years_in_canada: 50
is_head: true
employment_income: 0
spouse:
age: 68
adult_years_in_canada: 45
is_spouse: true
employment_income: 0
household:
members: [head, spouse]
output:
# Maximum monthly for couple both OAS is $652.96
# Annual: $652.96 * 12 = $7,835.52 per person
gis: [7_835.52, 7_835.52]

- name: Couple with combined income gets reduced GIS
period: 2024
input:
people:
head:
age: 70
adult_years_in_canada: 50
is_head: true
employment_income: 10_000
spouse:
age: 68
adult_years_in_canada: 45
is_spouse: true
employment_income: 5_000
household:
members: [head, spouse]
output:
# Combined income: $15,000
# Reduction: $15,000 * 0.5 = $7,500
# GIS: $7,835.52 - $7,500 = $335.52 per person
gis: [335.52, 335.52]
39 changes: 39 additions & 0 deletions policyengine_canada/tests/gov/cra/benefits/gis/gis_eligible.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
- name: 65 year old with low income is eligible
period: 2024
input:
age: 65
adult_years_in_canada: 40
employment_income: 5_000
self_employment_income: 0
output:
gis_eligible: true

- name: 65 year old with high income is not eligible
period: 2024
input:
age: 65
adult_years_in_canada: 40
employment_income: 50_000
self_employment_income: 0
output:
gis_eligible: false

- name: 64 year old is not eligible (too young for OAS)
period: 2024
input:
age: 64
adult_years_in_canada: 40
employment_income: 5_000
self_employment_income: 0
output:
gis_eligible: false

- name: 65 year old with insufficient residency is not eligible
period: 2024
input:
age: 65
adult_years_in_canada: 5 # Less than 10 years required for OAS
employment_income: 5_000
self_employment_income: 0
output:
gis_eligible: false
31 changes: 31 additions & 0 deletions policyengine_canada/tests/gov/cra/benefits/gis/gis_income.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
- name: Employment income only
period: 2024
input:
employment_income: 15_000
self_employment_income: 0
output:
gis_income: 15_000

- name: Self-employment income only
period: 2024
input:
employment_income: 0
self_employment_income: 20_000
output:
gis_income: 20_000

- name: Mixed employment and self-employment income
period: 2024
input:
employment_income: 10_000
self_employment_income: 8_000
output:
gis_income: 18_000

- name: No income
period: 2024
input:
employment_income: 0
self_employment_income: 0
output:
gis_income: 0
1 change: 1 addition & 0 deletions policyengine_canada/variables/gov/benefits.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ class benefits(Variable):
"canada_workers_benefit",
"dental_benefit",
"oas_net",
"gis",
# Ontario programs.
"on_benefits",
# British Columbia programs.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
from policyengine_canada.model_api import *


class gis(Variable):
value_type = float
entity = Person
label = "Guaranteed Income Supplement"
unit = CAD
definition_period = YEAR
documentation = "Annual Guaranteed Income Supplement payment for low-income seniors"

def formula(person, period, parameters):
# Check eligibility
eligible = person("gis_eligible", period)

if not eligible.any():
return person.empty_array()

# Get GIS-specific income
gis_income = person("gis_income", period)

# Get marital status at person level
is_head = person("is_head", period)
is_spouse = person("is_spouse", period)

# Check if household is single (will be same for all household members)
is_single_household = person.household("is_single", period)

# Get parameters
p_gis = parameters(period).gov.cra.benefits.guaranteed_income_supplement

# Calculate base amount and threshold based on marital status
# For now, simplified to single vs couple where both get OAS
# TODO: Add other couple scenarios (spouse no OAS, spouse gets Allowance)
max_amount = where(
is_single_household,
p_gis.amount.single * 12, # Convert monthly to annual
p_gis.amount.couple_both_oas * 12
)

income_threshold = where(
is_single_household,
p_gis.threshold.single,
p_gis.threshold.couple_both_oas
)

# For couples, use combined income
# Aggregate household income for GIS calculation
household_gis_income = where(
is_single_household,
gis_income,
person.household.sum(gis_income) # Sum all household members' GIS income
)

# Calculate reduction based on income
# GIS is reduced by 50 cents for every dollar of income
# The threshold is actually the maximum income to receive any GIS
reduction = household_gis_income * p_gis.reduction_rate

# Calculate final benefit
gis_benefit = max_(0, max_amount - reduction)

# Apply eligibility
return where(eligible, gis_benefit, 0)
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
from policyengine_canada.model_api import *


class gis_eligible(Variable):
value_type = bool
entity = Person
label = "Guaranteed Income Supplement eligibility"
definition_period = YEAR
documentation = "Eligibility for the Guaranteed Income Supplement based on OAS eligibility and income"

def formula(person, period, parameters):
# Must be receiving OAS to get GIS
oas_eligible = person("oas_eligibility", period)

# Income test - simplified for now, will be refined with proper income calculation
# GIS uses a special income definition that excludes OAS but includes most other income
employment_income = person("employment_income", period)
self_employment_income = person("self_employment_income", period)

# For now, use basic income for eligibility
# This will need to be expanded to include other income sources
gis_income = employment_income + self_employment_income

p_gis = parameters(period).gov.cra.benefits.guaranteed_income_supplement

# For singles, check if income would still result in positive GIS
# Maximum GIS phases out at twice the maximum amount (at 50% reduction rate)
# TODO: Add proper couple handling
max_gis = p_gis.amount.single * 12
phase_out_income = max_gis / p_gis.reduction_rate
income_eligible = gis_income < phase_out_income

return oas_eligible & income_eligible
Loading
Loading