信贷计算器
本文讨论了通用信用计算器的软件实现。 主要重点是模块的内部结构,关键算法,数据结构和方法,以确保准确性,灵活性和易于与代码单元掩码接口集成。
1. 一般架构
该模块围绕一个中心功能构建 CreditCalculator,其作为两个独立的计算算法的门面:年金和微分。 所有辅助函数都被封装,返回的数据以命名元组的形式标准化(NamedTuple)及表格 DataFrame 从包 DataFrames.jl.
主要组件:
-CreditCalculator是一个调度程序,它验证输入参数并选择一个方法。
-calculate_annuity/calculate_differentiated-实现财务公式的纯函数。
-compare_payment_types是用于比较两个方案的服务函数。
-print_payment_schedule是格式化显示的输出函数(副作用)。
这种设计提供了职责分离:计算与输入/输出分离,返回的结构可用于后续分析或可视化。
include("lib.jl")
2. 输入参数和验证
功能 CreditCalculator 在键入时使用命名参数,这增加了代码的可读性,并允许您以任何顺序设置值。:
function CreditCalculator(; amount::Float64, rate::Float64, term::Int,
payment_type::String="annuity",
start_date::Date=today(),
loan_type::String="consumer")
验证在入口处执行:
-核实金额、出价及期限是否为正数。
-检查一下 payment_type 属于集 {"annuity", "differentiated"}.
这可以防止在早期阶段进行错误的计算,并提供清晰的错误消息。
3. 计算算法
3.1. 年金付款
年金比率是用经典公式计算的:
其中r=利率/(100*n)是月利率,n是以月为单位的期限。
实现功能:
-每月付款计算为 amount * coef.
-每个月,计算余额的利息和本金债务的偿还金额。
-最后付款的更正:由于四舍五入,可能会累积错误,因此,在最后一步,本金债务的金额被强制设置等于余额,并重新计算付款。 这可确保最终余额为零。
-所有金额均四舍五入至小数点后两位 round(..., digits=2).
-数据累积在 DataFrame 连续打电话 push!.
3.2. 差异化付款
在这里,本金债务的每月部分是固定的:
每月利息是从当前余额计算的. 支付线性下降。
特点:
-与年金不同,不需要调整最后一次付款,因为余额会在最后一次付款后重置(前提是金额准确地除以整数个月)。
-为了便于比较,保存了第一次和最后一次付款。
-建造桌子时 principal_part 它仅在输出期间被舍入,但在计算中使用全精度以避免误差累积。
4. 返回数据的结构
两个选项都返回 NamedTuple 使用相同的字段,这允许您编写通用代码。:
(loan_type = ..., payment_type = ..., amount = ..., rate = ..., term = ...,
total_payment = ..., total_interest = ..., overpayment_percent = ...,
payments_table = DataFrame(...))
年金还有一个额外的字段 monthly_payment,对于差异化 – first_payment 和 last_payment. 这种结构便于后续加工。
付款表 payments_table 包含列:
month-月号(Int)date-付款日期(Date)payment-付款金额(Float64)principal-主要债务的部分(Float64)interest-百分比部分(Float64)remaining_debt-付款后的债务余额(Float64)
使用 DataFrame 允许您将包的所有功能应用于结果。 DataFrames.jl (过滤,聚合,合并),而无需额外的转换。
5. 处理边界条件
该代码提供了以下边缘情况:
-零或负参数-抛出错误。
-不正确的付款类型是一个错误与明确的消息。
-年金在 term = 1 年金比率公式仍在工作,最后一次付款的修正保证了准确性。
-具有差异化计算 principal_part 它不是四舍五入以避免在长时间内累积错误。
6. 测试和使用示例
草图中呈现的四个例子不仅可以作为演示,还可以作为隐式测试。 让我们看看他们检查哪些方面。
例1。 年金贷款
-检查年金系数计算的正确性。
-确保最后一次付款调整,余额重置为零。
-显示四舍五入到便士。
Ставка = 9.01 # @param {type:"slider",min:0,max:100,step:0.01}
Срок = 12 # @param {type:"slider",min:1,max:240,step:1}
Сумма = 2151100 # @param {type:"slider",min:100,max:50000000,step:1000}
consumer_loan = CreditCalculator(amount=Float64(Сумма), rate=Ставка, term=Срок, payment_type="annuity", loan_type="consumer")
println(consumer_loan.payments_table)
例2。 按揭(差异付款)
-检查工作与日期(转移 start_date 并通过以下方式计算日期 Dates.Month).
-通过输出完整的图表 print_payment_schedule,确认格式化正确。
-比较第一次和最后一次付款,以确保线性下降。
print_payment_schedule -付款时间表输出。 功能 print_payment_schedule 接受结果作为输入 CreditCalculator 并输出格式化报告。 其实现使用字符串操作(rpad, Dates.format)并遍历行 DataFrame. 这种方法将表示与计算逻辑分开。 如有必要,可以很容易地将输出替换为另一个输出(例如,在文件或HTML中)。
start_date = "2026-03-30" # @param {type:"date"}
Ставка = 9.01 # @param {type:"slider",min:0,max:100,step:0.01}
Срок = 12 # @param {type:"slider",min:1,max:240,step:1}
Сумма = 2151100 # @param {type:"slider",min:100,max:50000000,step:1000}
mortgage = CreditCalculator(amount=Float64(Сумма), rate=Ставка, term=Срок, payment_type="differentiated", loan_type="mortgage", start_date=Date(start_date))
print_payment_schedule(mortgage)
例3。 付款类别比较
-检查功能 compare_payment_types 返回包含三个字段的结构。
-比较多付的数值,确认年金提供了一个略高的多付与相同的参数。
compare_payment_types -比较功能,它调用两次 CreditCalculator 与不同的 payment_type 并生成最终表。 该表创建为 DataFrame 有三列:指标,年金值和差异化值。 这演示了如何使用单个模块的结果来构建更复杂的报告。
Ставка = 9.01 # @param {type:"slider",min:0,max:100,step:0.01}
Срок = 12 # @param {type:"slider",min:1,max:240,step:1}
Сумма = 2151100 # @param {type:"slider",min:100,max:50000000,step:1000}
comparison_result=compare_payment_types(金额=Float64(金额),费率=出价,期限=期限)
println(comparison_result.comparison)
例4。 付款表数据分析
-显示如何提取前五行(first).
-计算利息的最大值,最小值和金额-从而验证列 payment 和 interest 它们包含正确的数字数据。
-证明返回的 DataFrame 它功能齐全,可用于统计分析。
first_payments = first(mortgage.payments_table, 5)
println("首5个按揭付款:")
println(first_payments)
println("\付款统计:")
println("最高付款额: ", maximum(mortgage.payments_table.payment))
println("最低付款额: ", minimum(mortgage.payments_table.payment))
println("第一年的利息金额: ", sum(mortgage.payments_table.interest[1:12]))
结论
开发的模块演示了Julia功能的有效使用:通过命名参数进行多次调度,类型安全和方便的数据结构(NamedTuple, DataFrame)和功能性组合物。 这种方法可以轻松维护代码,添加新类型的计算(例如,考虑到提前还款)并将计算器集成到更大的财务应用程序中。 测试用例同时作为算法正确性的文档和确认.