Forum de mathématiques - Bibm@th.net
Vous n'êtes pas identifié(e).
- Contributions : Récentes | Sans réponse
Pages : 1
Discussion fermée
#1 30-05-2009 11:40:05
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 991
[Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Bonjour à tous,
Programme (encore dispo) écrit en "Locomotive Basic" (Amstrad CPC 6128) et traduit aujourd'hui en Python.
Il vous propose :
* +- PHYNANCE -+ *
* Logiciel de calculs financiers *
*******************************************
1. Echéancier de prêt à remboursement constant
2. Echéancier de prêt à amortissement constant
3. Echéancier de prêt à remboursements progressifs
4. Echéancier de prêt à remboursements "ronds" + reliquat
5. Somme obtenue après placement d'un Capital donné
6. Somme à placer pour obtenir un Capital donné
7. Durée nécessaire pour obtenir un Capital donné à partir d'une somme fixée
8. Taux nécessaire pour obtenir un Capital donné à partir d'une somme fixée
9. Capital obtenu par dépôt périodique d'une somme toujours identique
10. Capital obtenu par dépôt périodique d'une somme -également- croissante
0. Sortie du programme
Votre choix :
Ce programme en Basic Amstrad était tellement mal programmé et l'option 3. tellement absconse pour moi aujourd'hui, que j'ai mis beaucoup de temps à le réécrire à peu près "proprement" en Python...
Il ne devrait pas receler d'erreurs, si toutefois vous en trouviez une, me le signaler, merci.
Les échéanciers proposés sont évidemment hors assurances, en général facultatives.
L'option 3. , donc, présente un type de prêt qui n'est plus proposé aujourd'hui (du moins, je ne crois pas) et qui conduisait à des situations aberrantes.
L'exemple que je vous propose est tiré d'une situation réelle et colle au centime près à l'échéancier du Crédit Foncier que j'ai pu me procurer et correspond à des sommes étiquetées en Francs (et pas en € comme aujourd'hui), puisque cet exemple date du temps (de feu Raymond BARRE ?) d'une inflation > 10 %.
Emprunt 358255 F.
Taux n°1 : 10.8 % Durée 4 ans
Taux n°2 : 12.9 % Durée 3 ans
Taux n°3 : 14.7 % Durée 13 ans
Amortissement trimestriel (donc 4 remboursements par an).
Différé d'amortissement : 2 ans (Les deux premières années, on ne paie que des intérêts !)
Progressivité annuelle : 4 % (Le montant du remboursement trimestriel augmente de 4 % par an à partir du début de la 4e année)
L'aberration est là :
Remboursements nos : Amortissement en capital
17 -60.23
18 -62.17
19 -64.18
20 -66.25
Le même phénomène se reproduit pour les versements 29 - 30 - 31 - 32...
Que se passe-t-il donc ?
Et bien, Pour maintenir (au changement de taux) une trimestrialité constante sur l'année, le montant des intérêts dus étant tellement élevé qu'il dépasse la valeur de l'échéance trimestrielle, on vous... rend (!) donc du capital !!!
Voilà le code :
# -*- coding: cp1252 -*-
from math import log, exp
def titre_general():
# Titre clin d'oeil à la "Pompe à phynances" d'Alfred JARRY...
print
print
print
print " *******************************************"
print " * +- PHYNANCE -+ *"
print " * Logiciel de calculs financiers *"
print " *******************************************"
print
def titres(titre):
blancs,etoiles=[15,15,9,7],[50,50,60,65]
suite=["à remboursement constant *","à amortissement constant *",\
"progressifs à un ou plusieurs taux *","à remboursements ronds + reliquat final *"]
print
print
print " "*blancs[titre]+"*"*etoiles[titre]
print " "*blancs[titre]+"* Echéancier de prêts "+suite[titre]
print " "*blancs[titre]+"*"*etoiles[titre]
print
print
def sortie():
print
print
print " Au revoir !"
def formate(nbr):
if nbr.find(".")==-1:
nbr+=".00"
else:
if len(nbr)==nbr.find(".")+2:
nbr+="0"
return nbr
def cout_credit(co):
print " Pour un coût total du crédit de %.2f" % co,"€"
print
def incorrect():
print " ...Désolé, valeur incorrecte. Veuillez recommencer ..."
def pas_nb():
print " ... Ce n'est pas un nombre. Veuillez recommencer..."
def chx_message(ch):
ch=' ... Pour retourner au menu,; ... Pour la suite,'
return ch
def message(mess):
print
print " ",mess,"Presser ENTREE ..."
raw_input("")
def demande_nb_taux(nb):
while nb==0:
try:
nb=int(raw_input(" Nombre de taux (1, 2 ou 3): "))
if nb <1 or nb >3:
nb=0
print "Entrée non comprise entre 1 et 3. Veuillez recommencer..."
except ValueError:
pas_nb()
return nb
def demande_tx(ta):
while ta==0:
try:
ta=float(raw_input("? "))
if ta<0:
ta=0
incorrect()
elif ta==0:
print "Taux nul... Veuillez recommencer..."
elif ta >33.33:
ta=0
print "Taux supérieur au taux d'usure. Veuillez recommencer..."
except ValueError:
pas_nb()
return ta
def demande_duree(dur,periode):
noms={1:"années",2:"semestres",4:"trimestres",12:"mois"}
coeff={1:12,2:2,4:4,12:1}
print "Exprimée en nombre d"+"e ,'".split(",")[periode==1]+noms[periode]+",",
while dur==0:
try:
dur=int(raw_input("durée (de 1 à "+str(360/coeff[periode])+" "+noms[periode]+") ? "))
if dur >360/coeff[periode]:
dur = 0
incorrect()
except ValueError:
pas_nb()
return dur
def demande_mensualite_souhaitee(vsmt):
while vsmt==0:
try:
vsmt=int(raw_input(" Mensualité "+chr(34)+"ronde"+chr(34)+\
" souhaitée (multiple de 50 €) ? "))
if vsmt%50 != 0:
vsmt=0
incorrect()
except ValueError:
pas_nb()
return vsmt
def demande_depot(ca,sod,mode):
if mode==0:
while ca==0:
try:
print "Quel est le montant du dépôt",
ca=float(raw_input("initial,régulier".split(",")[mode]+" ? "))
if ca<0:
ca=0
incorrect()
except ValueError:
pas_nb()
else:
while sod==0:
try:
sod=float(raw_input("Montant de l'augmentation régulière : "))
if sod<0:
sod=0
incorrect()
except ValueError:
pas_nb()
return ca,sod
def demande_periodicite(periode):
chx_per,per,ch=0,[12,4,2,1],[]
#ch=chx_message(ch)
print
print " La périodicité sera-t-elle :"
print " 1. Mensuelle"
print " 2. Trimestrielle"
print " 3. Semestrielle"
print " 4. Annuelle"
print
while chx_per==0:
try:
chx_per=int(raw_input(" ** Votre choix ? ** "))
if chx_per<1 or chx_per>4:
chx_per=0
incorrect()
except ValueError:
pas_nb()
periode=per[chx_per-1]
print
return periode
def demande_capital_emprunte(cap,cap_min):
while cap==0:
try:
cap=float(raw_input(" Somme empruntée (entre "+str(cap_min)+" et 500000 €) : "))
if cap <cap_min or cap >500000:
cap=0
incorrect()
except ValueError:
pas_nb()
return cap
def demande_capital(cap,mot):
while cap==0:
try:
cap=float(raw_input( "Quel est votre capital "+mot+" (entre 1000 et 50000 €) : "))
if cap <1000 or cap >50000:
cap=0
incorrect()
except ValueError:
pas_nb()
return cap
def entete_tableau():
print "|------|------------|----------|-----------|----------|------------|------------|"
print "| Vsmt | Capital | Rembsmt | Intérêt | Amortmt | Amort. | Capital |"
print "| n° | | | | | cumulé | restant dû |"
print "|------|------------|----------|-----------|----------|------------|------------|"
def affiche_corps_tableau(i, v1, v2, v3, v4, v5,v6):
print "| %3i" % i," |%11s" % v1,"|%9s"% v2,"| %9s" % v3,"| %8s" % v4,
print "|%11s" % v5,"|%11s" % v6,"|"
def pied_tableau():
print "|------|------------|----------|-----------|----------|------------|------------|"
def affichage_fin_tranche(v,ta,periode,ch):
pied_tableau()
message(ch.split(';')[1])
affiche_cap_taux(v,ta,periode)
entete_tableau()
def affiche_cap_taux(v,ta,periode):
print " Capital emprunté :","%11s" % v,"€ Taux :",ta*100*periode,"%"
def remboursement_constant():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,ch=0,1000,0,0,0,0,0,0,0,0,''
titres(0)
ch=chx_message(ch)
cap=demande_capital_emprunte(cap,cap_min)
v=formate(str(cap))
periode=demande_periodicite(periode)
n=demande_duree(dur,periode)
print "A quel taux",
ta=demande_tx(ta)
ta=ta/periode/100.0
vsmt=round(cap/(((1+ta)**n-1)/(ta*(1+ta)**n)),2)
am=cap*ta/((1+ta)**n-1)
print
print
titres(0)
print "Capital emprunté :","%11s" % v,"€ Taux :",ta*100*periode,"%"
entete_tableau()
for i in xrange(1,n+1):
#if i%12==1 and i >1: # <| Supprimer le # devant ces lignes
#affichage_fin_tranche(v,ta,12,ch) # <| pour un affichage par 12 versements
intr = round(cap*ta,2)
if i==n:
am=cap
intr=vsmt-cap
else:
am = round(vsmt-intr,2)
amcu = round(amcu+am,2)
co=round(co+intr,2)
v1=formate(str(cap))
v2=formate(str(vsmt))
v3=formate(str(intr))
v4=formate(str(am))
v5=formate(str(amcu))
cap = round(cap-am,2)
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5, v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print
return
def amortissement_constant():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,mess,ch=0,1000,0,0,0,0,0,0,0,0,[],''
titres(1)
ch=chx_message(ch)
cap=demande_capital_emprunte(cap,cap_min)
v=formate(str(cap))
periode=demande_periodicite(periode)
n=demande_duree(dur,periode)
print "A quel taux",
ta=demande_tx(ta)
ta=ta/periode/100.0
am = round(cap/n,2)
print
print
titres(1)
affiche_cap_taux(v,ta,periode)
entete_tableau()
for i in xrange(1,n+1):
#if i%12==1 and i >1: # <| Supprimer le # devant ces lignes
#affichage_fin_tranche(v,ta,12,ch) # <| pour un affichage par 12 versements
intr = round(cap*ta,2)
vsmt=round(am+intr,2)
co=round(co+intr,2)
amcu=round(am*i,2)
v1=formate(str(cap))
v4=formate(str(am))
cap = round(cap-am,2)
v6=formate(str(cap))
if i==n:
correctif=round(amcu-float(v),2)
cap=0
if correctif<0:
intr=round(intr+correctif,2)
vsmt=round(vsmt+correctif,2)
co=round(co+intr+correctif,2)
elif correctif>0:
intr=round(intr-correctif,2)
vsmt=round(vsmt-correctif,2)
co=round(co+intr-correctif,2)
v2=formate(str(vsmt))
v3=formate(str(intr))
v5=formate(str(amcu))
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5,v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print
return
def remboursements_progressifs():
am,amcu,co,n,nb,cap,periode,ch=0,0,0,0,0,0,0,''
x2,x3,cap_min,tx,dur_tx=0,0,100000,[0,0,0],[0,0,0]
ch=chx_message(ch)
titres(2)
cap=demande_capital_emprunte(cap,cap_min)
periode=demande_periodicite(periode)
nb=demande_nb_taux(nb)
for i in xrange(nb):
ta,dur=0,0
print "Taux",
if nb>1:
print "no "+str(i+1)+" :",
else:
print ":",
ta=demande_tx(ta)
tx[i]=ta/periode/100.0
dur_tx[i]=demande_duree(dur,1)
n+=dur_tx[i]
print" ---------------"
n*=periode
diff_am=-1
while diff_am<0:
try:
diff_am=int(raw_input("Durée du différé d'amortissement (de 1 à 4 ans): ** ? ** "))
if diff_am<1 or diff_am>4:
print
diff_am=-1
incorrect()
print
except ValueError:
pas_nb()
print
diff_am*=periode
print" ---------------"
prg=-1
while prg<0:
try:
prg=int(raw_input("Progressivité annuelle (en %)) : ** ? ** "))
if prg<0:
print
prg=0
incorrect()
print
except ValueError:
pas_nb()
print
x1,x2,x3=0,0,0
prg=prg/100.0
ai1=1/(1+tx[0])
ai2=1/(1+tx[1])
ai3=1/(1+tx[2])
n1=float(dur_tx[0]-diff_am/periode)
a1=(1+prg)/(1+tx[0])
a2=(ai1**periode-1)/(ai1-1)
a3=((1+prg)**n1*ai1**(n1*periode)-1)/((1+prg)*ai1**periode-1)
x1=a1*a2*a3
if nb > 1:
a1=((1+prg)/(1+tx[0])**periode)**n1
a2=(1+prg)/(1+tx[1])
a3=(ai2**periode-1)/(ai2-1)
a4=((1+prg)**dur_tx[1]*ai2**(dur_tx[1]*periode)-1)/((1+prg)*ai2**periode-1)
x2=a1*a2*a3*a4
if nb > 2:
a1=((1+prg)/(1+tx[0])**periode)**n1
a2=((1+prg)/(1+tx[1])**periode)**dur_tx[1]
a3=(1+prg)/(1+tx[2])
a4=(ai3**periode-1)/(ai3-1)
a5=((1+prg)**dur_tx[2]*ai3**(dur_tx[2]*periode)-1)/((1+prg)*ai3**periode-1)
x3=a1*a2*a3*a4*a5
vsmt=cap/(x1+x2+x3)
vo=vsmt
print
print
titres(2)
v=formate(str(cap))
print "Capital emprunté :","%11s" % v,"€"
for i in xrange(nb):
print " Taux n° "+str(i+1)+" : "+formate(str(round(tx[i]*100*periode,2))).rjust(5)+" % ",
print "Durée : "+str(dur_tx[i]).rjust(2)+" ans"
print
entete_tableau()
a=tx[0]
dur1,dur2=dur_tx[0]*periode+1,(dur_tx[0]+dur_tx[1])*periode+1
for i in xrange(1,n+1):
#if i%12==1 and i>1: # <| Supprimer le # devant ces lignes
#pied_tableau() # <| pour un
#message(ch.split(';')[1]) # <| affichage de l'échéancier
#entete_tableau() # <| per 12 versements
if i<=diff_am:
am=0
intr=round(cap*a,2)
vsmt=intr
v2=formate(str(vsmt))
elif i<n:
if i==dur1:
a=tx[1]
elif i==dur2:
a=tx[2]
vsmt=round(vo*(1+prg)**(1+(i-diff_am-1)/periode),2)
intr=round(cap*a,2)
am=round(vsmt-intr,2)
else:
am=cap
intr=round(vsmt-am,2)
amcu+=am
co+=intr
v1=formate(str(cap))
v2=formate(str(vsmt))
v3=formate(str(intr))
v4=formate(str(am))
v5=formate(str(amcu))
cap=round(cap-am,2)
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5, v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print
return
def remboursements_ronds_reliquat():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,mens,ch=0,1000,0,0,0,0,0,0,0,0,0,''
ch=chx_message(ch)
titres(3)
cap=demande_capital_emprunte(cap,cap_min)
print "A quel taux",
ta=demande_tx(ta)
print
print " - Notez bien : l'amortissement est mensuel ! -"
print
vsmt=demande_mensualite_souhaitee(vsmt)
ta = ta/1200.0
q = 1 + ta
n = int(cap/vsmt)+1
mens = q*(q**(n-1)*cap-vsmt*(q**(n-1)-1)/ta)
while mens>vsmt:
n+=1
mens = q*(q**(n-1)*cap-vsmt*(q**(n-1)-1)/ta)
print
print " La durée de remboursement sera obligatoirement de", n/12, "ans",n%12,"mois."
message(ch.split(';')[1])
am = round(float(cap/n),2)
v1=formate(str(cap))
v=v1
print
print
titres(3)
v2 = formate(str(vsmt))
affiche_cap_taux(v,ta,12)
entete_tableau()
for i in xrange(1,n+1):
#if i%12==1 and i >1: # <| Supprimer le # devant ces lignes
#affichage_fin_tranche(v,ta,12,ch) # <| pour un affichage par 12 versements
v1=formate(str(cap))
intr = round(cap*ta,2)
if i==n:
am=cap
vsmt=round(am+intr,2)
cap=0
else:
am = round(vsmt - intr,2)
cap = round(cap - am,2)
amcu = round(amcu + am,2)
co= round(co + intr,2)
v2 = formate(str(vsmt))
v3=formate(str(intr))
v4 = formate(str(am))
v5=formate(str(amcu))
v6=formate(str(cap))
affiche_corps_tableau(i,v1,v2,v3,v4,v5,v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print
return
def cherche_taux():
cap,cap_fin,ta,dur,periode,ch=0,0,0,0,0,''
ch=chx_message(ch)
print
print
print " ************************************************"
print " * Recherche du taux de placement d'un capital *"
print " ************************************************"
print
print
mot="de départ"
cap=demande_capital(cap,mot)
mot="final"
cap_fin=demande_capital(cap_fin,mot)
dur=demande_duree(dur,12)
ta = 100*(exp(log(cap_fin/cap)/(dur/12.0))-1)
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print " Le taux nécessaire à un capital de", cap,"€ pour devenir",cap_fin,"€ après", dur/12,"ans",dur%12,"mois est :"
print " %.2f" % ta,"%"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print
print "N-B : Pour une même durée, ce résultat ne dépend que du rapport entre les capitaux d'arrivée et de départ ..."
print
message(ch.split(';')[0])
return
def cherche_capital_depart():
cap,ta,dur,mot,ch=0,0,0,"final",''
ch=chx_message(ch)
print
print
print " ************************************"
print " * Recherche du capital de départ *"
print " ************************************"
print
print
cap=demande_capital(cap,mot)
print "Taux du placement (en %)",
ta=demande_tx(ta)
ta=ta/100.0
dur=demande_duree(dur,12)
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print "Le capital à placer pour obtenir",cap,"€ à", ta*100,"% pendant",dur/12,"ans",dur%12,"mois est :"
v=formate(str(round(cap*(1+ta)**(-dur/12.0),2)))
print " ","%11s" % v,"€"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print
message(ch.split(';')[0])
return
def cherche_capital_final():
cap,ta,dur,mot,ch=0,0,0,"de départ",''
ch=chx_message(ch)
print
print
print " *******************************"
print " * Recherche du capital final *"
print " *******************************"
print
print
cap=demande_capital(cap,mot)
print "Taux du placement (en %)",
ta=demande_tx(ta)
ta=ta/100.0
dur=demande_duree(dur,12)
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print "Le capital obtenu après placement de",cap,"€ à", ta*100,"% pendant",dur/12,"ans",dur%12,"mois sera :"
v=formate(str(round(cap*(1+ta)**(dur/12.0),2)))
print " ","%11s" % v,"€"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print
message(ch.split(';')[0])
def cherche_duree_placement():
cap,cap_fin,ta,dur,nbf,ch=0,0,0,0,0,''
ch=chx_message(ch)
print
print
print " ****************************************************"
print " * Recherche de la durée de placement d'un capital *"
print " ****************************************************"
print
print
mot="de départ"
cap=demande_capital(cap,mot)
mot="final"
cap_fin=demande_capital(cap_fin,mot)
print "Taux du placement (en %) ",
ta=demande_tx(ta)
ta=ta/100.0
nbf=float(cap_fin/cap)
tp= log(nbf)/log(1+ta)
dur = int(360*tp)
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print " La durée de placement à",ta*100,"% pour passer de",cap,"€ à",round(cap*(1+ta)**tp,2),"€ est :"
print
print " ",round(tp,2),"années"
print
print " Soit encore ",int(dur/360.0),"ans",int((dur%360.0)/30),"mois"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print
print "N-B : Pour un même taux, ce résultat ne dépend que du rapport entre les capitaux d'arrivée et de départ ..."
print
message(ch.split(';')[0])
return
def calcul_depot_constant():
sod,sof,ta,dur,periode,mode,ca,ch=0,0,0,0,0,0,0,''
ch=chx_message(ch)
print
print
print " *******************************************"
print " * Placement à dépôt régulier et constant *"
print " *******************************************"
print
periode=demande_periodicite(periode)
dico_per={12:'mois',4:'trimestre)',2:'semestre)',1:'année'}
dur=demande_duree(dur,periode)
ca,sod=demande_depot(ca,sod,mode)
print "Taux annuel du placement (en %)",
ta=demande_tx(ta)
q=1+ta/100.0/periode
sof = ca*q*(q**dur-1)/(q-1)
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print " Après "+str(dur)+" versements chaque "+dico_per[periode]+" de "+str(ca)+" € au taux annuel \
de "+str(ta)+" %"
print " vous serez à la tête de %.2f" % sof, "€"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
message(ch.split(';')[0])
return
def calcul_depot_progressif():
n,ta,sod,vsmt,q,periode,dur,ca,ch=0,0,0,0,0,0,0,0,''
ch=chx_message(ch)
dico_per={12:'mois',4:'trimestre',2:'semestre',1:'année'}
print
print
print " *****************************************************"
print " * Placement à dépôt régulier régulier et croissant *"
print " - toujours de la même somme - *"
print " *****************************************************"
print
periode=demande_periodicite(periode)
print "Taux annuel du placement :",
ta=demande_tx(ta)
print "---------------------"
q=1+ta/100.0/periode
n=demande_duree(dur,periode)
mode = 0
ca,sod=demande_depot(ca,sod,mode)
mode=1
ca,sod=demande_depot(ca,sod,mode)
sof = q*((ca+sod/(q-1))*(q**n-1)/(q-1)-n*sod/(q-1))
print
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
print " Après "+str(n)+" versements de "+str(ca),str(ca+sod),str(ca+2*sod)+"..."+str(ca+(n-1)*sod)\
+" € au taux annuel de "+str(ta)+" %"
print " vous serez à la tête de %.2f" % sof, "€"
print " +++++++++++++++++++++++++++++++++++++++++++++++++"
message(ch.split(';')[0])
return
fin=100
while fin>0:
titre_general()
print " 1. Echéancier de prêt à remboursement constant"
print " 2. Echéancier de prêt à amortissement constant"
print " 3. Echéancier de prêt à remboursements progressifs"
print " 4. Echéancier de prêt à remboursements \"ronds\" + reliquat"
print " 5. Somme obtenue après placement d'un Capital donné"
print " 6. Somme à placer pour obtenir un Capital donné"
print " 7. Durée nécessaire pour obtenir un Capital donné à partir d'une somme fixée"
print " 8. Taux nécessaire pour obtenir un Capital donné à partir d'une somme fixée"
print " 9. Capital obtenu par dépôt périodique d'une somme toujours identique"
print "10. Capital obtenu par dépôt périodique d'une somme -également- croissante"
print
print " 0. Sortie du programme"
chx_menu='100'
while chx_menu=='100':
try:
chx_menu=raw_input(" Votre choix : ")
fin = int(chx_menu)
choix2 = {'1': remboursement_constant,
'2': amortissement_constant,
'3': remboursements_progressifs,
'4': remboursements_ronds_reliquat,
'5': cherche_capital_final,
'6': cherche_capital_depart,
'7': cherche_duree_placement,
'8': cherche_taux,
'9': calcul_depot_constant,
'10': calcul_depot_progressif,
'0': sortie}
if fin <0 or fin>10:
chx_menu='100'
incorrect()
except ValueError:
pas_nb()
choix2[chx_menu]()
Réactions, commentaires bienvenus...
@+
Arx Tarpeia Capitoli proxima...
Hors ligne
#2 30-05-2009 12:37:32
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Hello tutti,
Désolé yoshi, mais cette (im)pertinente remarque est erronée : l'échéance initiale = 3.171,38 FFR pour 100.000 FFR empruntés.
Toute l'astuce consistait à fixer un taux initial à un niveau tel qu'il évite cet effet malheureux d'intérêt reportés.
C'était un prêt PAP (aide de l'État à la pierre) des années 1985 distribué par le Crédit Foncier de France.
Les aides de l'État à la pierre sont distribuées aujourd'hui sous la forme du prêt à taux 0 % sous conditions de
revenus.
La règle de la progression annuelle des échéances s'applique à l'issue de la première année d'entrée en amortissement, à l'issue des deux premières années de différé d'amortissement.
Je n'ai pas bien regarder ton pgm, sorry !
Dernière modification par freddy (30-05-2009 12:46:42)
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#3 30-05-2009 12:43:13
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
On pourrait d'ailleurs ouvrir une rubrique sur les calculs financiers et les formules actuarielles ad hoc ?
T'en penses quoi, Fred ?
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#4 30-05-2009 13:11:41
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 991
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Salut Freddy,
Merci de ton intérêt, j'étais à peu près sûr que tu allais te manifester, aussi depuis 8 jours, je contrôle tout sur toutes les coutures... ;-)
Cela dit, je ne comprends pas très bien le sens de ta remarque : ce que je reproduis est conforme à l'échéancier officiel du Crédit Foncier de France relayé par le Comptoir Des Entrepreneurs.
Quant à la date, je l'ai trouvée, c'est plus vieux que ça encore : 1982 !!!
Voilà le début de l'échéancier avec remboursement trimestriel :
* Echéancier de prêts progressifs à un ou plusieurs taux *
************************************************************
Capital emprunté : 358255.00 €
Taux n° 1 : 10.80 % Durée : 4 ans
Taux n° 2 : 12.90 % Durée : 3 ans
Taux n° 3 : 14.70 % Durée : 13 ans
|------|------------|----------|-----------|----------|------------|------------|
| Vsmt | Capital | Rembsmt | Intérêt | Amortmt | Amort. | Capital |
| n° | | | | | cumulé | restant dû |
|------|------------|----------|-----------|----------|------------|------------|
| 1 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 2 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 3 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 4 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 5 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 6 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 7 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 8 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 9 | 358255.00 | 10387.35 | 9672.89 | 714.46 | 714.46 | 357540.54 |
| 10 | 357540.54 | 10387.35 | 9653.59 | 733.76 | 1448.22 | 356806.78 |
| 11 | 356806.78 | 10387.35 | 9633.78 | 753.57 | 2201.79 | 356053.21 |
| 12 | 356053.21 | 10387.35 | 9613.44 | 773.91 | 2975.70 | 355279.30 |
| 13 | 355279.30 | 10802.85 | 9592.54 | 1210.31 | 4186.01 | 354068.99 |
| 14 | 354068.99 | 10802.85 | 9559.86 | 1242.99 | 5429.00 | 352826.00 |
| 15 | 352826.00 | 10802.85 | 9526.30 | 1276.55 | 6705.55 | 351549.45 |
| 16 | 351549.45 | 10802.85 | 9491.84 | 1311.01 | 8016.56 | 350238.44 |
| 17 | 350238.44 | 11234.96 | 11295.19 | -60.23 | 7956.33 | 350298.67 |
| 18 | 350298.67 | 11234.96 | 11297.13 | -62.17 | 7894.16 | 350360.84 |
| 19 | 350360.84 | 11234.96 | 11299.14 | -64.18 | 7829.98 | 350425.02 |
| 20 | 350425.02 | 11234.96 | 11301.21 | -66.25 | 7763.73 | 350491.27 |
| 21 | 350491.27 | 11684.36 | 11303.34 | 381.02 | 8144.75 | 350110.25 |
| 22 | 350110.25 | 11684.36 | 11291.06 | 393.30 | 8538.05 | 349716.95 |
| 23 | 349716.95 | 11684.36 | 11278.37 | 405.99 | 8944.04 | 349310.96 |
| 24 | 349310.96 | 11684.36 | 11265.28 | 419.08 | 9363.12 | 348891.88 |
| 25 | 348891.88 | 12151.73 | 11251.76 | 899.97 | 10263.09 | 347991.91 |
| 26 | 347991.91 | 12151.73 | 11222.74 | 928.99 | 11192.08 | 347062.92 |
| 27 | 347062.92 | 12151.73 | 11192.78 | 958.95 | 12151.03 | 346103.97 |
| 28 | 346103.97 | 12151.73 | 11161.85 | 989.88 | 13140.91 | 345114.09 |
| 29 | 345114.09 | 12637.80 | 12682.94 | -45.14 | 13095.77 | 345159.23 |
| 30 | 345159.23 | 12637.80 | 12684.60 | -46.80 | 13048.97 | 345206.03 |
| 31 | 345206.03 | 12637.80 | 12686.32 | -48.52 | 13000.45 | 345254.55 |
| 32 | 345254.55 | 12637.80 | 12688.10 | -50.30 | 12950.15 | 345304.85 |
| 33 | 345304.85 | 13143.31 | 12689.95 | 453.36 | 13403.51 | 344851.49 |
@+
PS Bonne suggestion, mais les formules sont loin d'être aussi simples qu'on pourrait le croire (je dis ça pour les autres)...
Au fait, ma référence :
Pierre BONNEAU, "Mathématiques financières" Ed Dunod (dépôt légal : mai 1986 !!!)
Arx Tarpeia Capitoli proxima...
Hors ligne
#5 30-05-2009 14:03:33
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
"Bonneau" est bien, mais compliqué à l'extrême. Je recommande plutôt "Piermay et Lazimi", chez Economica, collection Gestion. C'est moins pédagogique, à l'image des auteurs, mais plus simple et efficace car très orienté professionnel.
Pour le Tableau ci-dessus, je peux démontrer qu'il est faux, mais pas à cause du CFF ...
Je suis allé trop vite et j'ai dû corriger le déroulé de mon TA pour intégrer la périodicité trimestrielle : j'avais démarré sur du mensuel ... au temps pour moi.
Si tu veux caler ton programme, retiens que la première échéance à l'issue de la période de différé (qui est plutôt une période d'anticipation, ce qui veut dire qu'elle s'ajoute à la durée d'amortissement, elle ne s'en déduit pas) doit être égale à :
Si amortissement sur 20 ans = 9.582,27 FFR pour le montant emprunté indiqué et
si amortissement sur 18 ans seulement : 9.922,94 FFR pour le même montant.
(sauf erreur ...)
Pour la remarque, il faut savoir pour la petite histoire que les taux d'intérêts indiqués étaient "construits" par les Enarques de la Direction du Trésor et du Logement, en lien direct avec ce que voulaient les ministres.
Il s'agissait en effet de prêts bonifiés par l'État (l'emprunt Mauroy de cette époque était assorti d'un coupon de 16,25 % sur 15 ans, ce qui donne une idée des taux des crédits de l'époque !!!).
Les financiers "publics" contrôlaient le coût budgétaire des mesures, sous contrainte des objectifs que s'assignaient les Pouvoirs publics.
Par ailleurs, le premier taux des trois paliers était fixé pour que ce que tu signalesà juste titre (échéances trimestrielles < montant des intérêts) ne se produisent pas.
Sinon, la rubrique pourrait s'intituler "mathématiques de la finance", et je pense que ça pourrait venir en aide à quelques étudiants qui peuvent peiner sur ces sujets un peu "déroutants" parfois.
PS : je viens de comprendre pourquoi tu n'es pas surpris de ma réaction ...
Dernière modification par freddy (30-05-2009 14:19:28)
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#6 30-05-2009 14:22:13
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 991
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Re,
Pour les précisions concernant la nouvelle rubrique, ça me paraît bien.
Pour le tableau d'amortissement, les formules (effroyables ! Il y a 30 ans je les avais comprises, aujourd'hui j'ai dû pomper mon prg de l'époque...) de calcul sortent du bouquin cité ; après, l'exemple donné m'a permis de les vérifier les calculs et voir comment caler les arrondis...
Le tableau en question est peut-être faux, cela dit l'heureux bénéficiaire (?) de ce prêt a bien dû payer les sommes indiquées puisque l'échéancier fourni est un document officiel, annexe d'un acte notarié...
@+
Arx Tarpeia Capitoli proxima...
Hors ligne
#7 30-05-2009 19:34:30
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Re,
ça ne m'étonne pas, les calculs développés par le "Bonneau et Wisniak" (depuis 1995) sont en taux actuariels, et pas proportionnels.
Quant à l'heureux bénéficiaire, je pense qu'il a payé un peu trop ...Mais chut, je pense qu'il y a prescription ...
Sinon, en termes de formulaires et autres méthodes financières, il y a eu beaucoup de progrès réalisés, et sans tomber dans un formalisme exagéré, on peut donner des bases logiques, saines et robustes.
Je pense qu'on peut toucher un public assez large (au moins ceux que je fais souffrir régulièrement ...)
Sinon, dès que j'ai le temps, je posterai, sous latext, les formules à utiliser pour déterminer cette échéance initiale.
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#8 01-06-2009 10:54:10
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Re,
Pour faire simple et démarrer avec le cas cité (crédit PAP consenti par le CFF via le CDE pour des raisons amusantes à connaître), j'ai calculé la première échéance en utilisant Excel et son utilitaire intégré "valeur cible" de la manière suivante (Rq : l'échéance initiale étant proportionnelle au montant emprunté, un TA pour 10 ou 100.000 suffit, voire pour 1 €), pour une durée n en années et un montant M :
Formule de récurrence d'un TA :
[tex]CRD_{i+1}=(1+TX_i)\times CRD_{i} - ECH_i[/tex] pour i compris entre 0 et 4n (nombre de trimestre). (je n'ai pas trouvé assez vite le bon code latex ...)
On a par, définition
[tex]M_0 = M[/tex] et [tex]M_{4n} = 0[/tex]
Dans le TA, le calcul de l'échéance débute deux ans après le différé d'amortissement. On peut toutefois faire le calcul sans la phase d'anticipation, cela ne change en rien les résultats comme établi plus tard.
Pour chaque date i, on prend bien soin de retenir le taux trimestriel proportionnel correspondant :
[tex]TX_i = Taux_i/4[/tex] avec les périodes indiquées plus haut, et la bonne échéance majorée de 4 % l'an en utilisant une petite congruence modulo 4.
Une fois qu'on a déroulé le tapis (i. e le Capital Restand Dû = CRD) sur 80 lignes, on détermine la valeur initiale de ECH(1) telle que le CRD en "i" = 80" est égal à 0 ET CRD(79) > 0 !... (utiliser la fonction valeur cible d'Excel, assez robuste dans les cas de fonctions qui se "comportent bien").
Pour complément, on a, toujours par définition :
Intérêts de la période (i+1) : INT(i+1)=CRD(i)xTaux(i)/4
Amortissement de la période i : AMORT(i+1) = CRD(i+1) - CRD(i)= ECH(i+1) - INT(i+1)
Principe financier = on paie d'abord les intérêts dû sur (i+1) (prix de la location du capital de montant CRD(i)), la différence par rapport à l'échéance de la période est appliquée au remboursement du principal.
Par prudence, on vérifie que la somme des amortissements : le capital emprunté par tout moyen possible, les erreurs difficiles à détecter se cachent souvent dans le nom respect de ce principe.
PS : je développerai les formules actuarielles de base plus tard. Elles sont assez simples sur le fond.
@++
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#9 02-06-2009 21:27:07
- freddy
- Membre chevronné
- Lieu : Paris
- Inscription : 27-03-2009
- Messages : 7 457
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Re,
de manière plus générale, voici quelques principes de base.
Tout d'abord, un taux est toujours exprimé en % sur une année. Les complications apparaissent quand il s'agit de définir le montant des intérêts à calculer sur une durée inférieure à l'année. Par exemple, sur le marché monétaire interbancaire, la convention de taux est la suivante : nombre exact de jours (une des deux bornes exclue) rapportée à une année de 360 jours. En clair, un taux nominal annuel de 12 % sur un an coûte en réalité 12*365/360 pour cent euros empruntés, soit 12,17 € pour une année non bissextiles. Sur des durées plus longues, dans le cadre des emprunt obligataire, les coupons "tombent" annuellement en Europe et semi annuellement aux USA ...
C'est ainsi que les actuaires en sont venus à définir la notion de taux actuariel de la manière suivante.
Si I est le montant d'intérêts payés pour un prêt de montant K d'une durée de n jour(s), le taux actuariel txact annuel équivalent vérifie l'équation :
[tex](1+\frac{I}{K}) = (1+txact)^\frac{n}{365}[/tex] pour une année normale.
C'est, en quelque sorte, le mètre étalon du gardien de la méridienne.
Pour les crédit hypothécaires, on retient la notion de taux proportionnel, ou bien base 30/360, à savoir que l'année compte 12 mois de 30 jours chacun. C'est le même principe pour le calcul obligataire.
Nota : pour la Sécurité Sociale (branche Maladie), une année compte 13 mois de 28 jours ... Pour la branche Vieillesse, une année est composée de 4 trimestres qui peuvent être composés d'un seul mois ...
Soient M le montant emprunté, m l'échéance constante acquittée selon une périodicité infra annuelle p (12 si mensuelle, 4 si trimestrielle, 2 si semestrielle et 1 si annuelle) , au taux annuel TAUX, soit au taux période proportionnel [tex]x = \frac{taux}{p}[/tex], on a alors :
[tex]M = \sum_{k=1}^n \frac{m}{(1+x)^k}[/tex]
S'agissant des prêts d'épargne logement, le taux période est, par convention, un taux mensuel équivalent au taux annuel, soit :
[tex]x = (1+taux)^{\frac{1}{12}}-1[/tex]
PS : j'ai coutume d'appeler cette opération "la division actuarielle !... ".
Concernant les prêts à taux 0 % de l'État, les conventions de calculs sont aussi en taux mensuel équivalent.
Remarque : Les taux période des crédits hypothécaires belges sont tous calculés selon la méthode dite des taux équivalents, et non selon la méthode dite des taux proportionnels. Ceci cache une subtilité financière qui a fait en partie la fortune des banques jusqu'au dernier quart du vingtième siècle, et quand les taux étaient supérieurs à, disons, 7/8 %.
Si les échéances sont définies de manière distinctes, on a toujours :
[tex]M = \sum_{k=1}^n \frac{m_k}{(1+x)^k}[/tex]
A chaque date p, on peut calculer le capital restant dû :
[tex]CRD_p = \sum_{k=1}^{n-p} \frac{m_k}{(1+x)^k}[/tex]
Si les échéances sont distinctes et s'il y a plusieurs taux différents durant la période de remboursement du crédit, on montre qu'on a encore :
[tex]M = \sum_{k=1}^n \frac{m_k}{\prod_{j=1}^k (1+x_j)}[/tex]
Ce résultat s'obtient pas la résolution de l'équation de base du déroulement périodique d'un tableau d'amortissement (TA) de #8.
Si les échéances mensuelles croissent selon un taux annuel constant (il peut même avoir plusieurs paliers), on voit qu'il suffit de connaître la première échéance pour en déduire toutes les autres.
De fait, les programmes informatiques s'en trouvent simplifiés, ainsi que les formules dont se servent les actuaires en finance ou en assurance.
Dernière modification par freddy (03-06-2009 07:42:22)
De la considération des obstacles vient l’échec, des moyens, la réussite.
Hors ligne
#10 22-09-2018 08:20:01
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 991
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Bonjour,
Version fonctionnelle pour la branche Python 3.x :
#!/usr/bin/python
# -*- coding: UTF-8 -*-
from math import log, exp
def titre_general():
print ()
print ()
print ()
print (" *******************************************")
print (" * +- PHYNANCE -+ *")
print (" * Logiciel de calculs financiers *")
print (" *******************************************")
print ()
def titres(titre):
blancs,etoiles=[15,15,9,7],[50,50,60,65]
suite=["à remboursement constant *","à amortissement constant *",\
"progressifs à un ou plusieurs taux *","à remboursements ronds + reliquat final *"]
print ()
print ()
print (" "*blancs[titre]+"*"*etoiles[titre])
print (" "*blancs[titre]+"* Echéancier de prêts "+suite[titre])
print (" "*blancs[titre]+"*"*etoiles[titre])
print ()
print ()
def sortie():
print ()
print ()
print (" Au revoir !")
def formate(nbr):
if nbr.find(".")==-1:
nbr+=".00"
else:
if len(nbr)==nbr.find(".")+2:
nbr+="0"
return nbr
def cout_credit(co):
print (" Pour un coût total du crédit de %.2f" % co,"€")
print ()
def incorrect():
print (" ...Désolé, valeur incorrecte. Veuillez recommencer ...")
def pas_nb():
print (" ... Ce n'est pas un nombre. Veuillez recommencer...")
def chx_message(ch):
ch=' ... Pour retourner au menu,; ... Pour la suite, '
return ch
def message(mess):
print ()
print (" ",mess,"Presser ENTREE ...")
input("")
def demande_nb_taux(nb):
while nb==0:
try:
nb=int(input(" Nombre de taux (1, 2 ou 3): "))
if nb <1 or nb >3:
nb=0
print ("Entrée non comprise entre 1 et 3. Veuillez recommencer...")
except ValueError:
pas_nb()
return nb
def demande_tx(ta):
while ta==0:
try:
ta=float(input("Quel le taux annuel ? "))
if ta<0:
ta=0
incorrect()
elif ta==0:
print ("Taux nul... Veuillez recommencer...")
elif ta >33.33:
ta=0
print ("Taux supérieur au taux d'usure. Veuillez recommencer...")
except ValueError:
pas_nb()
return ta
def demande_dur(dur):
while dur==0:
try:
dur=int(input("Durée (de 1 à 30 ans) ? "))
if dur<=0 or dur>30:
dur = 0
incorrect()
except ValueError:
pas_nb()
return dur
def demande_duree(dur):
while dur==0:
try:
dur=int(input("durée choisie (maximum 30 ans) : ? "))
if dur<=0 or dur>300:
dur=0
incorrect()
except ValueError:
pas_nb()
return dur
def demande_mensualite_souhaitee(vsmt):
while vsmt==0:
try:
vsmt=int(input(" Mensualité "+chr(34)+"ronde"+chr(34)+" souhaitée (multiple de 50 €) ? "))
if vsmt%50 != 0:
vsmt=0
incorrect()
except ValueError:
pas_nb()
return vsmt
def demande_depot(ca,sod,mode):
if mode==0:
while ca==0:
try:
print ("Quel est le montant du dépôt ",end="")
ca=float(input("initial,régulier".split(",")[mode]+" ? "))
if ca<0:
ca=0
incorrect()
except ValueError:
pas_nb()
else:
while sod==0:
try:
sod=float(input("Montant de l'augmentation régulière : "))
if sod<0:
sod=0
incorrect()
except ValueError:
pas_nb()
return ca,sod
def demande_periodicite(periode):
chx_per,per,ch=0,"12040301",[]
print ()
print (" La périodicité sera-t-elle :")
print (" 1. Mensuelle")
print (" 2. Trimestrielle")
print (" 3. Semestrielle")
print (" 4. Annuelle")
print ()
while chx_per==0:
try:
chx_per=int(input(" ** Votre choix ? ** "))
if chx_per<1 or chx_per>4:
chx_per=0
incorrect()
except ValueError:
pas_nb()
chx_per -= 1
periode=int(per[2*chx_per:2*chx_per+2])
print ()
return periode
def demande_capital_emprunte(cap,cap_min):
while cap==0:
try:
cap=float(input(" Somme empruntée (entre "+str(cap_min)+" et 500000 €) : "))
if cap <cap_min or cap >500000:
cap=0
incorrect()
except ValueError:
pas_nb()
return cap
def demande_capital(cap,mot):
while cap==0:
try:
cap=float(input("Quel est votre capital "+mot+" (entre 1000 et 50000 €) : "))
if cap <1000 or cap >50000:
cap=0
incorrect()
except ValueError:
pas_nb()
return cap
def entete_tableau():
print ("|-----|------------|----------|-----------|----------|------------|------------|")
print ("| Vst | Capital | Rembsmt | Intérêt | Amortmt | Amort. | Capital |")
print ("| n° | | | | | cumulé | restant dû |")
print ("|-----|------------|----------|-----------|----------|------------|------------|")
def affiche_corps_tableau(i, v1, v2, v3, v4, v5,v6):
print ("| %3i" % i,"|%11s" % v1,"|%9s"% v2,"| %9s" % v3,"| %8s" % v4,end=" ")
print ("|%11s" % v5,"|%11s" % v6,"|")
def pied_tableau():
print ("|-----|------------|----------|-----------|----------|------------|------------|")
def affichage_fin_tranche(v,ta,periode,ch):
pied_tableau()
message(ch.split(';')[1])
affiche_cap_taux(v,ta,periode)
entete_tableau()
def affiche_cap_taux(v,taa,periode):
print (" Capital emprunté :","%11s" % v,"€ Taux :",taa,"%")
def type_pret():
print ( "\n+- Type de crédit\n")
print (" A. Prêts Immobiliers ou aux Professionnels")
print (" B. Prêts autres notamment à la consommation")
print ()
pret="C"
while pret not in("AB"):
pret=input(" Votre choix : ")
return pret
def remboursement_constant():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,ch=0,1000,0,0,0,0,0,0,0,0,''
titres(0)
ch=chx_message(ch)
cap=demande_capital_emprunte(cap,cap_min)
v=formate(str(cap))
n=demande_dur(dur)
taa=demande_tx(ta)
periode=demande_periodicite(periode)
n*=periode
pret=type_pret()
if pret =="A":
ta=taa/periode/100.0
vsmt=round(cap/(((1+ta)**n-1)/(ta*(1+ta)**n)),2)
else:
ta=(1+taa/100)**(1/periode) - 1
vsmt=round((cap*ta)/(1-(1+ta)**(-n)),2)
am=cap*ta/((1+ta)**n-1)
print ()
print ()
titres(0)
print ("Capital emprunté :","%11s" % v,"€ Taux :",taa,"%")
entete_tableau()
for i in range(1,n+1):
if i%12==1 and i >1: # <| Ajouter un # devant ces lignes
affichage_fin_tranche(v,taa,12,ch) # <| pour un affichage en continu
intr = round(cap*ta,2)
if i==n:
am=cap
else:
am = round(vsmt-intr,2)
amcu = round(amcu+am,2)
co=round(co+intr,2)
v1=formate(str(cap))
v2=formate(str(vsmt))
v3=formate(str(intr))
v4=formate(str(am))
v5=formate(str(amcu))
cap = round(cap-am,2)
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5, v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print ()
return
def amortissement_constant():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,mess,ch=0,1000,0,0,0,0,0,0,0,0,[],''
ch=chx_message(ch)
titres(1)
cap=demande_capital_emprunte(cap,cap_min)
v=formate(str(cap))
n=demande_dur(dur)
print ("A quel taux ",end="")
taa=demande_tx(ta)
periode=demande_periodicite(periode)
n*=periode
ta=taa/periode/100.0
am = round(cap/n,2)
print ()
print ()
titres(1)
affiche_cap_taux(v,taa,periode)
entete_tableau()
for i in range(1,n+1):
if i%12==1 and i >1: # <| Ajouter un # devant ces lignes
affichage_fin_tranche(v,taa,12,ch) # <| pour un affichage en continu
intr = round(cap*ta,2)
vsmt=round(am+intr,2)
co=round(co+intr,2)
amcu=round(am*i,2)
v1=formate(str(cap))
v4=formate(str(am))
cap = round(cap-am,2)
v6=formate(str(cap))
if i==n:
correctif=round(amcu-float(v),2)
cap=0
if correctif<0:
intr=round(intr+correctif,2)
vsmt=round(vsmt+correctif,2)
co=round(co+intr+correctif,2)
elif correctif>0:
intr=round(intr-correctif,2)
vsmt=round(vsmt-correctif,2)
co=round(co+intr-correctif,2)
v2=formate(str(vsmt))
v3=formate(str(intr))
v5=formate(str(amcu))
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5,v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print ()
return
def remboursements_progressifs():
am,amcu,co,n,nb,cap,periode,ch=0,0,0,0,0,0,0,''
x2,x3,cap_min,tx,dur_tx=0,0,100000,[0,0,0],[0,0,0]
ch=chx_message(ch)
titres(2)
cap=demande_capital_emprunte(cap,cap_min)
periode=demande_periodicite(periode)
nb=demande_nb_taux(nb)
for i in range(nb):
ta,dur=0,0
print ("Taux ",end="")
if nb>1:
print ("no "+str(i+1)+" : ",end="")
else:
print (": ",end="")
taa=demande_tx(ta)
tx[i]=taa/periode/100.0
dur_tx[i]=demande_dur(dur)
n+=dur_tx[i]
print (" ---------------")
n*=periode
diff_am=-1
while diff_am<0:
try:
diff_am=int(input("Durée du différé d'amortissement (de 1 à 4 ans): ** ? ** "))
if diff_am<1 or diff_am>4:
print ()
diff_am=-1
incorrect()
print ()
except ValueError:
pas_nb()
print ()
diff_am*=periode
print (" ---------------")
prg=-1
while prg<0:
try:
prg=int(input("Progressivité annuelle (en %)) : ** ? ** "))
if prg<0:
print ()
prg=0
incorrect()
print ()
except ValueError:
pas_nb()
print ()
x1,x2,x3=0,0,0
prg=prg/100.0
ai1=1/(1+tx[0])
ai2=1/(1+tx[1])
ai3=1/(1+tx[2])
n1=float(dur_tx[0]-diff_am/periode)
a1=(1+prg)/(1+tx[0])
a2=(ai1**periode-1)/(ai1-1)
a3=((1+prg)**n1*ai1**(n1*periode)-1)/((1+prg)*ai1**periode-1)
x1=a1*a2*a3
if nb > 1:
a1=((1+prg)/(1+tx[0])**periode)**n1
a2=(1+prg)/(1+tx[1])
a3=(ai2**periode-1)/(ai2-1)
a4=((1+prg)**dur_tx[1]*ai2**(dur_tx[1]*periode)-1)/((1+prg)*ai2**periode-1)
x2=a1*a2*a3*a4
if nb > 2:
a1=((1+prg)/(1+tx[0])**periode)**n1
a2=((1+prg)/(1+tx[1])**periode)**dur_tx[1]
a3=(1+prg)/(1+tx[2])
a4=(ai3**periode-1)/(ai3-1)
a5=((1+prg)**dur_tx[2]*ai3**(dur_tx[2]*periode)-1)/((1+prg)*ai3**periode-1)
x3=a1*a2*a3*a4*a5
vsmt=cap/(x1+x2+x3)
vo=vsmt
print()
print()
titres(2)
v=formate(str(cap))
print ("Capital emprunté :","%11s" % v,"€")
for i in range(nb):
print (" Taux n° "+str(i+1)+" : "+formate(str(round(tx[i]*100*periode,2))).rjust(5)+" % ",end="")
print ("Durée : "+str(dur_tx[i]).rjust(2)+" ans")
print ()
entete_tableau()
a=tx[0]
dur1,dur2=dur_tx[0]*periode+1,(dur_tx[0]+dur_tx[1])*periode+1
for i in range(1,n+1):
if i%12==1 and i>1: # <| Ajouter un # devant ces lignes
pied_tableau() # <| pour un
message(ch.split(';')[1]) # <| affichage de l'échéancier
entete_tableau() # <| en continu
if i<=diff_am:
am=0
intr=round(cap*a,2)
vsmt=intr
v2=formate(str(vsmt))
elif i<n:
if i==dur1:
a=tx[1]
elif i==dur2:
a=tx[2]
vsmt=round(vo*(1+prg)**(1+(i-diff_am-1)/periode),2)
intr=round(cap*a,2)
am=round(vsmt-intr,2)
else:
am=cap
intr=round(vsmt-am,2)
amcu+=am
co+=intr
v1=formate(str(cap))
v2=formate(str(vsmt))
v3=formate(str(intr))
v4=formate(str(am))
v5=formate(str(amcu))
cap=round(cap-am,2)
v6=formate(str(cap))
affiche_corps_tableau(i, v1, v2, v3, v4, v5, v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print ()
return
def remboursements_ronds_reliquat():
cap,cap_min,am,amcu,vsmt,n,ta,dur,periode,co,mens,ch=0,1000,0,0,0,0,0,0,0,0,0,''
ch=chx_message(ch)
titres(3)
cap=demande_capital_emprunte(cap,cap_min)
taa=demande_tx(ta)
print ()
print (" - Notez bien : Dans ce cas, l'amortissement est mensuel ! -")
print ()
vsmt=demande_mensualite_souhaitee(vsmt)
ta = taa/1200.0
q = 1 + ta
n = int(cap/vsmt)+1
mens = q*(q**(n-1)*cap-vsmt*(q**(n-1)-1)/ta)
while mens>vsmt:
n+=1
mens = q*(q**(n-1)*cap-vsmt*(q**(n-1)-1)/ta)
print ()
print (" La durée de remboursement sera obligatoirement de", n//12,"ans"[:2+(n//12>1)],n%12,"mois.")
message(ch.split(';')[1])
am = round(float(cap/n),2)
v1=formate(str(cap))
v=v1
print ()
print ()
titres(3)
v2 = formate(str(vsmt))
affiche_cap_taux(v,taa,12)
entete_tableau()
for i in range(1,n+1):
if i%12==1 and i >1: # <| Ajouter un # devant ces lignes
affichage_fin_tranche(v,taa,12,ch) # <| pour un affichage en continu
v1=formate(str(cap))
intr = round(cap*ta,2)
if i==n:
am=cap
vsmt=round(am+intr,2)
cap=0
else:
am = round(vsmt - intr,2)
cap = round(cap - am,2)
amcu = round(amcu + am,2)
co= round(co + intr,2)
v2 = formate(str(vsmt))
v3=formate(str(intr))
v4 = formate(str(am))
v5=formate(str(amcu))
v6=formate(str(cap))
affiche_corps_tableau(i,v1,v2,v3,v4,v5,v6)
pied_tableau()
cout_credit(co)
message(ch.split(';')[0])
print ()
return
def cherche_taux():
cap,cap_fin,ta,dur,periode,ch=0,0,0,0,0,''
ch=chx_message(ch)
print ()
print ()
print (" ************************************************")
print (" * Recherche du taux de placement d'un capital *")
print (" ************************************************")
print ()
print ()
mot="de départ"
cap=demande_capital(cap,mot)
mot="final"
cap_fin=demande_capital(cap_fin,mot)
print ("Exprimée en mois pleins : ",end="")
dur=demande_duree(dur)
ta = 100*(exp(log(cap_fin/cap)/(dur/12.0))-1)
print ()
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print (" Le taux nécessaire à un capital de", cap,"€ pour devenir",cap_fin,"€ après", dur/12,"ans",dur%12,"mois est :")
print (" %.2f" % ta,"%")
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ()
print ("N-B : Pour une même durée, ce résultat ne dépend que du rapport entre les capitaux d'arrivée et de départ ...")
print ()
message(ch.split(';')[0])
return
def cherche_capital_depart():
cap,ta,dur,mot,ch=0,0,0,"final",''
ch=chx_message(ch)
print ()
print ()
print (" ************************************")
print (" * Recherche du capital de départ *")
print (" ************************************")
print ()
print ()
cap=demande_capital(cap,mot)
print ("Taux du placement (en %) ",end="")
taa=demande_tx(ta)
ta=taa/100.0
print ("Exprimée en mois pleins, ",end="")
dur=demande_duree(dur)
print ()
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ("Le capital à placer pour obtenir",cap,"€ à", taa,"% pendant",dur/12,"ans",dur%12,"mois est :")
v=formate(str(round(cap*(1+ta)**(-dur/12.0),2)))
print (" ","%11s" % v,"€")
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ()
message(ch.split(';')[0])
return
def cherche_capital_final():
cap,ta,dur,mot,ch=0,0,0,"de départ",''
ch=chx_message(ch)
print ()
print ()
print (" ********************************")
print (" * Recherche du capital final *")
print (" ********************************")
print ()
print ()
cap=demande_capital(cap,mot)
print ("Taux du placement (en %) ",end="")
taa=demande_tx(ta)
ta=taa/100.0
print ("Exprimée en mois pleins, ",end="")
dur=demande_duree(dur)
print ()
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ("Le capital obtenu après placement de",cap,"€ à", taa,"% pendant",dur/12,"ans",dur%12,"mois sera :")
v=formate(str(round(cap*(1+ta)**(dur/12.0),2)))
print (" ","%11s" % v,"€")
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ()
message(ch.split(';')[0])
def cherche_duree_placement():
cap,cap_fin,ta,dur,nbf,ch=0,0,0,0,0,''
ch=chx_message(ch)
print ()
print ()
print (" ****************************************************")
print (" * Recherche de la durée de placement d'un capital *")
print (" ****************************************************")
print ()
print ()
mot="de départ"
cap=demande_capital(cap,mot)
mot="final"
cap_fin=demande_capital(cap_fin,mot)
print ("Taux du placement ",end="")
taa=demande_tx(ta)
ta=taa/100.0
nbf=float(cap_fin/cap)
tp= log(nbf)/log(1+ta)
dur = int(360*tp)
print ()
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print (" La durée de placement à",taa,"% pour passer de",cap,"€ à",round(cap*(1+ta)**tp,2),"€ est :")
print ()
print (" ",round(tp,2),"années")
print ()
print (" Soit encore ",int(dur/360.0),"ans",int((dur%360.0)/30),"mois")
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print ()
print ("N-B : Pour un même taux, ce résultat ne dépend que du rapport entre les capitaux d'arrivée et de départ ...")
print ()
message(ch.split(';')[0])
return
def calcul_depot_constant():
sod,sof,ta,dur,periode,mode,ca,ch=0,0,0,0,0,0,0,''
ch=chx_message(ch)
print ()
print ()
print (" *******************************************")
print (" * Placement à dépôt régulier et constant *")
print (" *******************************************")
print ()
periode=demande_periodicite(periode)
dico_per={12:'mois',4:'trimestre)',2:'semestre)',1:'année'}
print ()
print ("Exprimée en "+dico_per[periode]+", ",end="")
dur=demande_duree(dur)
ca,sod=demande_depot(ca,sod,mode)
print ("Taux annuel du placement (en %) ",end="")
taa=demande_tx(ta)
q=1+taa/100.0/periode
sof = ca*q*(q**dur-1)/(q-1)
print ()
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
print (" Après "+str(dur)+" versements chaque "+dico_per[periode]+" de "+str(ca)+" € au taux annuel \
de "+str(taa)+" %")
print (" vous serez à la tête de %.2f" % sof, "€")
print (" +++++++++++++++++++++++++++++++++++++++++++++++++")
message(ch.split(';')[0])
return
def calcul_depot_progressif():
n,ta,sod,vsmt,q,periode,dur,ca,ch=0,0,0,0,0,0,0,0,''
ch=chx_message(ch)
dico_per={12:'mois',4:'trimestre',2:'semestre',1:'année'}
print ()
print ()
print (" *****************************************************")
print (" * Placement à dépôt régulier régulier et croissant *")
print (" * - toujours de la même somme - *")
print (" *****************************************************")
print ()
periode=demande_periodicite(periode)
print ( "Taux annuel du placement : ",end="")
taa=demande_tx(ta)
print ( "---------------------")
q=1+taa/100.0/periode
print ("Exprimée en "+dico_per[periode]+", ",end="")
n=demande_duree(dur)
mode = 0
ca,sod=demande_depot(ca,sod,mode)
mode=1
ca,sod=demande_depot(ca,sod,mode)
sof = q*((ca+sod/(q-1))*(q**n-1)/(q-1)-n*sod/(q-1))
print ()
print ( " +++++++++++++++++++++++++++++++++++++++++++++++++")
print ( " Après "+str(n)+" versements de "+str(ca),str(ca+sod),str(ca+2*sod)+"€ ..."+str(ca+(n-1)*sod)\
+" € au taux annuel de "+str(taa)+" %")
print ( " vous serez à la tête de %.2f" % sof, "€")
print ( " +++++++++++++++++++++++++++++++++++++++++++++++++")
message(ch.split(';')[0])
return
fin=100
while fin>0:
titre_general()
print (" 1. Echéancier de prêt à remboursement constant")
print (" 2. Echéancier de prêt à amortissement constant")
print (" 3. Echéancier de prêt à remboursements progressifs")
print (" 4. Echéancier de prêt à remboursements \"ronds\" + reliquat")
print (" 5. Somme obtenue après placement d'un Capital donné")
print (" 6. Somme à placer pour obtenir un Capital donné")
print (" 7. Durée nécessaire pour obtenir un Capital donné à partir d'une somme fixée")
print (" 8. Taux nécessaire pour obtenir un Capital donné à partir d'une somme fixée")
print (" 9. Capital obtenu par dépôt périodique d'une somme toujours identique")
print ("10. Capital obtenu par dépôt périodique d'une somme -également- croissante")
print ()
print ( " 0. Sortie du programme")
chx_menu='100'
while chx_menu=='100':
try:
chx_menu=input(" Votre choix : ")
fin = int(chx_menu)
choix2 = {'1': remboursement_constant,
'2': amortissement_constant,
'3': remboursements_progressifs,
'4': remboursements_ronds_reliquat,
'5': cherche_capital_final,
'6': cherche_capital_depart,
'7': cherche_duree_placement,
'8': cherche_taux,
'9': calcul_depot_constant,
'10': calcul_depot_progressif,
'0': sortie}
if fin <0 or fin>10:
chx_menu='100'
incorrect()
except ValueError:
pas_nb()
choix2[chx_menu]()
@+
Arx Tarpeia Capitoli proxima...
Hors ligne
#11 25-10-2018 20:29:15
- yoski
- Invité
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Salut Freddy,
Merci de ton intérêt, j'étais à peu près sûr que tu allais te manifester, aussi depuis 8 jours, je contrôle tout sur toutes les coutures... ;-)
Cela dit, je ne comprends pas très bien le sens de ta remarque : ce que je reproduis est conforme à l'échéancier officiel du Crédit Foncier de France relayé par le Comptoir Des Entrepreneurs.
Quant à la date, je l'ai trouvée, c'est plus vieux que ça encore : 1982 !!!Voilà le début de l'échéancier avec remboursement trimestriel :
************************************************************
* Echéancier de prêts progressifs à un ou plusieurs taux *
************************************************************
Capital emprunté : 358255.00 €
Taux n° 1 : 10.80 % Durée : 4 ans
Taux n° 2 : 12.90 % Durée : 3 ans
Taux n° 3 : 14.70 % Durée : 13 ans
|------|------------|----------|-----------|----------|------------|------------|
| Vsmt | Capital | Rembsmt | Intérêt | Amortmt | Amort. | Capital |
| n° | | | | | cumulé | restant dû |
|------|------------|----------|-----------|----------|------------|------------|
| 1 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 2 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 3 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 4 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 5 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 6 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 7 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 8 | 358255.00 | 9672.89 | 9672.89 | 0.00 | 0.00 | 358255.00 |
| 9 | 358255.00 | 10387.35 | 9672.89 | 714.46 | 714.46 | 357540.54 |
| 10 | 357540.54 | 10387.35 | 9653.59 | 733.76 | 1448.22 | 356806.78 |
| 11 | 356806.78 | 10387.35 | 9633.78 | 753.57 | 2201.79 | 356053.21 |
| 12 | 356053.21 | 10387.35 | 9613.44 | 773.91 | 2975.70 | 355279.30 |
| 13 | 355279.30 | 10802.85 | 9592.54 | 1210.31 | 4186.01 | 354068.99 |
| 14 | 354068.99 | 10802.85 | 9559.86 | 1242.99 | 5429.00 | 352826.00 |
| 15 | 352826.00 | 10802.85 | 9526.30 | 1276.55 | 6705.55 | 351549.45 |
| 16 | 351549.45 | 10802.85 | 9491.84 | 1311.01 | 8016.56 | 350238.44 |
| 17 | 350238.44 | 11234.96 | 11295.19 | -60.23 | 7956.33 | 350298.67 |
| 18 | 350298.67 | 11234.96 | 11297.13 | -62.17 | 7894.16 | 350360.84 |
| 19 | 350360.84 | 11234.96 | 11299.14 | -64.18 | 7829.98 | 350425.02 |
| 20 | 350425.02 | 11234.96 | 11301.21 | -66.25 | 7763.73 | 350491.27 |
| 21 | 350491.27 | 11684.36 | 11303.34 | 381.02 | 8144.75 | 350110.25 |
| 22 | 350110.25 | 11684.36 | 11291.06 | 393.30 | 8538.05 | 349716.95 |
| 23 | 349716.95 | 11684.36 | 11278.37 | 405.99 | 8944.04 | 349310.96 |
| 24 | 349310.96 | 11684.36 | 11265.28 | 419.08 | 9363.12 | 348891.88 |
| 25 | 348891.88 | 12151.73 | 11251.76 | 899.97 | 10263.09 | 347991.91 |
| 26 | 347991.91 | 12151.73 | 11222.74 | 928.99 | 11192.08 | 347062.92 |
| 27 | 347062.92 | 12151.73 | 11192.78 | 958.95 | 12151.03 | 346103.97 |
| 28 | 346103.97 | 12151.73 | 11161.85 | 989.88 | 13140.91 | 345114.09 |
| 29 | 345114.09 | 12637.80 | 12682.94 | -45.14 | 13095.77 | 345159.23 |
| 30 | 345159.23 | 12637.80 | 12684.60 | -46.80 | 13048.97 | 345206.03 |
| 31 | 345206.03 | 12637.80 | 12686.32 | -48.52 | 13000.45 | 345254.55 |
| 32 | 345254.55 | 12637.80 | 12688.10 | -50.30 | 12950.15 | 345304.85 |
| 33 | 345304.85 | 13143.31 | 12689.95 | 453.36 | 13403.51 | 344851.49 |@+
PS Bonne suggestion, mais les formules sont loin d'être aussi simples qu'on pourrait le croire (je dis ça pour les autres)...
Au fait, ma référence :
Pierre BONNEAU, "Mathématiques financières" Ed Dunod (dépôt légal : mai 1986 !!!)
yoshi pas trèes sympas de faire sa , mes bon merci de ton aide
#12 25-10-2018 21:07:42
- yoshi
- Modo Ferox
- Inscription : 20-11-2005
- Messages : 16 991
Re : [Python] Simulateur d'échéancier de prêts et Calculs de capitalisation
Bonsoir,
yoshi pas trèes sympas de faire sa , mes bon merci de ton aide
Quelqu'un a un décodeur ?
Pourquoi ?
Qu'est-ce qui n'est pas sympa ?
Je t'ai aidé en quoi ?
@+
Arx Tarpeia Capitoli proxima...
Hors ligne
Pages : 1
Discussion fermée