10.1 동적해지율 엔진설계#

이 챕터는 설계 노트입니다 — 아직 구현되지 않았습니다

아래 API · 필드 · 코드 스케치는 현재 엔진에 없습니다. 실행되는 레시피가 아니라, 동적해지율 (dynamic lapse) 을 fastcashflow 에 어떻게 넣을지의 설계 방향을 기록한 로드맵입니다. 지금 동적해지가 필요하면 이 챕터의 코드를 그대로 쓸 수 없습니다 — 단계함수 해지율 등 정적 표현으로 근사해야 합니다 (3.2 paid-up 의 변형 절 참조).

배경 — 해지율의 네 단계#

같은 위험률이라도 해지율은 여러 축으로 달라집니다. 그 의존성을 표현하는 정교함은 네 단계로 나뉘고, 현 엔진은 처음 셋까지 표현합니다:

종류

무엇에 의존

현 엔진

평탄 (flat)

상수

duration 의존

가입경과 (policy duration) — 납입후 하락이 여기

됨 (lapse_annual(d))

상태 의존

상태 모델의 상태 (active / paidup 등)

됨 (lapse_paidup)

동적 (dynamic)

금리 경로 · 해약환급금 moneyness · 계좌가치 등 시나리오 변수

안 됨 — 이 챕터의 주제

여기서 moneyness (해약환급금이 계약을 계속 유지하는 것 대비 얼마나 유리한지) 란, 예를 들어 시장금리가 적용금리보다 높아 해약 후 재투자가 유리해지면 해지가 늘고, 반대면 줄어드는 행동을 가리킵니다.

처음 세 종류의 공통점은 해지율이 exogenous (투영을 시작하기 전에 (sex, issue_age, duration, ...) 만으로 미리 정해지는, 외생적) 이라는 점입니다. 그래서 엔진이 투영 전에 (성별, 연령, 연도) 격자에 해지율을 미리 깔아두고, 이를 전이확률 (edge probability — 한 상태에서 다음 상태로 넘어가는 월별 확률) 에 합쳐 둘 수 있습니다.

왜 단순 추가가 아니라 구조 변경인가#

동적해지율은 endogenous (투영 내부에서 매월 굴러가며 정해지는, 내생적) 입니다. 그 달의 moneyness 나 금리 스프레드를 보고 해지율이 정해지는데, 그 변수 자체가 시간 루프 안에서 비로소 알려집니다. 따라서:

  • 해지율을 투영 전에 격자로 미리 깔 수 없습니다.

  • 시간 루프 안에서 매월 재평가 해야 합니다.

즉 엔진의 “격자를 미리 깔고 → 루프를 돌린다” 아키텍처에서, 해지 한 항목만 ‘루프 안에서 평가’로 옮기는 것 이 설계의 본질입니다. 나머지 (사망 · 납입면제) 는 그대로 미리 깔아도 됩니다.

핵심 설계 결정 세 가지#

① 어디서 평가하나 — 속도가 지배한다#

fastcashflow 의 시간 루프는 numba @njit 커널 (파이썬 코드를 기계어로 미리 컴파일해 빠르게 도는 핵심 루프) 안에서 돕니다. 평가 위치 선택은 이 제약에 지배됩니다.

방안

내용

판정

(A) Python 콜백 주입

매월 임의의 파이썬 함수를 커널에서 호출

@njit 안에서는 파이썬 함수를 못 부름 → 루프가 순수 파이썬으로 추락, 속도 원칙 위배

(B) 계수표 + 루프 내 룩업

base 해지 격자 + moneyness 를 이산화한 배수표 (multiplier table) 를 미리 만들고, 루프 안에서 그 달 moneyness 로 배수를 룩업해 곱함

✓ numba 호환 (배열 인덱싱 / 보간만). 권장

(C) 닫힌형 공식 하드코딩

arctan / 구간선형 공식을 스칼라 파라미터로 커널 안에 직접

✓ 빠름. 단 함수형이 고정 — (B) 보다 덜 유연

(B) 가 정답입니다. 동적해지를 코드 가 아니라 데이터 (배수표) 로 표현하면 numba 커널이 그대로 돌립니다.

② 순환을 피하는 driver 선택#

해지율이 “계속 유지 가치 vs 해지 가치” 같은 완전한 경제가치 에 반응하면, 값과 해지율이 서로를 참조합니다 — 값을 알아야 해지율이 정해지고, 해지율을 알아야 값이 정해지는 순환입니다. 이를 풀려면 fixed-point iteration (고정점 반복 — 값과 해지율이 수렴할 때까지 번갈아 다시 계산) 이 필요하고, 이는 scope 밖입니다.

driver (해지율을 움직이는 변수) 를 계좌가치 (VFA)시장금리 - 적용금리 스프레드 처럼 루프에서 forward 로 (앞쪽으로 한 번에) 이미 계산되는 양으로 잡으면 순환이 없습니다. 둘 다 BEL을 몰라도 매월 구해집니다. fastcashflow 에는 이미 surrender_cf (해약환급금) 가 있으므로, moneyness driver 가 그것을 바로 재사용합니다.

③ 시나리오 차원#

진짜 동적해지는 확률적 금리 분포 아래에서 의미가 큽니다. 그런데 fastcashflow 는 결정론 커널입니다. 따라서 여기서의 동적해지는 단일 결정론 시나리오 (포워드 커브 / 스트레스 경로) 에 반응하는 해지 를 한 번 굴리는 것이고, 여러 시나리오는 커널을 시나리오마다 돌려 밖에서 집계 합니다 (scenario-conditioned projection — 시나리오별로 결정론 투영을 돌리고 결과를 합치는 구조).

VFA의 return_scenarios (펀드 수익률 경로를 받아 보증의 시간가치 TVOG를 계산) 가 이미 이 구조라, 동적해지가 같은 자리에 꽂힙니다. nested stochastic (시나리오 안에서 다시 시나리오를 도는 중첩 확률투영) 은 영원히 scope 밖 입니다.

fastcashflow 구체 제안 (VFA 먼저, 최소 · 속도보존)#

1. 새 옵션 필드 — 콜백이 아니라 spec 개체#

# 설계 스케치 -- 아직 구현 안 됨
@dataclass(frozen=True, slots=True)
class DynamicLapse:
    driver: str                      # {"account_value_moneyness", "rate_spread"}
    breakpoints: FloatArray          # moneyness 구간 경계 (오름차순)
    multipliers: FloatArray          # 각 구간의 base lapse 배수
    # → 구간선형 / 계단형. 코드가 아닌 '데이터' 라 numba 가 룩업으로 처리

Basis.dynamic_lapse: DynamicLapse | None = None 로 추가합니다. None 이면 기존 정적 해지 그대로 — back-compat (기존 입력이 손대지 않아도 동작) 가 설계 제약입니다.

2. 커널 변경 — VFA 경로부터#

VFA 커널에는 이미 계좌가치 av[t] 와 시나리오가 흐릅니다. 매월:

moneyness  = f(av[t], 보증가치)            # 또는 rate_spread = market[t] - credited
mult       = lookup(moneyness, breakpoints, multipliers)   # 배수표 룩업
eff_lapse  = base_lapse[year] * mult
eff_lapse  = clamp(eff_lapse, 0.0, 1.0)    # [0, 1] 범위로 자름
# → 정적 격자값 대신 eff_lapse 를 그 달의 해지 decrement 로 투입

GMM 경로보다 VFA가 먼저인 이유는, AV 궤적과 시나리오 plumbing (데이터를 커널까지 전달하는 배관) 이 이미 깔려 있기 때문입니다.

3. edge 합성만 부분 변경#

해지 edge 하나만 루프 안에서 합성하고 (base 격자 + 배수표), 나머지 edge (사망 · 납입면제) 는 기존대로 루프 전에 합성합니다. 전면 재작성이 아니라 전이확률 합성 단계의 한 자리만 손봅니다.

4. GMM 경로는 더 큰 작업#

rate_spread 기반 동적해지는 금리 경로 (n_time,) 를 커널 인자로 받아야 합니다 → 시나리오 경로 배관 추가가 VFA보다 큽니다. 인자가 없으면 정적 해지로 fallback 합니다.

5. 검증#

moneyness 가 breakpoint 를 넘는 2~3개월짜리 손계산 케이스를 만들어, 배수가 점프하는 달의 in-force 궤적이 손계산과 일치하는지 assert 합니다 — 쿡북의 다른 챕터와 같은 손계산 검증 원칙입니다.

비용 · 순서#

단계

분량

VFA 동적해지 (계좌가치 moneyness) — AV · 시나리오 배관이 이미 있어 가장 쌈

중간

GMM 동적해지 (금리 스프레드) — 시나리오 경로 배관 추가

N 시나리오 집계 (동적해지의 TVOG) — 커널 밖 집계, scenario-conditioned 재사용

별도

한 줄 요약: 동적해지율은 “정적 격자 → 루프 내 배수표 룩업” 으로 해지 한 항목만 내생화하는 작업이고, VFA 경로 (계좌가치 moneyness) 부터 붙이는 것이 가장 자연스럽고 싸다.

인접 레시피#