Как реализовать Excel ACCRINT

Как часть проекта Formula.js, я пытаюсь переделать Excel ACCRINT (в JavaScript, но язык не должен иметь значения). Я пытался найти правильное описание того, как он должен работать (особенно в отношении параметра first_interest), но ничего не нашел.

Интересно, что Excel, Google Spreadsheets, Apple Numbers, Gnumeric и OpenOffice не согласны с тем, как реализовать его, хотя все три основные версии Excel (Win, Mac, Web), похоже, согласуются друг с другом. В этом блоге можно найти еще несколько контекстов.

Десятки тестов и моя текущая (исправленная) реализация можно найти здесь.

Любая помощь будет принята с благодарностью!

ОБНОВЛЕНИЕ: чтобы быть ясным, проблема не, связанная с счетчиком дневных счетов, которую мы реализовали с помощью David Wheeler псевдокод для YEARFRAC, который сам был подтвержден более чем 32 миллионами тестов, охватывающих все пять базовых вариантов. Проблема исходит из параметра first_interest, который, по-видимому, никто не понимает. Насколько мы можем судить, этот параметр просто игнорируется многими альтернативными электронными таблицами, включая OpenOffice (он комментируется в исходном коде). И этот параметр действительно ведет себя странным образом. Если вы используете Excel и вы измените его значение, вы увидите, что он изменит результаты, полученные функцией ACCRINT, но так, как будто они хаотичны. Попытайтесь изменить дату first_interest на полный век, и вы увидите, что начисленные проценты меняются, но не сильно. Я действительно не могу понять. Если кто-нибудь может, я все уши...

2 ответа

Phil H от Quantitative Finance нашла эту . NET-библиотеку, которая обеспечивает реализация чистой комнаты для всех финансовых функций, и все, кроме двух, похоже, проходят тест (на самом деле, 201 349 тестовых случаев). К ним относятся ACCRINT. Код лицензирован согласно Creative Commons Attribution. Это написано в F #, но это довольно ясно. Код для ACCRINT находится в файле bonds.fs. Мы попытаемся перенести его на JavaScript и посмотреть, получим ли мы те же результаты, что и Excel. Подробнее об этом скоро...


Это в php (я думаю): от эта страница

/**
 * ACCRINT
 *
 * Returns the discount rate for a security.
 *
 * @param mixed issue The security issue date.
 * @param mixed firstinter The security first interest date.
 * @param mixed settlement The security settlement date.
 * @param float rate The security annual coupon rate.
 * @param float par The security par value.
 * @param int basis The type of day count to use.
 * 0 or omitted US (NASD) 30/360
 * 1 Actual/actual
 * 2 Actual/360
 * 3 Actual/365
 * 4 European 30/360
 * @return float
 */
public static function ACCRINT($issue, $firstinter, $settlement, $rate, $par=1000, $frequency=1, $basis=0) {
 $issue = self::flattenSingleValue($issue);
 $firstinter = self::flattenSingleValue($firstinter);
 $settlement = self::flattenSingleValue($settlement);
 $rate = (float) self::flattenSingleValue($rate);
 $par = (is_null($par)) ? 1000 : (float) self::flattenSingleValue($par);
 $frequency = (is_null($frequency)) ? 1 : (int) self::flattenSingleValue($frequency);
 $basis = (is_null($basis)) ? 0 : (int) self::flattenSingleValue($basis);
 // Validate
 if ((is_numeric($rate)) && (is_numeric($par))) {
 if (($rate <= 0) || ($par <= 0)) {
 return self::$_errorCodes['num'];
 }
 $daysBetweenIssueAndSettlement = self::YEARFRAC($issue, $settlement, $basis);
 if (!is_numeric($daysBetweenIssueAndSettlement)) {
 return $daysBetweenIssueAndSettlement;
 }
 $daysPerYear = self::_daysPerYear(self::YEAR($issue),$basis);
 if (!is_numeric($daysPerYear)) {
 return $daysPerYear;
 }
 $daysBetweenIssueAndSettlement *= $daysPerYear;
 return $par * $rate * ($daysBetweenIssueAndSettlement / $daysPerYear);
 }
 return self::$_errorCodes['value'];
 } // function ACCRINT()

licensed under cc by-sa 3.0 with attribution.