BookmarkSubscribeRSS Feed
crikriek
Calcite | Level 5

Hi everyone,

I'm facing an  issue when doing an itrative sum using factorials. This is the first time I use both an iterative sum and the FACT function so I guess there are a  lot of things wrong in my code.

Want I want is the formula I hereby attached.

Here it its:

data lsv.right;

set lsv.left;

do i=0 to i=(buy+sell);

right = ((fact(buy+sell)/ (fact(i)+fact(Buy+sell-i)))*(i/(buy+sell))*((1-Pt)**(Buy+sell-i))*abs((i/(buy+sell)-Pt)))+ right;

end;

run;

Here is a sample of data I have. BUy and sell are integers.

BuySellPtRight
342,7865
8106,78783

Could you please help me with it ?

Thank you


formula.PNG
24 REPLIES 24
RW9
Diamond | Level 26 RW9
Diamond | Level 26

Hi,

So what is the problem with it, is it giving an Error/Warning or not giving you the result you expect.  If you are not getting the result you expect then break the formula down into parts, e.g.:

data ...;

     temp1=fact(buy+sell);

     temp2=temp1 /....

If it is error/warning then post the log.

crikriek
Calcite | Level 5

Here is the log error message

NOTE: Invalid argument to function FACT at line 36 column 11.

NOTE: Invalid argument to function FACT at line 36 column 36.

NOTE: Invalid argument to function FACT at line 36 column 11.

NOTE: Invalid argument to function FACT at line 36 column 36.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Well, I would first check that all your variables are numeric (I suspect this is your problem).  Buy, sell and pt.  If not then you are passing a character to a function which is requiring a numeric.  I would also re-iterate to break the formula up so you have a bit more clarity of what is going on (this works for me), like:

data have;
  attrib Buy Sell Pt format=best.;
  buy=3; sell=4; pt=27865; output; 
  buy=8; sell=10; pt=678783; output;
run;

data want;
  set have;
  bs=buy + sell;
  right=0;
  do i=0 to bs;
    calc1=(fact(bs) / (fact(i) + fact(bs-i)));
    calc2=calc1 * (i/(bs)) * ((1-Pt)**(bs-i)) * abs((i/(bs)-Pt));
    right=calc2 + right;
  end;
run;

SteveDenham
Jade | Level 19

Wild guess, that 'buy' and/or 'sell' are character variables in dataset lsv.left as mentioned by , judging by the location in the line for these NOTEs.. 

You may wish to consider reparameterizing and using LFACT (log of the factorial) in order to avoid a noncomputable result for moderately large arguments.

Steve Denham

crikriek
Calcite | Level 5

I used your code and I made sure that I treat with numeric variables. I create a num variable n that is the sum of buy and sell. But it still shows the same log error

Proc SQL;

  alter table lsv.left

  add n num label='n';

  Proc SQL;

  update lsv.left

  set n=buy+sell;

  data  lsv.right;

  set lsv.left;

  right=0;

  do i=0 to i=n;

    calc1=(fact(n) / (fact(i) * fact(n-i)));

    calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));

    right=calc2 + right;

  end;

run;

RW9
Diamond | Level 26 RW9
Diamond | Level 26

In your code you have:

do I=0 to I=n;

This is incorrect, you want a range, so I=0 to n;

crikriek
Calcite | Level 5

Thank you, I corrected it and nows the log error message becomes

Invalid DO loop control information, either the INITIAL or TO expression is missing or the

       BY expression is missing, zero, or invalid.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Check what N in lsv.left as it sound like that is not being create properly.   So do this:

Run the first SQL statement, check the lsv.left.  Does this look correct.

Run the second SQL statement, check the lsv.left table looks correct.

crikriek
Calcite | Level 5

I did it and there actually was a problem. The fact is that n was worth '.' when there were a buy or sell =0. So I corrected it this way

Proc SQL;

  update lsv.left

  set n=buy where sell=.;

  Proc SQL;

  Update lsv.left

  set n=sell where buy=.;

But I still have the same error message

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Could you post some test data of lsv.left after the two proc sql statements have run.  I suspect you still have a . or missing in your data i.e. what happens if both buy and sell are missing, then that row should be removed as the procedures cannot work on that data.

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Maybe get rid of the SQL part and just add a clause in your datastep:

data lsv.right;

  set lsv.left;

  right=0;

  if buy ne . or sell ne . then do;

    if buy=. then n=sell;

    else n=buy;

    do i=0 to i=n;

      calc1=(fact(n) / (fact(i) * fact(n-i)));

      calc2=calc1 * (i/(n)) * ((1-Pt)**(n-i)) * abs((i/(n)-Pt));

      right=calc2 + right;

    end;

  end;

run;

crikriek
Calcite | Level 5

Thanks a lot ! YOu were right. One row had both sell and buy equal to .

i deleted it and now it's working, thanks a lot ! Smiley Happy

crikriek
Calcite | Level 5

Unfortunately i'm still facing an issue I can't solve; The value I otain for right is  always >1 and sometimes superhigh. In actual facts this formula always lead to a result <1.

FYI: the input Pt is always around 0,5

Do you have an idea of the problem in the code ?

RW9
Diamond | Level 26 RW9
Diamond | Level 26

Sorry, am a code monkey not a stato, its all greek to me.  Maybe post a question in the stats section.

sas-innovate-2024.png

Join us for SAS Innovate April 16-19 at the Aria in Las Vegas. Bring the team and save big with our group pricing for a limited time only.

Pre-conference courses and tutorials are filling up fast and are always a sellout. Register today to reserve your seat.

 

Register now!

What is Bayesian Analysis?

Learn the difference between classical and Bayesian statistical approaches and see a few PROC examples to perform Bayesian analysis in this video.

Find more tutorials on the SAS Users YouTube channel.

Click image to register for webinarClick image to register for webinar

Classroom Training Available!

Select SAS Training centers are offering in-person courses. View upcoming courses for:

View all other training opportunities.

Discussion stats
  • 24 replies
  • 1921 views
  • 0 likes
  • 4 in conversation