Заемщик при существующей ставке в p процентов должен внести в банк k последовательных платежей. Первый платеж в a0 денежных единиц необходимо осуществить через t0 периодов, второй платеж в a1 единиц - через t1 периодов и т.д. и, наконец, k-й платеж в ak-1 единиц - через tk-1 периодов. Все величины tn (n=0. . k-1) отсчитываются от момента получения займа. Из-за невозможности внести первый взнос заемщик просит консолидировать его платежи, то есть разрешить ему через некоторое время заплатить сразу весь долг a0+a1+…+ak-1. Через какое количество q периодов заемщик обязан рассчитаться, чтобы ничьи интересы не пострадали?
Решение. Будем исходить из того, что современная стоимость потока платежей заемщика и современная стоимость единовременно вносимой им суммы должны совпадать. Отсюда для нахождения значения q получаем так называемое уравнение эквивалентности процентных ставок при дисконтировании:
(9)Параметр q можно непосредственно определить из этой формулы. Пусть a и t- векторы платежей и периодов:
a=(a0,a1,…,ak-1) T, t=(t0,t1,…,tk-1) T. (10)
Будем вычислять q с помощью функции conso(a,t,p) и вспомогательной рекурсивной функции summa(a,t,p), служащей для нахождения сумм в (9). Значение q=conso(a,t,p) может оказаться дробным.
Выглядят эти функции так:
(11) (12)Замечание. Величины tn (n=0. . k-1) можно измерять в долях целого периода. Например, если один период - это год, то tn можно измерять в месяцах, днях, а при необходимости - и в часах. При этом процентная ставка p должна быть скорректирована соответственно на p/12, p/365 или p/(365×24).
Контрольные примеры.
Банк выдал заемщику кредит в S денежных единиц на k периодов с необходимостью выплаты долга равными частями в конце каждого периода. Определить величину разовых выплат, если процентная ставка банка за один период равна p.
Решение. Эта задача весьма поучительна. Она дает нам возможность на конкретном примере поговорить об одном необычном способе построения эффективных рекурсивных алгоритмов решения определенного класса задач, отправляясь от “алгоритмов с бесконечным числом рекурсивных обращений”. Обозначим через pay(S,p,k) решение задачи. Попробуем обсудить приведенный ниже текст программы вычисления pay(S,p,k):
(13)С точки зрения логики здесь как будто бы все в порядке. Фактически записано, что если k=1, то есть расчет должен произойти в конце первого периода, то выплатить придется всю задолженность сразу, а именно, S×(1+p/100) денежных единиц. В противном случае необходимо поступить так. Произвести расчет в конце первого периода и с оставшейся задолженностью
(14)рассчитываться следующие k-1 периодов. Что же в этом рассуждении не работает? Дело в том, что в (14) величина pay(S,p,k) неизвестна. Именно её по условию задачи и требуется вычислить. Поэтому попытка реально реализовать счет по программе-функции (13) всегда будет завершаться аварийно - переполнением стека рекурсивных вызовов. Иными словами, тело рекурсивной функции не может содержать ссылку на эту же функцию с тем же самым набором параметров! Но не будем отчаиваться. Подставим в теле (13) вместо pay(S,p,k) некоторый параметр X:
(15)Полученная функция payw() при любом фиксированном X уже вполне пригодна для вычислений. Здесь рекурсия четко организована по параметру k. Правда, непонятно, что payw() вычисляет? Но это и знать незачем. Все, что нам требуется - это зафиксировать X не произвольно, а таким образом, чтобы полученное в результате вычислений по (15) значение для payw(S,p,k) оказалось равным X. В этом случае фактически будет вычислено pay(S,p,k) в (13), то есть решена исходная задача. Однако метод хаотичных проб и ошибок вряд ли здесь может привести к успеху. Необходимо научиться управлять параметром X, изменяя его значение в правильном направлении. Для этих целей к аргументам функции payw(S,p,k) добавим X:
(16)Получили функцию paywi(). При любом фиксированном X значения функций (15) и (16) равны. Поэтому поиск решения исходной задачи окончательно свелся к нахождению в (16) такого X, при котором
g(S,p,k,X) ºpaywi(S,p,k,X) - X=0.
Фиксируем значения S, p и k. Тогда g(S,p,k,X) - непрерывная на всей числовой оси функция одной переменной. Нам необходимо найти по крайней мере один её вещественный корень X* (g(S,p,k,X*) º0). Делать это можно по-разному. Например, определить отрезок, на котором g() принимает значения разных знаков, а затем использовать быстро сходящийся метод дихотомии (деления отрезка пополам).
Приведенная ниже рекурсивная программа-функция dicho(f,a,b,e) для произвольной непрерывной на отрезке [a,b] (a<b) функции f(x) при условии f(a) ×f(b) £0 c заданной точностью e>0 находит некоторый вещественный корень f(x). Эту функцию и будем использовать далее:
(17)Контрольный пример. Подсчитать величину равных платежей в конце каждого периода, если заем в 1000 денежных единиц взят под 10 процентов на каждый из 4 периодов.
Предложенный способ решения задачи (10) не является наилучшим. Можно было бы для этих целей предложить и такие рекурсивные функции:
(18) (19)Функция paywi1() отличается от функции paywi2() количеством рекурсивных вызовов при вычислениях. Порядок их в первом случае равен k, а во втором -log2(k).
Решение предложенной задачи может быть осуществлено и по конечной формуле (20). Выводится она так. Пусть W=W(S,p,k). С одной стороны, задолженность через k периодов должна быть полностью погашена, а с другой - её можно подсчитать так:
Приравнивая последнее выражение нулю, и разрешая полученное уравнение относительно W, получаем формулу (20):
(20)Контрольные примеры.
Замечание. Мы решали задачу, предполагая, что платежи поступают в конце каждого из периодов. Это совсем не обязательно. Формула (20) остается справедливой (с поправками) и в следующих двух случаях:
Производится по m1 платежей через равные промежутки времени в каждый из k периодов. В (20) вместо k и p необходимо подставить соответственно значения k×m1 и p/m1.
Платежи проводятся через m2 периодов. В (20) вместо k и p необходимо подставить соответственно значения k/m2 и p×m2.
Указанное замечание касается и многих других ранее рассмотренных функций.
Задача о равных платежах в конце или начале каждого периода.
Банк выдал заемщику кредит в pv денежных единиц на nper периодов с необходимостью выплаты долга равными частями в конце (type=0) или начале (type=1) каждого периода. Определить величину pmt разовых выплат, если процентная ставка банка за один период равна rate.
Решение. Данная задача может быть решена с помощью встроенной в Excel функции pmt=pmt(rate,nper,pv,type). При type=0 задачи 10 и 11 идентичны. Ниже приведено решение для общего случая, основанное на легко получаемой рекуррентной формуле. Будем исходить из того, что современная стоимость всех внесенных платежей должна быть равной произведенному займу pv. Пусть через pmtn (n=1,2,…) обозначена ставка платежей при выплатах за n периодов. Найдем связь между pmtn и pmtn-1, исходя из баланса современной стоимости платежей при любом n. Пусть type=0. Тогда
Отсюда
(21)То же самое соотношение получается и для type=1. Иными словами, при любом допустимом значении type имеет место следующая рекуррентная формула:
(22)Раскрывая рекуррентность (22), получаем
(23) (24)Соотношения (24) и (22) и взяты соответственно в качестве базы и декомпозиции при реализации рекурсивной программы-функции pmt():
Из соотношений (23) и (24) при n=nper получается конечная формула для вычисления значений pmt():
Контрольные примеры.
Некто занял pv денежных единиц на nper периодов при процентной ставке в rate процентов за период. Платежи ppmt по займу должны иметь одинаковую современную стоимость и производиться в конце (type=0) или начале (type=1) каждого периода. Определить величину платежа в период per (per=1,2,…,nper).