Struct

Ici le but était d’essayer d’utiliser les structs julia. J’ai eu l’occasion de faire un projet python très orienté objet et j’ai donc traduit le programme original en julia avec les attributs dans une struct et les méthodes devenant des fonctions normales dont la signature est spécifique au type Emprunt créée au début.

A l’origine le programme utilisait du templating pour générer un rapport en pdf grâce à LaTeX, mais ici on a directement relié la création de l’objet avec le frontend Dash, qui est beaucoup plus flexible et réactif. C’est un programme simple qui affiche l’échéance des amortissements.

struct Emprunt
    cout::Int
    taux::Float64
    annee::Int 
    apport::Number
    periodicite::Int 
    differe::Int 
    type_differe::Int
    salaire_net::Number
    frais_garantie::Int
    taux_assurance::Float64
    frais_notaire::Int 
    frais::Int 
    nom::String
    montant_emprunte::Int 
    projet::Float64

    function Emprunt(
        cout,
        taux_annuel,
        annee,

        apport=0,
        periodicite=12,

        differe=0,
        type_differe=0, 

        salaire_net=0,

        frais_garantie=0,
        taux_assurance=0,
        frais_notaire=0,
        frais=1000,
        nom="")

        taux=taux_annuel/100
        taux_assurance = taux_assurance / 100 

        projet = cout+frais+frais_notaire +frais_garantie
        montant_emprunte = projet - apport
        

        return new(cout,
                    taux,
                    annee,
                    apport,
                    periodicite,
                    differe, 
                    type_differe,
                    salaire_net,
                    frais_garantie,
                    taux_assurance,
                    frais_notaire,
                    frais,
                    nom,
                    montant_emprunte,
                    projet)
    end 
end
[...]
Code
using DataFrames
struct Emprunt
    cout::Int
    taux::Float64
    annee::Int 
    apport::Number
    periodicite::Int 
    differe::Int 
    type_differe::Int
    salaire_net::Number
    frais_garantie::Int
    taux_assurance::Float64
    frais_notaire::Int 
    frais::Int 
    nom::String
    montant_emprunte::Int 
    projet::Float64

    function Emprunt(
        cout,
        taux_annuel,
        annee,

        apport=0,
        periodicite=12,

        differe=0,
        type_differe=0, 

        salaire_net=0,

        frais_garantie=0,
        taux_assurance=0,
        frais_notaire=0,
        frais=1000,
        nom="")

        taux=taux_annuel/100
        taux_assurance = taux_assurance / 100 

        projet = cout+frais+frais_notaire +frais_garantie
        montant_emprunte = projet - apport
        

        return new(cout,
                    taux,
                    annee,
                    apport,
                    periodicite,
                    differe, 
                    type_differe,
                    salaire_net,
                    frais_garantie,
                    taux_assurance,
                    frais_notaire,
                    frais,
                    nom,
                    montant_emprunte,
                    projet)
    end 
end

function nb_periodes(ep::Emprunt)
    return (ep.annee* ep.periodicite) + ep.differe
end

function nb_periode_pure(ep::Emprunt)
    return (ep.annee * ep.periodicite)
end

function mois(ep::Emprunt)
    return ep.annee*12
end

function taux_effectif(ep::Emprunt)
    return ep.taux / ep.periodicite
end

function mensualite(ep::Emprunt)
    if ep.taux!=0
        ep.montant_emprunte * (taux_effectif(ep)/(1 - (1 + taux_effectif(ep))^(-nb_periode_pure(ep))))
    else 
        ep.montant_emprunte/(ep.annee * ep.periodicite)
    end
end


function mensualite_totale(ep::Emprunt)
    mensualite(ep) + assurance_par_periode(ep)


end

function assurance_par_periode(ep::Emprunt)
    ep.montant_emprunte * (ep.taux_assurance / ep.periodicite)
end

function cout_assurance(ep::Emprunt)
    nb_periodes(ep) * assurance_par_periode(ep)
end

function get_taeg(ep::Emprunt)
    f(x) = ((1 - (1 + x)^(- mois(ep))) / x) - ((ep.montant_emprunte - frais_totaux(ep))/mensualite(ep))
    
    f = resout(f) / 100
    return (1+f)^(ep.periodicite) -1
end

function get_taeg_sans_assurance(ep::Emprunt)
    f(x) = ((1 - (1 + x)^(- mois(ep))) / x) - ((ep.montant_emprunte - frais_totaux(ep) - cout_assurance(ep))/mensualité(ep))
    
    f = resout(f) / 100
    return (1+f)^(ep.periodicite) -1

end


function frais_totaux(ep::Emprunt)
    ep.frais_garantie + ep.frais
end

function cout_credit(ep::Emprunt, t::Bool)
    if t==true 
        tableau_amortissement(0)[2]
    else
        tableau_amortissement(1)[2]
    end
end

function capacite_mensuelle(ep::Emprunt)
    ep.salaire_net/3
end

function taux_annuel_effectif_assurance(ep::Emprunt)
    get_taeg(ep) - get_taeg_sans_assurance(ep)

end

function tableau_amortissement(ep::Emprunt, mode_amort::Int)
    t_max = nb_periodes(ep)
    temp = range(1,t_max)

    if mode_amort == 0
        echeance = mensualite(ep)

        echeances = echeance * ones(t_max)
        capital_restant = zeros(t_max)
        interets = zeros(t_max)
        amortissement = zeros(t_max)
        assurance = assurance_par_periode(ep) *  ones(t_max)
        capital_post_versement = zeros(t_max)

        capital_restant[1] = ep.montant_emprunte
        if ep.differe > 0
            interets[1] = capital_restant[1] * taux_effectif(ep) * ep.type_differe
            amortissement[1] = 0
            echeances[1] = 0
        else
            interets[1] = capital_restant[1] * taux_effectif(ep) 
            amortissement[1] = echeance - interets[1]
        end 
        capital_post_versement[1] = capital_restant[1] - amortissement[1]
        
        for i in 2:t_max 
            capital_restant[i] = capital_restant[i-1] - amortissement[i-1]
            if i < ep.differe
                # pendant différé
                interets[i] = capital_restant[i] * taux_effectif(ep) * ep.type_differe
            else
                # Remboursement normal
                interets[i] = capital_restant[i] * taux_effectif(ep)
                amortissement[i] = echeance - interets[i]
            end
        end
        rep = DataFrame(Dict(
            "capital_restant_avant_versement"=> capital_restant,
            "interets"=> interets,
            "amortissement"=> amortissement,
            "assurance" => assurance,
            "echeance"=> echeance
        ))
        rep.echeance = echeances .+ assurance_par_periode(ep) 
            rep[!,"capital_restant après versement"] = rep.capital_restant_avant_versement - rep.amortissement

            return rep, sum(interets)
    end
    if mode_amort == 1
        A = ep.montant_emprunte/nb_periode_pure(ep)
        amortissement = A * ones(t_max)

        capital_restant = zeros(t_max)
        interets = zeros(t_max)

        capital_restant = (ep.montant_emprunte * ones(t_max))
        if ep.differe > 1
            interets[1] = capital_restant[1] * taux_effectif(ep) * ep.type_differe
            amortissement[1] = 0
        else
            interets[1] = capital_restant[1] * taux_effectif(ep) 
            amortissement[1] = A
        end

        
        for i in 2:t_max 
            capital_restant[i] = capital_restant[i-1] - amortissement[i-1]
                if i < ep.differe
                    interets[i] = capital_restant[i] * taux_effectif(ep) * ep.type_differe
                    amortissement[i] = 0
                else
                    interets[i] = capital_restant[i] * taux_effectif(ep)
                end
        end

        echeances = (assurance_par_periode(ep) * ones(t_max)) + interets + amortissement

        rep = DataFrame(Dict(
            "capital_restant_avant_versement"=> capital_restant,
            "interets"=> interets,
            "amortissement"=> amortissement,
            "assurance" => assurance_par_periode(ep) * ones(t_max),
            "echeance"=> echeances
        ))
            rep[!,"c2"] = rep.capital_restant_avant_versement - rep.amortissement
            return  rep,sum(interets)
    end
    if mode_amort == 2
            amortissement = zeros(t_max)
            interets = zeros(t_max)
            capital_restant = zeros(t_max)

            # phase de départ
            capital_restant[1] = ep.montant_emprunte
            interets[:end] = taux_effectif(ep) * ep.montant_emprunte
            amortissement[:end] = 0

            amortissement[end] = ep.montant_emprunte
            capital_restant[end] = 0

            echeances = interets + amortissement + assurance_par_periode


            rep = pd.DataFrame(Dict(  "capital_restant"=> capital_restant,
                                    "interets"=> interets,
                                    "amortissement"=> amortissement,
                                    "echeance"=> echeances,
                                    )
            )
            rep["c2"] = rep.capital_restant - rep.amortissement
            rep.echeance = echeances + assurance_par_periode(ep)
            return  rep,sum(interets)
    end
end

function premieres_mensualites(ep::Emprunt, t= 0)
    if t == 0
        return mensualite(ep) + assurance_par_periode(ep)
    else
        return ep.montant_emprunte / nb_periode_pure(ep) + (ep.montant_emprunte * taux_effectif(ep)) + assurance_par_periode(ep)
    end
end

function resout(f::Function)
    x = range(0.00001,1,100000)
    y = abs.(f.(x))
    return x[argmin(y)] * 100
end
Code
using StatsPlots

main_simple_duree = 27
main_simple = Emprunt(
        185540,
        1.5,
        main_simple_duree,
        1000 + 1105 + 5170,        
        1,
         0,
         0,
         2133,

         1105,
         0.1,
         5170,
         1000,
        
        "main_simple"
)
df = tableau_amortissement(main_simple,1)[1]

i = df[:,:interets]
a = df[:,:amortissement]

groupedbar([i a],
            bar_position = :stack,
            xticks = collect(range(1,size(df)[1])),
            label = ["interets" "amortissement"], 
            size = (1000,800), 
            title = "Décomposition des remboursements à chaque échéance",
            xlabel = "Années",
            ylabel = "Euros")