สร้าง Loan amortization schedule แบบ “ไม่” ปกติด้วย Python และ SAS

Sasiwut Chaiyadecha
2 min readOct 6, 2020

--

Amortization schedule

จากตอนก่อนหน้านี้ ได้พูดถึงการสร้าง Repayment schedule เพื่อตัดยอดหนี้แบบ Amortization แบบปกติกันไปแล้ว ถ้าต้องการอ่านรายละเอียดเกี่ยวกับ Amortization หรือวิธีการเขียน Code ทั้งภาษา Python และ SAS สามารถย้อนกลับไปอ่านที่ Link ด้านล่างได้

วันนี้ขอมาพูดถึงการ Amortization ที่ “ไม่ปกติ” บ้าง เรื่องนี้เป็นหนึ่งใน Situation ที่เจอระหว่างทำงานอีกเช่นเดิม เนื่องจากการคำนวณ Repayment schedule ต้องเกิดจาก 3 ตัวแปรด้วยกันคือ 1.ยอดหนี้ 2.ดอกเบี้ย และ 3.จำนวนงวด เพื่อที่สามารถคำนวณหาจำนวนเงินที่ต้องจ่ายในแต่ละงวดได้ ซึ่งทั้งหมดนี้คือสิ่งที่สามารถทำย้อนกลับไปมาได้ และควรมีค่าเท่ากันเสมอตามสมการ

Amortization schedule pmt function
ตัวอย่างการหา payment ในแต่ละงวด

ขอเล่าถึงปัญหาที่มาของคำว่าไม่ปกติ สิ่งที่เกิดขึ้นคือค่า Installment รายเดือนที่มีให้ ไม่สามารถคำนวณย้อนกลับได้ Case ที่เจอคือต้องใช้ค่า Installment ที่มีมาให้ในการคำนวณ

ดังนั้นถ้าต้องใช้ยอด Installment จากระบบเพื่อตัดยอดหนี้ ณ เดือนนั้น ๆ ด้วยดอกเบี้ยทจากระบบ ผลที่เกิดขึ้นคือ Maturity ของ Loan จะจบไม่ตรงกับที่ระบุไว้ในสัญญา

ดังนั้นหมายความว่าฟังก์ชั่น numpy_financial.pmt numpy_financial.ppmt และ numpy_financial.ipmt จึงไม่สามารถใช้งานได้ การคำนวณต้องเขียนสูตร Manual ขึ้นมา

Python

ขอใช้ตัวอย่างจากตอนก่อนหน้านี้ โดยกำหนดอัตราดอกเบี้ยเท่ากับ 3.6% ต่อปี มียอดหนี้เท่ากับ 5 แสน แต่เปลี่ยน Installment ที่เกิดขึ้นเป็น 15,000 ต่อเดือนแทน และไม่ได้กำหนด Term เพราะต้องใช้ Installment ในการตัดยอดหนี้ลงในแต่ละเดือนจนหมด

เริ่มต้นเขียน Function balances เพื่อคำนวณหายอดหนี้ในเดือนถัดไป สิ่งที่ต้องหาก่อนเป็นอย่างแรกคือ interest_amount ณ เดือนนั้น ๆ ด้วยการเอายอดหนี้คูณด้วยอัตราดอกเบี้ย โดยที่ต้องหาร 100 และ 12 เพราะเปลี่ยนเป็นเปอร์เซ็นต์ และทำให้อยู่ใน Basis ของเดือน จากนั้นจึงสามารถหา next_balance ได้โดยเอายอดหนี้บวกด้วยดอกเบี้ยที่ลูกหนี้ต้องจ่าย และลบเงินต้นออก เพื่อเหลือยอดหนี้คงค้างของเดือนหน้า os + interest_amount — payment

เมื่อได้ Function ในการยอดหนี้เดือนถัดไปแล้ว สิ่งที่ต้องการถัดมาคือสร้าง Repayment schedual ขึ้นมา ซึ่งสามารถใช้ While loop ประกอบกับ Function ที่เขียนขึ้นมา โดยเริ่มจากกำหนดให้ x เป็นยอดหนี้ตั้งต้น และประกาศ amortization เป็น list ว่าง

จากนั้นประกาศ While loop โดยที่ while x > 0: คือการให้ Function คำนวณยอดหนี้เดือนถัดไปไปเรื่อย ๆ จนกว่ายอดหนี้จะน้อยกว่าหรือเท่ากับ 0 โดยในแต่ละรอบต้อง .append() ค่าเก็บไว้เพื่อการคำนวณยอดหนี้เดือนถัดไป มีการเขียน If statement ไว้คือถ้า x มีค่าน้อยกว่าหรือเท่ากับ 0 ให้หยุดการทำงานของลูปนี้

เมื่อได้ list ที่เก็บไว้ในตัวแปร amortization สามารถนับจำนวนสมาชิกทั้งหมดใน list ค่าที่ออกมาคือจำนวน Term ทั้งหมดที่ลูกหนี้ต้องทำการจ่ายหนี้

Number of term to repay: 35
ตัวอย่าง repayment table ที่ออกมาจากการใช้ function

Full code สามารถดูได้ที่ Link ด้านบน

SAS

ลองแก้ปัญหาที่เกิดขึ้นด้วยภาษา SAS ซึ่งพิจารณาจากโจทย์แล้ว SAS ดูเหมือนเขียนง่ายและตรงไปตรงมากกว่า

ใช้เป็นตัวเลขเหมือนเดิมเพื่อเปรียบเทียบตัวอย่างการคำนวณของทั้ง 2 ภาษาได้ ดูจากโค้ด SAS แล้วเหมือนกันตัวอย่างก่อนหน้านี้มาก สิ่งที่ต่างกันคือไม่จำเป็นต้องใช้ฟังก์ชั่น FINANCE แล้ว

เริ่มจากสร้าง Column ใหม่ขึ้นมาชื่อว่า Ending_balance โดยให้เท่ากับยอดหนี้ตั้งต้น จากนั้นใช้ While loop ซึ่งใน SAS ใช่คู่กับ Do statement โดยสามารถเขียนได้ว่า do while(Ending_balance > 0); จากนั้นเริ่มการคำนวณด้วย Logic เดิมคือยอดหนี้เดือนถัดไปหาได้จาก ดอกเบี้ยที่ต้องจ่ายบวกกับเข้าไปในยอดหนี้ แล้วลบออกด้วยเงินต้น เขียน If statement หนึ่งชั้นเพื่อลบค่าผลลัพธ์ที่น้อยกว่า 0 จากนั้นใช้ output; เพื่อเก็บค่าที่คำนวณเอาไว้ในแต่ละลูป

แถมด้วยการสร้าง Column terms ทั้งหมดที่ต้องจ่ายด้วยการให้เรียงลำดับ 1, 2, 3, … ไปเรื่อย ๆ จนถึงงวดสุดท้าย ใน SAS สามารถใช้คำสั่ง retain Column และ +1 เพื่อใส่ค่าแบบมีลำดับเข้าไปได้

ตัวอย่าง table ที่ได้ออกมาจากการเขียน sas

Full code สามารถดูได้ที่ Link ด้านบน

Conclusion

จบไปอีกหนึ่งตัวอย่างสำหรับการทำ Amortization ซึ่งแน่นอนว่าไม่ได้มีแค่ 2 แบบที่เขียนออกมาแน่ ๆ ยังมีอีกหลายแบบที่พบเจอกันได้ใน Market ถ้ามีโอกาสเจอการทำ Amortization ที่น่าสนใจ คงมาเล่าให้ฟังอีกเช่นเคย

--

--