-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #14 from openfisca/refactor-regimes
Refactor regimes
- Loading branch information
Showing
6 changed files
with
184 additions
and
164 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
'''Helper functions''' | ||
|
||
|
||
import bottleneck | ||
from numpy import minimum as min_ | ||
|
||
|
||
def pension_generique(trimestres_valides, sal_ref, age, taux_annuite_base, taux_annuite_supplemetaire, duree_stage, | ||
age_elig, periode_remplacement_base, plaf_taux_pension, smig): | ||
taux_pension = ( | ||
(trimestres_valides < 4 * periode_remplacement_base) * (trimestres_valides / 4) * taux_annuite_base | ||
+ (trimestres_valides >= 4 * periode_remplacement_base) * ( | ||
taux_annuite_base * periode_remplacement_base | ||
+ (trimestres_valides / 4 - periode_remplacement_base) * taux_annuite_supplemetaire | ||
) | ||
) | ||
montant = min_(taux_pension, plaf_taux_pension) * sal_ref | ||
return montant | ||
|
||
|
||
def mean_over_k_largest(vector, k): | ||
'''Return the mean over the k largest values of a vector''' | ||
if k == 0: | ||
return 0 | ||
|
||
if k <= len(vector): | ||
return vector.sum() / len(vector) | ||
|
||
z = -bottleneck.partition(-vector, kth = k) | ||
return z.sum() / k |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
import functools | ||
from numpy import ( | ||
apply_along_axis, | ||
maximum as max_, | ||
vstack, | ||
) | ||
|
||
from openfisca_core import periods | ||
from openfisca_core.model_api import * | ||
from openfisca_tunisia_pension.entities import Individu | ||
|
||
|
||
class salaire_reference_rsa(Variable): | ||
value_type = float | ||
entity = Individu | ||
label = 'Salaires de référence du régime des salariés agricoles' | ||
definition_period = YEAR | ||
|
||
def formula(individu, period): | ||
# TODO: gérer le nombre d'année | ||
# TODO: plafonner les salaires à 2 fois le smag de l'année d'encaissement | ||
base_declaration_rsa = 180 | ||
base_liquidation_rsa = 300 | ||
|
||
n = 3 | ||
mean_over_largest = functools.partial(mean_over_k_largest, k = n) | ||
salaire = apply_along_axis( | ||
mean_over_largest, | ||
axis = 0, | ||
arr = vstack([ | ||
individu('salaire', period = periods.period('year', year)) | ||
for year in range(period.start.year, period.start.year - n, -1) | ||
]), | ||
) | ||
salaire_refererence = salaire * base_liquidation_rsa / base_declaration_rsa | ||
return salaire_refererence | ||
|
||
|
||
class pension_rsa(Variable): | ||
value_type = float | ||
entity = Individu | ||
label = 'Salaires de référence du régime des salariés agricoles' | ||
definition_period = YEAR | ||
|
||
def formula(individu, period, parameters): | ||
rsa = parameters.retraite.rsa(period) | ||
taux_annuite_base = rsa.taux_annuite_base | ||
taux_annuite_supplemetaire = rsa.taux_annuite_supplemetaire | ||
duree_stage = rsa.stage_requis | ||
age_elig = rsa.age_legal | ||
periode_remplacement_base = rsa.periode_remplacement_base | ||
plaf_taux_pension = rsa.plaf_taux_pension | ||
smag = parameters(period).marche_travail.smag * 25 | ||
duree_stage_validee = trimestres_valides > 4 * duree_stage | ||
pension_min = rsa.pension_min | ||
salaire_reference = individu('salaire_reference_rsa', period) | ||
|
||
montant = pension_generique(trimestres_valides, sal_ref, age, taux_annuite_base, taux_annuite_supplemetaire, | ||
duree_stage, age_elig, periode_remplacement_base, plaf_taux_pension, smag) | ||
|
||
elig_age = age > age_elig | ||
elig = duree_stage_validee * elig_age * (salaire_reference > 0) | ||
montant_percu = max_(montant, pension_min * smag) | ||
pension = elig * montant_percu | ||
return pension |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
import functools | ||
from numpy import ( | ||
apply_along_axis, | ||
logical_not as not_, | ||
maximum as max_, | ||
vstack, | ||
) | ||
|
||
from openfisca_core.model_api import * | ||
from openfisca_tunisia_pension.entities import Individu | ||
from openfisca_tunisia_pension.variables.helpers import mean_over_k_largest, pension_generique | ||
|
||
|
||
class salaire_reference_rsna(Variable): | ||
value_type = float | ||
entity = Individu | ||
label = 'Salaires de référence du régime des salariés non agricoles' | ||
definition_period = YEAR | ||
|
||
def formula(individu, period): | ||
# TODO: gérer le nombre d'année n | ||
# TODO: plafonner les salaires à 6 fois le smig de l'année d'encaissement | ||
n = 10 | ||
mean_over_largest = functools.partial(mean_over_k_largest, k = n) | ||
salaire_refererence = apply_along_axis( | ||
mean_over_largest, | ||
axis = 0, | ||
arr = vstack([ | ||
individu('salaire', period = year) | ||
for year in range(period.start.year, period.start.year - n, -1) | ||
]), | ||
) | ||
return salaire_refererence | ||
|
||
|
||
class pension_rsna(Variable): | ||
value_type = float | ||
entity = Individu | ||
label = 'Pension des affiliés au régime des salariés non agricoles' | ||
definition_period = YEAR | ||
|
||
def formula(individu, period, parameters): | ||
trimestres_valides = individu('trimestres_valides', period = period) | ||
salaire_reference = individu('salaire_reference_rsna', period = period) | ||
age = individu('age', period = period) | ||
|
||
rsna = parameters(period).retraite.rsna | ||
taux_annuite_base = rsna.taux_annuite_base | ||
taux_annuite_supplemetaire = rsna.taux_annuite_supplemetaire | ||
duree_stage = rsna.stage_derog | ||
age_eligible = rsna.age_dep_anticip | ||
periode_remplacement_base = rsna.periode_remplacement_base | ||
plaf_taux_pension = rsna.plaf_taux_pension | ||
smig = parameters(period).marche_travail.smig_48h | ||
|
||
pension_min_sup = rsna.pension_minimale.sup | ||
pension_min_inf = rsna.pension_minimale.inf | ||
|
||
stage = trimestres_valides > 4 * duree_stage | ||
pension_minimale = ( | ||
stage * pension_min_sup + not_(stage) * pension_min_inf | ||
) | ||
montant = pension_generique( | ||
trimestres_valides, | ||
salaire_reference, | ||
age, | ||
taux_annuite_base, | ||
taux_annuite_supplemetaire, | ||
duree_stage, | ||
age_eligible, | ||
periode_remplacement_base, | ||
plaf_taux_pension, | ||
smig, | ||
) | ||
# eligibilite | ||
eligibilite_age = age > age_eligible | ||
eligibilite = stage * eligibilite_age * (salaire_reference > 0) | ||
# plafonnement | ||
montant_pension_percu = max_(montant, pension_minimale * smig) | ||
return eligibilite * montant_pension_percu |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters