There's an extract from the code where I've got a macro MonteCarlo which runs MC simulations for a specified k, and a macro Back_testing which calls the macro MonteCarlo in a cycle for 250 times.
With the last part of MonteCarlo being commented (proc univariate, data-step and proc append) the code runs successfully. But when I'm trying to run it as whole the process never stops (Task Status Box says that proc sql / proc iml is running), although the messages in the log indicate that all the iterations were completed successfully (no errors, no warnings), even %put statement (the last one in the code) was executed. The code has no command to be back to the macro MonteCarlo. Why does it go? And why does it stop here?..
I tried to relpace the procedures commented (proc univariate, data-step and proc append) with the simple data step like data VALUE_AT_RISK; VaR = 1; run;
but it also failed (without this data step the code is executed, but placing it in the code makes execution process never stop).
And the last note: when I run the whole code in smaller cycles (for k = 2 to 100, then for k = 101 to 200 and lastly for k = 201 to 251) everything goes right as well.
I would greatly appreciate it if you could comment on the case.
Thank you in advance,
Here's the extract:
%let _date = %scan(&_dates251,&k,' ');
%let _fut_date = %scan(&_dates251,&k-1,' ');
proc sql noprint;
select count(Currency_Cd) into :_count from POSITION where Day_Dt = &_date;
select '"' || trim(Currency_Cd) || '"' into :_curs separated by ' ' from POSITION where Day_Dt = &_date;
select '"' || trim(Currency_Cd) || '"' into :_curs1 separated by ' ' from POSITION where Day_Dt = &_date and Currency_Cd ne 'USD';
select Currency_Rate format=best12. into :_USD_rate from RATES where Day_Dt = &_date and Currency_Cd = 'USD';
select Currency_Rate format=best12. into :_USD_rate_actual from RATES where Day_Dt = &_fut_date and Currency_Cd = 'USD';
select Position format=best12. into :_USD_position from POSITION where Day_Dt = &_date and Currency_Cd = 'USD';
select sum(Position) into :_port_value from POSITION where Day_Dt = &_date;
%let _unquoted_curs = %sysfunc(compress(&_curs,'"'));
%let _unquoted_curs1 = %sysfunc(compress(&_curs1,'"'));
use LN_RATES1 (firstobs=&k obs=%eval(&k+249) keep=&_unquoted_curs1);
read all into R;
C = corr(R);
H = root(C);
avg = R[:,];
dif = R - repeat(avg,250,1);
ssq = dif[##,];
std = sqrt(ssq/249);
std = T(std);
use POSITION1 (firstobs=&k obs=&k keep=&_unquoted_curs1);
read all into pos;
pos = T(pos);
use RATES_USD_BASED1 (firstobs=&k obs=&k keep=&_unquoted_curs1);
read all into rates;
rates = T(rates);
posNom = pos/(rates#&_USD_rate);
portLoss = J(&_num_scenarios,1,1);
do j=1 to &_num_scenarios;
y = normal(repeat(0,&_count-1,1));
z = T(H)*y;
futRates = rates#exp(std#z#sqrt(10));
futUSDRate = (&_h_USD_edge - &_l_USD_edge) * ranuni(0) + &_l_USD_edge;
futPortValue = futUSDRate#(sum(posNom#futRates)+&_USD_position/&_USD_rate);
portLoss = futPortValue - &_port_value;
create SCENARIOS from portLoss [colname = 'Portfolio_Loss'];
append from portLoss;
use RATES_USD_BASED1 (firstobs=%eval(&k-1) obs=%eval(&k-1) keep=&_unquoted_curs1);
read all into futRatesAct;
futRatesAct = T(futRatesAct);
futPortValueAct = &_USD_rate_actual#(sum(posNom#futRatesAct)+&_USD_position/&_USD_rate);
portLossAct = futPortValueAct - &_port_value;
create ACTUAL_PORT_LOSS from portLossAct [colname = 'Actual_Portfolio_Loss'];
append from portLossAct;
/*proc univariate data = SCENARIOS noprint;
output out = VALUE_AT_RISK p1 = VaR;
merge VALUE_AT_RISK ACTUAL_PORT_LOSS;
proc append base = BCKTST_RES data = bt; run;*/
At a very quick glance I would say that your problem is that you don't have a QUIT; statement terminating your PROC SQL. This is something I have fallen foul of on several occasions and a quick scan of your code couldn't find a quit.
I can't comment on the PROC IML but this could be something similar, or the PROC is running inside the PROC SQL.
Indeed, I've got the same general idea of the case: some of the steps within the macro don't exit properly. This might be the reason why execution process somehow goes back to them.
So I put QUIT statement into PROC SQL, and also closed all the data sets within PROC IML explicitly. The code runs successfully when only PROC SQL and PROC IML are included in the macro. However, it still fails to finish executing when I try to add, for instance, PROC UNIVARIATE. I put QUIT statement into PROC UNIVARIATE also. But it doesn't help.
Could somebody give any suggestions of the ways to terminate those procedures (SQL, IML, UNIVARIATE, APPEND) and data-step explicitly? I tried some, but it's still in question, unfortunately...
Any other ideas would be also appreciated. Thank you for the attention