Financial.IRR не рассчитывается в C#
Я не могу рассчитать IRR. Я использую Microsoft.VisualBasic для расчета IRR. Вот случай:
using Microsoft.VisualBasic;
...
static void Main(string[] args)
{
double[] tmpCashflows = new double[] {
-480117.0,
4471.5158140594149,
6841.5950239895265,
6550.383550359461,
6295.8611873818609,
6074.6070899770129,
5883.532880960287,
6006.9907860976427,
6133.1633945923877
,6262.1156759885489
//,6393.9143799520116
};
decimal irr = 0;
try
{
double tmpIrr = Financial.IRR(ref tmpCashflows);
...
}
catch (Exception ex)
{
irr = 0;
}
}
Это дает исключение типа "Аргумент недействителен" (в Microsoft.VisualBasic.Financial.IRR(Double[]& ValueArray, Double Guess)). Однако, это не показывает никаких ошибок, если я делаю вычисления в Excel.
1 ответ
Вы должны предоставить хорошее значение Guess в качестве второго параметра этого API. Значение по умолчанию 0,1 не подходит для ваших входов.
Попробуй это:
double tmpIrr = Financial.IRR(ref tmpCashflows, 0.3);
и вы должны вернуться IRR of -0.2987
Похоже, что API обрабатывает только определенные случаи ввода и дает сбой другим для любого предположения. Это ошибка IRR API для Microsoft, признанная здесь.
Вам лучше рассчитывать IRR, используя стороннюю надежную библиотеку, если угадайте, если возникнет проблема.
Причина, по которой вы получаете Argument is not valid
Исключением является то, что IRR не может быть рассчитан для значения Guess по умолчанию 0,1. Обратите внимание, что данные значения удовлетворяют условию одного отрицательного значения (платежа) и одного положительного значения. (чек)
Внутренне **Microsoft.VisualBasic.Financial.IRR**
проходит через входные значения и пытается рассчитать IRR за 40 итераций. Он никогда не сталкивается с условием прерывания для действительного IRR и, следовательно, в конечном итоге выдает эту ошибку.
Обратите внимание, что Excel дает значение -30%.
В то же время, пытаясь IRR для массива, как
tmpCashflows = new double[] { -100, 200, 300 };
double tmpIrr = Microsoft.VisualBasic.Financial.IRR(ref tmpCashflows);
дает IRR 2,0 или 200%. (как через код, так и в Excel)
public static class Interpolation
{
public static double IRR(this Dictionary<double, double> cashFlow) //term in years, amount
{
int count = 0;
double r1=0.1d, r2=0.05d, v1, v2, r = 0, v;
v1 = cashFlow.DiscountedValue(r1);
v2 = cashFlow.DiscountedValue(r2);
while (Math.Abs(v2 - v1) > .001 && count < 1000)
{
count++;
r = (0 - v1) / (v1-v2) * (r1 - r2) + r1;
v = cashFlow.DiscountedValue(r);
v1 = v2;
r1 = r2;
v2 = v;
r2 = r;
}
if (count == 1000) return -1;
return r;
}
public static double DiscountedValue(this Dictionary<double, double> cashFlow, double rate)
{
double dv = 0d;
for (int i = 0; i < cashFlow.Count; i++)
{
var element = cashFlow.ElementAt(i);
dv += element.Value * Math.Pow(1 + rate, -(element.Key));
}
return dv;
}
}