BookmarkSubscribeRSS Feed
🔒 This topic is solved and locked. Need further help from the community? Please sign in and ask a new question.
AaronAardvaark
Calcite | Level 5

Dear IML Users,

I initially posted this query elsewhere, but realised it should be posted here instead.

I am populating a matrix using the row values of another matrix (this is a part of a bigger programming issue I have and I have tried to simplify the issue down to its basics - I understand that do loops should be avoided in Proc IML, but in this case it is unavoidable)

The issue is that the program works fine as individual statements, but when I insert a do loop, the 'vwap' matrix no longer updates properly - it inserts the number of rows and values from the last iteration and remain unchanged thereafter.  I dont understand this as all the other elements update correctly and their properties are the same, so I cant see why it should fail.

To see what is happening run the code below, I have hard coded the first two iterations and they work fine, vwap updates with the correct number of rows and the right values inserted.  When I used a do loop to control the third execution, the same number of rows and values are inserted from the last iteration.

Any help you could give would be most appreciated as this really has be perplexed.

proc iml;

reset print;

xxx = {10 2 2.91, 10 3 3.05, 10 1 3.07};

volume = xxx[1,2];

price = xxx[1,3];

call symput ('volume', char(volume));

call symput ('price', char(price));

vwap = {[&volume] &price}`;

volume = xxx[2,2];

price = xxx[2,3];

call symput ('volume', char(volume));

call symput ('price', char(price));

vwap = vwap//{[&volume] &price}`;

do i = 3 to 3;

     volume = xxx[i,2];

     price = xxx[i,3];

     call symput ('volume', char(volume));

     call symput ('price', char(price));

     vwap = VWAP//{[&volume] &price}`;

end;

quit;

1 ACCEPTED SOLUTION

Accepted Solutions
Rick_SAS
SAS Super FREQ

This is a good question, and definitely nonobvious until you start to think about it.

The key point to remember that &price is evaluated by the macro preprocessor AT PARSE TIME, not at run time. The SAS/IML code never sees &price at run time, only the constant that was substituted.

You probably already nknew that, but what you might not know is that the SAS/IML language parses the ENTIRE body of the DO loop prior to execution. (This is done for efficiency and to check for syntax errors.) The preprocessor substitutes the current values of the macro variables AT PARSE TIME. When the DO loop executes, the values are constant within the loop.

I would not recommend the approach that you are using. Creating all those macro variables is less efficient than just using the SAS/IML values. However, if you insist upon using macro variables, use the SYMGET function to grab the values of the macros at run time.

PS. That concatenation within the loop is going to kill the performance. See Tip #3 at Eight tips to make your simulation run faster - The DO Loop

View solution in original post

6 REPLIES 6
Rick_SAS
SAS Super FREQ

This is a good question, and definitely nonobvious until you start to think about it.

The key point to remember that &price is evaluated by the macro preprocessor AT PARSE TIME, not at run time. The SAS/IML code never sees &price at run time, only the constant that was substituted.

You probably already nknew that, but what you might not know is that the SAS/IML language parses the ENTIRE body of the DO loop prior to execution. (This is done for efficiency and to check for syntax errors.) The preprocessor substitutes the current values of the macro variables AT PARSE TIME. When the DO loop executes, the values are constant within the loop.

I would not recommend the approach that you are using. Creating all those macro variables is less efficient than just using the SAS/IML values. However, if you insist upon using macro variables, use the SYMGET function to grab the values of the macros at run time.

PS. That concatenation within the loop is going to kill the performance. See Tip #3 at Eight tips to make your simulation run faster - The DO Loop

AaronAardvaark
Calcite | Level 5

Rick,

Thanks so much for your reply.  It is much appreciated (as are your other posts to this forum).

I understand the concerns around this code, but I just cant think of a better way to do it.

What I am trying to calculate is the volume weighted average price of a portfolio of assets.  A person buys and sell shares - column 2 of the xxx matrix is the size of the trade and column 3 is the price (column 1 is a buy sell indicator and at the moment I only have buys (=10) until I get the code right).

The problem with calculating VWAP is when an investor sells that shares as, depending on what assumption you make about which shares are being sold, the vwap of the remaining shares held in the portfolio will be different.  The two standard conventions are last in, first out (LIFO) and first in, first out (FIFO).

My approach to this was to create a vector consisting of a price entry for each share (hence why I am using the repetition factor set equal to volume to stack up a vector of prices).  The average of this vector is the vwap of the holding.  When a sale of shares happens, I can modify this vector by deleting a number of rows equal to the number of shares sold either at the beginning or the end of the vector depending on whether the LIFO or FIFO assumption is employed .  By taking the average of the remaining values in the vector  I will get the vwap of the shares held in the portfolio after the sale.  Then we move on to the next trade.

I hope all this makes sense.  Not the most elegant solution, but I am not sure how else to do it.

Thanks again.

Rick_SAS
SAS Super FREQ

Use the REPEAT function, which eliminates the need for the repitition factor.

AaronAardvaark
Calcite | Level 5

Thanks Rick, all sorted now.

SAS Innovate 2025: Save the Date

 SAS Innovate 2025 is scheduled for May 6-9 in Orlando, FL. Sign up to be first to learn about the agenda and registration!

Save the date!

Multiple Linear Regression in SAS

Learn how to run multiple linear regression models with and without interactions, presented by SAS user Alex Chaplin.

Find more tutorials on the SAS Users YouTube channel.

From The DO Loop
Want more? Visit our blog for more articles like these.
Discussion stats
  • 6 replies
  • 1824 views
  • 3 likes
  • 2 in conversation