Post Reply 
Cash Flow (IRR, MIRR, NPV)
05-21-2015, 03:49 PM (This post was last modified: 05-27-2015 05:42 PM by salvomic.)
Post: #1
Cash Flow (IRR, MIRR, NPV)
hi all,
here a program to calculate Cash Flow operations with the Prime (IRR, MIRR, NPV).
The program is presented in two version: the first give three routines to calculate (Net Present Value, Internal Rate of Return and Modified Internal Rate of Return, like that in the HP 12C); the second will follow with a "Drawmenu" version with only a command, Cash_Flow that executes the same routines internally.
NPV included is the nice program by Eddie W. Shore (here in the Forum).
I would like to thank who has helped me to do this program: Dale (DRD), Cyrille de Brébisson, Akmon, Didier Lachiese, kharpster, who has transformed the program into "menu-ized" version...)

Warning: both version use list L1 or matrix M1 to store data, so, if you have important data in there, please, first save them otherwhere...
I advice to use the list for series of cash flow with few data to treat or edit {CF0, CF1, CF2, ... CFj...}, and a matrix when there are more data with frequency repeated (i.e [CF0, 1], [CF1, 2], [CF2, 1], [CF3, 8], ...,[CFj],... [CF last, 1]).

You can store data into list (or matrix) first of use the program, or inside the program, editing them.

Enjoy!

Salvo Micciché (salvomic)

Version with commands separately exported
Code:

EXPORT IRR()
// Credits: Cyrille de Brébisson, Akmon, Dale (DrD), salvomic (Salvo Micciché), 
// Eddie W. Shore, Didier Lachiese, kharpster
// Interal Rate of Return. Cash flows in {L1} list or M1 (matrix with frequencies)
// by Salvo Micciché
BEGIN
local ch, irr;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
MSGBOX("IRR() with {list} or [matrix with frequencies]");
RETURN;
END; // case
irr:= solve(ΣLIST(MAKELIST((L1(I)/X^(I-1)),I,1,SIZE(L1))),X)-1;
IF (irr(1)>=1 OR irr(1)<=-1) THEN irr:=tail(irr); END;
// formula by akmon, Cyrille, Dale
PRINT;
PRINT("Internal Rate of Return

IRR = ");
PRINT(EVAL(ROUND(100*irr,4)) + "%");
RETURN irr;
END;

EXPORT MIRR()
// Calc Modified Internal Return Rate
// Salvo Micciché 2015
BEGIN
LOCAL sr, rr, flpos:={}, flneg:={}, sz ;
LOCAL sz1, sz2, npvp, npvn, n ;
LOCAL ch, fvp, ppyr, mirrvalue;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Modified Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
MSGBOX("MIRR() with {list} or [matrix with frequencies]");
KILL;
END; // case

INPUT ({sr, rr, ppyr},"Safe and risk rate", {"sr", "rr", "ppyr"}, 
{"Safe rate CF-", "Risk (reinvestment) Rate CF+", "n Payments for year"}, {0,0, 12},{0,0, 12});
// sr and rr yearly rates (es. 6%, 10%), ppyr number of payments in a year
sz:= SIZE(L1);
sr:=sr/ppyr; rr:=rr/ppyr;
n:=sz-1;
flneg:=MIN(L1,0); flpos:=MAX(L1,0); // one list -> two list, tnx Didier
sz1:= SIZE(flpos); sz2:= SIZE(flneg);
npvp:= NPV(rr, flpos);
npvp:=-npvp;
fvp:=Finance.CalcFV(n,rr*ppyr,npvp,0,ppyr,12,0);
npvn:= NPV(sr, flneg);
// RETURN 100*((fvp/-npvn)^(1/n)-1 );  HP 12C formula (equal to the next)
mirrvalue:= Finance.CalcIPYR(n,npvn,0,fvp,ppyr,12,0)/ppyr;
PRINT;
PRINT ("Modified Internal Rate of Return

Safe rate " + EVAL(ROUND(sr*ppyr,3)) + "% - Risk (reinvestment) rate " + EVAL(ROUND(rr*ppyr,3)) + "% 
with " + STRING(ppyr) + " n. payments per year.

NPV negative flows " + STRING(ROUND(npvn,3)) + "
NPV positve flows " + STRING(ROUND(npvp,3)) + "
FV of posive flows NPV " + STRING(ROUND(fvp,3)) + "
MIRR monthly rate " + STRING(ROUND(mirrvalue,3)) + "%
MIRR yearly   rate " + EVAL(ROUND(mirrvalue*ppyr,3)) + "%"
);
RETURN {mirrvalue, ppyr*mirrvalue}; // return monthly and yearly MIRR
END;

EXPORT NPV(r, flows)
// routine by Eddie W. Shore
 BEGIN
 LOCAL t:=0, k, s;
 r:=1+0.01*r;
 CASE
 // list
 IF TYPE(flows)==6 THEN
 s:=SIZE(flows);
 FOR k FROM 1 TO s DO
 t:=t+flows(k)/(r^(k-1));
 END;
 END;
 // matrix
 IF TYPE(flows)==4 THEN

 LOCAL j, n;
 s:=SIZE(flows);
 k:=0;
 FOR j FROM 1 TO s(1) DO
 FOR n FROM 1 TO flows(j,2) DO
 t:=flows(j,1)/(r^k)+t;
 k:=k+1;
 END; // for
 END; // for 2
 END; // if
 DEFAULT
 MSGBOX("NPV(rate, list) or NPV(rate, [flow, freq])");
 KILL;
 END; // Case
 RETURN t;
 END;

recall_npv()
BEGIN
local ch, r;
INPUT (r, "Rate", "rate%", "Rate for Net Present Value", 0, 10);
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
MSGBOX("IRR() with {list} or [matrix with frequencies]");
KILL;
END; // case
NPV(r, L1);
END;

EXPORT about()
BEGIN
PRINT;
PRINT ("Program created by by Salvo Micciché (salvomic). 
Credits: Cyrille de Brébisson, Akmon, Dale (DrD), Eddie W. Shore, Didier Lachiese, kharpster");
RETURN;
END;

Here Cash_Flows, the version with Drawmenu, every functions inside the program...
This version exports variables in CF_IRR, CF_MIRR, CF_NPV inside Vars->User->Cash_Flow

Code:

export CF_IRR:=0;
export CF_MIRR:={0,0};
export CF_NPV:=0;

// Initialize procedures used in project (by khapster)
EVENTHANDLER();
PUTMENU();
GETMENU();

IRR();
MIRR();
NPV();
recall_npv();
about();

// Initialize variables used globally in project
mSEL;
eTYP;
kP;
m;
m1;

EXPORT Cash_Flow()
BEGIN
// Initialize local variables used within this procedure
 LOCAL mx,my,mTXT,EXITPGM;

 // Set the menu text (this is softcoded and determines if a menu item is valid)
 mTXT := {"NPV","IRR","MIRR","About","","Quit"};

 // MAIN CODE - Loop until ESC is pressed, then exit the program
 EXITPGM := 0;
 WHILE EXITPGM == 0 DO

   // Clear the screen and draw the menu
   RECT_P();
TEXTOUT_P("Cash Flow Utility", 100, 10, 5, RGB(255,0,0));
TEXTOUT_P("NPV Net Present Value", 25, 50);
TEXTOUT_P("IRR Internal Rate of Return", 25, 70);
TEXTOUT_P("MIRR Modified Internal Rate of Return", 25, 90);
TEXTOUT_P("by Salvo Micciché, 2015", 25, 120);
TEXTOUT_P("Credits: Cyrille de Brébisson, Akmon", 25, 150);
TEXTOUT_P("Dale (DrD), Eddie W. Shore", 25, 170);
TEXTOUT_P("Didier Lachiese, kharpster", 25, 190);
   PUTMENU(mTXT);

   // Flush the mouse buffer
   WHILE MOUSE(1) ≥ 0 DO END;

   // Loop until we have a keyboard or mouse event
   REPEAT
     EVENTHANDLER();
   UNTIL eTYP <> "";

    CASE

     // If the event type was a keyboard action then process it
     IF eTYP == "K" THEN
       // If the ESC key was pressed set the program to end
       IF kP == 4 THEN
         EXITPGM := 1;  
       ELSE
         // ESC was not pressed do what you want with the keypress, we are just going to do a TEXTOUT        
       END;        
     END;

     // If the event type was mouse action then process it
     IF eTYP == "M" THEN
       // Convert mouse coordinates to decimal
       mx := B→R(m1(1));  
       my := B→R(m1(2));
       // Determine if mouse coordinates are inside of a valid menu item otherwise return a zero
       GETMENU(mx,my,mTXT);
       // If a valid menu item was selected, do something, we are just going to do a TEXTOUT
       IF mSEL > 0 THEN
         CASE 
          // If menu item 1 was selected display a choose box for the user to select from
           IF mSEL == 1 THEN
             recall_npv();  
           END;
           IF mSEL == 2 THEN
             IRR();
           END;
           IF mSEL == 3 THEN
             MIRR(); 
           END;
           IF mSEL == 4 THEN
       about();
           END;
           IF mSEL == 6 THEN
             EXITPGM := 1;         
           END;
         DEFAULT
           // This is the default action for the menu selection and will only run if no case statement is satisfied

         END;
       ELSE
       // Mouse not in menu, do something if needed
       END;
     END;
   END;  
 END;
END;

// -------------------------------------------------------------------
// Detect keyboard or mouse input (keyboard has priority)
// -------------------------------------------------------------------
EVENTHANDLER()
BEGIN
 eTYP := "";
 kP := GETKEY;
 IF kP <> -1 THEN
   eTYP := "K";
 ELSE
   m := MOUSE;
   m1 := m(1);
   IF  SIZE(m1) > 0 THEN
     eTYP := "M";
   END;
 END;
END;

// ----------------------------------------------
// Draw the menu using the list passed in
// ----------------------------------------------
PUTMENU(mTXT)
BEGIN
 DRAWMENU(mTXT(1),mTXT(2),mTXT(3),mTXT(4),mTXT(5),mTXT(6));
END;

// ------------------------------------------------------------------------------------------
// Get the number of the menu item selected (1-6) by checking mouse position
// Menu items with empty/blank text will return a zero
// ------------------------------------------------------------------------------------------
GETMENU(mx,my,mTXT)
BEGIN
 mSEL := 0;
 IF my≥220 AND my≤239 THEN
   CASE
     IF mx≥0 AND mx≤51 AND mTXT(1)>"" THEN
       mSEL := 1;
     END;
     IF mx≥53 AND mx≤104 AND mTXT(2)>"" THEN
       mSEL := 2;
     END;
     IF mx≥106 AND mx≤157 AND mTXT(3)>"" THEN
       mSEL := 3;
     END;
     IF mx≥159 AND mx≤210AND mTXT(4)>""  THEN
       mSEL := 4;
     END;
     IF mx≥212 AND mx≤263 AND mTXT(5)>"" THEN
       mSEL := 5;
     END;
     IF mx≥265 AND mx≤319 AND mTXT(6)>"" THEN
       mSEL := 6;
     END;
   END;
 END;
END;

// ------------------------------------------------------------------------------------------
// Cash Flow application Code
// ------------------------------------------------------------------------------------------

IRR()
// Credits: Cyrille de Brébisson, Akmon, Dale (DrD), salvomic (Salvo Micciché), 
// Eddie W. Shore, Didier Lachiese, kharpster
// Interal Rate of Return. Cash flows in {L1} list or M1 (matrix with frequencies)
// by Salvo Micciché
BEGIN
local ch, irr;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: IRR() with {list} or [matrix with frequencies]", 5, 30);
WAIT;
RETURN;
END; // case
irr:= solve(ΣLIST(MAKELIST((L1(I)/X^(I-1)),I,1,SIZE(L1))),X)-1;
IF (irr(1)>=1 OR irr(1)<=-1) THEN irr:=tail(irr); END;
// formula by akmon, Cyrille, Dale
sto(irr, CF_IRR);
RECT_P(0,0,319,219);
TEXTOUT_P("IRR Internal Rate of Return", 0, 10);
TEXTOUT_P(EVAL(ROUND(100*irr, 3))+ "%", 0, 30, 0, RGB(255,0,0));
WAIT;
RETURN irr;
END;

MIRR()
// Calc Modified Internal Return Rate
// Salvo Micciché 2015
BEGIN
LOCAL sr, rr, flpos:={}, flneg:={}, sz ;
LOCAL sz1, sz2, npvp, npvn, n ;
LOCAL ch, fvp, ppyr, mirrvalue;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Modified Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: MIRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
INPUT ({sr, rr, ppyr},"Safe and risk rate", {"sr", "rr", "ppyr"}, 
{"Safe rate -", "Risk Rate +", "n Pmt for year"}, {0,0, 12},{0,0, 12});
// sr and rr yearly rates (es. 6%, 10%), ppyr number of payments in a year
sz:= SIZE(L1);
sr:=sr/ppyr; rr:=rr/ppyr;
n:=sz-1;
flneg:=MIN(L1,0); flpos:=MAX(L1,0); // one list -> two list, tnx Didier
sz1:= SIZE(flpos); sz2:= SIZE(flneg);
npvp:= NPV(rr, flpos);
npvp:=-npvp;
fvp:=Finance.CalcFV(n,rr*ppyr,npvp,0,ppyr,12,0);
npvn:= NPV(sr, flneg);
// RETURN 100*((fvp/-npvn)^(1/n)-1 );  HP 12C formula (equal to the next)
mirrvalue:= Finance.CalcIPYR(n,npvn,0,fvp,ppyr,12,0)/ppyr;
sto({mirrvalue, ppyr*mirrvalue}, CF_MIRR);
RECT_P(0,0,319,219);
TEXTOUT_P("Modified Internal Rate of Return", 0, 10);
TEXTOUT_P("Safe rate " + EVAL(ROUND(sr*ppyr, 3)) + "%", 0, 30);
TEXTOUT_P("Risk rate " + EVAL(ROUND(rr*ppyr, 3)) + "%", 0, 50);
TEXTOUT_P("with " + STRING(ppyr) + " payments per year", 0, 70);
TEXTOUT_P("NPV negative flows " + STRING(ROUND(npvn,3)), 0, 90);
TEXTOUT_P("FV of posive flows NPV " + STRING(ROUND(fvp,3)), 0, 110);
TEXTOUT_P("MIRR monthly rate " + STRING(ROUND(mirrvalue,3)) + "%", 0, 130, 0, RGB(255,0,0));
TEXTOUT_P("MIRR yearly rate " + EVAL(ROUND(mirrvalue*ppyr, 3)) + "%", 0, 150, 0, RGB(255,0,0));
WAIT;
RETURN {mirrvalue, ppyr*mirrvalue}; // return monthly and yearly MIRR
END;


NPV(r, flows)
// routine by Eddie W. Shore
 BEGIN
 LOCAL t:=0, k, s;
 r:=1+0.01*r;
 CASE
 // list
 IF TYPE(flows)==6 THEN
 s:=SIZE(flows);
 FOR k FROM 1 TO s DO
 t:=t+flows(k)/(r^(k-1));
 END;
 END;
 // matrix
 IF TYPE(flows)==4 THEN

 LOCAL j, n;
 s:=SIZE(flows);
 k:=0;
 FOR j FROM 1 TO s(1) DO
 FOR n FROM 1 TO flows(j,2) DO
 t:=flows(j,1)/(r^k)+t;
 k:=k+1;
 END; // for
 END; // for 2
 END; // if
 DEFAULT
TEXTOUT_P("Use: NPV(rate, list) or NPV(rate, [flow, freq])", 0, 30);
 END; // Case
sto(t, CF_NPV);
RECT_P(0,0,319,219);
TEXTOUT_P("NPV Net Present Value: " + EVAL(t), 0, 50, 0, RGB(255,0,0) );
RETURN t;
 END;

recall_npv()
BEGIN
local ch, r;
INPUT (r, "Rate", "rate%", "Rate for Net Present Value", 0, 10);
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("IRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
NPV(r, L1);
WAIT;
END;

about()
BEGIN

RECT_P(0,0,319,219);
TEXTOUT_P("Program created by by Salvo Micciché (salvomic)", 5, 10);
TEXTOUT_P("Credits", 5, 40, 0, RGB(0,255,0));
TEXTOUT_P("Cyrille de Brébisson, Akmon, Dale (DrD)", 5, 60);
TEXTOUT_P("Eddie W. Shore, Didier Lachiese, kharpster", 5, 80);

WAIT;
RETURN;
END;

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-21-2015, 10:27 PM
Post: #2
RE: Cash Flow (IRR, MIRR, NPV)
Great, Salvo, very attractive environment. Thank you for the credits. ;-)
Find all posts by this user
Quote this message in a reply
05-21-2015, 10:43 PM
Post: #3
RE: Cash Flow (IRR, MIRR, NPV)
(05-21-2015 10:27 PM)akmon Wrote:  Great, Salvo, very attractive environment. Thank you for the credits. ;-)

you're welcome! :-)
I'm glad to have been useful.

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-27-2015, 05:22 PM
Post: #4
RE: Cash Flow (IRR, MIRR, NPV)
Salvo, this is fantastic! I do have a question, I'm getting a syntax error after I do a check after importing the script. Any suggestions ?


Attached File(s) Thumbnail(s)
   
Find all posts by this user
Quote this message in a reply
05-27-2015, 05:45 PM
Post: #5
RE: Cash Flow (IRR, MIRR, NPV)
(05-27-2015 05:22 PM)gregnbrown Wrote:  Salvo, this is fantastic! I do have a question, I'm getting a syntax error after I do a check after importing the script. Any suggestions ?

thank you for compliments!
For the sake of precision, I've put the working code again on the post above ("Cash Flow" with drawmenu)...
However, if you get any errors, go to Programs, open cashflow program, hit check, then observe where is the cursor: it indicates that first there is an error; perhaps it helps...

First, try to copy again the code above.
Tell me if it works Smile

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-27-2015, 06:08 PM (This post was last modified: 05-27-2015 06:14 PM by gregnbrown.)
Post: #6
RE: Cash Flow (IRR, MIRR, NPV)
Thanks! The error is at EDITLIST(L1,

I am new to the HP Prime programming. Some background. I created a new program, and copied pasted the code into the program.
Find all posts by this user
Quote this message in a reply
05-27-2015, 06:16 PM
Post: #7
RE: Cash Flow (IRR, MIRR, NPV)
(05-27-2015 06:08 PM)gregnbrown Wrote:  Thanks! The error is at EDITLIST(L1,

I am new to the HP Prime programing. Some background. I created a new program, and copied pasted the code into the program.

do you copied *this* code?
It should works, almost, here it works well in the real calculator (now I'm trying in the emulator)...

Copy it via Connection Kit into the program.

Code:

export CF_IRR:=0;
export CF_MIRR:={0,0};
export CF_NPV:=0;

// Initialize procedures used in project (by khapster)
EVENTHANDLER();
PUTMENU();
GETMENU();

IRR();
MIRR();
NPV();
recall_npv();
about();

// Initialize variables used globally in project
mSEL;
eTYP;
kP;
m;
m1;

EXPORT Cash_Flow()
BEGIN
// Initialize local variables used within this procedure
 LOCAL mx,my,mTXT,EXITPGM;

 // Set the menu text (this is softcoded and determines if a menu item is valid)
 mTXT := {"NPV","IRR","MIRR","About","","Quit"};

 // MAIN CODE - Loop until ESC is pressed, then exit the program
 EXITPGM := 0;
 WHILE EXITPGM == 0 DO

   // Clear the screen and draw the menu
   RECT_P();
TEXTOUT_P("Cash Flow Utility", 100, 10, 5, RGB(255,0,0));
TEXTOUT_P("NPV Net Present Value", 25, 50);
TEXTOUT_P("IRR Internal Rate of Return", 25, 70);
TEXTOUT_P("MIRR Modified Internal Rate of Return", 25, 90);
TEXTOUT_P("by Salvo Micciché, 2015", 25, 120);
TEXTOUT_P("Credits: Cyrille de Brébisson, Akmon", 25, 150);
TEXTOUT_P("Dale (DrD), Eddie W. Shore", 25, 170);
TEXTOUT_P("Didier Lachiese, kharpster", 25, 190);
   PUTMENU(mTXT);

   // Flush the mouse buffer
   WHILE MOUSE(1) ≥ 0 DO END;

   // Loop until we have a keyboard or mouse event
   REPEAT
     EVENTHANDLER();
   UNTIL eTYP <> "";

    CASE

     // If the event type was a keyboard action then process it
     IF eTYP == "K" THEN
       // If the ESC key was pressed set the program to end
       IF kP == 4 THEN
         EXITPGM := 1;  
       ELSE
         // ESC was not pressed do what you want with the keypress, we are just going to do a TEXTOUT        
       END;        
     END;

     // If the event type was mouse action then process it
     IF eTYP == "M" THEN
       // Convert mouse coordinates to decimal
       mx := B→R(m1(1));  
       my := B→R(m1(2));
       // Determine if mouse coordinates are inside of a valid menu item otherwise return a zero
       GETMENU(mx,my,mTXT);
       // If a valid menu item was selected, do something, we are just going to do a TEXTOUT
       IF mSEL > 0 THEN
         CASE 
          // If menu item 1 was selected display a choose box for the user to select from
           IF mSEL == 1 THEN
             recall_npv();  
           END;
           IF mSEL == 2 THEN
             IRR();
           END;
           IF mSEL == 3 THEN
             MIRR(); 
           END;
           IF mSEL == 4 THEN
       about();
           END;
           IF mSEL == 6 THEN
             EXITPGM := 1;         
           END;
         DEFAULT
           // This is the default action for the menu selection and will only run if no case statement is satisfied

         END;
       ELSE
       // Mouse not in menu, do something if needed
       END;
     END;
   END;  
 END;
END;

// -------------------------------------------------------------------
// Detect keyboard or mouse input (keyboard has priority)
// -------------------------------------------------------------------
EVENTHANDLER()
BEGIN
 eTYP := "";
 kP := GETKEY;
 IF kP <> -1 THEN
   eTYP := "K";
 ELSE
   m := MOUSE;
   m1 := m(1);
   IF  SIZE(m1) > 0 THEN
     eTYP := "M";
   END;
 END;
END;

// ----------------------------------------------
// Draw the menu using the list passed in
// ----------------------------------------------
PUTMENU(mTXT)
BEGIN
 DRAWMENU(mTXT(1),mTXT(2),mTXT(3),mTXT(4),mTXT(5),mTXT(6));
END;

// ------------------------------------------------------------------------------------------
// Get the number of the menu item selected (1-6) by checking mouse position
// Menu items with empty/blank text will return a zero
// ------------------------------------------------------------------------------------------
GETMENU(mx,my,mTXT)
BEGIN
 mSEL := 0;
 IF my≥220 AND my≤239 THEN
   CASE
     IF mx≥0 AND mx≤51 AND mTXT(1)>"" THEN
       mSEL := 1;
     END;
     IF mx≥53 AND mx≤104 AND mTXT(2)>"" THEN
       mSEL := 2;
     END;
     IF mx≥106 AND mx≤157 AND mTXT(3)>"" THEN
       mSEL := 3;
     END;
     IF mx≥159 AND mx≤210AND mTXT(4)>""  THEN
       mSEL := 4;
     END;
     IF mx≥212 AND mx≤263 AND mTXT(5)>"" THEN
       mSEL := 5;
     END;
     IF mx≥265 AND mx≤319 AND mTXT(6)>"" THEN
       mSEL := 6;
     END;
   END;
 END;
END;

// ------------------------------------------------------------------------------------------
// Cash Flow application Code
// ------------------------------------------------------------------------------------------

IRR()
// Credits: Cyrille de Brébisson, Akmon, Dale (DrD), salvomic (Salvo Micciché), 
// Eddie W. Shore, Didier Lachiese, kharpster
// Interal Rate of Return. Cash flows in {L1} list or M1 (matrix with frequencies)
// by Salvo Micciché
BEGIN
local ch, irr;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: IRR() with {list} or [matrix with frequencies]", 5, 30);
WAIT;
RETURN;
END; // case
irr:= solve(ΣLIST(MAKELIST((L1(I)/X^(I-1)),I,1,SIZE(L1))),X)-1;
IF (irr(1)>=1 OR irr(1)<=-1) THEN irr:=tail(irr); END;
// formula by akmon, Cyrille, Dale
sto(irr, CF_IRR);
RECT_P(0,0,319,219);
TEXTOUT_P("IRR Internal Rate of Return", 0, 10);
TEXTOUT_P(EVAL(ROUND(100*irr, 3))+ "%", 0, 30, 0, RGB(255,0,0));
WAIT;
RETURN irr;
END;

MIRR()
// Calc Modified Internal Return Rate
// Salvo Micciché 2015
BEGIN
LOCAL sr, rr, flpos:={}, flneg:={}, sz ;
LOCAL sz1, sz2, npvp, npvn, n ;
LOCAL ch, fvp, ppyr, mirrvalue;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Modified Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: MIRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
INPUT ({sr, rr, ppyr},"Safe and risk rate", {"sr", "rr", "ppyr"}, 
{"Safe rate -", "Risk Rate +", "n Pmt for year"}, {0,0, 12},{0,0, 12});
// sr and rr yearly rates (es. 6%, 10%), ppyr number of payments in a year
sz:= SIZE(L1);
sr:=sr/ppyr; rr:=rr/ppyr;
n:=sz-1;
flneg:=MIN(L1,0); flpos:=MAX(L1,0); // one list -> two list, tnx Didier
sz1:= SIZE(flpos); sz2:= SIZE(flneg);
npvp:= NPV(rr, flpos);
npvp:=-npvp;
fvp:=Finance.CalcFV(n,rr*ppyr,npvp,0,ppyr,12,0);
npvn:= NPV(sr, flneg);
// RETURN 100*((fvp/-npvn)^(1/n)-1 );  HP 12C formula (equal to the next)
mirrvalue:= Finance.CalcIPYR(n,npvn,0,fvp,ppyr,12,0)/ppyr;
sto({mirrvalue, ppyr*mirrvalue}, CF_MIRR);
RECT_P(0,0,319,219);
TEXTOUT_P("Modified Internal Rate of Return", 0, 10);
TEXTOUT_P("Safe rate " + EVAL(ROUND(sr*ppyr, 3)) + "%", 0, 30);
TEXTOUT_P("Risk rate " + EVAL(ROUND(rr*ppyr, 3)) + "%", 0, 50);
TEXTOUT_P("with " + STRING(ppyr) + " payments per year", 0, 70);
TEXTOUT_P("NPV negative flows " + STRING(ROUND(npvn,3)), 0, 90);
TEXTOUT_P("FV of posive flows NPV " + STRING(ROUND(fvp,3)), 0, 110);
TEXTOUT_P("MIRR monthly rate " + STRING(ROUND(mirrvalue,3)) + "%", 0, 130, 0, RGB(255,0,0));
TEXTOUT_P("MIRR yearly rate " + EVAL(ROUND(mirrvalue*ppyr, 3)) + "%", 0, 150, 0, RGB(255,0,0));
WAIT;
RETURN {mirrvalue, ppyr*mirrvalue}; // return monthly and yearly MIRR
END;


NPV(r, flows)
// routine by Eddie W. Shore
 BEGIN
 LOCAL t:=0, k, s;
 r:=1+0.01*r;
 CASE
 // list
 IF TYPE(flows)==6 THEN
 s:=SIZE(flows);
 FOR k FROM 1 TO s DO
 t:=t+flows(k)/(r^(k-1));
 END;
 END;
 // matrix
 IF TYPE(flows)==4 THEN

 LOCAL j, n;
 s:=SIZE(flows);
 k:=0;
 FOR j FROM 1 TO s(1) DO
 FOR n FROM 1 TO flows(j,2) DO
 t:=flows(j,1)/(r^k)+t;
 k:=k+1;
 END; // for
 END; // for 2
 END; // if
 DEFAULT
TEXTOUT_P("Use: NPV(rate, list) or NPV(rate, [flow, freq])", 0, 30);
 END; // Case
sto(t, CF_NPV);
RECT_P(0,0,319,219);
TEXTOUT_P("NPV Net Present Value: " + EVAL(t), 0, 50, 0, RGB(255,0,0) );
RETURN t;
 END;

recall_npv()
BEGIN
local ch, r;
INPUT (r, "Rate", "rate%", "Rate for Net Present Value", 0, 10);
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("IRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
NPV(r, L1);
WAIT;
END;

about()
BEGIN

RECT_P(0,0,319,219);
TEXTOUT_P("Program created by by Salvo Micciché (salvomic)", 5, 10);
TEXTOUT_P("Credits", 5, 40, 0, RGB(0,255,0));
TEXTOUT_P("Cyrille de Brébisson, Akmon, Dale (DrD)", 5, 60);
TEXTOUT_P("Eddie W. Shore, Didier Lachiese, kharpster", 5, 80);

WAIT;
RETURN;
END;

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-27-2015, 06:28 PM
Post: #8
RE: Cash Flow (IRR, MIRR, NPV)
Thanks. Same error, however, I am trying it on the emulator. Just to make sure, it is a complete copy and paste into a new document? Overwrite the default syntax:

EXPORT program()
BEGIN
END;
Find all posts by this user
Quote this message in a reply
05-27-2015, 06:32 PM
Post: #9
RE: Cash Flow (IRR, MIRR, NPV)
(05-27-2015 06:28 PM)gregnbrown Wrote:  Thanks. Same error, however, I am trying it on the emulator. Just to make sure, it is a complete copy and paste into a new document? Overwrite the default syntax:

EXPORT program()
BEGIN
END;

you must overwrite those lines and paste code (without [code] and [ / code]) into the blank text.
Here it works also in emulator (and ...in Parallels emulator Windows 7 into Mac OS X, hi)...

The program begins with export(); and ends with END;
don't copy other lines first and after.

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-28-2015, 12:27 AM
Post: #10
RE: Cash Flow (IRR, MIRR, NPV)
(05-27-2015 06:32 PM)salvomic Wrote:  you must overwrite those lines and paste code (without [code] and [ / code]) into the blank text.
Here it works also in emulator (and ...in Parallels emulator Windows 7 into Mac OS X, hi)...

Don't forget to add the "pragma" line to make sure it will work properly on systems with other comma/hex settings!

TW

Although I work for HP, the views and opinions I post here are my own.
Find all posts by this user
Quote this message in a reply
05-28-2015, 03:48 AM
Post: #11
RE: Cash Flow (IRR, MIRR, NPV)
Works great, no errors. Thanks. Last question, I now see it in vars-->user. What is the exact syntax I would use to calculate the IRR ?
Find all posts by this user
Quote this message in a reply
05-28-2015, 07:56 AM (This post was last modified: 05-28-2015 08:06 AM by salvomic.)
Post: #12
RE: Cash Flow (IRR, MIRR, NPV)
(05-28-2015 12:27 AM)Tim Wessman Wrote:  Don't forget to add the "pragma" line to make sure it will work properly on systems with other comma/hex settings!

you're are right, Tim.
I should see how it's its syntax for this program, then add it.
Is only this ok?
Code:
#pragma mode(separator(.,;) integer(h32))

(05-28-2015 03:48 AM)gregnbrown Wrote:  Works great, no errors. Thanks. Last question, I now see it in vars-->user. What is the exact syntax I would use to calculate the IRR ?

great!
Var -> user -> cash flow: click on CF_IRR to get IRR, on CF_MIRR to get modified IRR, CF_NPV to get Net Present Value of the last calculations (after using the program), no parenthesis, no other...

To calculate IRR you need to have a list or a matrix (inside the program) with the cash flows (CF0, CFj...) and an interest rate, the first is generally negative (expense), the others flows are or negative or positive; IRR will have more values for more changement of sign or only one, not always it's possible to calculate it and in some cases financially is more suitable to calculate MIRR (see here, i.e.).
IRR is obtained setting NPV to 0 in the equation...

An example to test: -80000, -500, 4500 (3 times), 130000
You buy a mansion 80000$, the second year pay 500 (tax...), 3rd-5th year to get 4500 from rent, then sell to 130000$ at 13% of rate of yield preview.
You should get NPV +212.18.
Then try IRR with the same cashflow, the program gives you 13.72% (about the previewed one)


Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-28-2015, 08:20 AM
Post: #13
RE: Cash Flow (IRR, MIRR, NPV)
I've added pragma, now:

Code:

#pragma mode(separator(.,;) integer(h32))

export CF_IRR:=0;
export CF_MIRR:={0,0};
export CF_NPV:=0;

// Initialize procedures used in project (by khapster)
EVENTHANDLER();
PUTMENU();
GETMENU();

IRR();
MIRR();
NPV();
recall_npv();
about();

// Initialize variables used globally in project
mSEL;
eTYP;
kP;
m;
m1;

EXPORT Cash_Flow()
BEGIN
// Initialize local variables used within this procedure
 LOCAL mx,my,mTXT,EXITPGM;

 // Set the menu text (this is softcoded and determines if a menu item is valid)
 mTXT := {"NPV","IRR","MIRR","About","","Quit"};

 // MAIN CODE - Loop until ESC is pressed, then exit the program
 EXITPGM := 0;
 WHILE EXITPGM == 0 DO

   // Clear the screen and draw the menu
   RECT_P();
TEXTOUT_P("Cash Flow Utility", 100, 10, 5, RGB(255,0,0));
TEXTOUT_P("NPV Net Present Value", 25, 50);
TEXTOUT_P("IRR Internal Rate of Return", 25, 70);
TEXTOUT_P("MIRR Modified Internal Rate of Return", 25, 90);
TEXTOUT_P("by Salvo Micciché, 2015", 25, 120);
TEXTOUT_P("Credits: Cyrille de Brébisson, Akmon", 25, 150);
TEXTOUT_P("Dale (DrD), Eddie W. Shore", 25, 170);
TEXTOUT_P("Didier Lachiese, kharpster", 25, 190);
   PUTMENU(mTXT);

   // Flush the mouse buffer
   WHILE MOUSE(1) ≥ 0 DO END;

   // Loop until we have a keyboard or mouse event
   REPEAT
     EVENTHANDLER();
   UNTIL eTYP <> "";

    CASE

     // If the event type was a keyboard action then process it
     IF eTYP == "K" THEN
       // If the ESC key was pressed set the program to end
       IF kP == 4 THEN
         EXITPGM := 1;  
       ELSE
         // ESC was not pressed do what you want with the keypress, we are just going to do a TEXTOUT        
       END;        
     END;

     // If the event type was mouse action then process it
     IF eTYP == "M" THEN
       // Convert mouse coordinates to decimal
       mx := B→R(m1(1));  
       my := B→R(m1(2));
       // Determine if mouse coordinates are inside of a valid menu item otherwise return a zero
       GETMENU(mx,my,mTXT);
       // If a valid menu item was selected, do something, we are just going to do a TEXTOUT
       IF mSEL > 0 THEN
         CASE 
          // If menu item 1 was selected display a choose box for the user to select from
           IF mSEL == 1 THEN
             recall_npv();  
           END;
           IF mSEL == 2 THEN
             IRR();
           END;
           IF mSEL == 3 THEN
             MIRR(); 
           END;
           IF mSEL == 4 THEN
       about();
           END;
           IF mSEL == 6 THEN
             EXITPGM := 1;         
           END;
         DEFAULT
           // This is the default action for the menu selection and will only run if no case statement is satisfied

         END;
       ELSE
       // Mouse not in menu, do something if needed
       END;
     END;
   END;  
 END;
END;

// -------------------------------------------------------------------
// Detect keyboard or mouse input (keyboard has priority)
// -------------------------------------------------------------------
EVENTHANDLER()
BEGIN
 eTYP := "";
 kP := GETKEY;
 IF kP <> -1 THEN
   eTYP := "K";
 ELSE
   m := MOUSE;
   m1 := m(1);
   IF  SIZE(m1) > 0 THEN
     eTYP := "M";
   END;
 END;
END;

// ----------------------------------------------
// Draw the menu using the list passed in
// ----------------------------------------------
PUTMENU(mTXT)
BEGIN
 DRAWMENU(mTXT(1),mTXT(2),mTXT(3),mTXT(4),mTXT(5),mTXT(6));
END;

// ------------------------------------------------------------------------------------------
// Get the number of the menu item selected (1-6) by checking mouse position
// Menu items with empty/blank text will return a zero
// ------------------------------------------------------------------------------------------
GETMENU(mx,my,mTXT)
BEGIN
 mSEL := 0;
 IF my≥220 AND my≤239 THEN
   CASE
     IF mx≥0 AND mx≤51 AND mTXT(1)>"" THEN
       mSEL := 1;
     END;
     IF mx≥53 AND mx≤104 AND mTXT(2)>"" THEN
       mSEL := 2;
     END;
     IF mx≥106 AND mx≤157 AND mTXT(3)>"" THEN
       mSEL := 3;
     END;
     IF mx≥159 AND mx≤210AND mTXT(4)>""  THEN
       mSEL := 4;
     END;
     IF mx≥212 AND mx≤263 AND mTXT(5)>"" THEN
       mSEL := 5;
     END;
     IF mx≥265 AND mx≤319 AND mTXT(6)>"" THEN
       mSEL := 6;
     END;
   END;
 END;
END;

// ------------------------------------------------------------------------------------------
// Cash Flow application Code
// ------------------------------------------------------------------------------------------

IRR()
// Credits: Cyrille de Brébisson, Akmon, Dale (DrD), salvomic (Salvo Micciché), 
// Eddie W. Shore, Didier Lachiese, kharpster
// Interal Rate of Return. Cash flows in {L1} list or M1 (matrix with frequencies)
// by Salvo Micciché
BEGIN
local ch, irr;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: IRR() with {list} or [matrix with frequencies]", 5, 30);
WAIT;
RETURN;
END; // case
irr:= solve(ΣLIST(MAKELIST((L1(I)/X^(I-1)),I,1,SIZE(L1))),X)-1;
IF (irr(1)>=1 OR irr(1)<=-1) THEN irr:=tail(irr); END;
// formula by akmon, Cyrille, Dale
sto(irr, CF_IRR);
RECT_P(0,0,319,219);
TEXTOUT_P("IRR Internal Rate of Return", 0, 10);
TEXTOUT_P(EVAL(ROUND(100*irr, 3))+ "%", 0, 30, 0, RGB(255,0,0));
WAIT;
RETURN irr;
END;

MIRR()
// Calc Modified Internal Return Rate
// Salvo Micciché 2015
BEGIN
LOCAL sr, rr, flpos:={}, flneg:={}, sz ;
LOCAL sz1, sz2, npvp, npvn, n ;
LOCAL ch, fvp, ppyr, mirrvalue;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Modified Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: MIRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
INPUT ({sr, rr, ppyr},"Safe and risk rate", {"sr", "rr", "ppyr"}, 
{"Safe rate -", "Risk Rate +", "n Pmt for year"}, {0,0, 12},{0,0, 12});
// sr and rr yearly rates (es. 6%, 10%), ppyr number of payments in a year
sz:= SIZE(L1);
sr:=sr/ppyr; rr:=rr/ppyr;
n:=sz-1;
flneg:=MIN(L1,0); flpos:=MAX(L1,0); // one list -> two list, tnx Didier
sz1:= SIZE(flpos); sz2:= SIZE(flneg);
npvp:= NPV(rr, flpos);
npvp:=-npvp;
fvp:=Finance.CalcFV(n,rr*ppyr,npvp,0,ppyr,12,0);
npvn:= NPV(sr, flneg);
// RETURN 100*((fvp/-npvn)^(1/n)-1 );  HP 12C formula (equal to the next)
mirrvalue:= Finance.CalcIPYR(n,npvn,0,fvp,ppyr,12,0)/ppyr;
sto({mirrvalue, ppyr*mirrvalue}, CF_MIRR);
RECT_P(0,0,319,219);
TEXTOUT_P("Modified Internal Rate of Return", 0, 10);
TEXTOUT_P("Safe rate " + EVAL(ROUND(sr*ppyr, 3)) + "%", 0, 30);
TEXTOUT_P("Risk rate " + EVAL(ROUND(rr*ppyr, 3)) + "%", 0, 50);
TEXTOUT_P("with " + STRING(ppyr) + " payments per year", 0, 70);
TEXTOUT_P("NPV negative flows " + STRING(ROUND(npvn,3)), 0, 90);
TEXTOUT_P("FV of posive flows NPV " + STRING(ROUND(fvp,3)), 0, 110);
TEXTOUT_P("MIRR monthly rate " + STRING(ROUND(mirrvalue,3)) + "%", 0, 130, 0, RGB(255,0,0));
TEXTOUT_P("MIRR yearly rate " + EVAL(ROUND(mirrvalue*ppyr, 3)) + "%", 0, 150, 0, RGB(255,0,0));
WAIT;
RETURN {mirrvalue, ppyr*mirrvalue}; // return monthly and yearly MIRR
END;


NPV(r, flows)
// routine by Eddie W. Shore
 BEGIN
 LOCAL t:=0, k, s;
 r:=1+0.01*r;
 CASE
 // list
 IF TYPE(flows)==6 THEN
 s:=SIZE(flows);
 FOR k FROM 1 TO s DO
 t:=t+flows(k)/(r^(k-1));
 END;
 END;
 // matrix
 IF TYPE(flows)==4 THEN

 LOCAL j, n;
 s:=SIZE(flows);
 k:=0;
 FOR j FROM 1 TO s(1) DO
 FOR n FROM 1 TO flows(j,2) DO
 t:=flows(j,1)/(r^k)+t;
 k:=k+1;
 END; // for
 END; // for 2
 END; // if
 DEFAULT
TEXTOUT_P("Use: NPV(rate, list) or NPV(rate, [flow, freq])", 0, 30);
 END; // Case
sto(t, CF_NPV);
RECT_P(0,0,319,219);
TEXTOUT_P("NPV Net Present Value: " + EVAL(t), 0, 50, 0, RGB(255,0,0) );
RETURN t;
 END;

recall_npv()
BEGIN
local ch, r;
INPUT (r, "Rate", "rate%", "Rate for Net Present Value", 0, 10);
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L1, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M1, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("IRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
NPV(r, L1);
WAIT;
END;

about()
BEGIN

RECT_P(0,0,319,219);
TEXTOUT_P("Program created by by Salvo Micciché (salvomic)", 5, 10);
TEXTOUT_P("Credits", 5, 40, 0, RGB(0,255,0));
TEXTOUT_P("Cyrille de Brébisson, Akmon, Dale (DrD)", 5, 60);
TEXTOUT_P("Eddie W. Shore, Didier Lachiese, kharpster", 5, 80);

WAIT;
RETURN;
END;

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
05-28-2015, 09:39 AM (This post was last modified: 05-28-2015 09:43 AM by fhub.)
Post: #14
RE: Cash Flow (IRR, MIRR, NPV)
(05-28-2015 07:56 AM)salvomic Wrote:  An example to test: -80000, -500, 4500 (3 times), 130000
You buy a mansion 80000$, the second year pay 500 (tax...), 3rd-5th year to get 4500 from rent, then sell to 130000$ at 13% of rate of yield preview.
You should get NPV +212.18.
Then try IRR with the same cashflow, the program gives you 13.72% (about the previewed one)
Don't confuse the users of your program with wrong results, Salvo! Wink

I tried to get your 'results' with my TVM/Cashflow program, but no matter how I entered these values, I just couldn't get your NPV or IRR results.
And since I've checked my program (when I wrote it) against ALL examples that I've found in any of the HP financial calculator manuals (and of course they were all correct), I'm sure that there are no bugs in my program.

For your conditions (given above) the results should be NPV=-480.87 and IRR=12.8575%.

But after a short look at the HP12 manual I saw that you've just used an example from there, but instead of 3-times 4500 the cashflows are in fact 4500/5500/4500 - this would give your NPV=212.18 (and an IRR=13.0629%).

And your IRR=13.72% is from the following example (in the manual) with completely different cashflows ...

Franz
Visit this user's website Find all posts by this user
Quote this message in a reply
05-28-2015, 09:47 AM (This post was last modified: 05-28-2015 09:48 AM by salvomic.)
Post: #15
RE: Cash Flow (IRR, MIRR, NPV)
(05-28-2015 09:39 AM)fhub Wrote:  ...
But after a short look at the HP12 manual I saw that you've just used an example from there, but instead of 3-times 4500 the cashflows are in fact 4500/5500/4500 - this would give your NPV=212.18 (and an IRR=13.0629%).

And your IRR=13.72% is from the following example (in the manual) with completely different cashflows ...

Franz

right, Franz Smile
I was aware of the error (too hurry...), but I hadn't time to correct it...
yes, the right example is this, I wrote without attention.

Anyway, that is the way how the program works.

And your programs are also correct!

Salvo

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
04-23-2016, 03:07 PM
Post: #16
RE: Cash Flow (IRR, MIRR, NPV)
New Version (2.0) after firmware 10077.
This version doesn't works with the previous firmwares.

Code:

#pragma mode(separator(.,;) integer(h32))
// Cash Flow v. 2.0 2016 require firmware >10077

export CF_IRR:=0;
export CF_MIRR:={0,0};
export CF_NPV:=0;

// Initialize procedures used in project (by khapster)
EVENTHANDLER();
PUTMENU();
GETMENU();

IRR();
MIRR();
NPV();
recall_npv();
about();

// Initialize variables used globally in project
mSEL;
eTYP;
kP;
m;
m1;

EXPORT Cash_Flow()
BEGIN
// Initialize local variables used within this procedure
 LOCAL mx,my,mTXT,EXITPGM;

 // Set the menu text (this is softcoded and determines if a menu item is valid)
 mTXT := {"NPV","IRR","MIRR","About","","Quit"};

 // MAIN CODE - Loop until ESC is pressed, then exit the program
 EXITPGM := 0;
 WHILE EXITPGM == 0 DO

   // Clear the screen and draw the menu
   RECT_P();
TEXTOUT_P("Cash Flow Utility", 100, 10, 5, RGB(255,0,0));
TEXTOUT_P("NPV Net Present Value", 25, 50);
TEXTOUT_P("IRR Internal Rate of Return", 25, 70);
TEXTOUT_P("MIRR Modified Internal Rate of Return", 25, 90);
TEXTOUT_P("by Salvo Micciché, 2015", 25, 120);
TEXTOUT_P("Credits: Cyrille de Brébisson, Akmon", 25, 150);
TEXTOUT_P("Dale (DrD), Eddie W. Shore", 25, 170);
TEXTOUT_P("Didier Lachiese, kharpster", 25, 190);
   PUTMENU(mTXT);

   // Flush the mouse buffer
   WHILE MOUSE(1) ≥ 0 DO END;

   // Loop until we have a keyboard or mouse event
   REPEAT
     EVENTHANDLER();
   UNTIL eTYP <> "";

    CASE

     // If the event type was a keyboard action then process it
     IF eTYP == "K" THEN
       // If the ESC key was pressed set the program to end
       IF kP == 4 THEN
         EXITPGM := 1;  
       ELSE
         // ESC was not pressed do what you want with the keypress, we are just going to do a TEXTOUT        
       END;        
     END;

     // If the event type was mouse action then process it
     IF eTYP == "M" THEN
       // Convert mouse coordinates to decimal
       mx := B→R(m1(1));  
       my := B→R(m1(2));
       // Determine if mouse coordinates are inside of a valid menu item otherwise return a zero
       GETMENU(mx,my,mTXT);
       // If a valid menu item was selected, do something, we are just going to do a TEXTOUT
       IF mSEL > 0 THEN
         CASE 
          // If menu item 1 was selected display a choose box for the user to select from
           IF mSEL == 1 THEN
             recall_npv();  
           END;
           IF mSEL == 2 THEN
             IRR();
           END;
           IF mSEL == 3 THEN
             MIRR(); 
           END;
           IF mSEL == 4 THEN
       about();
           END;
           IF mSEL == 6 THEN
             EXITPGM := 1;         
           END;
         DEFAULT
           // This is the default action for the menu selection and will only run if no case statement is satisfied

         END;
       ELSE
       // Mouse not in menu, do something if needed
       END;
     END;
   END;  
 END;
END;

// -------------------------------------------------------------------
// Detect keyboard or mouse input (keyboard has priority)
// -------------------------------------------------------------------
EVENTHANDLER()
BEGIN
 eTYP := "";
 kP := GETKEY;
 IF kP <> -1 THEN
   eTYP := "K";
 ELSE
   m := MOUSE;
   m1 := m(1);
   IF  SIZE(m1) > 0 THEN
     eTYP := "M";
   END;
 END;
END;

// ----------------------------------------------
// Draw the menu using the list passed in
// ----------------------------------------------
PUTMENU(mTXT)
BEGIN
 DRAWMENU(mTXT(1),mTXT(2),mTXT(3),mTXT(4),mTXT(5),mTXT(6));
END;

// ------------------------------------------------------------------------------------------
// Get the number of the menu item selected (1-6) by checking mouse position
// Menu items with empty/blank text will return a zero
// ------------------------------------------------------------------------------------------
GETMENU(mx,my,mTXT)
BEGIN
 mSEL := 0;
 IF my≥220 AND my≤239 THEN
   CASE
     IF mx≥0 AND mx≤51 AND mTXT(1)>"" THEN
       mSEL := 1;
     END;
     IF mx≥53 AND mx≤104 AND mTXT(2)>"" THEN
       mSEL := 2;
     END;
     IF mx≥106 AND mx≤157 AND mTXT(3)>"" THEN
       mSEL := 3;
     END;
     IF mx≥159 AND mx≤210AND mTXT(4)>""  THEN
       mSEL := 4;
     END;
     IF mx≥212 AND mx≤263 AND mTXT(5)>"" THEN
       mSEL := 5;
     END;
     IF mx≥265 AND mx≤319 AND mTXT(6)>"" THEN
       mSEL := 6;
     END;
   END;
 END;
END;

// ------------------------------------------------------------------------------------------
// Cash Flow application Code
// ------------------------------------------------------------------------------------------

IRR()
// Credits: Cyrille de Brébisson, Akmon, Dale (DrD), salvomic (Salvo Micciché), 
// Eddie W. Shore, Didier Lachiese, kharpster
// Interal Rate of Return. Cash flows in {L1} list or M1 (matrix with frequencies)
// by Salvo Micciché
BEGIN
local ch, irr;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L0, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M0, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M1);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M1(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("Use: IRR() with {list} or [matrix with frequencies]", 5, 30);
WAIT;
RETURN;
END; // case
irr:= solve(ΣLIST(MAKELIST((L0(I)/X^(I-1)),I,1,SIZE(L0))),X)-1;
IF (irr(1)>=1 OR irr(1)<=-1) THEN irr:=tail(irr); END;
// formula by akmon, Cyrille, Dale
sto(irr, CF_IRR);
RECT_P(0,0,319,219);
TEXTOUT_P("IRR Internal Rate of Return", 0, 10);
TEXTOUT_P(EVAL(ROUND(100*irr, 3))+ "%", 0, 30, 0, RGB(255,0,0));
WAIT;
RETURN irr;
END;

MIRR()
// Calc Modified Internal Return Rate
// Salvo Micciché 2015
BEGIN
LOCAL sr, rr, flpos:={}, flneg:={}, sz ;
LOCAL sz1, sz2, npvp, npvn, n ;
LOCAL ch, fvp, ppyr, mirrvalue;
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L0, "Modified Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M0, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M0);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M1(j,2) DO
flows:= append(flows, M0(j,1));
 END; END; // for 1, 2
L0:= flows;
END;
DEFAULT
TEXTOUT_P("Use: MIRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
INPUT ({sr, rr, ppyr},"Safe and risk rate", {"sr", "rr", "ppyr"}, 
{"Safe rate -", "Risk Rate +", "n Pmt for year"}, {0,0, 12},{0,0, 12});
// sr and rr yearly rates (es. 6%, 10%), ppyr number of payments in a year
sz:= SIZE(L1);
sr:=sr/ppyr; rr:=rr/ppyr;
n:=sz-1;
flneg:=MIN(L0,0); flpos:=MAX(L0,0); // one list -> two list, tnx Didier
sz1:= SIZE(flpos); sz2:= SIZE(flneg);
npvp:= NPV(rr, flpos);
npvp:=-npvp;
fvp:=Finance.TvmFV(n,rr*ppyr,npvp,0,ppyr,12,0);
npvn:= NPV(sr, flneg);
// RETURN 100*((fvp/-npvn)^(1/n)-1 );  HP 12C formula (equal to the next)
mirrvalue:= Finance.TvmIPYR(n,npvn,0,fvp,ppyr,12,0)/ppyr;
sto({mirrvalue, ppyr*mirrvalue}, CF_MIRR);
RECT_P(0,0,319,219);
TEXTOUT_P("Modified Internal Rate of Return", 0, 10);
TEXTOUT_P("Safe rate " + EVAL(ROUND(sr*ppyr, 3)) + "%", 0, 30);
TEXTOUT_P("Risk rate " + EVAL(ROUND(rr*ppyr, 3)) + "%", 0, 50);
TEXTOUT_P("with " + STRING(ppyr) + " payments per year", 0, 70);
TEXTOUT_P("NPV negative flows " + STRING(ROUND(npvn,3)), 0, 90);
TEXTOUT_P("FV of posive flows NPV " + STRING(ROUND(fvp,3)), 0, 110);
TEXTOUT_P("MIRR monthly rate " + STRING(ROUND(mirrvalue,3)) + "%", 0, 130, 0, RGB(255,0,0));
TEXTOUT_P("MIRR yearly rate " + EVAL(ROUND(mirrvalue*ppyr, 3)) + "%", 0, 150, 0, RGB(255,0,0));
WAIT;
RETURN {mirrvalue, ppyr*mirrvalue}; // return monthly and yearly MIRR
END;


NPV(r, flows)
// routine by Eddie W. Shore
 BEGIN
 LOCAL t:=0, k, s;
 r:=1+0.01*r;
 CASE
 // list
 IF TYPE(flows)==6 THEN
 s:=SIZE(flows);
 FOR k FROM 1 TO s DO
 t:=t+flows(k)/(r^(k-1));
 END;
 END;
 // matrix
 IF TYPE(flows)==4 THEN

 LOCAL j, n;
 s:=SIZE(flows);
 k:=0;
 FOR j FROM 1 TO s(1) DO
 FOR n FROM 1 TO flows(j,2) DO
 t:=flows(j,1)/(r^k)+t;
 k:=k+1;
 END; // for
 END; // for 2
 END; // if
 DEFAULT
TEXTOUT_P("Use: NPV(rate, list) or NPV(rate, [flow, freq])", 0, 30);
 END; // Case
sto(t, CF_NPV);
RECT_P(0,0,319,219);
TEXTOUT_P("NPV Net Present Value: " + EVAL(t), 0, 50, 0, RGB(255,0,0) );
RETURN t;
 END;

recall_npv()
BEGIN
local ch, r;
INPUT (r, "Rate", "rate%", "Rate for Net Present Value", 0, 10);
CHOOSE(ch,"Flows List or Matrix w/ freq","Cash Flows List","CF Matrix whit frequencies");
CASE
IF ch==1 THEN
EDITLIST(L0, "Internal Rate of Return");
END;
IF ch==2 THEN
EDITMAT(M0, "Internal Rate of Return");
 LOCAL flows:={}, j, k, s;
 s:=SIZE(M0);
 FOR j FROM 1 TO s(1) DO
 FOR k FROM 1 TO M0(j,2) DO
flows:= append(flows, M0(j,1));
 END; END; // for 1, 2
L1:= flows;
END;
DEFAULT
TEXTOUT_P("IRR() with {list} or [matrix with frequencies]", 0, 30);
END; // case
NPV(r, L0);
WAIT;
END;

about()
BEGIN

RECT_P(0,0,319,219);
TEXTOUT_P("Program created by by Salvo Micciché (salvomic)", 5, 10);
TEXTOUT_P("Credits", 5, 40, 0, RGB(0,255,0));
TEXTOUT_P("Cyrille de Brébisson, Akmon, Dale (DrD)", 5, 60);
TEXTOUT_P("Eddie W. Shore, Didier Lachiese, kharpster", 5, 80);

WAIT;
RETURN;
END;

∫aL√0mic (IT9CLU) :: HP Prime 50g 41CX 71b 42s 39s 35s 12C 15C - DM42, DM41X - WP34s Prime Soft. Lib
Visit this user's website Find all posts by this user
Quote this message in a reply
08-22-2017, 08:42 AM
Post: #17
RE: Cash Flow (IRR, MIRR, NPV)
Hi Salvomic,

Thank you for your program which could be very interesting for me as I'm a finance student.

I've tried it but I don't know how to create a list in order to calculate the IRR.

For example, I want to calculate the IRR of these Cash Flows :
-1 000 000 (Investment in O, which is CF0)
+ 272 092 (CF1)
+ 232 165 (CF2)
+ 237 569 (CF3)
+ 243 524 (CF4)
+ 250 016 (CF5).

Actually I don't know how to write these Cash Flows on your program in the window "Listes" after having selected "IRR" in your program.

This window :
[attachment=5134]

Thank you for your help.
Find all posts by this user
Quote this message in a reply
Post Reply 




User(s) browsing this thread: 1 Guest(s)