Bonjour

Voilà un sujet que nous concerne quasiment tous. Nous allons ici nous donner les moyens de calculer en Python les différents paramètres des crédits proposés par les banques et organismes de crédit.

Les propositions de crédits sont des offres commerciales que vous prenez ou pas. Mais ces calculs vont vous permettre de préparer, de comprendre l'offre et si nécessaire de discuter avec le banquier (pour autant qu'on puisse encore discuter avec un être humain dans ce domaine...).

Ces calculs vous permettront aussi de vérifier que le TAEG (Taux Annuel Effectif Global) qu'on vous présente est correct. Ce TAEG intègre tous les frais qui accompagnent le crédit lui-même: frais de dossier, cotisations d'assurance, etc... Tout offre commerciale doit légalement le présenter dans l'offre, mais j'ai déjà vu des écarts suspects avec le calcul... Plus d'informations ici: https://www.service-public.fr/partic...osdroits/F2456.

NB: j'ai un peu simplifié les calculs en ne prenant pas en compte les cas où le dernier mois a une mensualité différente des autres mois. Par exemple, vous trouvez par le calcul une mensualité de 50.123456789€, mais aucune banque ne vous proposera cela! Il faudrait donc considérer, par exemple, une mensualité de 50.13€, et avoir un dernier mois légèrement plus faible pour compenser. De plus, les fonctions Python ci-dessous renvoient des nombres réels avec leur pleine précision, mais il faudra ne les afficher qu'après les avoir arrondis puisque les mouvements d'argent ne se font pas en dessous des centimes. Mon objectif ici est de donner des bases solides mais simplifiées. Et si ces calculs mathématiques sont précis, ne les opposez pas au centime près auprès des banques. Vous aurez toutefois de très bons ordres de grandeur qui vous permettront de faire vos choix.

Le principe des calculs est assez simple:
- on reçoit le capital emprunté au début du mois 0.
- au début du mois 1, le capital a travaillé 1 mois (vu du prêteur), et on doit donc payer les intérêts correspondants: Capital*intérêts_mensuels, mais on va aussi rembourser une partie du capital. L'ensemble partie intérêt + partie capital constitue la "mensualité".
- au début du mois 2, le capital restant dû (puisqu'on en a déjà remboursé une partie) va aussi générer des intérêts, et on continuera à rembourser une partie du capital.
- etc...
Il faudra en plus définir des mensualités identiques pour toute la durée du remboursement, ce qui nécessite un peu de mathématiques. Je n'ai pas utilisé de formules trouvées sur le web, mais je les ai recalculées. Je n'aborde pas ici la partie purement mathématique de l'établissement des formules, mais si ça intéresse quelqu'un, je peux les développer.

Il y a 4 paramètres à considérer:
- le capital emprunté,
- l'intérêt annuel,
- le nombre de mois de remboursement
- la mensualité.
Il suffit de connaître 3 de ces paramètres pour calculer le 4ème. Voilà les fonctions Python qui permettent de le faire.

Il existe sur le web des sites qui permettent de calculer des crédits. Vous pourrez ainsi vérifier que vos calculs sont justes. Par exemple:
https://www.tableau-amortissement.org
https://www.calculatricecredit.com/
etc...


1- Calcul de la mensualité

Exemple: je veux emprunter 1000€ à 5% par an à rembourser sur 24 mois. Combien devrais-je rembourser par mois?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
def creditmens(C, IA, N):
    """Mensualité M d'un capital C emprunté à IA%/an, à rembourser en N mois
    """
    # si le capital est nul, il n'y a rien à rembourser
    if C==0:
        return 0
    # si l'intérêt est nul, la mensualité ne dépend plus que de C et N
    if IA==0:
        return C/N
    # calcul de la mensualité dans le cas général
    I = IA/1200 # I = intérêt mensuel en décimales
    return C*I*(1-1/(1-(1+I)**N))
Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
M = creditmens(1000, 5, 24)
print("Mensualité:", round(M, 2))
Mensualité: 43.87

2- Calcul du nombre de mois de remboursement

Je veux emprunter 1000€ à 5% par an, mais je ne veux payer par mois que 43.87€: combien me faudra-t-il de mois de remboursement?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
def creditmois(C, IA, M):
    """Nombre de mois de remboursement d'un capital C 
       emprunté à IA%/an et remboursé avec une mensualité M
    """
    # Si le capital=0, il n'y a rien a rembourser
    if C==0:
        return 0
    # Si l'intérêt=0, la mensualité ne dépend plus que de C et M
    if IA==0:
        return C/M
    # Calcul du nombre de mois de remboursement
    I = IA/1200
    return log(1-1/(1-M/(C*I)))/log(1+I)
Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
nbmois = creditmois(1000, 5, 43.87)
print("Nombre de mois:", round(nbmois, 2))
Nombre de mois: 24.0
NB: si vous prenez une autre mensualité, par exemple 45€ ou 50€, vous risquez de tomber sur un nombre de mois non entier. On pourrait avoir une mensualité différente le dernier mois. C'est possible de faire ce calcul, mais ça se complique sérieusement, et ça dépasse le but de cette présentation.


3- Calcul du capital emprunté

Je peux rembourser 43.87€ par mois sur 24 mois avec un intérêt annuel de 5%, combien puis-je emprunter?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
def creditcapit(IA, M, N):
    """Capital emprunté à IA%/an d'intérêt, remboursé 
       en N mois avec une mensualité de M
    """
    # Si l'intérêt=0, le capital est facile à calculer!
    if IA==0:
        return M*N
    # Calcul du capital emprunté
    I = IA/1200
    return M/(I*(1-(1/(1-(1+I)**N))))
Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
capital = creditcapit(5, 43.87, 24)
print("Capital:", int(round(capital, 2)))
Capital: 1000

4- Calcul de l'intérêt annuel

On me propose un crédit avec un capital emprunté de 1000€, des mensualités de 43.87€ à rembourser sur 24 mois: Quel est l'intérêt annuel en % de ce crédit?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
def creditinter(C, M, N):
    """Intérêt en %/an, connaissant le capital emprunté C, 
       la mensualité M et le nb de mois de remboursement N
    """
    # Vérification de la cohérence des données
    if M*N < C:
        raise ValueError("Erreur creditinter: données incohérentes")
    # Cas où l'intérêt est manifestement nul
    if N*M==C:
        return 0.0
    # Calcul de l'intérêt mensuel I par recherche de zéro
    IA = 5.0 # intérêt annuel de départ en %
    I = IA/1200 # interêt mensuel en décimal
    F2 = M-C*I*(1-1/(1-(1+I)**N)) # 1er calcul de F2
    DI = I/5 # incrément de départ pour l'intérêt mensuel
    eps = 1e-12 # écart maxi cherché pour F2
    while fabs(F2)>eps:
        F1 = F2
        F2 = M-C*I*(1-1/(1-(1+I)**N))
        if fabs(F2) > fabs(F1) or F2*F1 < 0.0:
            DI = -DI/2 # on inverse le sens avec un inc. /2
        I += DI
    return I*1200 # retour de l'intérêt annuel en %
Il s'agit ici d'un calcul plus complexe, puisque la formule est une équation implicite pour I (on ne peut pas calculer I=...). On recherche donc le I qui permet à f(I) d'être très près de 0 (à 1e-12 près).

Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
interet = creditinter(1000, 43.87, 24)
print("Intérêt:", round(interet, 2))
Intérêt: 5.0

5- Calcul du coût du crédit

C'est facile à faire: on compare le capital emprunté avec tout ce qu'on rembourse: mensualité * nombre de mois.

Par exemple, pour un capital emprunté de 1000€, on rembourse 43.87€ par mois pendant 24 mois: quel est le coût du crédit?

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
def creditcout(C, M, N, coutsup=0):
    """Coût d'un crédit connaissant le capital C, la 
       mensualité M et le nb de mois de remboursement N 
       (coutsup = coût supplémentaire optionnel à ajouter)
    """
    # Vérification de la cohérence des données
    if M*N < C:
        raise ValueError("Erreur creditcout: données incohérentes")
    return M*N-C+coutsup
J'ai ajouté la possibilité d'ajouter des frais de dossier quand on les connait.

Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
cout = creditcout(1000, 43.87, 24, coutsup=0)
print("Coût:", round(cout, 2))
Coût: 52.91

6- Calcul du tableau d'amortissement

Le tableau d'amortissement décrit mois par mois comment on rembourse petit à petit le capital emprunté, ainsi que le capital qui reste dû. Cela permet, en particulier, d'évaluer ce qui reste à rembouser en cas d'arrêt anticipé du crédit. Attention quand même, dans ce cas, certains crédits s'accompagnent d'une pénalité en cas d'arrêt anticipé.

Ici, la formule retourne une liste de listes, chaque sous-liste contenant:
- le numéro du mois
- un rappel de la mensualité
- la part capital de la mensualité
- la part intérêt de la mensualité
- le capital restant dû

Exemple pour un crédit avec un capital emprunté de 1000€ avec des remboursements de 43.87€/mois sur 24 mois.

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
def creditamort(C, IA, N):
    """Tableau d'amortissement d'un crédit connaissant le 
       capital emprunté C, le nb de mois de remboursement N 
       et la mensualité M
       En sortie: liste des valeurs mensuelles retournées:
         k: numéro de mois (de 1 à N)
         M: rappel de la mensualité
         Ck: part de capital remboursé dans le mois k
         Ik: part des intérêts payés dans le mois k
         CRD: capital restant dû le mois k
       
    """
    I = IA/1200 # Intérêt mensuel en décimal
    M = C*I*(1-1/(1-(1+I)**N))
    tabamort = [] # tableau d'amortissement
    CR = 0 # cumul du capital remboursé
    for k in range(1, N+1):
        # part du capital remboursé du mois
        Ck = (M-I*C)*(1+I)**(k-1)
        # part des intérêts payés dans le mois
        Ik = M-Ck
        # cumul du capital remboursé
        CR += Ck
        # capital restant dû
        CRD = C-CR
        # enregistrement des résultats du mois
        #tabamort.append([k, M, round(Ck, 2), round(Ik, 2), fabs(round(CRD, 2))])
        tabamort.append([k, M, Ck, Ik, fabs(CRD)])
    return tabamort
Application pour l'exemple donné:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
tabamort = creditamort(1000, 5, 24)
for k, M, Ck, Ik, CRD in tabamort:
    print("{:3d}  {:8.2f}  {:8.2f}  {:8.2f}  {:12.2f}".format(k, M, Ck, Ik, CRD))
  1     43.87     39.70      4.17        960.30
  2     43.87     39.87      4.00        920.43
  3     43.87     40.04      3.84        880.39
  4     43.87     40.20      3.67        840.19
  5     43.87     40.37      3.50        799.82
  6     43.87     40.54      3.33        759.28
  7     43.87     40.71      3.16        718.57
  8     43.87     40.88      2.99        677.69
  9     43.87     41.05      2.82        636.64
 10     43.87     41.22      2.65        595.42
 11     43.87     41.39      2.48        554.03
 12     43.87     41.56      2.31        512.47
 13     43.87     41.74      2.14        470.74
 14     43.87     41.91      1.96        428.83
 15     43.87     42.08      1.79        386.74
 16     43.87     42.26      1.61        344.48
 17     43.87     42.44      1.44        302.04
 18     43.87     42.61      1.26        259.43
 19     43.87     42.79      1.08        216.64
 20     43.87     42.97      0.90        173.67
 21     43.87     43.15      0.72        130.52
 22     43.87     43.33      0.54         87.20
 23     43.87     43.51      0.36         43.69
 24     43.87     43.69      0.18          0.00
Je n'ai donné que des exemples de simples crédits à la consommation, mais ça marche aussi, bien sûr pour les crédits immobiliers!


Voici le code complet, à importer par les codes utilisateurs:

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
#!/usr/bin/python
# -*- coding: utf-8 -*-
 
from math import log, fabs
 
#############################################################################
def creditmens(C, IA, N):
    """Mensualité M d'un capital C emprunté à IA%/an, à rembourser en N mois
    """
    # si le capital est nul, il n'y a rien à rembourser
    if C==0:
        return 0
    # si l'intérêt est nul, la mensualité ne dépend plus que de C et N
    if IA==0:
        return C/N
    # calcul de la mensualité dans le cas général
    I = IA/1200 # I = intérêt mensuel en décimales
    return C*I*(1-1/(1-(1+I)**N))
 
############################################################
def creditmois(C, IA, M):
    """Nombre de mois de remboursement d'un capital C 
       emprunté à IA%/an et remboursé avec une mensualité M
    """
    # Si le capital=0, il n'y a rien a rembourser
    if C==0:
        return 0
    # Si l'intérêt=0, la mensualité ne dépend plus que de C et M
    if IA==0:
        return C/M
    # Calcul du nombre de mois de remboursement
    I = IA/1200
    return log(1-1/(1-M/(C*I)))/log(1+I)
 
############################################################
def creditcapit(IA, M, N):
    """Capital emprunté à IA%/an d'intérêt, remboursé 
       en N mois avec une mensualité de M
    """
    # Si l'intérêt=0, le capital est facile à calculer!
    if IA==0:
        return M*N
    # Calcul du capital emprunté
    I = IA/1200
    return M/(I*(1-(1/(1-(1+I)**N))))
 
############################################################
def creditinter(C, M, N):
    """Intérêt en %/an, connaissant le capital emprunté C, 
       la mensualité M et le nb de mois de remboursement N
    """
    # Vérification de la cohérence des données
    if M*N < C:
        raise ValueError("Erreur creditinter: données incohérentes")
    # Cas où l'intérêt est manifestement nul
    if N*M==C:
        return 0.0
    # Calcul de l'intérêt mensuel I par recherche de zéro
    IA = 5.0 # intérêt annuel de départ en %
    I = IA/1200 # interêt mensuel en décimal
    F2 = M-C*I*(1-1/(1-(1+I)**N)) # 1er calcul de F2
    DI = I/5 # incrément de départ pour l'intérêt mensuel
    eps = 1e-12 # écart maxi cherché pour F2
    while fabs(F2)>eps:
        F1 = F2
        F2 = M-C*I*(1-1/(1-(1+I)**N))
        if fabs(F2) > fabs(F1) or F2*F1 < 0.0:
            DI = -DI/2 # on inverse le sens avec un inc. /2
        I += DI
    return I*1200 # retour de l'intérêt annuel en %
 
############################################################
def creditcout(C, M, N, coutsup=0):
    """Coût d'un crédit connaissant le capital C, la 
       mensualité M et le nb de mois de remboursement N 
       (coutsup = coût supplémentaire optionnel à ajouter)
    """
    # Vérification de la cohérence des données
    if M*N < C:
        raise ValueError("Erreur creditcout: données incohérentes")
    return M*N-C+coutsup
 
############################################################ 
def creditamort(C, IA, N):
    """Tableau d'amortissement d'un crédit connaissant le 
       capital emprunté C, le nb de mois de remboursement N 
       et la mensualité M
       En sortie: liste des valeurs mensuelles retournées:
         k: numéro de mois (de 1 à N)
         M: rappel de la mensualité
         Ck: part de capital remboursé dans le mois k
         Ik: part des intérêts payés dans le mois k
         CRD: capital restant dû le mois k
       
    """
    I = IA/1200 # Intérêt mensuel en décimal
    M = C*I*(1-1/(1-(1+I)**N))
    tabamort = [] # tableau d'amortissement
    CR = 0 # cumul du capital remboursé
    for k in range(1, N+1):
        # part du capital remboursé du mois
        Ck = (M-I*C)*(1+I)**(k-1)
        # part des intérêts payés dans le mois
        Ik = M-Ck
        # cumul du capital remboursé
        CR += Ck
        # capital restant dû
        CRD = C-CR
        # enregistrement des résultats du mois
        #tabamort.append([k, M, round(Ck, 2), round(Ik, 2), fabs(round(CRD, 2))])
        tabamort.append([k, M, Ck, Ik, fabs(CRD)])
    return tabamort

Comme je ne suis pas banquier, ces calculs sont donnés sans garantie. Mais rien ne vous empêche d'utiliser les simulateurs du web pour vérifier. Et n'hésitez pas à signaler d'éventuels problèmes d'application.

Bons calculs! Mais "consommez" vos crédits avec modération...