0
votes

I am using a SAS macro to execute a function whereby one of the input parameters is from a SAS data table and the second parameter (date) is hardcoded, like this-

data _null_;
  set RTick.Co_list;
  call execute('%trade_participation(01012013,'|| scrip10 ||');');
run ;

The macro looks as follows-

%macro trade_participation(date,scrip10);

data Trade_data (drop = time Record_ind segment series trade_no symbol trd_prc trd_q trade_time
buy_order_no buy_client_flg buy_algo_ind sell_order_no sell_client_flg sell_algo_ind);
    set Rttrade.Cash_trades_&date;

    if symbol = "&scrip10"; 
    if Record_ind = "RM";
    if segment = "CASH";
    if series = "EQ";
    time = trade_time/65536;
    time = time/3600;
    timeseqno = int((time-9)*60)+1;
    if timeseqno > 15;      
    if (buy_client_flg = 2)&((buy_algo_ind = 0)|(buy_algo_ind = 2)) = 1 then buy_HFT = 1;
    if (sell_client_flg = 2)&((sell_algo_ind = 0)|(sell_algo_ind = 2)) = 1 then sell_HFT = 1;
    trade_val = trd_prc*trd_q/100;
run;

/* more SAS code to do a bunch of other tasks to do on the subsetted 
file Trade_data */

%mend;

The problem I am facing right now is that some of the input values in the Co_list file (scrip10 variable) have special characters, such as 'bbbbbbM&M' or 'BAJAJ-AUTO'. As soon as these pass through the macro, it fails - 'Apparent symbolic reference M not resolved.' (for the first example -bbbbbbM&M')

Can anyone suggest a workaround?

2

2 Answers

1
votes

In your particular case why not just include the actual quotes into the macro parameter value instead of adding them in the macro?

So change the macro definition:

if symbol = &scrip10 ; 

Then in the code generation step add the quotes. Use single quotes and any & or % characters will be ignored by the macro processor.

call execute(cats('%nrstr(%trade_participation)(01012013,',quote(scrip10,"'"),')'));

Wrapping the macro invocation, %trade_participation, inside of the %nrstr() macro function will make your SAS log a lot easier to read. Example:

+     %trade_participation(01012013,'bbbbbbM&M')
+     %trade_participation(01012013,'BAJAJ-AUTO')
0
votes

If you're going to do the macro quoting route, you have to %nrstr twice - as it's "resolved" twice, once when call execute does its thing, and once inside the macro.

data have;
  input @1 callparam $10.;
  datalines;
abcdefghij
a&bc&de&fg
a%bc%de%fg
;;;;
run;

%macro showme(param=);
   data _null_;
    x = "&param";
    put x=;
   run;
%mend showme;

options mprint symbolgen;
data want;
  set have;
  paramstr = cats('%nrstr(',callparam,')');
  callstr = cats('%nrstr(%showme(param=',paramstr,'))');
  call execute(callstr);
run;

This does not work with one special case, though: quotes inside the variable. That has to be resolved by doubling them (' -> '') or a few other options (like %' inside a %quote block).

In general, this isn't a great way to do things. This is the downside to parameters and macro language - it's too easy to get into a mess. Instead, if I were doing this, I might pull the value out of the data inside the macro. That avoids most of these issues. Create a format, maybe. Or use DOSUBL and/or RUN_MACRO both of which would allow you to do this without as many steps. Or do this all in one pass and don't try to split it up for each symbol. There're a bunch of ways to do this sort of thing that avoid the macro language - which tends to be overused - and usually are faster, too!