逐条规则找出 349 元差额的来源
한국어 원문으로 표시합니다.
목표
중도 해지 계약의 미경과보험료를 다시 계산하고, 일수 기준과 반올림 방식과 구간 분리가 만드는 차이를 계약 단위로 지목해 정정 목록까지 낸다.
왜 중요한가
환급액은 "연보험료 곱하기 미경과일수 나누기 총일수" 한 줄처럼 보이지만, 그 한 줄 안에 정책으로 정해야 하는 값이 세 개 숨어 있다. 일수를 어떻게 세는가, 어디서 끊는가, 기중 변경을 반영하는가. 세 값을 다르게 잡은 두 시스템은 각자 맞는 계산을 하면서도 다른 답을 낸다. 그때 필요한 것은 "차이가 납니다" 가 아니라 "이 계약의 차이는 일수 기준 때문이고 저 계약은 구간 때문" 이라는 설명이다. 채점기는 여러분이 적은 숫자끼리 견주지 않는다. 1단계 자료에서 기준값을 다시 계산해 대조하니, 안내의 규칙을 그대로 따라야 한다.
단계
- /root/prem/gen_prem.py 를 만들어 실행해 /root/prem/policies.csv(60건)와 /root/prem/changes.csv(15건)를 만든다.
- 계약마다 실제 일수와 30/360 두 기준의 총일수·경과일수·미경과일수를 /root/prem/daycount.json 에 적는다.
- 실제 일수 기준으로 미경과보험료를 계산해 /root/prem/refund_actual.json 에 적는다.
- 같은 계약을 30/360 기준으로 계산해 /root/prem/refund_30360.json 에 적고 3단계와의 차이를 함께 남긴다.
- 보장 변경이 있는 계약을 변경일 앞뒤로 쪼개 /root/prem/segments.json 에 구간별 환급액을 적는다.
- 구간마다 끊은 합과 끝에서 한 번만 끊은 값의 차이, 그리고 월납 12분할을 /root/prem/rounding.json 에 적는다.
- 청구 시스템과 회계 시스템의 계산을 나란히 돌려 /root/prem/diff.json 에 계약별 차이와 원인을 적는다.
- 정정 목록과 결론을 /root/prem/report.json 하나로 묶고 policies.csv 의 sha256 을 함께 적는다.
참고
- 1단계 계약 규칙(i 는 0 부터 59): policy_id 는
P0001부터 네 자리, 시작일은 2024-01-01 에(i * 59) % 730일을 더한 날, 만기일은 시작일의 1년 뒤 같은 날에서 하루 전(그 날이 없으면 그 달 말일로 당긴 뒤 하루 전), pay_mode 는 i 가 홀수면 monthly 짝수면 annual, 연보험료는120000 + (i * 7777) % 880001, 해지일은 시작일에37 + (i * 29) % 300일을 더한 날이다. - 1단계 변경 규칙: i 를 4로 나눈 나머지가 2 인 계약만 변경이 있다. 변경일은 시작일에
30 + (i * 47) % 260일을 더한 날, 새 연보험료는연보험료 + 60000 + (i * 3331) % 200000이다. - 일수 정의: 총일수는 시작일과 만기일을 모두 포함해 세고, 경과일수는 해지일에서 시작일을 뺀 날수(해지일 당일은 보장하지 않는다), 미경과일수는 총일수에서 경과일수를 뺀 값이다.
- 30/360(US) 규칙: 앞 날짜의 일이 31 이면 30 으로 당기고, 뒤 날짜의 일이 31 이면서 앞이 30 이상이면 30 으로 당긴 뒤
360 * 연차 + 30 * 월차 + 일차로 센다. 총일수와 미경과일수는 여기에 실제 일수와 같은 방식으로 1 을 더해 양끝을 포함시킨다. - 환급액:
연보험료 * 미경과일수 / 총일수를 1원 단위로 끊는다. 3 · 4 · 5단계의 정책은 ROUND_HALF_UP 이다. - 구간 미경과일수: 구간이 해지일부터 만기일까지와 겹치는 날만 센다. 겹치지 않으면 0 이다.
- 7단계 두 경로: 청구 시스템은 실제 일수 · ROUND_HALF_UP · 구간 반영이고, 회계 시스템은 30/360 · 원 미만 절사(ROUND_DOWN) · 구간 무시(원래 연보험료로 전체 기간)다. 원인은 회계 계산에서 규칙 하나만 청구 쪽으로 바꿨을 때 값이 달라지는 것만
daycount,rounding,segment순서로 적는다. - 흔한 실수: 미경과일수에 해지일 당일을 넣기, 30/360 에서 양끝 포함을 빼먹기, 구간이 미경과 구간과 겹치지 않는데 1일로 세기, 월납 분할에서 나머지 버리기.
- 확인:
python3 -c "import json;print(json.load(open('/root/prem/diff.json'))['by_cause'])"
계약과 보장 변경 자료 만들기
/root/prem/gen_prem.py 를 만들어 실행해 /root/prem/policies.csv(60건)와 /root/prem/changes.csv(15건)를 만드세요.
만기일이 까다롭습니다. 시작일의 1년 뒤 같은 날이 없는 경우(2024-02-29)를 그 달 말일로 당겨야 하는데, calendar.monthrange 가 그 달의 마지막 날을 알려 줍니다. 날짜는 전부 YYYY-MM-DD 로 적습니다.
일수 기준 두 가지를 갈라 놓기
계약마다 term_days, used_days, unused_days 와 30/360 판 세 값을 /root/prem/daycount.json 에 적고, 보험기간에 2월 29일이 들어 있는 계약 목록과 두 기준의 미경과일수가 다른 계약 수도 함께 남기세요.
실제 일수는 date 뺄셈으로 바로 나옵니다. 30/360 은 31일을 당기는 두 규칙을 먼저 적용한 뒤 연·월·일 차이를 더합니다. 양끝을 포함할지 말지를 두 기준에서 똑같이 정해야 비교가 성립합니다.
실제 일수로 미경과보험료 계산하기
/root/prem/refund_actual.json 에 basis, rounding, 계약별 unused_days 와 refund_krw, 그리고 total_krw 를 적으세요. 이 단계는 보장 변경을 무시하고 원래 연보험료로 전체 기간을 계산합니다.
Decimal 로 곱하고 나눈 뒤 quantize 로 1원 자리에서 끊습니다. 실수로 계산하면 0.5 가 정확히 0.5 가 아니라서 반올림 모드를 고르는 일 자체가 무의미해집니다.
분모를 30/360 으로 바꿔 보기
/root/prem/refund_30360.json 에 30/360 기준 환급액과 3단계와의 diff_krw, 그리고 diff_rows 와 total_diff_krw 를 적으세요.
분모와 분자를 모두 30/360 으로 바꿔야 합니다. 한쪽만 바꾸면 기간이 1년인 계약의 환급률이 1 을 넘는 일이 생깁니다. diff_krw 는 30/360 값에서 실제 일수 값을 뺀 것입니다.
기중 보장 변경을 구간으로 쪼개기
보장 변경이 있는 계약 15건만 골라 /root/prem/segments.json 에 구간 2개(from, to, annual_krw, unused_days, refund_krw)와 구간 합산 refund_krw, 변경을 무시한 whole_period_refund_krw, 그 차이 gap_krw 를 적으세요.
앞 구간은 변경일 하루 전까지입니다. 미경과일수는 구간이 해지일부터 만기일까지와 겹치는 날만 세니, 변경일이 해지일보다 앞이면 앞 구간의 미경과일수는 0 입니다. 분모는 두 구간 모두 계약 전체의 총일수입니다.
끊는 자리를 어디에 둘 것인가
/root/prem/rounding.json 에 segment_rounding(policies_with_gap, total_gap_krw)과 monthly_split(policies, count, all_exact)을 적으세요. 월납 계약의 12개월 분할은 합이 연보험료와 정확히 같아야 합니다.
구간마다 끊은 합과, 구간별 정확한 값을 다 더한 뒤 한 번만 끊은 값을 견줍니다. 월납 분할은 몫을 내림으로 준 뒤 남은 원을 앞 달부터 1원씩 더 붙이면 합이 맞습니다.
두 시스템의 차이를 규칙 단위로 지목하기
/root/prem/diff.json 에 두 시스템의 규칙, 계약별 claims_krw, acct_krw, diff_krw, causes, 그리고 diff_rows, total_diff_krw, by_cause 를 적으세요.
원인은 짐작으로 붙이지 않습니다. 회계 계산에서 규칙을 하나만 청구 쪽으로 바꿔 다시 계산해 보고, 값이 달라지는 규칙만 원인입니다. 세 규칙을 각각 한 번씩 토글하면 됩니다.
정정 목록과 결론을 한 장으로
/root/prem/report.json 에 policies_sha256, policies, changed_policies, refund_actual_total_krw, refund_30360_total_krw, basis_gap_krw, segment_gap_policies, diff_rows, total_diff_krw, by_cause, corrections, policy_basis, policy_rounding, verdict 를 적으세요. verdict 는 claims-system-is-authoritative 입니다.
corrections 에는 차이가 난 계약만 policy_id 오름차순으로, policy_id·from_krw·to_krw·delta_krw 네 키만 담습니다. from 은 고칠 값(회계), to 는 기준으로 삼기로 한 값(청구)입니다. 해시는 지금 policies.csv 에서 다시 계산합니다.