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 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-21-2015, 10:27 PM
Post: #2
 akmon Member Posts: 191 Joined: Jun 2014
RE: Cash Flow (IRR, MIRR, NPV)
Great, Salvo, very attractive environment. Thank you for the credits. ;-)
05-21-2015, 10:43 PM
Post: #3 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-27-2015, 05:22 PM
Post: #4
 gregnbrown Junior Member Posts: 4 Joined: May 2015
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) 05-27-2015, 05:45 PM
Post: #5 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 Salvo

∫aL√0mic (IT9CLU), HP Prime 50g 41CX 71b 42s 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-27-2015, 06:08 PM (This post was last modified: 05-27-2015 06:14 PM by gregnbrown.)
Post: #6
 gregnbrown Junior Member Posts: 4 Joined: May 2015
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.
05-27-2015, 06:16 PM
Post: #7 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-27-2015, 06:28 PM
Post: #8
 gregnbrown Junior Member Posts: 4 Joined: May 2015
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;
05-27-2015, 06:32 PM
Post: #9 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-28-2015, 12:27 AM
Post: #10 Tim Wessman Senior Member Posts: 2,233 Joined: Dec 2013
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 the HP calculator group, the views and opinions I post here are my own.
05-28-2015, 03:48 AM
Post: #11
 gregnbrown Junior Member Posts: 4 Joined: May 2015
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 ?
05-28-2015, 07:56 AM (This post was last modified: 05-28-2015 08:06 AM by salvomic.)
Post: #12 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-28-2015, 08:20 AM
Post: #13 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
RE: Cash Flow (IRR, MIRR, NPV)

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 12C 15C - DM42 WP34s :: Prime Soft. Lib
05-28-2015, 09:39 AM (This post was last modified: 05-28-2015 09:43 AM by fhub.)
Post: #14
 fhub Member Posts: 188 Joined: Dec 2013
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! 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
05-28-2015, 09:47 AM (This post was last modified: 05-28-2015 09:48 AM by salvomic.)
Post: #15 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 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 12C 15C - DM42 WP34s :: Prime Soft. Lib
04-23-2016, 03:07 PM
Post: #16 salvomic Senior Member Posts: 1,366 Joined: Jan 2015
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 12C 15C - DM42 WP34s :: Prime Soft. Lib
08-22-2017, 08:42 AM
Post: #17
 seb83 Junior Member Posts: 1 Joined: Aug 2017
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]