대출 상환 계획 스킬
Wikiprompt, 무료 프롬프트 백과사전에서
대출 상환 계획 스킬 대출 상환 계획 수립을 위한 완전한 스킬 정의로, 시스템 프롬프트, 워크플로우, 참조 가이드, 템플릿, 예시, 그리고 상환 전략 비교를 위한 테스트된 Python 계산기를 포함합니다.
프롬프트 내용저장
🌐
---
name: loan-amortization-planner
description: 고정금리 대출 및 모기지 상환 일정을 만들고, 각 납입금 중 이자로 가는 금액을 보여주며, 추가 월 납입, 일시금, 더 높은 고정 납입, 또는 더 짧은 기간과 같은 상환 전략을 비교합니다. 이자 절감액, 절약 개월 수, 상환 완료일, 수수료가 있는 경우 APR 추정치를 제공합니다. 사용자가 "이자를 얼마나 내야 하나요?", "모기지를 추가 상환해야 할까요?", "한 달에 200을 더 내면 어떻게 되나요?"라고 묻거나 자동차, 학자금, 개인, 주택 대출에 대한 상환 계획을 원할 때 사용합니다. 테스트된 표준 라이브러리 Python 계산기를 포함합니다.
---
# 대출 상환 계획 도우미
당신은 사람들이 대출의 실제 비용을 이해하고, 예산에 맞는 방식으로 더 빨리 갚는 방법을 이해하도록 돕습니다. 숫자를 정확하게 계산하고, 쉬운 언어로 설명하며, 현실적인 옵션을 나란히 비교하고, 누군가가 대출 기관에 추가 금액을 보내기 전에 트레이드오프(비상금, 다른 부채, 조기 상환 규칙)를 지적합니다.
## 이 스킬의 파일
- `scripts/amortize.py` - 추가 월 납입, 일시금, 고정 납입, 수수료 및 APR 추정치, 연도별 표, CSV 일정이 포함된 고정금리 대출의 월별 상환 계산 (Python 3 표준 라이브러리만 사용)
- `references/amortization-basics.md` - 상환 방식, 공식, 사람들이 혼동하는 용어 (금리 vs APR, 기간 vs 상환 완료일)
- `references/prepayment-decision-guide.md` - 추가 상환이 합리적인 경우, 대출 계약서에서 확인할 사항, 우선순위
- `templates/loan-plan.md` - 반환할 보고서
- `examples/example-mortgage-overpayment.md` - 모기지에 대한 세 가지 추가 상환 전략의 비교 예시
## 작업 흐름
### 1. 사실 수집
질문하거나, 가정하고 그렇게 말합니다:
- 아직 갚아야 할 금액(또는 빌릴 금액), 이자율, 남은 기간, 알고 있는 경우 현재 월 납입금.
- 고정 또는 변동 금리, 고정 기간이 끝나는 시점.
- 수수료: 설정 또는 개설 수수료, 조기 상환 위약금 또는 연간 추가 상환 한도.
- 사용자가 감당할 수 있는 것: 월 추가 금액, 예상 보너스 또는 일시금, 비상금 및 기타 부채.
- 목표: 총 이자 최소화, 특정 날짜까지 부채 완전 상환, 또는 월 납입금 최소화.
### 2. 기본 시나리오 실행
```bash
python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --start 2026-12
python3 scripts/amortize.py --principal 18500 --rate 7.9 --months 48 --fee 400 # 수수료가 있는 자동차 대출: APR 추정치
```
계산된 납입금이 대출 기관의 명세서와 수 센트 이내로 일치하는지 확인합니다. 일치하지 않으면 대출에 다른 날짜 계산 방식, 잔액에 포함된 수수료, 또는 납입금에 포함된 보험이 있을 수 있습니다: 질문하거나 실제 금액으로 `--payment`를 사용하세요.
### 3. 시나리오 실행
```bash
python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --extra 200
python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --lump 12:10000 --lump 24:10000
python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 30 --payment 2000 --yearly
python3 scripts/amortize.py --principal 300000 --rate 4.5 --years 20 # 더 짧은 기간
python3 scripts/amortize.py ... --schedule plan.csv --json
```
사용자가 실제로 감당할 수 있는 2~4가지 옵션을 비교합니다. 각각에 대해 월 지출, 상환 완료일, 총 이자, 절감 이자, 절약 개월 수를 기록합니다. 스크립트를 실행할 수 없으면 `references/amortization-basics.md`의 공식을 사용하고 숫자가 근사치라고 말합니다.
### 4. 수학뿐만 아니라 결정도 확인
`references/prepayment-decision-guide.md`를 검토합니다: 비상금 우선, 고금리 부채 우선, 조기 상환 위약금 및 한도, 세금 효과(현지 확인), 대안(저축 또는 투자)의 세후 수익률. 추가 상환이 항상 옳다고 제시하지 마세요.
### 5. 전달
`templates/loan-plan.md`를 작성합니다: 대출을 한 줄로, 기본 시나리오, 시나리오 비교 표, 이유가 포함된 권장 사항, 대출 기관에 물어볼 사항, 다음 단계. `examples/example-mortgage-overpayment.md`의 스타일을 따릅니다.
## 규칙
- 모든 숫자에 통화를 표시하고 돈은 센트로 반올림합니다. 추정치는 추정치로 표시합니다.
- 계산기는 고정 금리, 월별 납입, 추가 납입이 즉시 원금에 적용되고 납입금은 변경되지 않는다고 가정합니다(기간 단축). 그렇게 말하고, 변동 금리나 납입금을 재계산하는 대출 기관을 표시합니다.
- 개인 투자 또는 세금 조언을 제공하지 마세요. 트레이드오프를 설명하고 사용자에게 대출 기관이나 공인된 조언자에게 확인할 사항을 알려주세요.
- 납입금이 이자조차 충당하지 못하면 명확히 말하고 중단합니다: 잔액이 늘어날 것입니다.
- 설명을 짧고 구체적으로 유지하세요: "추가 100마다 약 120의 이자를 절약합니다"가 이론의 문단보다 낫습니다.
FILE:references/amortization-basics.md
# 상환 기본 사항
## 고정금리 대출이 상환되는 방식
매월 대출 기관은 아직 갚지 않은 잔액에 대해 이자를 부과합니다. 납입금은 먼저 그 이자를 충당하고, 나머지는 잔액(원금)을 줄입니다. 잔액이 줄어들기 때문에 이자 부분은 매월 줄어들고 원금 부분은 늘어나며, 납입금은 동일하게 유지됩니다. 초기 납입금은 대부분 이자이고, 후기 납입금은 대부분 원금입니다.
## 공식
- 월 이자율: r = 연 이자율 / 12 (예: 4.5% -> 0.00375).
- n개월 동안 P 대출의 납입금: M = P * r / (1 - (1 + r)^-n). r = 0인 경우: M = P / n.
- 이번 달 이자: 잔액 * r. 이번 달 원금: M - 이자.
- 총 이자: 이자 부분의 합 또는 대략 M * n - P.
- 납입금 M으로 상환하는 데 걸리는 개월 수: n = -ln(1 - P * r / M) / ln(1 + r). P * r >= M이면 대출은 끝나지 않습니다.
빠른 확인: 30년 동안 6%의 200,000 -> 월 1,199.10. 30년 동안 4.5%의 300,000 -> 월 1,520.06.
## 추가 납입이 많은 돈을 절약하는 이유
추가 납입은 잔액을 즉시 줄이므로 이후 모든 달은 더 작은 금액에 대해 이자를 부과합니다. 절약액은 대략 추가 금액에 대출의 나머지 기간 동안 그 금액이 부담했을 이자를 곱한 것입니다. 그래서 대출 초기에 납입한 돈이 같은 금액을 나중에 납입하는 것보다 더 많은 돈을 절약합니다.
## 사람들이 혼동하는 용어
| 용어 | 의미 |
|---|---|
| 명목 금리 | 계약서의 연간 금리로, 월 이자를 계산하는 데 사용됩니다. |
| APR | 수수료를 포함한 연간 비율로, 제안을 비교합니다. 금리가 낮지만 수수료가 높은 대출은 APR이 더 높을 수 있습니다. |
| 기간 | 계획된 길이 (예: 30년). |
| 상환 완료일 | 잔액이 실제로 0이 되는 날짜. 추가 납입으로 더 빨라집니다. |
| 기간 단축 vs 납입금 감소 | 추가 상환 후 일부 대출 기관은 납입금을 유지하고 기간을 단축하고(더 많은 이자를 절약), 다른 기관은 더 낮은 납입금을 재계산합니다. 어느 쪽인지 물어보세요. |
| 원금 | 미래 이자를 제외한 아직 갚아야 할 금액. |
| 상환 일정 | 납입금, 이자, 원금, 잔액의 월별 표. |
## 반올림 및 작은 차이
대출 기관은 매월 센트로 반올림하고 rate / 12 대신 일일 이자(실제 일수 / 365)를 사용할 수 있습니다. 결과는 월별 몇 센트, 총 이자에서 몇 단위까지 다를 수 있습니다. 마지막 납입금은 일반적으로 반올림 차이를 흡수합니다.
## 고정금리 계산기의 한계
- 변동 또는 추적 금리: 현재 금리와 +1, +2 퍼센트 포인트에서 시나리오를 실행합니다.
- 이자만 지불 기간, 풍선 지불, 납입 유예: 별도로 또는 수동으로 모델링합니다.
- 월 납입금에 포함된 보험, 에스크로 또는 계좌 수수료는 이자가 아닙니다. 비교 전에 제거하세요.
FILE:references/prepayment-decision-guide.md
# 대출을 더 빨리 갚아야 할까요? 결정 가이드
대출을 추가 상환하면 대출 이자율과 동일한 보장되고 무위험한 "수익"을 얻습니다. 그것은 좋지만, 항상 여유 돈을 가장 잘 사용하는 방법은 아닙니다. 다음 단계를 순서대로 진행하세요.
## 1. 안전 우선
- 비상금: 추가 상환 전에 필수 비용의 약 3~6개월치를 쉽게 접근할 수 있는 저축에 보관하세요. 대출 기관에 보낸 돈은 되돌리기 어렵습니다.
- 안정적인 수입: 직장 변경, 육아 휴직 또는 큰 지출이 예정되어 있다면 먼저 현금을 확보하세요.
## 2. 가장 비싼 부채부터 갚기
이자율 순으로 부채를 정렬합니다(눈사태 방법): 신용카드 및 당좌 대월, 그 다음 개인 및 자동차 대출, 그 다음 학자금 대출 및 모기지. 가장 높은 금리를 먼저 추가 상환하세요. 동기 부여가 문제라면 가장 작은 잔액부터 갚는 것(눈덩이)도 괜찮지만, 그 비용이 무엇인지 말하세요.
## 3. 계약서 읽기
- 조기 상환 위약금 또는 조기 상환 수수료(주로 고정 금리 기간 동안 추가 상환 금액의 일정 비율).
- 연간 추가 상환 허용 한도(예: 수수료 없이 연간 잔액의 10%).
- 추가 상환이 기간을 단축합니까 아니면 납입금을 줄입니까? 선택할 수 있습니까?
- 최소 추가 상환 금액과 방법(온라인, 전화, 서면 지시).
## 4. 대안과 비교
- 고용주 퇴직 매칭은 일반적으로 어떤 추가 상환보다 낫습니다. 먼저 전체 매칭을 받으세요.
- 대출 금리를 저축에서 얻을 수 있는 세후, 수수료 후 수익과 비교하세요. 2% 모기지 대 4% 저축 계좌: 종이상 저축이 이깁니다. 7% 자동차 대출 대 3% 저축 계좌: 추가 상환이 이깁니다.
- 투자는 장기적으로 저금리 대출을 이길 수 있지만 위험이 따릅니다. 추가 상환 수익은 확실합니다.
- 세금: 일부 국가에서는 모기지 이자가 세금 공제 대상이 되어 실효 금리가 낮아집니다. 현지에서 확인하세요. 가정하지 마세요.
## 5. 전략 선택
| 전략 | 좋은 경우 |
|---|---|
| 월 고정 추가 납입 | 안정적인 수입, 습관 형성, 일찍 시작하면 같은 총액으로 가장 많이 절약. |
| 일시금 (보너스, 세금 환급) | 불규칙한 수입, 연중 유연성 유지. |
| 더 높은 고정 납입 | 명확한 부채 완전 상환 날짜를 원함. |
| 더 짧은 기간으로 재융자 | 더 낮은 금리가 가능하고 더 높은 납입금을 감당할 수 있을 때. 수수료 비교. |
| 현금 보유, 나중에 추가 상환 | 고정 기간이 곧 끝남(이후 위약금 없이 추가 상환 가능), 또는 비상금이 충분하지 않음. |
## 6. 검토
1년에 한 번, 금리가 변경될 때, 또는 수입이 변경될 때 숫자를 다시 계산하세요. 추가 상환은 항상 중단할 수 있지만, 계약상 더 높은 납입금은 일반적으로 중단할 수 없다는 점을 사용자에게 상기시키세요.
FILE:templates/loan-plan.md
# 대출 계획: ${loan_name}
**대출:** ${balance} (${rate}% ${fixed_or_variable}), 남은 기간 ${remaining_term}, 월 납입금 ${payment}, 이 계획의 첫 납입 ${start_month}
**수수료 및 규칙:** ${fees}; 추가 상환 한도 또는 위약금: ${prepayment_rules}
**목표:** ${goal}
**추가 납입 예산:** ${extra_budget}
## 기본 시나리오
- 월 납입금:
- 현재부터 총 이자:
- 상환 완료일:
- 첫 납입 분할: 이자 ... / 원금 ...
## 시나리오
| 옵션 | 월 지출 | 상환 완료일 | 총 이자 | 절감 이자 | 절약 개월 수 |
|---|---|---|---|---|---|
| 기본 | | | | - | - |
| A: | | | | | |
| B: | | | | | |
| C: | | | | | |
## 권장 사항
옵션 ... 이유:
1.
2.
3.
염두에 둘 트레이드오프:
## 추가 상환 전에
- [ ] 비상금이 ... 개월을 충당합니다
- [ ] 더 높은 금리의 부채가 없습니다(또는 그것이 우선입니다)
- [ ] 조기 상환 위약금 / 허용 한도를 대출 기관에 확인했습니다
- [ ] 추가 상환이 기간을 단축하도록 설정되었습니다(또는 원하는 경우 납입금)
## 대출 기관에 물어볼 질문
1.
2.
## 다음 단계
1.
2.
*가정: 고정 금리, 월별 납입, 추가 납입은 즉시 원금에 적용됩니다. 이는 추정치이며 재정 조언이 아닙니다.*
FILE:examples/example-mortgage-overpayment.md
# 예시: 세 가지 모기지 추가 상환 전략 비교
## 사용자 요청
"모기지 잔액이 320,000이고 금리가 4.1% 고정이며 25년이 남았습니다. 이 계획의 첫 납입은 2026년 12월입니다. 매달 약 300을 추가로 낼 수 있고, 앞으로 3년 동안 매년 15,000의 보너스를 받습니다. 친구는 그냥 매달 2,400으로 바꾸라고 합니다. 무엇이 가장 좋을까요? 비상금은 6개월치가 있고 다른 부채는 없습니다. 은행은 수수료 없이 연간 10% 추가 상환을 허용합니다."
## 명령어
```bash
python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12
python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --extra 300
python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --lump 12:15000 --lump 24:15000 --lump 36:15000
python3 scripts/amortize.py --principal 320000 --rate 4.1 --years 25 --start 2026-12 --payment 2400
```
출력 (축약):
```
기본: 월 1,706.80, 이자 192,038.38, 총 지불 512,038.38, 2051-11에 상환 완료 (300회 납입)
계획 (+300.00/월): 2046-02에 상환 완료 (231회 납입), 이자 143,068.39
48,969.99 이자와 69개월 (5년 9개월) 절약; 추가 100마다 70.97 절약
계획 (12회차에 15,000.00, 24회차에 15,000.00, 36회차에 15,000.00 일시금): 2046-11에 상환 완료 (240회 납입), 이자 133,018.73
59,019.65 이자와 60개월 (5년 0개월) 절약; 추가 100마다 131.15 절약
계획 (고정 납입 2,400.00): 2041-10에 상환 완료 (179회 납입), 이자 107,805.37
84,233.01 이자와 121개월 (10년 1개월) 절약
```
## 대출 계획 (작성된 템플릿, 축약)
**대출:** 320,000.00 (4.1% 고정), 남은 기간 25년, 월 납입금 1,706.80, 첫 납입 2026년 12월
**수수료 및 규칙:** 연간 잔액의 최대 10% 추가 상환은 무료
**목표:** 유연성을 잃지 않고 이자 절약
| 옵션 | 월 지출 | 상환 완료일 | 총 이자 | 절감 이자 | 절약 개월 수 |
|---|---|---|---|---|---|
| 기본 | 1,706.80 | 2051-11 | 192,038.38 | - | - |
| A: 월 +300 | 2,006.80 | 2046-02 | 143,068.39 | 48,969.99 | 69 |
| B: 1~3년차 15,000 보너스 | 1,706.80 + 총 45,000 | 2046-11 | 133,018.73 | 59,019.65 | 60 |
| C: 고정 월 2,400 | 2,400.00 | 2041-10 | 107,805.37 | 84,233.01 | 121 |
**권장 사항:** 옵션 B, 예산이 허락한다면 A를 추가하세요. 보너스는 대출 초기에 지불되므로 추가 상환 100마다 약 131의 이자를 절약하며, 이는 월 납입 계획(100당 약 71, 그 돈의 상당 부분이 나중에 지불되기 때문)의 거의 두 배입니다. 월 예산 변경이 필요 없고, 각 15,000은 무료 10% 허용 한도(1년차 32,000) 내에 있습니다. 옵션 C는 15년 동안 약 124,000의 추가 금액을 보내므로 가장 많이 절약하지만, 고정 지출을 월 693만큼 늘립니다. 편안하게 감당할 수 있을 때만 하세요. 그리고 중단할 수 있도록 새 계약 납입금이 아닌 자발적 추가 상환으로 설정하세요.
**트레이드오프:** 추가 상환한 돈은 되돌리기 어렵습니다. 6개월치 비상금은 건드리지 마세요. 저축 계좌가 세후 4.1% 이상을 지불한다면 저축이 종이상 추가 상환보다 나을 수 있습니다. 금리와 현지 세금 규칙을 확인하세요.
**대출 기관에 물어볼 질문:**
1. 추가 상환이 납입금을 유지한 채 기간을 단축합니까(위에서 가정), 아니면 납입금을 재계산합니까?
2. 10% 허용 한도가 달력 연도 기준으로 재설정됩니까, 아니면 대출 연도 기준입니까?
*가정: 전체 기간 동안 고정 금리, 월별 납입, 추가 상환은 즉시 원금에 적용됩니다. 추정치이며 재정 조언이 아닙니다.*
FILE:scripts/amortize.py
#!/usr/bin/env python3
"""추가 납입 및 시나리오 비교가 포함된 고정금리 대출 상환 계산.
사용법:
python3 amortize.py --principal 250000 --rate 4.2 --years 30 [옵션]
python3 amortize.py --principal 18000 --rate 7.9 --months 60 --extra 150
옵션:
--principal N 대출 금액 (필수)
--rate PCT 명목 연 이자율(퍼센트), 예: 4.2 (필수; 0 허용)
--years N | --months N 기간 (둘 중 하나 필수)
--start YYYY-MM 첫 납입 월 (기본값: 다음 달)
--extra N 모든 월 납입금에 추가되는 금액
--extra-from N --extra가 시작되는 납입 번호 (기본값 1)
--lump N:AMOUNT 납입 번호 N의 일시금 추가 납입 (반복 가능)
--payment N 계산된 금액 대신 이 고정 월 납입금을 지불
--fee N 비용 및 APR 추정에 사용되는 일회성 선불 수수료
--schedule FILE 전체 월별 일정을 CSV로 작성
--yearly 연도별 표 출력
--json 결과를 JSON으로 출력
추가 납입은 조기 상환 위약금 없이 즉시 원금을 줄이고 동일한 월 납입금을 유지한다고 가정합니다(기간 단축). 금리는 명목 연간이며 월 복리(월 rate / 12)입니다. 돈은 매월 센트로 반올림됩니다. 종료 코드: 0 정상, 2 사용법 또는 입력 오류. Python 3 표준 라이브러리만 사용.
"""
import argparse
import csv
import datetime as dt
import json
import sys
def monthly_payment(principal, annual_rate, n):
r = annual_rate / 100 / 12
if r == 0:
return principal / n
return principal * r / (1 - (1 + r) ** -n)
def add_months(ym, k):
y, m = ym
m0 = m - 1 + k
return (y + m0 // 12, m0 % 12 + 1)
def schedule(principal, annual_rate, n, payment=None, extra=0.0, extra_from=1, lumps=None):
r = annual_rate / 100 / 12
base = round(payment if payment else monthly_payment(principal, annual_rate, n), 2)
lumps = lumps or {}
bal = round(principal, 2)
rows = []
k = 0
while bal > 0.005:
k += 1
if k > 1200:
raise ValueError("대출이 100년 내에 상환되지 않습니다. 납입금이 이자에 비해 너무 작습니다.")
interest = round(bal * r, 2)
if base + (extra if k >= extra_from else 0) <= interest and not lumps.get(k):
raise ValueError(f"납입금 {base:.2f}이(가) 월 이자 {interest:.2f}을(를) 충당하지 못합니다. 잔액이 늘어납니다.")
sched = min(base, bal + interest)
if payment is None and k == n:
sched = bal + interest # 마지막 예정 납입금이 반올림 차이를 흡수
ext = min(extra if k >= extra_from else 0.0, max(bal + interest - sched, 0))
lump = min(lumps.get(k, 0.0), max(bal + interest - sched - ext, 0))
principal_paid = round(sched + ext + lump - interest, 2)
bal = round(bal - principal_paid, 2)
rows.append({"n": k, "payment": round(sched, 2), "extra": round(ext + lump, 2), "interest": interest,
"principal": principal_paid, "balance": max(bal, 0.0)})
return base, rows
def summarize(rows):
return {"months": len(rows), "total_interest": round(sum(x["interest"] for x in rows), 2),
"total_paid": round(sum(x["payment"] + x["extra"] for x in rows), 2),
"total_extra": round(sum(x["extra"] for x in rows), 2)}
def apr_estimate(principal, fee, payment, n):
"""납입금이 원금 - 수수료와 같게 만드는 연간 금리 (이분법)."""
target = principal - fee
lo, hi = 0.0, 1.0
for _ in range(100):
mid = (lo + hi) / 2
r = mid / 12
pv = payment * n if r == 0 else payment * (1 - (1 + r) ** -n) / r
lo, hi = (mid, hi) if pv > target else (lo, mid)
return round(lo * 100, 3)
def fmt_ym(ym):
return f"{ym[0]:04d}-{ym[1]:02d}"
def main(argv):
p = argparse.ArgumentParser(add_help=True, description="추가 납입이 포함된 대출 상환 계산")
p.add_argument("--principal", type=float, required=True)
p.add_argument("--rate", type=float, required=True)
g = p.add_mutually_exclusive_group(required=True)
g.add_argument("--years", type=float)
g.add_argument("--months", type=int)
p.add_argument("--start")
p.add_argument("--extra", type=float, default=0.0)
p.add_argument("--extra-from", type=int, default=1)
p.add_argument("--lump", action="append", default=[])
p.add_argument("--payment", type=float)
p.add_argument("--fee", type=float, default=0.0)
p.add_argument("--schedule")
p.add_argument("--yearly", action="store_true")
p.add_argument("--json", action="store_true")
try:
a = p.parse_args(argv)
except SystemExit as e:
return 0 if e.code == 0 else 2
try:
n = a.months if a.months else round(a.years * 12)
if a.principal <= 0 or n <= 0 or a.rate < 0 or a.extra < 0 or a.fee < 0:
raise ValueError("원금과 기간은 양수여야 하며, 금리, 추가 납입, 수수료는 음수일 수 없습니다.")
if a.rate > 100:
raise ValueError("금리는 연간 퍼센트입니다. 예: 4.2%는 4.2")
lumps = {}
for item in a.lump:
num, _, amt = item.partition(":")
try:
if not num.isdigit():
raise ValueError
value = float(amt)
except ValueError:
raise ValueError(f"--lump는 24:5000 (납입 번호:금액) 형식이어야 합니다. 입력값: {item!r}") from None
lumps[int(num)] = lumps.get(int(num), 0.0) + value
if a.start:
try:
y, m = a.start.split("-")
start = (int(y), int(m))
except ValueError:
raise ValueError(f"--start는 2026-11 형식이어야 합니다. 입력값: {a.start!r}") from None
if not 1 <= start[1] <= 12:
raise ValueError("--start 월은 01에서 12 사이여야 합니다.")
else:
t = dt.date.today()
start = add_months((t.year, t.month), 1)
base_pay, base_rows = schedule(a.principal, a.rate, n, payment=None)
scenario = bool(a.extra or lumps or a.payment)
pay, rows = schedule(a.principal, a.rate, n, payment=a.payment, extra=a.extra,
extra_from=a.extra_from, lumps=lumps) if scenario else (base_pay, base_rows)
except ValueError as e:
print(f"오류: {e}", file=sys.stderr)
return 2
base_sum, plan_sum = summarize(base_rows), summarize(rows)
result = {
"inputs": {"principal": a.principal, "annual_rate_pct": a.rate, "term_months": n, "first_payment": fmt_ym(start),
"extra_monthly": a.extra, "extra_from_payment": a.extra_from, "lumps": lumps, "fixed_payment": a.payment, "fees": a.fee},
"baseline": {"monthly_payment": base_pay, **base_sum, "payoff": fmt_ym(add_months(start, base_sum["months"] - 1))},
}
if a.fee:
result["baseline"]["apr_estimate_pct"] = apr_estimate(a.principal, a.fee, base_pay, n)
result["baseline"]["total_cost_incl_fees"] = round(base_sum["total_interest"] + a.fee, 2)
if scenario:
result["plan"] = {"monthly_payment": pay, **plan_sum, "payoff": fmt_ym(add_months(start, plan_sum["months"] - 1)),
"months_saved": base_sum["months"] - plan_sum["months"],
"interest_saved": round(base_sum["total_interest"] - plan_sum["total_interest"], 2)}
if plan_sum["total_extra"]:
result["plan"]["interest_saved_per_100_extra"] = round(100 * result["plan"]["interest_saved"] / plan_sum["total_extra"], 2)
yearly = []
for i in range(0, len(rows), 12):
chunk = rows[i:i + 12]
yearly.append({"year": i // 12 + 1, "paid": round(sum(x["payment"] + x["extra"] for x in chunk), 2),
"interest": round(sum(x["interest"] for x in chunk), 2),
"principal": round(sum(x["principal"] for x in chunk), 2), "end_balance": chunk[-1]["balance"]})
result["yearly"] = yearly
first = base_rows[0]
result["baseline"]["first_payment_split"] = {"interest": first["interest"], "principal": first["principal"]}
if a.schedule:
try:
with open(a.schedule, "w", newline="", encoding="utf-8") as f:
w = csv.writer(f)
w.writerow(["n", "month", "payment", "extra", "interest", "principal", "balance"])
for x in rows:
w.writerow([x["n"], fmt_ym(add_months(start, x["n"] - 1)), f"{x['payment']:.2f}", f"{x['extra']:.2f}",
f"{x['interest']:.2f}", f"{x['principal']:.2f}", f"{x['balance']:.2f}"])
except OSError as e:
print(f"오류: 일정을 쓸 수 없습니다 {a.schedule}: {e.strerror}", file=sys.stderr)
return 2
if a.json:
print(json.dumps(result, indent=2))
return 0
b = result["baseline"]
print(f"대출 {a.principal:,.2f} ({a.rate}%, {n}개월), 첫 납입 {fmt_ym(start)}")
print(f"기본: 월 {b['monthly_payment']:,.2f}, 이자 {b['total_interest']:,.2f}, "
f"총 지불 {b['total_paid']:,.2f}, {b['payoff']}에 상환 완료 ({b['months']}회 납입)")
if a.fee:
print(f" 수수료 {a.fee:,.2f} 포함: 총 차입 비용 {b['total_cost_incl_fees']:,.2f}, APR 약 {b['apr_estimate_pct']}%")
print(f" 첫 납입: 이자 {first['interest']:,.2f}, 원금 {first['principal']:,.2f}")
if scenario:
pl = result["plan"]
what = []
if a.payment:
what.append(f"고정 납입 {a.payment:,.2f}")
if a.extra:
what.append(f"+{a.extra:,.2f}/월" + (f" (납입 {a.extra_from}부터)" if a.extra_from > 1 else ""))
if lumps:
what.append("일시금 " + ", ".join(f"납입 {k}에 {v:,.2f}" for k, v in sorted(lumps.items())))
print(f"계획 ({'; '.join(what)}): {pl['payoff']}에 상환 완료 ({pl['months']}회 납입), "
f"이자 {pl['total_interest']:,.2f}")
ms = pl["months_saved"]
if ms >= 0 and pl["interest_saved"] >= 0:
print(f" 이자 {pl['interest_saved']:,.2f}와 {ms}개월 ({ms // 12}년 {ms % 12}개월) 절약"
+ (f"; 추가 100마다 {pl['interest_saved_per_100_extra']:,.2f} 절약" if pl.get("interest_saved_per_100_extra") else ""))
else:
print(f" 경고: 이 계획은 기본보다 이자가 {-pl['interest_saved']:,.2f} 더 들고 {-ms}개월 더 걸립니다.")
if a.yearly:
print(f"\n연도별 ({'계획' if scenario else '기본'}):")
print(f"{'연도':>4} {'지불':>12} {'이자':>12} {'원금':>12} {'잔액':>12}")
for y in yearly:
print(f"{y['year']:>4} {y['paid']:>12,.2f} {y['interest']:>12,.2f} {y['principal']:>12,.2f} {y['end_balance']:>12,.2f}")
if a.schedule:
print(f"\n일정이 {a.schedule}에 작성되었습니다 ({len(rows)}행)")
return 0
if __name__ == "__main__":
sys.exit(main(sys.argv[1:]))
전체 프롬프트를 보려면 로그인하세요
Continue with:
By logging in, you agree to our Terms of Use and Privacy Policy
사용법
이 프롬프트는 personal와 함께 사용하도록 설계되었습니다. 위의 프롬프트 내용을 복사하여 원하는 AI 도구에 붙여넣으세요.
최상의 결과를 얻으려면 자리 표시자(대괄호 또는 대문자로 표시)를 특정 요구 사항으로 사용자 지정할 수 있습니다.
토론
댓글 0개