28%macro irmst_riskagg_hicopula_run( in_ds_corr_mapping =
29 , in_ds_all_hierarchy_rows=
30 , in_ds_aggregate_config =
33 , hicopula_parsed_alpha =
34 , hicopula_parsed_seed =
35 , hicopula_parsed_ndraws =
44 data &out_libref..aggregate_config;
45 set &in_ds_aggregate_config.;
46 length Correlation_Key 8 COPULA_TYPE $32.;
47 Correlation_Key = input(prxchange(
's/.+"key":(\d+).*/$1/', 1,correlation),8.);
48 COPULA_TYPE = copulaType;
52 %
if(%rsk_getattr(&in_ds_corr_mapping., nobs) > 0) %then %
do;
53 %let corr_map_Flg=TRUE;
56 %
if &corr_map_Flg.=TRUE %then %
do;
57 data &in_ds_corr_mapping.;
58 set &in_ds_corr_mapping.;
63 create table &out_libref..disaggregate_config
66 r.corrMatVar as CORRELATIONMATRIXVARIABLE
68 &in_ds_all_hierarchy_rows. as l
70 &in_ds_corr_mapping. as r
77 data &out_libref..disaggregate_config;
78 set &in_ds_all_hierarchy_rows.;
84 %irm_rest_get_rgf_mrs(host = &rgf_protocol.:
85 , server = &rgf_service.
86 , solution = &rgf_solution.
88 , tgt_ticket = &tgt_ticket.
89 , key = &basecase_scenario.
91 , outds = &out_libref..basecase_scenario_data
92 , outVarTicket = ticket
93 , outSuccess = httpSuccess
94 , outResponseStatus = responseStatus
99 %
if(not &httpSuccess.) %then %
do;
100 %put ERROR: Unable to retrive the basecase scenario;
106 %irm_rest_get_rgf_mrs(host = &rgf_protocol.:
107 , server = &rgf_service.
108 , solution = &rgf_solution.
110 , tgt_ticket = &tgt_ticket.
111 , key = &adverse_scenario.
113 , outds = &out_libref..adverse_scenario_data
114 , outVarTicket = ticket
115 , outSuccess = httpSuccess
116 , outResponseStatus = responseStatus
121 %
if(not &httpSuccess.) %then %
do;
122 %put ERROR: Unable to retrive the adverse scenario;
127 select min(mrsShortName), min(periodType), forecastTime, count(forecastTime) into :basecase_scenario_name, :basecase_period_type, :basecase_ft_list separated by
" ", :cnt_basecase_ft_list
128 from &out_libref..basecase_scenario_data;
129 select min(mrsShortName), min(periodType), forecastTime, count(forecastTime) into :adverse_scenario_name, :adverse_period_type, :adverse_ft_list separated by
" ", :cnt_adverse_ft_list
130 from &out_libref..adverse_scenario_data;
133 %
if &cnt_basecase_ft_list. NE &cnt_adverse_ft_list. %then %
do;
134 %put ERROR: The number of forecastTime in the Basecase scenario does not match the number of forecastTime in the Adverse scenario.;
139 %
do i_basecase_ft=1 %to &cnt_basecase_ft_list.;
140 %let basecase_element=%scan(&basecase_ft_list.,&i_basecase_ft.,%str( ));
141 %
do i_adverse_ft=1 %to &cnt_adverse_ft_list.;
142 %let adverse_element=%scan(&adverse_ft_list.,&i_adverse_ft.,%str( ));
143 %
if &basecase_element.=&adverse_element. %then %
do;
144 %let check=%eval(&check.+1);
150 %
if &check NE &cnt_basecase_ft_list. %then %
do;
151 %put ERROR: The list of forecastTime in the Basecase scenario does not match the list of forecastTime in the Adverse scenario.;
155 %let hierarchy_levels_space_sep=%sysfunc(prxchange(s/\W+/ /i, -1, %superq(hierarchy_levels)));
156 %let higher_level_var=%scan(&hierarchy_levels_space_sep.,1,%str( ));
157 %let lower_level_var=%scan(&hierarchy_levels_space_sep.,2,%str( ));
159 %let copula_level_cnt=%sysfunc(countw(&hierarchy_levels_space_sep.,
" "));
165 data &out_libref..RISKAGG_HICOPULA_COPULA_ORIG(keep = REPORTING_DT
173 &out_libref..RISKAGG_HICOPULA_COPULA_MAP(keep = &higher_level_var.
176 length REPORTING_DT 8.
184 frankcopula_id_list $500.
185 frankcopula_theta_list $500.
188 set &out_libref..aggregate_config end=last;
189 retain corrid_index 0 corrname_list
"" corrid_list
"" frankcopula_id_cnt 0 frankcopula_id_list
"" frankcopula_theta_list
"";
191 NAME=cats(
"copula",_N_);
192 if upcase(&higher_level_var.)=
"ALL" then
do;
193 &higher_level_var.=
"+";
197 CVALUE=lowcase(COPULA_TYPE);
198 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
199 output &out_libref..RISKAGG_HICOPULA_COPULA_MAP;
200 if Correlation_Key NE . then
do;
201 corrid_index=corrid_index+1;
203 CVALUE=cats(
"corr_mat",corrid_index);
205 corrid_list=catx(
" ",corrid_list,Correlation_Key);
206 corrname_list=catx(
" ",corrname_list,CVALUE);
207 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
209 if THETA NE . then
do;
210 if (lowcase(COPULA_TYPE)=
"clayton" and THETA<=0) then
do;
211 put
"ERROR: You cannot specify THETA<=0 for a Clayton Copula.";
212 call symput(
"httpSuccess", 0);
214 if (lowcase(COPULA_TYPE)=
"gumbel" and THETA<=1) then
do;
215 put
"ERROR: You cannot specify THETA<=1 for a Gumbel Copula.";
216 call symput(
"httpSuccess", 0);
218 if (lowcase(COPULA_TYPE)=
"frank") then
do;
219 frankcopula_id_cnt=frankcopula_id_cnt+1;
220 frankcopula_id_list=catx(
" ",frankcopula_id_list,NAME);
221 frankcopula_theta_list=catx(
" ",frankcopula_theta_list,THETA);
226 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
228 if degreesFreedom NE . then
do;
229 if (lowcase(COPULA_TYPE)=
"t" and degreesFreedom<=0) then
do;
230 put
"ERROR: You cannot specify DF<=0 for a Student T Copula.";
231 call symput(
"httpSuccess", 0);
234 NVALUE=degreesFreedom;
236 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
239 call symputx(
"corr_id_list",corrid_list,
"L");
240 call symputx(
"corr_id_list_cnt",corrid_index,
"L");
241 call symputx(
"corrn_name_list",corrname_list,
"L");
242 call symputx(
"frank_copula_id_cnt",frankcopula_id_cnt,
"L");
243 call symputx(
"frank_copula_id_list",frankcopula_id_list,
"L");
244 call symputx(
"frank_copula_theta_list",frankcopula_theta_list,
"L");
253 %
if(not &httpSuccess.) %then %
do;
257 data &out_libref..RISKAGG_HICOPULA_COPULA;
258 format REPORTING_DT yymmdd10.;
259 set &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
260 REPORTING_DT=input(
"&base_dt.",yymmdd10.);
261 %
do i_adverse_ft=1 %to &cnt_adverse_ft_list.;
262 %let adverse_element=%scan(&adverse_ft_list.,&i_adverse_ft.,%str( ));
263 SCENARIO_ID=catx(
"_",
"&adverse_scenario_name.",
"FT&adverse_element.");
266 %
do i_basecase_ft=1 %to &cnt_basecase_ft_list.;
267 %let basecase_element=%scan(&basecase_ft_list.,&i_basecase_ft.,%str( ));
268 SCENARIO_ID=catx(
"_",
"&basecase_scenario_name.",
"FT&basecase_element.");
275 %
do i_corr_id_list=1 %to &corr_id_list_cnt.;
276 %let corr_mat_key = %scan(&corr_id_list.,&i_corr_id_list.,%str( ));
277 %let httpSuccess = 0;
278 %let responseStatus = ;
279 %irm_rgf_retrieve_analysis_data(key = &corr_mat_key.
280 , libref = &out_libref.
281 , outds = &out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_UNSTRCTD
282 , host = &rgf_protocol.:
283 , server = &rgf_service.
286 , outSuccess = httpSuccess
287 , outResponseStatus = responseStatus
292 %
if(not &httpSuccess.) %then %
do;
293 %put ERROR: Unable to retrive the correlation matrix associated with key &corr_mat_key.;
297 %irmst_riskagg_corr_mat_check(ds_in_corr_mat=&out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_UNSTRCTD);
301 %irmc_riskagg_corr_mat_parser( ds_in_corr_matrix =&out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_UNSTRCTD
302 , working_libname =&out_libref.
303 , ds_out_matrix =&out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_ORIG
306 data &out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ));
307 set &out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_ORIG;
308 if SCENARIO_ID="Adverse" then do;
309 %do i_adverse_ft=1 %to &cnt_adverse_ft_list.;
310 %let adverse_element=%scan(&adverse_ft_list.,&i_adverse_ft.,%str( ));
311 SCENARIO_ID=catx("_","&adverse_scenario_name.","FT&adverse_element.");
315 if SCENARIO_ID="Basecase" then do;
316 %do i_basecase_ft=1 %to &cnt_basecase_ft_list.;
317 %let basecase_element=%scan(&basecase_ft_list.,&i_basecase_ft.,%str( ));
318 SCENARIO_ID=catx("_","&basecase_scenario_name.","FT&basecase_element.");
325 proc sort data=&out_libref..DISAGGREGATE_CONFIG(where=(CorrMap="true")) out=&out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
326 by &higher_level_var. &lower_level_var.;
329 data &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG(keep = REPORTING_DT
340 &out_libref..MARGINAL_MAP_RAW(keep = MARGINAL
343 length REPORTING_DT 8.
346 &higher_level_var. $32.
347 %if &copula_level_cnt.=2 %then %do;
348 &lower_level_var. $32.
358 set &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
360 declare hash h(dataset:"&out_libref..RISKAGG_HICOPULA_COPULA_MAP(rename=(&higher_level_var.=LOOKUP_KEY))");
361 h.defineKey("lookup_key");
362 h.defineData("NAME");
368 retain group_index 1;
369 retain margina_index 1;
370 if upcase(&higher_level_var.)="ALL" then do;
371 put "ERROR: You cannot specify the 'All' option for the primary variable of aggregation &higher_level_var.";
372 call symput("httpSuccess", 0);
374 %if &copula_level_cnt.=2 %then %do;
375 if upcase(&lower_level_var.)="ALL" then do;
376 &lower_level_var.="+";
380 if upcase(&lower_level_var.) NE "ALL" then do;
381 MARGINAL=cats("marginal",margina_index);
382 margina_index=margina_index+1;
385 if &lower_level_var.="+" then do;
391 group_index=group_index+1;
394 lookup_key=&higher_level_var.;
397 GROUP=cats("group",group_index);
401 %if &copula_level_cnt.=1 %then %do;
402 MARGINAL=cats("marginal",margina_index);
403 margina_index=margina_index+1;
407 GROUP=cats("group",group_index);
410 if CORRELATIONMATRIXVARIABLE="" then do;
411 %if &copula_level_cnt.=2 %then %do;
412 REFNAME=catx("_",substr(&higher_level_var.,1,10),substr(&lower_level_var.,1,10));
415 REFNAME=&higher_level_var.;
419 REFNAME=CORRELATIONMATRIXVARIABLE;
421 output &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
422 if MARGINAL NE "nosrc" then do;
423 output &out_libref..MARGINAL_MAP_RAW;
427 %if(not &httpSuccess.) %then %do;
436 %do i_frank_copula_id_list=1 %to &frank_copula_id_cnt.;
438 select count(*) into :copula_frank_dimension
439 from &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG(where=(COPULA="%scan(&frank_copula_id_list.,&i_frank_copula_id_list.,%str( ))"));
441 %if &copula_frank_dimension.=2 and %scan(&frank_copula_theta_list.,&i_frank_copula_id_list.,%str( ))=0 %then %do;
442 %put ERROR: You cannot specify a 2-component Frank Copula with THETA=0;
445 %if &copula_frank_dimension.>2 and %scan(&frank_copula_theta_list.,&i_frank_copula_id_list.,%str( ))<=0 %then %do;
446 %put ERROR: You cannot specify a Frank Copula on 3 components or more with THETA<=0;
451 data &out_libref..RISKAGG_HICOPULA_CONFIG;
452 format REPORTING_DT yymmdd10.;
453 set &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
454 REPORTING_DT=input("&base_dt.",yymmdd10.);
455 %do i_adverse_ft=1 %to &cnt_adverse_ft_list.;
456 %let adverse_element=%scan(&adverse_ft_list.,&i_adverse_ft.,%str( ));
457 SCENARIO_ID=catx("_","&adverse_scenario_name.","FT&adverse_element.");
460 %do i_basecase_ft=1 %to &cnt_basecase_ft_list.;
461 %let basecase_element=%scan(&basecase_ft_list.,&i_basecase_ft.,%str( ));
462 SCENARIO_ID=catx("_","&basecase_scenario_name.","FT&basecase_element.");
467 data &out_libref..MARGINAL_MAP;
468 length ldsummidindex_list $500.
471 set &out_libref..MARGINAL_MAP_RAW(rename=(MARGINAL=NAME)) end=last;
472 retain ldsummid_index 0 ldsummidindex_list ldsummid_list "";
473 ldsummid_index=ldsummid_index+1;
474 ldsummidindex_list=catx(" ",ldsummidindex_list,ldsummid_index);
475 ldsummid_list=catx(" ",ldsummid_list,LDSUMMARY);
477 call symputx("ldsumm_id_cnt",ldsummid_index,"L");
478 call symputx("ldsumm_id_index_list",ldsummidindex_list,"L");
479 call symputx("ldsumm_id_list",ldsummid_list,"L");
484 %do i_ldsumm_id_list=1 %to &ldsumm_id_cnt.;
485 %let ld_summ_key = %scan(&ldsumm_id_list.,&i_ldsumm_id_list.,%str( ));
486 %let httpSuccess = 0;
487 %let responseStatus = ;
488 %irm_rgf_retrieve_analysis_data(key = &ld_summ_key.
489 , libref = &out_libref.
490 , outds = &out_libref..ldsumm&i_ldsumm_id_list.
491 , host = &rgf_protocol.:
492 , server = &rgf_service.
495 , outSuccess = httpSuccess
496 , outResponseStatus = responseStatus
500 %if(not &httpSuccess.) %then %do;
501 %put ERROR: Unable to retrieve the loss distribution associated with key &ld_summ_key..;
506 set &out_libref..ldsumm&i_ldsumm_id_list.;
507 if VALUEATRISK_ALPHA=. then do;
508 put "ERROR: VALUEATRISK_ALPHA cannot be missing in the loss distribution associated with key &ld_summ_key.";
509 call symput("httpSuccess", 0);
511 if VALUEATRISK=. then do;
512 put "ERROR: VALUEATRISK cannot be missing in the loss distribution associated with key &ld_summ_key.";
513 call symput("httpSuccess", 0);
515 if EXPECTEDLOSS=. then do;
516 put "ERROR: EXPECTEDLOSS cannot be missing in the loss distribution associated with key &ld_summ_key.";
517 call symput("httpSuccess", 0);
521 %if(not &httpSuccess.) %then %do;
527 data &out_libref..ldsumm&i_ldsumm_id_list.;
528 set &out_libref..ldsumm&i_ldsumm_id_list.;
530 when (find(scenario_id, catx("_","&basecase_scenario_name.","FT"), 1)>0) do;
531 p=find(scenario_id, catx("_","&basecase_scenario_name.","FT"), 1);
532 scenario_id=substr(scenario_id,p);
534 when (find(scenario_id, catx("_","&adverse_scenario_name.","FT"), 1)>0) do;
535 p=find(scenario_id, catx("_","&adverse_scenario_name.","FT"), 1);
536 scenario_id=substr(scenario_id,p);
545 data &out_libref..RISKAGG_HICOPULA_MARGINAL;
546 length REPORTING_DT 8.
554 %do i_ldsumm_id_list=1 %to &ldsumm_id_cnt.;
555 set &out_libref..ldsumm&i_ldsumm_id_list.;
556 ldsummid_index=&i_ldsumm_id_list.;
565 if (ValueAtRisk_Alpha>0.5 and (ValueAtRisk_Alpha-0.5)<&delta.) then sd=.;
566 else if (ValueAtRisk_Alpha<0.5 and (0.5-ValueAtRisk_Alpha)<&delta.) then sd=.;
567 else if (ValueAtRisk_Alpha=0.5) then sd=.;
568 else SD=(VALUEATRISK-EXPECTEDLOSS)/quantile('normal', ValueAtRisk_Alpha , 0, 1);
569 if (SD=. or SD<=0) then do;
570 put "ERROR: The provided ValueAtRisk and Expectedloss are not compatible with the assumption that the loss distribution is Normal.";
571 put "ERROR: The implied standard deviation is negative.";
572 call symput("httpSuccess", 0);
594 %if(not &httpSuccess.) %then %do;
598 data &out_libref..RISKAGG_HICOPULA_MARGINAL;
599 set &out_libref..RISKAGG_HICOPULA_MARGINAL;
601 declare hash h(dataset:"&out_libref..MARGINAL_MAP");
602 h.defineKey("ldsummid_index");
603 h.defineData("NAME");
618 %do i_corr_id_list=1 %to &corr_id_list_cnt.;
619 %let corr_tables=&corr_tables. &out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ));
623 %irmst_riskagg_hicopula( ds_in_configuration_table = &out_libref..RISKAGG_HICOPULA_CONFIG
624 , ds_in_copula_table = &out_libref..RISKAGG_HICOPULA_COPULA
625 , ds_in_marginal_table = &out_libref..RISKAGG_HICOPULA_MARGINAL
626 , ds_in_corr_tables = &corr_tables.
627 , working_libname = &out_libref.
628 , in_alpha = &hicopula_parsed_alpha.
629 , in_seed = &hicopula_parsed_seed.
630 , in_ndraws = &hicopula_parsed_ndraws.
631 , high_agg_level_var = &higher_level_var.
632 , low_agg_level_var = &lower_level_var.
633 , ds_out_risk_analysis_table = &out_libref..RISKAGG_SUMMARY_RESULTS
638 %let httpSuccess = 0;
639 %let responseStatus =;
640 %irm_rest_get_rgf_cycle(key = &cycle_key.
641 , host = &rgf_protocol:
643 , tgt_ticket = &tgt_ticket.
645 , outVarTicket = ticket
646 , outSuccess = httpSuccess
647 , outResponseStatus = responseStatus
649 %if(not &httpSuccess.) %then %do;
650 %put ERROR: Unable to retrieve information about the cycle associated with key &ld_summ_key..;
656 call symputx("cycle_baseDt", baseDt, "L");
657 call symputx("cycle_entityId", entityId, "L");
660 data &out_ds_results.;
661 length scenario_type $32;
662 set &out_libref..RISKAGG_SUMMARY_RESULTS;
663 %do i_adverse_ft=1 %to &cnt_adverse_ft_list.;
664 %let adverse_element=%scan(&adverse_ft_list.,&i_adverse_ft.,%str( ));
665 if SCENARIO_ID=catx("_",strip("&adverse_scenario_name."),"FT&adverse_element.") then
667 SCENARIO_NAME=strip("&adverse_scenario_name.");
668 SCENARIO_TYPE='Adverse';
669 FORECAST_PERIOD="&adverse_period_type.";
670 FORECAST_TIME=&adverse_element.;
673 %do i_basecase_ft=1 %to &cnt_basecase_ft_list.;
674 %let basecase_element=%scan(&basecase_ft_list.,&i_basecase_ft.,%str( ));
675 if SCENARIO_ID=catx("_",strip("&basecase_scenario_name."),"FT&basecase_element.") then
677 SCENARIO_NAME=strip("&basecase_scenario_name.");
678 SCENARIO_TYPE='Basecase';
679 FORECAST_PERIOD="&basecase_period_type.";
680 FORECAST_TIME=&basecase_element.;