Рассчитать процентную ставку от ежемесячного платежа в SQL - PullRequest
0 голосов
/ 04 декабря 2018

Есть ли способ, как рассчитать процентную ставку, зная сумму кредита, ежемесячный платеж и срок в SQL (Oracle)?Я могу легко рассчитать платеж, зная процентную ставку, однако обратный путь представляется гораздо более сложным.

Расчет ежемесячного платежа (Процентная ставка = 0,1 (10%), Размер кредита = 1000, Срок = 24):

   select (0.1/12 * 1000) / (1 - power(1 + 0.1/12, -24)) as mpayment 
   from dual;
   46.1449263375165

Вопрос в том, как перейти от ежемесячного платежа в размере 46,14 долл. США, размера кредита в 1000 долл. США, срока в 24 месяца и расчета процентной ставки 10%.

Например, в MS Excel функцияиспользовать будет RATE()

1 Ответ

0 голосов
/ 05 декабря 2018

Как я сказал в комментарии под вашим постом: то, что вы ищете, называется «внутренней нормой прибыли».На самом деле вы ищете совершенно особый случай - амортизированный кредит с равными выплатами через равные промежутки времени.Oracle предлагает функцию IRR в дополнительных пакетах;если вы хотите использовать только базовый SQL и PL / SQL, вам придется использовать UDF (пользовательскую функцию).

Вот один из способов его кодирования с использованием метода Ньютона.Я демонстрирую несколько вещей одновременно.Обратите внимание на числовые типы данных (которые относятся к PL / SQL и не могут использоваться в простом SQL; однако среда выполнения преобразует входные данные из NUMBER в типы данных PL / SQL, а возвращаемое значение обратно в NUMBER, прозрачно).Использование этих типов данных в коде делает функцию намного быстрее, особенно если вы используете собственную компиляцию (что сделано, как показано в первой строке кода ниже).

Пока что все должно работать в более старых версияхPL / SQL.Начиная с версии 12.1, и только если вы собираетесь вызывать функцию в основном из SQL, вы можете использовать объявление pragma udf, которое ускорит простой код SQL, вызывающий функцию.

Функция возвращает«Годовая» ставка по ипотечному кредиту (она рассчитывает месячную ставку, а затем просто умножает на 12 - без начисления процентов - так работает процентная ставка по ипотечному кредиту, по крайней мере, в США).Скорость возвращается в виде десятичного числа, не умноженного на 100;то есть не в процентах.Если ставка, возвращаемая функцией, равна 0,038, это означает 3,8% (годовая процентная ставка по ипотечному кредиту).В краткой демонстрации в конце я расскажу, как можно обернуть вызов функции в другой код SQL, чтобы украсить ответ.

Для примера в конце я взял 200 000 основных значений и рассчитал ежемесячный платеж.свыше 30 лет (360 месяцев) с процентной ставкой 6,5%;Я получил ежемесячный платеж в размере 1264,14.Затем я вычисляю процентную ставку из других значений.

Функция требует основную сумму и ежемесячный платеж, как NOT NULL, так и предполагаемые положительные.Термин (В МЕСЯЦАХ) также необходим, но я кодировал значение по умолчанию 360. (Возможно, было бы лучше не кодировать значение по умолчанию для этого и сделать его обязательным.) При желании вы можете ввести желаемую точность;По умолчанию я кодировал очень высокую точность, так как вычисления все равно очень быстрые.

Я не кодировал никакой обработки ошибок;очевидно, что это нужно будет сделать, если вы решите использовать эту функцию (или что-то подобное) для любых целей, кроме обучения / обучения.

alter session set plsql_code_type = native;

create or replace function mortgage_rate(
  p_principal       simple_double
, p_monthly_payment simple_double
, p_term            simple_integer default 360
, p_precision       simple_double  default 0.00000001
)
return number
as 
  pragma udf;     --  Comment out this line if Oracle version is < 12.1
  z     simple_double  := p_monthly_payment/p_principal; 
  u     simple_double  := 1 / (p_term * z);
  v     simple_double  := 0;
  delta simple_double  := 0;
begin
  for i in 1 .. 100 loop
    v     := power(u, p_term);
    delta := ( z * u * ( v - 1) - u + 1 ) / ( z * (p_term + 1) * v - z - 1 );
    u     := u - delta;
    exit when abs(delta) < p_precision;
  end loop;
  return 12 * (1/u - 1);
end;
/


select to_char( 100 * mortgage_rate(200000, 1264.14, 360), 'fm990.000')
       || '%' as interest_rate
from   dual; 


INTEREST_RATE
----------------
6.500%
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...