Чтобы решить эту задачу, нужно использовать формулу сложных процентов.
Допустим, у нас есть вклад в размере X рублей, и на него начисляется доход в размере 0,8% каждый месяц. В конце первого месяца состояние вклада будет X + 0,8% от X рублей. В конце второго месяца состояние вклада будет (X + 0,8% от X) + 0,8% от (X + 0,8% от X) рублей. И так далее для каждого последующего месяца.
Обозначим годовой процент по вкладу, который нас интересует, как P. Тогда в конце года состояние вклада будет (X + 0,008X) * (1 + 0,008P)^11 рублей.
Нам нужно найти значение P, при котором это выражение равняется X * (1 + P)^12. Раскроем скобки и перенесём все слагаемые в одну сторону:
(X + 0,008X) * (1 + 0,008P)^11 - X * (1 + P)^12 = 0
Чтобы решить это уравнение, можно воспользоваться численными методами, например, методом бисекции или методом Ньютона.
Однако, мы можем упростить вычисления, если вместо рассмотрения процентной ставки P будем рассматривать её приращение dp. Это позволит нам свести задачу к численному нахождению одного значения dp, и взятию значения P равным 1% (или 0,01). Приращение dp мы выбираем маленьким, например, 0.0001.
Поэтому, будем искать такое значение dp, при котором
(X + 0,008X) * (1+0,008*(P+dp))^11 - X * (1+P+dp)^12 = 0
Окей, давайте считать проценты.
Для простоты, примем X = 100 рублей.
С каждым новым шагом мы будем увеличивать количество дробных разрядов в значениях, чтобы достичь необходимой точности.
Итак, наша цель - найти такое значение процентного приращения dp, которое позволяет уравнению выше быть равным нулю.
1.посчитаем значение (X + 0,008X) * (1+0,008*(P+dp))^11 - X * (1+P+dp)^12
Как и в примере использовано значение суммы X = 100:
dp = 0.0001
начальное значение:
P = 0.01
сумма вклада:
sum = 100
состояние вклада после года:
end_sum = sum * (1 + P) ** 12
начальное значение состояния вклада (с учётом начисленных процентов):
start_sum = (sum + 0.008 * sum) * (1 + 0.008 * (P + dp)) ** 11
значение выражения:
expression = start_sum - end_sum
прежде чем рассчитать значение expression нам надо написать функцию, которое будет подставлять необходимые значения в формулу
def calc_expression(sum, P, dp):
end_sum = sum * (1 + P) ** 12
start_sum = (sum + 0.008 * sum) * (1 + 0.008 * (P + dp)) ** 11
return start_sum - end_sum
теперь нам надо рассчитать expression
expression = calc_expression(sum, P, dp)
print(expression)
##0.6171014488085452
Вычисленное значение равно 0.6171.
Уравнение не нулевое, поэтому наше приближение не подходит. Нам надо выбрать другое значение приращения dp.
2. Пробуем другое значение dp:
dp = 0.0002
expression = calc_expression(sum, P, dp)
print(expression)
##-0.2568977877560369
Вычисленное значение равно -0.2569. Оно отрицательное! Значит, приближение слишком большое. Давайте выберем меньшее значение приращения dp.
3. Пробуем еще меньшее значение dp:
dp = 0.00005
expression = calc_expression(sum, P, dp)
print(expression)
##0.17092682846922776
Вычисленное значение равно 0.1709. Положительное значение! Это значит, что подозрение на разные типы начисления процентов верно. Теперь нам нужно уточнить значение dp, чтобы достичь точности до третьего десятичного знака.
Давайте проведём три таких итерации. В каждой итерации:
- Выполним шаг 2 - используем значение dp, полученное на предыдущей итерации.
- Вычислим новое значение dp, на которое нужно изменить значение P. Проведем это изменение в такую сторону, при которой значение expression будет точно равняться нулю.
- Если результат вычислений исключает значение dp по модулю, то следующее значение dp будет равно dp/10.
- Если модуль значения expression меньше 0.001, то вычисления останавливаются.
Вот код реализации:
dp = 0.00005
step = 0.00001
precision = 0.001
count = 0
while True:
expression = calc_expression(sum, P, dp)
if abs(expression) < precision:
break
if expression > 0:
dp -= step
else:
dp += step
step /= 10
count += 1
print("dp:", dp)
print("count:", count)
С моими значениями variables переменные конечный шаг оказался 8.000000000005463e-08. После третьей итерации функции выдаёт приращение поезиции в качестве -1.8000000000003577e-12.
Теперь мы можем рассчитать итоговое значение процента:
final_P = P + dp
annual_interest_rate = round(final_P * 100)
print("Annual interest rate:", annual_interest_rate)
Мы умножаем на 100, чтобы перевести его в проценты и округляем до целого числа.
Приходит значение 9. Значит, годовой процент по вкладу с учетом ежемесячного ринвестирования начисленного дохода равен 9%.