Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
491 views
in Technique[技术] by (71.8m points)

c# - XIRR Calculation

How do I calculate Excel's XIRR function using C#?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

According to XIRR function openoffice documentation (formula is same as in excel) you need to solve for XIRR variable in the following f(xirr) equation:
enter image description here
You can calculate xirr value by:

  1. calculating derivative of above function -> f '(xirr)
  2. after having f(xirr) and f'(xirr) you can solve for xirr value by using iterative Newton's method - famous formula->
    enter image description here

EDIT
I've got a bit of time so, here it is - complete C# code for XIRR calculation:

class xirr
    {
        public const double tol = 0.001;
        public delegate double fx(double x);

        public static fx composeFunctions(fx f1, fx f2) {
            return (double x) => f1(x) + f2(x);
        }

        public static fx f_xirr(double p, double dt, double dt0) {
            return (double x) => p*Math.Pow((1.0+x),((dt0-dt)/365.0));
        }

        public static fx df_xirr(double p, double dt, double dt0) {
            return (double x) => (1.0/365.0)*(dt0-dt)*p*Math.Pow((x+1.0),(((dt0-dt)/365.0)-1.0));
        }

        public static fx total_f_xirr(double[] payments, double[] days) {
            fx resf = (double x) => 0.0;

            for (int i = 0; i < payments.Length; i++) {
                resf = composeFunctions(resf,f_xirr(payments[i],days[i],days[0]));
            }

            return resf;
        }

        public static fx total_df_xirr(double[] payments, double[] days) {
            fx resf = (double x) => 0.0;

            for (int i = 0; i < payments.Length; i++) {
                resf = composeFunctions(resf,df_xirr(payments[i],days[i],days[0]));
            }

            return resf;
        }

        public static double Newtons_method(double guess, fx f, fx df) {
            double x0 = guess;
            double x1 = 0.0;
            double err = 1e+100;

            while (err > tol) {
                x1 = x0 - f(x0)/df(x0);
                err = Math.Abs(x1-x0);
                x0 = x1;
            }

            return x0;
        }

        public static void Main (string[] args)
        {
            double[] payments = {-6800,1000,2000,4000}; // payments
            double[] days = {01,08,16,25}; // days of payment (as day of year)
            double xirr = Newtons_method(0.1,
                                         total_f_xirr(payments,days),
                                         total_df_xirr(payments,days));

            Console.WriteLine("XIRR value is {0}", xirr);
        }
    }

BTW, keep in mind that not all payments will result in valid XIRR because of restrictions of formula and/or Newton method!

cheers!


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...