SAS Documentation
SASĀ® Solution for Stress Testing
Reference manual - version 08.2021
Loading...
Searching...
No Matches
irmst_riskagg_hicopula_run.sas
Go to the documentation of this file.
1/*
2 Copyright (C) 2021 SAS Institute Inc. Cary, NC, USA
3*/
4
5/**
6 \file
7\anchor irmst_riskagg_hicopula_run
8
9 \brief It prepares the setup to run the hierarchical copula aggregation.
10
11 \param [in] in_ds_corr_mapping It contains mapping information about the correlation matrices.
12 \param [in] in_ds_all_hierarchy_rows It contains information about the hierarchy structure.
13 \param [in] in_ds_aggregate_config It contains information about the aggregation structure.
14 \param [in] out_ds_results name for the output data set name.
15 \param [in] out_libref When not running a production model, you can point to a temporary folder to debug intermmediate results. Default: work.
16 \param [in] hicopula_parsed_alpha It selects the alpha level of the Value-at-Risk.
17 \param [in] hicopula_parsed_seed It selects the seed for the random gerating process
18 \param [in] hicopula_parsed_ndraws It selects the number of samples used in the COPULA simulating process.
19 \param [in] hierarchy_levels Number of hierarchy levels.
20
21 \ingroup riskAggregation
22
23 \author SAS Institute Inc.
24 \date 2021
25*/
26
27
28%macro irmst_riskagg_hicopula_run( in_ds_corr_mapping =
29 , in_ds_all_hierarchy_rows=
30 , in_ds_aggregate_config =
31 , out_ds_results =
32 , out_libref =work
33 , hicopula_parsed_alpha =
34 , hicopula_parsed_seed =
35 , hicopula_parsed_ndraws =
36 , hierarchy_levels =
37 );
38 %local _scenario_ids_
39 i_scenario_ids
40 _corrtypes_
41 corr_map_Flg
42 ;
43
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;
49 run;
50
51
52 %if(%rsk_getattr(&in_ds_corr_mapping., nobs) > 0) %then %do;
53 %let corr_map_Flg=TRUE;
54 %end;
55
56 %if &corr_map_Flg.=TRUE %then %do;
57 data &in_ds_corr_mapping.;
58 set &in_ds_corr_mapping.;
59 rename key=newKey;
60 run;
61
62 proc sql noprint;
63 create table &out_libref..disaggregate_config
64 as select
65 l.*,
66 r.corrMatVar as CORRELATIONMATRIXVARIABLE
67 from
68 &in_ds_all_hierarchy_rows. as l
69 left join
70 &in_ds_corr_mapping. as r
71 on
72 r.newKey eq l.key
73 ;
74 quit;
75 %end;
76 %else %do;
77 data &out_libref..disaggregate_config;
78 set &in_ds_all_hierarchy_rows.;
79 run;
80 %end;
81
82 /*Retrieve the basecase scenario*/
83 %let ticket =;
84 %irm_rest_get_rgf_mrs(host = &rgf_protocol.://&rgf_host.
85 , server = &rgf_service.
86 , solution = &rgf_solution.
87 , port = &rgf_port.
88 , tgt_ticket = &tgt_ticket.
89 , key = &basecase_scenario.
90 , details_flg = Y
91 , outds = &out_libref..basecase_scenario_data
92 , outVarTicket = ticket
93 , outSuccess = httpSuccess
94 , outResponseStatus = responseStatus
95 , restartLUA = Y
96 , clearCache = Y
97 );
98
99 %if(not &httpSuccess.) %then %do;
100 %put ERROR: Unable to retrive the basecase scenario;
101 %abort cancel;
102 %end;
103
104 /*Retrieve the adverse scenario*/
105 %let ticket =;
106 %irm_rest_get_rgf_mrs(host = &rgf_protocol.://&rgf_host.
107 , server = &rgf_service.
108 , solution = &rgf_solution.
109 , port = &rgf_port.
110 , tgt_ticket = &tgt_ticket.
111 , key = &adverse_scenario.
112 , details_flg = Y
113 , outds = &out_libref..adverse_scenario_data
114 , outVarTicket = ticket
115 , outSuccess = httpSuccess
116 , outResponseStatus = responseStatus
117 , restartLUA = Y
118 , clearCache = Y
119 );
120
121 %if(not &httpSuccess.) %then %do;
122 %put ERROR: Unable to retrive the adverse scenario;
123 %abort cancel;
124 %end;
125
126 proc sql noprint;
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;
131 quit;
132
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.;
135 %abort cancel;
136 %end;
137
138 %let check=0;
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);
145 %*put &=check;
146 %end;
147 %end;
148 %end;
149
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.;
152 %abort cancel;
153 %end;
154
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( ));
158
159 %let copula_level_cnt=%sysfunc(countw(&hierarchy_levels_space_sep.," "));
160
161 /*-------------------------------------------------*/
162 /*-------------------------------------------------*/
163 /*-------------------------------------------------*/
164
165 data &out_libref..RISKAGG_HICOPULA_COPULA_ORIG(keep = REPORTING_DT
166 SCENARIO_ID
167 RISK_MEASURE
168 NAME
169 PARAMETER
170 CVALUE
171 NVALUE
172 )
173 &out_libref..RISKAGG_HICOPULA_COPULA_MAP(keep = &higher_level_var.
174 NAME
175 );
176 length REPORTING_DT 8.
177 SCENARIO_ID $64.
178 RISK_MEASURE $32.
179 NAME $32.
180 PARAMETER $32.
181 CVALUE $32.
182 corrname_list $500.
183 corrid_list $500.
184 frankcopula_id_list $500.
185 frankcopula_theta_list $500.
186 ;
187 /*NVALUE 8.;*/
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 "";
190 RISK_MEASURE="VaR";
191 NAME=cats("copula",_N_);
192 if upcase(&higher_level_var.)="ALL" then do;
193 &higher_level_var.="+";
194 end;
195 PARAMETER="type";
196 NVALUE=.;
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;
202 NVALUE=.;
203 CVALUE=cats("corr_mat",corrid_index);
204 PARAMETER="cov";
205 corrid_list=catx(" ",corrid_list,Correlation_Key);
206 corrname_list=catx(" ",corrname_list,CVALUE);
207 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
208 end;
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);
213 end;
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);
217 end;
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);
222 end;
223 PARAMETER="theta";
224 NVALUE=THETA;
225 CVALUE="";
226 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
227 end;
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);
232 end;
233 PARAMETER="df";
234 NVALUE=degreesFreedom;
235 CVALUE="";
236 output &out_libref..RISKAGG_HICOPULA_COPULA_ORIG;
237 end;
238 if last then do;
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");
245 end;
246 run;
247
248 /*-------------------------------------------------*/
249 /*-------------------------------------------------*/
250 /*-------------------------------------------------*/
251
252
253 %if(not &httpSuccess.) %then %do;
254 %abort cancel;
255 %end;
256
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.");
264 output;
265 %end;
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.");
269 output;
270 %end;
271 run;
272
273
274 /*Retrieve the correlation matrices*/
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.://&rgf_host.
283 , server = &rgf_service.
284 , solution = rmc
285 , port = &rgf_port.
286 , outSuccess = httpSuccess
287 , outResponseStatus = responseStatus
288 , restartLUA = Y
289 , clearCache = Y
290 );
291
292 %if(not &httpSuccess.) %then %do;
293 %put ERROR: Unable to retrive the correlation matrix associated with key &corr_mat_key.;
294 %abort cancel;
295 %end;
296
297 %irmst_riskagg_corr_mat_check(ds_in_corr_mat=&out_libref..%scan(&corrn_name_list.,&i_corr_id_list.,%str( ))_UNSTRCTD);
298
299
300 /*Parse the correlation matrices*/
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
304 );
305
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.");
312 output;
313 %end;
314 end;
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.");
319 output;
320 %end;
321 end;
322 run;
323 %end;
324
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.;
327 run;
328
329 data &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG(keep = REPORTING_DT
330 SCENARIO_ID
331 RISK_MEASURE
332 &higher_level_var.
333 &lower_level_var.
334 COPULA
335 MARGINAL
336 VAR
337 GROUP
338 REFNAME
339 )
340 &out_libref..MARGINAL_MAP_RAW(keep = MARGINAL
341 LDSUMMARY
342 );
343 length REPORTING_DT 8.
344 SCENARIO_ID $64.
345 RISK_MEASURE $32.
346 &higher_level_var. $32.
347 %if &copula_level_cnt.=2 %then %do;
348 &lower_level_var. $32.
349 %end;
350 COPULA $32.
351 MARGINAL $32.
352 VAR $32.
353 GROUP $32.
354 REFNAME $32.
355 NAME $32.
356 LOOKUP_KEY $32.
357 ;
358 set &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
359 if _N_=1 then do;
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");
363 h.defineDone();
364 call missing(NAME);
365 end;
366 RISK_MEASURE="VaR";
367 VAR="PL";
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);
373 end;
374 %if &copula_level_cnt.=2 %then %do;
375 if upcase(&lower_level_var.)="ALL" then do;
376 &lower_level_var.="+";
377 MARGINAL="nosrc";
378 end;
379 else do;
380 if upcase(&lower_level_var.) NE "ALL" then do;
381 MARGINAL=cats("marginal",margina_index);
382 margina_index=margina_index+1;
383 end;
384 end;
385 if &lower_level_var.="+" then do;
386 lookup_key="+";
387 rc=h.find();
388 COPULA=NAME;
389 GROUP="group1";
390 /*notice that are sorted in such a way that everytime &lower_level_var.="+" then the following entries belong to a new group*/
391 group_index=group_index+1;
392 end;
393 else do;
394 lookup_key=&higher_level_var.;
395 rc=h.find();
396 COPULA=NAME;
397 GROUP=cats("group",group_index);
398 end;
399 %end;
400 %else %do;
401 %if &copula_level_cnt.=1 %then %do;
402 MARGINAL=cats("marginal",margina_index);
403 margina_index=margina_index+1;
404 lookup_key="+";
405 rc=h.find();
406 COPULA=NAME;
407 GROUP=cats("group",group_index);
408 %end;
409 %end;
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));
413 %end;
414 %else %do;
415 REFNAME=&higher_level_var.;
416 %end;
417 end;
418 else do;
419 REFNAME=CORRELATIONMATRIXVARIABLE;
420 end;
421 output &out_libref..RISKAGG_HICOPULA_CONFIG_ORIG;
422 if MARGINAL NE "nosrc" then do;
423 output &out_libref..MARGINAL_MAP_RAW;
424 end;
425 run;
426
427 %if(not &httpSuccess.) %then %do;
428 %abort cancel;
429 %end;
430
431 /*Check the restrictions on the THETA parameter of A Frank Copula*/
432 /*Specifically:
433 - if copula_dim=2 then Theta should not be zero
434 - if copula_dim>2 then Theta should be positive*/
435
436 %do i_frank_copula_id_list=1 %to &frank_copula_id_cnt.;
437 proc sql noprint;
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( ))"));
440 quit;
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;
443 %abort cancel;
444 %end;
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;
447 %abort cancel;
448 %end;
449 %end;
450
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.");
458 output;
459 %end;
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.");
463 output;
464 %end;
465 run;
466
467 data &out_libref..MARGINAL_MAP;
468 length ldsummidindex_list $500.
469 ldsummid_list $500.
470 ;
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);
476 if last then do;
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");
480 end;
481 run;
482
483 /*Retrieve the loss distribution tables*/
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.://&rgf_host.
492 , server = &rgf_service.
493 , solution = rmc
494 , port = &rgf_port.
495 , outSuccess = httpSuccess
496 , outResponseStatus = responseStatus
497 , restartLUA = Y
498 , clearCache = Y
499 );
500 %if(not &httpSuccess.) %then %do;
501 %put ERROR: Unable to retrieve the loss distribution associated with key &ld_summ_key..;
502 %abort cancel;
503 %end;
504
505 data _NULL_;
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);
510 end;
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);
514 end;
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);
518 end;
519 run;
520
521 %if(not &httpSuccess.) %then %do;
522 %abort cancel;
523 %end;
524
525
526 /*It removes the BEP name from the scenario_id*/
527 data &out_libref..ldsumm&i_ldsumm_id_list.;
528 set &out_libref..ldsumm&i_ldsumm_id_list.;
529 select;
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);
533 end;
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);
537 end;
538 otherwise;
539 end;
540 run;
541
542 %end;
543
544 %let delta=0.001;
545 data &out_libref..RISKAGG_HICOPULA_MARGINAL;
546 length REPORTING_DT 8.
547 SCENARIO_ID $64.
548 RISK_MEASURE $32.
549 NAME $32.
550 PARAMETER $32.
551 CVALUE $32.
552 NVALUE 8.
553 ;
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.;
557 RISK_MEASURE="VaR";
558 /*
559 sd=(VaR-mu)/(sqrt(2)*qnorm((2*p-1+1)/2)/sqrt(2))
560 which simplifies to
561 sd=(VaR-mu)/qnorm(p)
562 Notice that if p->0.5 then sd-> non definite.
563 For stability reason we can create a neiboorhood around p=0.5 so that this stability issue is preventerd.
564 */
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);
573 end;
574 PARAMETER="type";
575 CVALUE="NORMAL";
576 NVALUE=.;
577 output;
578 PARAMETER="args";
579 CVALUE="";
580 NVALUE=2;
581 output;
582 PARAMETER="parm";
583 CVALUE="";
584 NVALUE=EXPECTEDLOSS;
585 output;
586 PARAMETER="parm";
587 CVALUE="";
588 NVALUE=SD;
589 output;
590 %end;
591 run;
592
593
594 %if(not &httpSuccess.) %then %do;
595 %abort cancel;
596 %end;
597
598 data &out_libref..RISKAGG_HICOPULA_MARGINAL;
599 set &out_libref..RISKAGG_HICOPULA_MARGINAL;
600 if _N_=1 then do;
601 declare hash h(dataset:"&out_libref..MARGINAL_MAP");
602 h.defineKey("ldsummid_index");
603 h.defineData("NAME");
604 h.defineDone();
605 end;
606 rc=h.find();
607 keep REPORTING_DT
608 SCENARIO_ID
609 RISK_MEASURE
610 NAME
611 PARAMETER
612 CVALUE
613 NVALUE
614 ;
615 run;
616
617 %let corr_tables=;
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( ));
620 %end;
621
622 /*Perform the copula aggregation*/
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
634 );
635
636 /*Get information from the cycle*/
637 %let ticket =;
638 %let httpSuccess = 0;
639 %let responseStatus =;
640 %irm_rest_get_rgf_cycle(key = &cycle_key.
641 , host = &rgf_protocol://&rgf_host.
642 , port = &rgf_port.
643 , tgt_ticket = &tgt_ticket.
644 , outds = cycle_info
645 , outVarTicket = ticket
646 , outSuccess = httpSuccess
647 , outResponseStatus = responseStatus
648 );
649 %if(not &httpSuccess.) %then %do;
650 %put ERROR: Unable to retrieve information about the cycle associated with key &ld_summ_key..;
651 %abort cancel;
652 %end;
653
654 data _null_;
655 set cycle_info;
656 call symputx("cycle_baseDt", baseDt, "L");
657 call symputx("cycle_entityId", entityId, "L");
658 run;
659
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
666 do;
667 SCENARIO_NAME=strip("&adverse_scenario_name.");
668 SCENARIO_TYPE='Adverse';
669 FORECAST_PERIOD="&adverse_period_type.";
670 FORECAST_TIME=&adverse_element.;
671 end;
672 %end;
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
676 do;
677 SCENARIO_NAME=strip("&basecase_scenario_name.");
678 SCENARIO_TYPE='Basecase';
679 FORECAST_PERIOD="&basecase_period_type.";
680 FORECAST_TIME=&basecase_element.;
681 end;
682 %end;
683 run;
684
685%mend;