Кредитный калькулятор
作者
function CreditCalculator(;amount::Float64, rate::Float64, term::Int, payment_type::String="annuity", start_date::Date=today(), loan_type::String="consumer")
if amount <= 0 || rate <= 0 || term <= 0
error("Сумма, ставка и срок должны быть положительными числами")
end
if payment_type ∉ ["annuity", "differentiated"]
error("Тип платежа должен быть 'annuity' или 'differentiated'")
end
monthly_rate = rate / 100 / 12
if payment_type == "annuity"
return calculate_annuity(amount, monthly_rate, term, start_date, loan_type)
else
return calculate_differentiated(amount, monthly_rate, term, start_date, loan_type)
end
end
function calculate_annuity(amount, monthly_rate, term, start_date, loan_type)
annuity_coef = monthly_rate * (1 + monthly_rate)^term / ((1 + monthly_rate)^term - 1)
monthly_payment = amount * annuity_coef
payments_table = DataFrame(month = Int[], date = Date[], payment = Float64[], principal = Float64[], interest = Float64[], remaining_debt = Float64[])
remaining = amount
total_interest = 0.0
for m in 1:term
interest_payment = remaining * monthly_rate
principal_payment = monthly_payment - interest_payment
if m == term
principal_payment = remaining
monthly_payment = principal_payment + interest_payment
end
remaining -= principal_payment
total_interest += interest_payment
push!(payments_table, (m, start_date + Dates.Month(m-1), round(monthly_payment, digits=2), round(principal_payment, digits=2), round(interest_payment, digits=2), round(max(remaining, 0.0), digits=2)))
end
total_payment = amount + total_interest
overpayment_percent = (total_payment / amount - 1) * 100
return (loan_type = loan_type, payment_type = "annuity", amount = amount, rate = monthly_rate * 12 * 100, term = term, monthly_payment = round(monthly_payment, digits=2), total_payment = round(total_payment, digits=2), total_interest = round(total_interest, digits=2), overpayment_percent = round(overpayment_percent, digits=2), payments_table = payments_table)
end
function calculate_differentiated(amount, monthly_rate, term, start_date, loan_type)
principal_part = amount / term
payments_table = DataFrame(month = Int[], date = Date[], payment = Float64[], principal = Float64[], interest = Float64[], remaining_debt = Float64[])
remaining = amount
total_interest = 0.0
first_payment = 0.0
last_payment = 0.0
for m in 1:term
interest_payment = remaining * monthly_rate
total_payment = principal_part + interest_payment
if m == 1
first_payment = total_payment
elseif m == term
last_payment = total_payment
end
remaining -= principal_part
total_interest += interest_payment
push!(payments_table, (m, start_date + Dates.Month(m-1), round(total_payment, digits=2), round(principal_part, digits=2), round(interest_payment, digits=2), round(max(remaining, 0.0), digits=2)))
end
total_payment = amount + total_interest
overpayment_percent = (total_payment / amount - 1) * 100
return (loan_type = loan_type,
payment_type = "differentiated",
amount = amount,
rate = monthly_rate * 12 * 100,
term = term,
first_payment = round(first_payment, digits=2),
last_payment = round(last_payment, digits=2),
total_payment = round(total_payment, digits=2),
total_interest = round(total_interest, digits=2),
overpayment_percent = round(overpayment_percent, digits=2),
payments_table = payments_table)
end
function compare_payment_types(;amount::Float64,rate::Float64,term::Int,start_date::Date=today())
annuity_result = CreditCalculator(amount=amount, rate=rate, term=term, payment_type="annuity", start_date=start_date)
diff_result = CreditCalculator(amount=amount, rate=rate, term=term, payment_type="differentiated", start_date=start_date)
comparison = DataFrame(
Показатель = ["Ежемесячный платеж (первый/последний)",
"Общая сумма выплат",
"Переплата (абс.)",
"Переплата (%)"],
Аннуитетный = [
"$(annuity_result.monthly_payment) / $(annuity_result.monthly_payment)",
annuity_result.total_payment,
annuity_result.total_interest,
annuity_result.overpayment_percent
],
Дифференцированный = [
"$(diff_result.first_payment) / $(diff_result.last_payment)",
diff_result.total_payment,
diff_result.total_interest,
diff_result.overpayment_percent
]
)
return (annuity=annuity_result, differentiated=diff_result, comparison=comparison)
end
function print_payment_schedule(result)
println("График платежей по кредиту:")
println("Тип кредита: $(result.loan_type)")
println("Тип платежей: $(result.payment_type)")
println("Сумма: $(result.amount) руб.")
println("Ставка: $(result.rate)% годовых")
println("Срок: $(result.term) мес.")
println("-"^100)
if result.payment_type == "annuity"
println("Ежемесячный платеж: $(result.monthly_payment) руб.")
else
println("Первый платеж: $(result.first_payment) руб.")
println("Последний платеж: $(result.last_payment) руб.")
end
println("Общая сумма выплат: $(result.total_payment) руб.")
println("Переплата: $(result.total_interest) руб. ($(result.overpayment_percent)%)")
println("-"^100)
println("Месяц | Дата | Платеж | Осн.долг | Проценты | Остаток")
println("-"^100)
for row in eachrow(result.payments_table)
println(
rpad(row.month, 6), "| ",
rpad(Dates.format(row.date, "dd.mm.yyyy"), 10), "| ",
rpad(row.payment, 9), "| ",
rpad(row.principal, 9), "| ",
rpad(row.interest, 9), "| ",
row.remaining_debt
)
end
end