SAS stored process to create auto loss ratio reports
/********************* STORED PROCESS MACRO CODE ***********************/
options nosource nosource2 nomprint nomlogic nomacrogen nosymbolgen notes=0;
/* MACRO */
%macro auto_year_indic;
%local filter_variav;
/* appends the username to the filename */
%let default_lib=comuser;
data _null_;
lib=scan("&outfile",1,".");
if lowcase(lib)="&default_lib"
then call symput("assign",1);
else call symput("assign",0);
name=scan("&outfile",2,".");
newname=compress(lib||"."||"&_metauser"||"_"||name);
call symput("outfile",compress(newname));
run;
%if &assign
%then %do;
libname &default_lib Base "/sasdata/comuser";
%end;
/* tests if the provided outfile is error free */
data &outfile;
run;
/* if no error with specified output file do */
%if &syserr=0
%then %do;
proc sql;
drop table &outfile;
quit;
%lib_actcom;
/* this part handles specifically the creation of the multiple filters */
%let name_filter1=company_code;
%let name_filter2=Driving_Record;
%let name_filter3=RISK_PROVINCE;
%let name_filter4=PRODUCT;
%let name_filter5=Coverage;
%let name_filter6=SS_SYUS_BRANCH;/* exception, #1 */
%let name_filter7=OFFICE_CODE;
%let name_filter8=Territory_RTM;
%let name_filter9=Veh_Class;
%let name_filter10=Risk_Number;
%let name_filter11=Coll_RG;/* exception, #1 */
%let name_filter12=Territory;/* exception, #1 */
%let selec=%str(Pol_Num Transaction_Code);
%let filter_comp=1;
%do i=1 %to 12;
/* name of the filter criteria variable */
%let variav=&&name_filter&i;
%let filter_variav=&variav;
/* exceptions for AUTO */
data _null_;
select ("&variav");
/* SS_SYUS_BRANCH */
when ("SS_SYUS_BRANCH")
do;
call symput("filter_variav","SS_SYUS_BRANCH1");
call symput("actual_var","SS_SYUS_BRANCH1");
end;
/* Coll_RG */
when ("Coll_RG")
do;
call symput("filter_variav","compress(Coll_RG)");
call symput("actual_var","Coll_RG");
end;
/* Territory */
when ("Territory")
do;
call symput("filter_variav","compress(Territory)");
call symput("actual_var","Territory");
end;
otherwise
do;
call symput("filter_variav","&variav");
call symput("actual_var","&variav");
end;
end;
run;
%if &&&variav.0=
%then %do;
%let &variav.0=1;
%let &variav.1=&&&variav;
%end;
%if &&&variav.0>0
%then %do;
%let filter="&&&variav.1";
%let selec=%str(&selec &actual_var);
/*%put ### i=&i variav=&variav actual_var=&actual_var;*/
%end;
%else %let filter="";
%do j=2 %to &&&variav.0;
%let filter=%str(&filter,"&&&variav&j");
%end;
%if &filter ne ""
%then %let filter_comp=%str(&filter_comp and &filter_variav in (&filter));
/* prints the filter step by step */
/*%put ### i=&i &filter_comp;*/
%end;
/* handles the policy number filter, if any */
%if &Pol_Num ne all
%then %let filter_comp=%str(&filter_comp and Pol_Num="&Pol_Num");
%put ### Filter=&filter_comp;
proc contents data=actcom.PREMIUM_AUTO out=contents(keep=name) noprint;
run;
/**********************************************************/
/**********************************************************/
/**********************************************************/
/**********************************************************/
%if %symexist(pick_var0)
%then %do;
%if &pick_var0=
%then %if "&pick_var" ne ""
%then %let pick_var0=1;
%else %let pick_var0=0;
%end;
%else %if "&pick_var" ne ""
%then %let pick_var0=1;
%else %let pick_var0=0;
%if &pick_var0=1
%then %let pick_var1=&pick_var;
%put ### pick_var0=&pick_var0;
%put ### pick_var1=&pick_var1;
/* THIS PART INCLUDES THE VARIABLES PICKED SECONDLY */
%if %symexist(sec_pick_var0)
%then %do;
%if &sec_pick_var0=
%then %if "&sec_pick_var" ne ""
%then %let sec_pick_var0=1;
%else %let sec_pick_var0=0;
%end;
%else %if "&sec_pick_var" ne ""
%then %let sec_pick_var0=1;
%else %let sec_pick_var0=0;
%if &sec_pick_var0=1
%then %let sec_pick_var1=&sec_pick_var;
%put ### sec_pick_var0=&sec_pick_var0;
%put ### sec_pick_var1=&sec_pick_var1;
%do j=1 %to &sec_pick_var0;
%let index=%eval(&pick_var0+&j);
%put ### SECOND VAR LIST j=&j index=&index;
%let pick_var&index=&&sec_pick_var&j;
%put ### j=&j pick_var&index=&&sec_pick_var&j;
%end;
%let pick_var0=%eval(&pick_var0+&sec_pick_var0);
%put ### NEW pick_var0=&pick_var0;
/**********************************************************/
/**********************************************************/
/**********************************************************/
/**********************************************************/
/* this part drops variables that were picked duplicately from the variables picklist */
/* by setting them to 'none' if they're duplicate */
%let group_selec=&pick_var1;
%do i=2 %to &pick_var0;
%let group_selec=%str(&group_selec,&&pick_var&i);
%end;
%put ### Picked variables=&group_selec;
/* creates the variable list to select*/
%do i=1 %to &pick_var0;
data _null_;
text=compress(lowcase("&selec"));
search=index(text,compress(lowcase(" &&pick_var&i ")));
if search ne 0
then call symput("pick_var&i","none");
run;
proc sql noprint;
select count(*)>0 into :exist
from contents
where lowcase("&&pick_var&i") in (select lowcase(name) from contents);
quit;
%if "&&pick_var&i" ne "none" and &exist
%then %let selec=%str(&selec &&pick_var&i);
%end;
%let selec=%str(&selec effective_date transaction_date expiry_date written_exposure written_premium);
proc sql;
drop table contents;
quit;
%put ### selec=&selec;
/* CREATE THE PERIOD PARAMETERS */
data _null_;
start=input("&start",yymmn6.0);
call symput("start_date",start);
end=input("&end",yymmn6.0);
end=intnx('month',end,1)-1;
call symput("end_date",end);
claims_as_of=input("&claims_as_of",yymmn6.0);
call symput("claims_as_of_date",claims_as_of);
format start end claims_as_of ddmmyy10.;
run;
/*CREATES A LABEL ON THE YEAR VARIABLE TO INFORM THE CRITERIA AND
CUT-OFF DATES*/
%let label=%sysfunc(compress(%superq(filter_comp),%str(%")));
%let label=criteria=%sysfunc(substr(&label,7)) start=&start end=&end claims_as_of=&claims_as_of;
%put Label=&label;
/**********************************************************************/
/******************************* PREMIUMS *****************************/
/**********************************************************************/
%put ### RUNNING THE FIRST PREMIUM PART...;
data premium;
retain &selec;
set actcom.PREMIUM_AUTO(keep=&selec Num_Vehicles Veh_Class);
where &filter_comp and max(transaction_date,&start_date)<=min(expiry_date,&end_date) and Transaction_Code not in ("3","7");
if transaction_date ne . and expiry_date ne . and (expiry_date-transaction_date) ne 0
then do;
full_term_wp=written_premium*(expiry_date-effective_date)/(expiry_date-transaction_date);
/* COMPUTE THE NUMBER OF MONTHS THAT FALL ONTO THE SELECTED MONTH RANGE */
begin_mth=max(transaction_date,&start_date);
end_mth=min(expiry_date,&end_date);
n_month=(year(end_mth)-year(begin_mth))*12+month(end_mth)-month(begin_mth)+1;
month=.;
next_month=.;
begin_day=.;
end_day=.;
days=.;
sign=SIGN(written_premium);
/* these vars are placed here just so they show up orderly on the table,*/
/* not needed though */
i=.;
length earned_month $6.;
earned_month="";
earned_exposure=.;
earned_premium=.;
do i=0 to n_month-1;
month=intnx('month',begin_mth,i);
next_month=intnx('month',begin_mth,i+1)-1;
earned_month=put(month,yymmn6.);
/* restrict the calculation to the months that fall onto the set interval */
if &start<=earned_month<=&end
then do;
begin_day=max(month,transaction_date);
end_day=min(next_month,expiry_date);
days=end_day-begin_day+1;
earned_exposure=Num_Vehicles*ROUND(days/365.25*sign,.001);
earned_premium=ROUND(full_term_wp*round(days/(expiry_date-effective_date),.001),.01);
IF -0.001&caploss then &caploss else calculated gross_incurred end as caploss format=12.0,
case when calculated gross_incurred>&caploss then 1 else 0 end as capcount,
sum(p_amt) as paid
from actcom.CLAIM_POLICY_AUTO
where &filter_comp and
&start_date<=CR_LOSS_DATE<=&end_date and
product_major_line="A" and
cr_transaction_date<=intnx('month',&claims_as_of_date,1)-1 and
rectype=1
group by CR_SYUS_COMPANY,LINE,CLAIMSYM,CR_CLAIM_NO,CR_LOSS_DATE,CR_OCCURANCE,
CR_BC0_CLAIMANT,TOU,CR_AUTO_DRIVER_REC_SECA,cr_fire_class,cr_coverage_cd,calculated KOL;
quit;
proc sort data=claims nodupkey;
by CR_SYUS_COMPANY LINE CLAIMSYM CR_CLAIM_NO CR_LOSS_DATE CR_OCCURANCE
CR_BC0_CLAIMANT TOU CR_AUTO_DRIVER_REC_SECA cr_fire_class cr_coverage_cd kol;
run;
proc sql;
create table claims2 as
select Year, &group_selec,
sum(claim_cnt) as claim_cnt,
sum(paid) as paid,
sum(gross_incurred) as gross_incurred,
sum(capcount) as capcount,
sum(caploss) as caploss
from claims
group by Year, &group_selec
order by Year, &group_selec;
quit;
%let group_selec_nocomma=%sysfunc(tranwrd(&group_selec,%str(,),%str( )));
data &outfile(label="&label");
merge premium2 claims2;
by year &group_selec_nocomma;
if paid=. then paid=0;
if claim_cnt=. then claim_cnt=0;
if gross_incurred=. then gross_incurred=0;
if capcount=. then capcount=0;
if caploss=. then caploss=0;
format
written_exposure earned_exposure 12.2
written_premium earned_premium gross_incurred caploss paid 12.0;
run;
/*proc sql;
drop table premium, premium2, premium3, claims, claims2;
quit;*/
%end;
/* User specified an invalid output filename or unaccessible library */
%else %do;
/*proc sql;
drop table &outfile;
quit;*/
%put ### ERROR, INVALID OUTPUT FILE: %trim(&outfile);
%end;
options source source2 notes=1;
%mend;
* %auto_year_indic;
/* VARIABLES to pick and choose */
%let pick_var0=3;
%let pick_var1=RISK_PROVINCE;
%let pick_var2=company_code;
%let pick_var3=product;/*Risk_Number*/
%let pick_var4=coverage;
%let pick_var5=Num_Vehicles;
%let pick_var6=Veh_Class;
%let pick_var=&pick_var1;
/* SECOND LIST OF VARIABLES to pick and choose */
%let sec_pick_var0=0;
%let sec_pick_var1=Pol_Num;
%let sec_pick_var2=product;
%let sec_pick_var=&pick_var1;
/* 1. company_number */
%let company_code0=1;
%let company_code1=04;
%let company_code2=10;
%let company_code=&company_code1;
/* 2. clear record */
%let Driving_Record0=0;
%let Driving_Record1=9;
%let Driving_Record2=5;
%let Driving_Record=&Driving_Record1;
/* 3. risk_province */
%let risk_province0=1;
%let risk_province1=ON;
%let risk_province2=AB;
%let risk_province=&risk_province1;
/* 4. Product */
%let PRODUCT0=1;
%let PRODUCT1=PERS AUTO; /* COMM VEH*/
%let PRODUCT2=FLEET COMM;
%let PRODUCT=&PRODUCT1;
/* 5. product, AUTO NAO TEM */
%let Coverage0=0;
%let Coverage1=AB;
%let Coverage2=TPL;
%let Coverage=&Coverage1;
/* 6. branch */
%let SS_SYUS_BRANCH0=0;
%let SS_SYUS_BRANCH1=17;
%let SS_SYUS_BRANCH2=01;
%let SS_SYUS_BRANCH=&SS_SYUS_BRANCH1;
/* 7. office code */
%let OFFICE_CODE0=0;
%let OFFICE_CODE1=12U;
%let OFFICE_CODE2=12L;
%let OFFICE_CODE=&OFFICE_CODE1;
/* 8. vehicle territory */
%let Territory_RTM0=0;
%let Territory_RTM1=3;
%let Territory_RTM2=1;
%let Territory_RTM=&Territory_RTM1;
/* 9. Class of use */
%let Veh_Class0=17;
%let Veh_Class1=01;
%let Veh_Class2=02;
%let Veh_Class3=03;
%let Veh_Class4=05;
%let Veh_Class5=06;
%let Veh_Class6=07;
%let Veh_Class7=08;
%let Veh_Class8=09;
%let Veh_Class9=10;
%let Veh_Class10=11;
%let Veh_Class11=12;
%let Veh_Class12=13;
%let Veh_Class13=18;
%let Veh_Class14=19;
%let Veh_Class15=21;
%let Veh_Class16=22;
%let Veh_Class17=23;
%let Veh_Class=&Veh_Class1;
/* 10. Risk number */
%let Risk_Number0=0;
%let Risk_Number1=001;
%let Risk_Number2=002;
%let Risk_Number=&Risk_Number1;
/* 11. Property industry code, AUTO NAO TEM */
%let Coll_RG0=0;
%let Coll_RG1=11;
%let Coll_RG2=12;
%let Coll_RG=&Coll_RG1;
/* 12. Property industry code, AUTO NAO TEM */
%let Territory0=0;
%let Territory1=0;
%let Territory2=3;
%let Territory=&Territory1;
/* 13. Policy number: 40159797 41021180 */
%let Pol_Num=all;
/* cut-off dates */
%let start=200501;
%let end=200512;
%let caploss=100000;
%let claims_as_of=200912;
/* file name */
%let _METAUSER=jsousa;
%let outfile=work.test;
%auto_year_indic;