SAS Documentation
SASĀ® Solution for Stress Testing
Reference manual - version 08.2021
Loading...
Searching...
No Matches
irmst_model_postcode_simMarket.sas
1/* ************************************************** *
2 * Model Post-Code Template *
3 * ************************************************** *
4
5 Purpose:
6 Injection point for executing custom code after the MIP model execution
7
8 Details:
9 The following SAS macro variables are available to the model at run time:
10 - ticket: SAS authentication service ticket (useful for performing operations that require authentication, i.e. interacting with REST services).
11 - rgf_protocol: Communication protocol (http/https) of the SAS Risk and Governance Framework web application
12 - rgf_host: Hostname of the SAS Risk and Governance Framework web application
13 - rgf_port: Port where the SAS Risk and Governance Framework web application is listening
14 - ds_in_model_result: Name of the input table containing the result of the MIP model execution
15 - ds_out_model_result: Name of the output table to be created by this code
16
17 * ************************************************** */
18
19
20 /*Process the the mip output (SIMSTAT) in order to extract the required information*/
21 /*notice that the collaterals need to be discarded as the they are not used to evaluate the EC.*/
22
23/* ********************************************* */
24/* Upload Data Script: Input Parameters */
25/* ********************************************* */
26
27/* Get the root location of the SAS Risk Workgroup Application */
28%let sas_risk_workgroup_dir = ${globals.sas_risk_workgroup_dir};
29
30/* Cycle Key */
31%let cycle_key = ${context.cycle.key};
32
33/* Analysis Run Key */
34%let analysis_run_key = ${context.analysisRun.key};
35
36
37%let current_dt_ymd = %sysfunc(date(), yymmddd10.);
38%let current_tm_tod = %sysfunc(time(), tod10.);
39
40%let custom_AnalysisName =${params.ANALYSISDATANAME};
41
42/* ********************************************* */
43
44%let ValueAtRisk_Level = ${params.VARLEVEL};
45
46/*Number of days which risk measurement should be rescaled to.*/
47%let rescaleInterval_count = ${params.RESCALEINTERVALCOUNT};
48
49/* Initialize the environment */
50%include "&sas_risk_workgroup_dir./groups/Public/SASRiskManagementCore/cycles/&cycle_key./init.sas" / lrecl = 32000 source2;
51
52/* Get information from the cycle */
53%let ticket =;
54%let httpSuccess = 0;
55%let responseStatus =;
56%irm_rest_get_rgf_cycle(key = &cycle_key.
57 , host = &rgf_protocol://&rgf_host.
58 , port = &rgf_port.
59 , tgt_ticket = &tgt_ticket.
60 , outds = cycle_info
61 , outVarTicket = ticket
62 , outSuccess = httpSuccess
63 , outResponseStatus = responseStatus
64 );
65data _null_;
66 set cycle_info;
67 call symputx("cycle_baseDt", baseDt, "L");
68 call symputx("cycle_entityId", entityId, "L");
69run;
70
71/*Retrieve results for credit risk detail*/
72data &ds_out_model_result.;
73set &ds_in_model_result.(
74 rename=(
75 VaR=ValueAtRisk
76 ContributionVaR=Component_ValueAtRisk
77 Mean=EXPECTEDLOSS
78 Alpha=ValueAtRisk_Alpha
79 ES=ExpectedShortfall
80 ContributionES=Component_ExpectedShortfall
81 _date_=EvalDate
82 ASSET_TYPE=ASSET_TYPE_DESC
83 )
84 );
85 /* Correct naming of simulation parts */
86 if simulationPart eq "P/L" then simulationPart="Profit and Loss";
87 else if simulationPart eq "_ACCINT_" then simulationPart="Accrued Interest";
88 else if simulationPart eq "_DUR_" then simulationPart="Duration";
89 else if simulationPart eq "_YIELD_" then simulationPart="Yield";
90 else if simulationPart eq "_SWAP_DUR_" then simulationPart="Swap Duration";
91 else if simulationPart eq "_VALUE_ORIG_CURRENCY_" then simulationPart="Value";
92 else if simulationPart eq "_DUR_CCY1_LEG_" then simulationPart="CCY 1 Leg Duration";
93 else if simulationPart eq "_DUR_CCY2_LEG_" then simulationPart="CCY 2 Leg Duration";
94 else if simulationPart eq "_DUR_FIX_LEG_" then simulationPart="Fix Leg Duration";
95 else if simulationPart eq "_DUR_FLOAT_LEG_" then simulationPart="Float Leg Duration";
96 /*for market risk, the economic capital is never adjusted for the expected loss.
97 This choice differs from credit risk*/
98 /*notice that if x_i~N(mu,sd^2)
99 then x_1+...x_n~N(n*mu,n*sd^2)
100 this implies that
101 VaR(x_1+...x_n)=n*mu+(VaR(x_i)-mu)*sqrt(n)*/
102 EXPECTEDLOSS =-EXPECTEDLOSS*&rescaleInterval_count.;/*rescale by n. Change the sign because of MIP convention*/
103 ValueAtRisk =EXPECTEDLOSS+(ValueAtRisk-EXPECTEDLOSS/&rescaleInterval_count.)*sqrt(&rescaleInterval_count.);/*VaR(x_1+...x_n)=n*mu+(VaR(x_i)-mu)*sqrt(n)*/
104 Component_ValueAtRisk =EXPECTEDLOSS+(Component_ValueAtRisk-EXPECTEDLOSS/&rescaleInterval_count.)*sqrt(&rescaleInterval_count.);/*VaR(x_1+...x_n)=n*mu+(VaR(x_i)-mu)*sqrt(n)*/
105 Economic_Capital =ValueAtRisk;
106 Component_Economic_Capital =Component_ValueAtRisk;
107 ExpectedShortfall =ExpectedShortfall *&rescaleInterval_count.;
108 Component_ExpectedShortfall =Component_ExpectedShortfall *&rescaleInterval_count.;
109 ValueAtRisk_Alpha=&ValueAtRisk_Level.;
110run;
111
112/*------------------------------------------------------------------------------------*/
113%macro custom_process_bep;
114
115 %let ds_in_bep_x_model = st_stg.bep_x_model;
116 %let ds_in_bep_details = st_stg.bep_details;
117 %let fromRow = 1;
118 %let TotRows = %rsk_attrn(&ds_in_bep_x_model., nobs);
119 %let toRow = &TotRows.;
120 %let TotRuns = &toRow.;
121
122
123 data _null_;
124 /* Subset the records for the current partition */
125 set &ds_in_bep_x_model.(firstobs = &fromRow. obs = &toRow.);
126 /* Set all macro variables */
127 call symputx(cats("bep_key_", put(_N_, 8.)), bepKey, "L");
128 call symputx(cats("planDataCount_", put(_N_, 8.)), planDataCount, "L");
129 call symputx(cats("bep_name_", put(_N_, 8.)), bepName, "L");
130 call symputx(cats("segmentation_vars_", put(_N_, 8.)), segmentationVarList, "L");
131 call symputx(cats("allocation_flg_", put(_N_, 8.)), allocationFlg, "L");
132 call symputx(cats("interval_", put(_N_, 8.)), interval, "L");
133 call symputx(cats("interval_count_", put(_N_, 8.)), intervalCount, "L");
134 call symputx(cats("target_var_", put(_N_, 8.)), targetVariable, "L");
135 call symputx(cats("model_key_", put(_N_, 8.)), modelKey, "L");
136 call symputx(cats("model_run_key_", put(_N_, 8.)), modelRunKey, "L");
137 call symputx(cats("planning_data_key_", put(_N_, 8.)), planningDataKey, "L");
138 call symputx(cats("alloc_scheme_key_", put(_N_, 8.)), allocationSchemekey, "L");
139 call symputx(cats("planDataCount", put(_N_, 8.)), planDataCount, "L");
140 run;
141
142
143 /* Get the TGT Ticket if it was not provided */
144 %if %sysevalf(%superq(tgt_ticket) =, boolean) %then %do;
145 %irm_rest_get_ticket(url = &rgf_protocol.://&rgf_host.:&rgf_port.
146 , username = &_i_run_rm_user_id.
147 , password = &_i_run_rm_user_password.
148 , ticketType = TGT
149 , outVarTicket = tgt_ticket
150 );
151 %end;
152
153 /* Make sure the temporary tables are deleted if they exist */
154 proc datasets library = work nolist nodetails nowarn;
155 delete planning_data_:;
156 quit;
157
158 /* Loop through all records */
159 %do _i_run_ = 1 %to &TotRuns.;
160
161 /* ****************************************** */
162 /* Set parameters for the current iteration */
163 /* ****************************************** */
164 %let segmentation_vars = &&segmentation_vars_&_i_run_..;
165 %let ds_in_bep_expectations = bep_expectations_&_i_run_.;
166 %let ds_in_bep_planning_data = planning_data_&&planning_data_key_&_i_run_..;
167 %let bep_target_var = &&target_var_&_i_run_..;
168
169
170
171
172 %if &&allocation_flg_&_i_run_.. = Y %then %do;
173 /* Subset the BEP details table to retrieve the records related to the current target variable */
174 data bep_expectations_&_i_run_.;
175 set &ds_in_bep_details.(where = (bepKey = &&bep_key_&_i_run_..));
176 keep
177 bepKey bepName
178 targetVarName ActivationHorizon
179 &&segmentation_vars_&_i_run_..
180 interval changeType modelKey
181 absoluteValue relativeValue relativePct
182 ;
183 run;
184
185 /* *************************************** */
186 /* Get Planning Data */
187 /* *************************************** */
188 %if(not %rsk_dsexist(planning_data_&&planning_data_key_&_i_run_..)) %then %do;
189 %let httpSuccess = 0;
190 %let responseStatus =;
191 %irm_rgf_retrieve_analysis_data(key = &&planning_data_key_&_i_run_..
192 , libref = rqsst
193 , outds = planning_data_&&planning_data_key_&_i_run_..
194 , outds_partition_list = partition_list_&_i_run_.
195 , out_type = view
196 , outds_dataInfo = planning_dataInfo_&_i_run_.
197 , outds_dataDef = planning_dataDef_&_i_run_.
198 , host = &rgf_protocol.://&rgf_host.
199 , server = &rgf_service.
200 , solution = &rgf_solution.
201 , port = &rgf_port.
202 , tgt_ticket = &tgt_ticket.
203 , outVarTicket = ticket
204 , outSuccess = httpSuccess
205 , outResponseStatus = responseStatus
206 , restartLUA = Y
207 , clearCache = Y
208 );
209
210 /* Exit in case of errors */
211 %if(not &httpSuccess. or not %rsk_dsexist(planning_data_&&planning_data_key_&_i_run_..)) %then
212 %return;
213
214 %end;
215
216 /* Check if there is a model to run (&&model_run_key_&_i_run_. is a number) */
217 %if(%sysfunc(prxmatch(/^(\d+)$/, &&model_run_key_&_i_run_..))) %then %do;
218
219 /* *************************************** */
220 /* Retrieve the code for the ModelRun */
221 /* *************************************** */
222 %let httpSuccess = 0;
223 %let responseStatus =;
224 %irm_rest_get_rgf_model_run(host = &rgf_protocol.://&rgf_host.
225 , server = &rgf_service.
226 , solution = &rgf_solution.
227 , port = &rgf_port.
228 , tgt_ticket = &tgt_ticket.
229 , key = &&model_run_key_&_i_run_..
230 , outds = model_run_&_i_run_.
231 , outds_params = model_run_params_&_i_run_.
232 , fout_code = fcd_&_i_run_.
233 , outVarTicket = ticket
234 , outSuccess = httpSuccess
235 , outResponseStatus = responseStatus
236 , restartLUA = Y
237 , clearCache = Y
238 );
239
240 /* Exit in case of errors */
241 %if(not &httpSuccess. or not %rsk_dsexist(model_run_&_i_run_.)) %then
242 %return;
243
244 /* **************************** */
245 /* BEP uses Allocation Scheme */
246 /* **************************** */
247
248 /* Compile dummy macro, it should be redefined inside the allocation model code */
249 %macro stm_allocate(gen_type =);
250 %put ERROR: The allocation model associated to the Business Evolution Plan &&bep_name_&_i_run_.. (key: &&bep_key_&_i_run_..) does not implement the macro STM_ALLOCATE;
251 %mend;
252
253 /* Compile the allocation model code */
254 %include fcd_&_i_run_. /source2 lrecl = 32000;
255
256 /*-------------------------------------------*/
257 /*ENABLE THE BEP PROCESSING IN POST EXECUTION*/
258 /*-------------------------------------------*/
259 %let post_run_flag=TRUE;
260
261 /* Run the allocation model */
262 %stm_allocate(gen_type =);
263
264
265
266
267 /*END: Case with allocation */
268 %end;
269 %else %do;
270 %put ERROR: An allocation scheme is needed;
271 %return;
272 %end;
273
274 /*END: %do i = 1 %to &TotRuns.;*/
275 %end;
276
277 /*END: %if market_alloc_model_type=aggregate_level %then %do;*/
278 %end;
279
280%mend;
281%custom_process_bep;