diff --git a/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/average_monthly.yaml b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/average_monthly.yaml new file mode 100644 index 000000000..e3b65f44d --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/average_monthly.yaml @@ -0,0 +1,15 @@ +description: Average monthly CPP retirement pension at age 65 +values: + 2020-01-01: 710.41 + 2021-01-01: 702.77 + 2022-01-01: 727.61 + 2023-01-01: 758.32 + 2024-01-01: 816.52 + 2025-01-01: 844.53 +metadata: + unit: currency-CAD + period: month + label: CPP average monthly retirement pension + reference: + - title: CPP retirement pension amount + href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/cpp-benefit/amount.html \ No newline at end of file diff --git a/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/eligibility_age.yaml b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/eligibility_age.yaml new file mode 100644 index 000000000..4c43dfb7a --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/eligibility_age.yaml @@ -0,0 +1,10 @@ +description: Minimum age for CPP retirement pension eligibility +values: + 2020-01-01: 60 +metadata: + unit: year + period: year + label: CPP retirement pension eligibility age + reference: + - title: CPP retirement pension eligibility + href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/cpp-benefit/eligibility.html \ No newline at end of file diff --git a/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/maximum_monthly.yaml b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/maximum_monthly.yaml new file mode 100644 index 000000000..564c1f49e --- /dev/null +++ b/policyengine_canada/parameters/gov/cra/benefits/cpp/retirement/maximum_monthly.yaml @@ -0,0 +1,15 @@ +description: Maximum monthly CPP retirement pension at age 65 +values: + 2020-01-01: 1_175.83 + 2021-01-01: 1_203.75 + 2022-01-01: 1_253.59 + 2023-01-01: 1_306.57 + 2024-01-01: 1_364.60 + 2025-01-01: 1_433.00 +metadata: + unit: currency-CAD + period: month + label: CPP maximum monthly retirement pension + reference: + - title: CPP retirement pension amount + href: https://www.canada.ca/en/services/benefits/publicpensions/cpp/cpp-benefit/amount.html \ No newline at end of file diff --git a/policyengine_canada/tests/benefits/cpp/cpp_retirement_pension.yaml b/policyengine_canada/tests/benefits/cpp/cpp_retirement_pension.yaml new file mode 100644 index 000000000..c6ce43d01 --- /dev/null +++ b/policyengine_canada/tests/benefits/cpp/cpp_retirement_pension.yaml @@ -0,0 +1,55 @@ +- name: CPP retirement pension with full contributions + period: 2024 + input: + age: 65 + cpp_years_of_contribution: 40 + output: + # Full contributions (40 years) = average monthly benefit + # $816.52 * 12 = $9,798.24 + cpp_retirement_pension: 9_798.24 + +- name: CPP retirement pension with partial contributions + period: 2024 + input: + age: 65 + cpp_years_of_contribution: 20 + output: + # 20/40 years = 50% of average benefit + # $816.52 * 0.5 * 12 = $4,899.12 + cpp_retirement_pension: 4_899.12 + +- name: No pension below age 60 + period: 2024 + input: + age: 55 + cpp_years_of_contribution: 30 + output: + cpp_retirement_pension: 0 + +- name: No pension without contributions + period: 2024 + input: + age: 65 + cpp_years_of_contribution: 0 + output: + cpp_retirement_pension: 0 + +- name: CPP retirement pension for 2025 + period: 2025 + input: + age: 70 + cpp_years_of_contribution: 45 + output: + # Capped at 40 years = full average benefit + # $844.53 * 12 = $10,134.36 + cpp_retirement_pension: 10_134.36 + +- name: Minimum contribution scenario + period: 2024 + input: + age: 60 + cpp_years_of_contribution: 1 + output: + # 1/40 years = 2.5% of average benefit + # $816.52 * 0.025 * 12 = $244.956 + cpp_retirement_pension: 244.956 \ No newline at end of file diff --git a/policyengine_canada/variables/gov/benefits.py b/policyengine_canada/variables/gov/benefits.py index 052eae5ed..9a0fd00fa 100644 --- a/policyengine_canada/variables/gov/benefits.py +++ b/policyengine_canada/variables/gov/benefits.py @@ -11,6 +11,7 @@ class benefits(Variable): "child_benefit", "child_disability_benefit", "canada_workers_benefit", + "cpp_retirement_pension", "dental_benefit", "oas_net", # Ontario programs. diff --git a/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_eligible.py b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_eligible.py new file mode 100644 index 000000000..2bbdc82c0 --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_eligible.py @@ -0,0 +1,22 @@ +from policyengine_canada.model_api import * + + +class cpp_retirement_eligible(Variable): + value_type = bool + entity = Person + label = "Eligible for CPP retirement pension" + definition_period = YEAR + documentation = "Whether person is eligible for CPP retirement pension" + + def formula(person, period, parameters): + p = parameters(period).gov.cra.benefits.cpp.retirement + + # Check age requirement (60+) + age = person("age", period) + meets_age = age >= p.eligibility_age + + # Check contribution requirement (simplified - at least 1 year) + years_contributed = person("cpp_years_of_contribution", period) + has_contributions = years_contributed > 0 + + return meets_age & has_contributions \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_pension.py b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_pension.py new file mode 100644 index 000000000..804814a79 --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_retirement_pension.py @@ -0,0 +1,32 @@ +from policyengine_canada.model_api import * + + +class cpp_retirement_pension(Variable): + value_type = float + entity = Person + label = "CPP retirement pension" + definition_period = YEAR + unit = CAD + documentation = "Annual CPP retirement pension amount" + + def formula(person, period, parameters): + p = parameters(period).gov.cra.benefits.cpp.retirement + + # Check eligibility + eligible = person("cpp_retirement_eligible", period) + + # Simplified calculation based on years of contribution + # Use average between 0 and maximum based on contribution years + years_contributed = person("cpp_years_of_contribution", period) + + # Assume full contributions after 40 years + contribution_factor = min_(years_contributed / 40, 1) + + # Calculate monthly amount between 0 and maximum + # For simplicity, use average as midpoint + monthly_amount = contribution_factor * p.average_monthly + + # Convert to annual + annual_amount = monthly_amount * 12 + + return where(eligible, annual_amount, 0) \ No newline at end of file diff --git a/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_years_of_contribution.py b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_years_of_contribution.py new file mode 100644 index 000000000..e5ea52f7d --- /dev/null +++ b/policyengine_canada/variables/gov/cra/benefits/cpp/cpp_years_of_contribution.py @@ -0,0 +1,10 @@ +from policyengine_canada.model_api import * + + +class cpp_years_of_contribution(Variable): + value_type = float + entity = Person + label = "Years of CPP contributions" + definition_period = YEAR + unit = "year" + documentation = "Number of years person has contributed to CPP" \ No newline at end of file