Имя: Пароль:
1C
1С v8
IRR - внутренняя ставка доходности, Где найти функцию как в Екселе - ВСД() ?
0 xsnika
 
25.04.12
14:12
Столкнулся с проблемой расчёта внутренней ставки доходности.  Может кто-то решал уже эту задачу и у кого-то есть готовая функция  похожая на Ексел-евскую ВСД()?
1 xsnika
 
27.04.12
10:00
IRR =-0.5;
   NVP = 1;
   
   ТекстШаблона = "";
   ТекстШаблона = СтрЗаменить(Строка(ПерваяСтрока),",",".")+"+";
   //На вход передаю Таблицу значений в котороё две колонки Период и Сумма
   Для каждого Стр Из ТЗ Цикл
       
       ТекстШаблона = ТекстШаблона + СтрЗаменить(Строка(Формат(Стр.Сумма,"ЧДЦ=3")),",",".")+"/Pow((1+х),"+Строка(Стр.ПериодЛизинга)+")+";
       
       
   КонецЦикла;
   ТекстШаблона = СтрЗаменить(ТекстШаблона,Символы.НПП,"");
   ТекстШаблона = Лев(ТекстШаблона,СтрДлина(ТекстШаблона)-1);
   
   //-
   ПредыдущийНВП = 0;
   Пока IRR<1 Цикл
       
       IRR = IRR + 0.000001;
       ТекущийТекстШаблона = СтрЗаменить(ТекстШаблона,"х","("+СтрЗаменить(СтрЗаменить(Строка(IRR),",","."),Символы.НПП,"")+")");
       NVP = Вычислить(ТекущийТекстШаблона);    
       Если (NVP <0 И ПредыдущийНВП > 0) ИЛИ (NVP >0 И ПредыдущийНВП < 0) Тогда
           
           Сообщить("IRR = "+ IRR*100*12);
           Возврат;
           
       КонецЕсли;
       
       ПредыдущийНВП = NVP;
   КонецЦикла;
2 xsnika
 
27.04.12
10:01
Вот этот код выполняется долго...
3 xsnika
 
27.04.12
10:03
http://www.financial-analysis.ru/methodses/metIAIRR.html


Код написан в соответствии с вот этой формулой
4 xsnika
 
27.04.12
10:08
ИРР1 =-0.9;
   ИРР2 =0.9999;
   
   NVP = 1;
   //Таблица  = Новый ТаблицаЗначений;
   //Таблица.Колонки.Добавить("IRR");
   //Таблица.Колонки.Добавить("NVP");
   //+
   ТекстШаблона = "";
   ТекстШаблона = СтрЗаменить(Строка(ПерваяСтрока),",",".")+"+";
   //ТекстШаблонаЭксель = Строка(ПерваяСтрока)+"+";
   Для каждого Стр Из ТЗ Цикл
   
       ТекстШаблона = ТекстШаблона + СтрЗаменить(Строка(Формат(Стр.Сумма,"ЧДЦ=3")),",",".")+"/Pow((1+х),"+Строка(Стр.ПериодЛизинга)+")+";
       //ТекстШаблонаЭксель = ТекстШаблонаЭксель + Строка(Стр.Сумма)+"/((1+х)^"+Строка(Стр.ПериодЛизинга)+")+";
   
   КонецЦикла;
   ТекстШаблона = СтрЗаменить(ТекстШаблона,Символы.НПП,"");
   ТекстШаблона = Лев(ТекстШаблона,СтрДлина(ТекстШаблона)-1);
   
   //-
   ПредыдущийНВП = 0;
   ТекущийТекстШаблона1 = СтрЗаменить(ТекстШаблона,"х","("+СтрЗаменить(СтрЗаменить(Строка(ИРР1),",","."),Символы.НПП,"")+")");
   НПВ1 = Вычислить(ТекущийТекстШаблона1);
   ТекущийТекстШаблона2 = СтрЗаменить(ТекстШаблона,"х","("+СтрЗаменить(СтрЗаменить(Строка(ИРР2),",","."),Символы.НПП,"")+")");
   НПВ2 = Вычислить(ТекущийТекстШаблона2);

   Точность = 0.00001;
   Пока Истина Цикл
   
       НовыйИРР = ИРР1+(ИРР2-ИРР1)/2;
       НовыйТекущийТекстШаблона = СтрЗаменить(ТекстШаблона,"х","("+СтрЗаменить(СтрЗаменить(Строка(НовыйИРР),",","."),Символы.НПП,"")+")");
       НовыйНПВ = Вычислить(НовыйТекущийТекстШаблона);

       Если НовыйНПВ*НПВ1 < 0 Тогда
           
           ИРР2 = НовыйИРР;
       Иначе
           ИРР1 = НовыйИРР;
           
       КонецЕсли;
       Если НовыйНПВ> -Точность И НовыйНПВ < Точность   Тогда
           Сообщить("IRR = "+ НовыйИРР*100*12);
           Возврат;
       КонецЕсли;
   
   КонецЦикла;
5 xsnika
 
27.04.12
10:09
А вот этот код работает быстро :) Писала девушка, математик, за что ей огромное спасибо!
6 xsnika
 
27.04.12
10:11
Код написан по формуле:  http://en.wikipedia.org/wiki/Secant_method
Чтобы обнаруживать ошибки, программист должен иметь ум, которому доставляет удовольствие находить изъяны там, где, казалось, царят красота и совершенство. Фредерик Брукс-младший