Skip to content

Instantly share code, notes, and snippets.

@boardwalk
Created November 14, 2019 21:13
Show Gist options
  • Save boardwalk/acd41e7185b51d17ed463f91b2d363dd to your computer and use it in GitHub Desktop.
Save boardwalk/acd41e7185b51d17ed463f91b2d363dd to your computer and use it in GitHub Desktop.
# pylint: disable=C0111
import csv
import datetime
import math
from config import *
home_dir = "C:\\Python\\IBNR\\"
#Define CSV inputs from Claim Download and DLR
UNIQUE_ID = 0
ACC_IND = 7
LOSS_AGE = 16
DOD = 17
CLAIM_BP = 18
CLAIM_DUR = 19
EP_ACC = 20
EP_ILL = 21
BENEFIT_AMT = 23
COLA_PCT = 37
TERM_DT = 38
STAT = 45
GAAP = 46
SKIP = 47
def conv_bp(claim_bp, dur_type, dis_dt):
if dur_type == 'D':
return dis_dt + datetime.timedelta(days = int(claim_bp)*30)
else:
return obs_end_dt
def addmonth(dt):
try:
if dt.month == 12:
return datetime.date(dt.year + 1, 1, dt.day)
else:
return datetime.date(dt.year, dt.month + 1, dt.day)
except ValueError:
return datetime.date(dt.year, dt.month + 2, 1) + datetime.timedelta(days=-1)
def begin_pay(acc_type, ep_ill, ep_acc, dis_dt):
if acc_type == 'S':
return dis_dt + datetime.timedelta(days = ep_ill)
else:
return dis_dt + datetime.timedelta(days = ep_acc)
def max_date(obs_dt, term_dt, row, dis_dt):
return min(obs_dt, term_dt, conv_bp(row[CLAIM_BP],row[CLAIM_DUR],dis_dt))
def cola_pmt(cola_rate, duration, benefit):
if cola_rate == 0:
return 0
else:
base_rate = 1 + (float(cola_rate)/100)
compound_rate = base_rate**math.floor(duration)
cola_factor = compound_rate - 1
return cola_factor*float(benefit)
def payment_fraction(curr_ptd, max_ptd):
if addmonth(curr_ptd) > max_ptd:
return (max_ptd - curr_ptd).days/30
else:
return 1
def present_value(payment, paid_dt, obs_dt):
return payment*((1/(1+valrate))**((paid_dt-obs_dt).days/365))
def main(input_path, output_path):
with open(input_path) as fin:
first = True
with open(output_path, 'w') as fout:
out = csv.writer(fout)
for row in csv.reader(fin):
if first:
first = False
out.writerow(["UniqueID", "AggPay", "Stat", "GAAP"])
continue
##Convert dates and set counters for each row
Date_of_disability = datetime.datetime.strptime(row[DOD], '%m/%d/%Y').date()
Paid_to_date = begin_pay(row[ACC_IND],int(row[EP_ILL]),int(row[EP_ACC]),Date_of_disability)
Begin_date = Paid_to_date
try:
Claim_term_date = datetime.datetime.strptime(row[TERM_DT], '%m/%d/%Y').date()
except ValueError:
Claim_term_date = datetime.date.max
Max_pay_date = max_date(obs_end_dt, Claim_term_date, row, Date_of_disability)
Duration = 0
Agg_payment = 0
if Date_of_disability < obs_start_dt or Date_of_disability > obs_end_dt:
continue
while Paid_to_date < Max_pay_date:
Gross_pmt = payment_fraction(Paid_to_date,Max_pay_date)*(float(row[BENEFIT_AMT]) + cola_pmt(row[COLA_PCT],(Duration/12),float(row[BENEFIT_AMT])))
Duration += 1
Paid_to_date = addmonth(Paid_to_date)
PV_pmt = present_value(Gross_pmt, Paid_to_date, obs_start_dt)
Agg_payment += PV_pmt
out.writerow([row[UNIQUE_ID], Agg_payment/trueup_pct, present_value(float(row[STAT])/trueup_pct, obs_end_dt, obs_start_dt), present_value(float(row[GAAP])/trueup_pct, obs_end_dt, obs_start_dt)])
if __name__ == '__main__':
main (home_dir+"IBNRData.csv", home_dir+"Results.csv")
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment