Taking this mostly out of macros and into arrays which are much more efficient.
%macro cashflow_macro(index=,aa_1=,aa_2=,aa_3=,aa_4=,);
*create variable with index - 1 for other variables;
%let index1 = %eval(&index - 1);
*declare arrays;
array _aa (*) aa_1-aa_&index (
%do i=1 %to &index;
&&&aa_&i.
%end;
);
array _bb(*) bb_1 - bb_&index1;
array _cc(*) cc_1 - cc_&index1;
*calculations;
do i=1 to &index1;
_bb(i) = _aa(i) - _aa(i+1);
_cc(i) = max(_bb(i), 0);
end;
%mend;
data ccc;
%cashflow_macro(index=4,aa_1=400,aa_2=300,aa_3=250,aa_4=270);
run;
And a possibly more simplified version:
%macro cashflow_macro_revised(series=);
*create variable with index - 1 for other variables;
%let index = %sysfunc(countw(&series));
%let index1 = %eval(&index - 1);
*declare arrays;
array _aa (*) aa_1-aa_&index (&series);
array _bb(*) bb_1 - bb_&index1;
array _cc(*) cc_1 - cc_&index1;
*calculations;
do i=1 to &index1;
_bb(i) = _aa(i) - _aa(i+1);
_cc(i) = max(_bb(i), 0);
end;
%mend;
data ccc;
%cashflow_macro_revised(series=400 300 250 270);
run;
If you really want to stick with macros this will work but does generate some warnings. I don't have time to debug beyond this but it seems to work.
%macro cashflow_macro(index=4,aa_1=,aa_2=,aa_3=,aa_4=,);
*create variable with index - 1 for other variables;
%let index1 = %eval(&index - 1);
%do i=1 %to &index1;
%let bb_&i = &&&aa_&i. - &&&aa_%eval(&i+1);
bb_&i = &&&bb_&i.;
cc_&i = max(&&&bb_&i, 0);
%end;
%mend;
data ccc1;
%cashflow_macro(index=4,aa_1=400,aa_2=300,aa_3=250,aa_4=270);
run;