Javascript 如何实现Excel';s账户
作为项目的一部分,我正在尝试重新实现Excel的功能(使用JavaScript,但语言不重要)。我一直在试图找到它应该如何工作的正确描述(特别是关于Javascript 如何实现Excel';s账户,javascript,excel,excel-formula,Javascript,Excel,Excel Formula,作为项目的一部分,我正在尝试重新实现Excel的功能(使用JavaScript,但语言不重要)。我一直在试图找到它应该如何工作的正确描述(特别是关于first\u interest参数),但找不到任何东西 有趣的是,Excel、Google电子表格、Apple数字、Gnumeric和OpenOffice在实现方式上都存在分歧,尽管Excel的三个主要版本(Win、Mac、Web)似乎彼此一致。关于这一点,可以找到更多的上下文 可以找到几十个测试用例和我当前的(有缺陷的)实现 任何帮助都将不胜感激
first\u interest
参数),但找不到任何东西
有趣的是,Excel、Google电子表格、Apple数字、Gnumeric和OpenOffice在实现方式上都存在分歧,尽管Excel的三个主要版本(Win、Mac、Web)似乎彼此一致。关于这一点,可以找到更多的上下文
可以找到几十个测试用例和我当前的(有缺陷的)实现
任何帮助都将不胜感激
更新:需要明确的是,该问题与我们使用David Wheeler的for实现的有关,它本身经过3200多万次测试验证,涵盖了所有五个基本选项。这个问题来自于first\u interest
参数,似乎没有人真正理解它。就我们所知,这个参数只是被许多其他电子表格忽略了,包括OpenOffice(它在源代码中被注释掉)。这个参数的行为真的很奇怪。如果您使用Excel并更改其值,您将看到它将更改函数给出的结果,但方式似乎很混乱。尝试将第一次利息日期更改整整一个世纪,您将看到应计利息的变化,但变化不大。我真的搞不懂。如果有人可以,我洗耳恭听……这是php语言(我想):来自
/**
*帐户
*
*返回证券的贴现率。
*
*@param混合发行证券的发行日期。
*@param在证券的第一个计息日。
*@param混合结算证券的结算日期。
*@param浮动利率证券的年票面利率。
*PARAM浮动与安全的面值一致。
*@param int basis要使用的天数类型。
*0或省略美国标准(NASD)30/360
*1实际/实际
*2实际值/360
*3实际/365
*4欧洲30/360
*@返回浮动
*/
公共静态函数ACCRINT($issue,$firstinter,$settlement,$rate,$par=1000,$frequency=1,$basis=0){
$issue=self::FlattSingleValue($issue);
$firstinter=self::flattsinglevalue($firstinter);
$consolution=自我价值($consolution);
$rate=(float)self::flattsinglevalue($rate);
$par=(为空($par))?1000:(浮动)自我::单一值($par);
$frequency=(is_null($frequency))?1:(int)self::flattsinglevalue($frequency);
$basis=(is_null($basis))?0:(int)self::flattsinglevalue($basis);
//证实
如果((是数字($rate))&(是数字($par))){
如果定量金融(Quantitative Finance)的($rate发现了这一点,它为所有金融功能提供了洁净室实现,除了两个之外,其他所有功能似乎都通过了测试(事实上是201349个测试用例)。其中包括ACCRINT。该代码是根据Creative Commons属性授权的。它是用F#编写的,但非常清楚。ACCRINT的代码在bonds.fs文件中。我们将尝试将其移植到JavaScript,看看是否得到与Excel返回的结果相同的结果。很快会有更多信息…哦,不!一个好问题!我该如何忍受?(+1)不幸的是,该代码没有考虑首次感兴趣的频率和日期。
/**
* ACCRINT
*
* Returns the discount rate for a security.
*
* @param mixed issue The security's issue date.
* @param mixed firstinter The security's first interest date.
* @param mixed settlement The security's settlement date.
* @param float rate The security's annual coupon rate.
* @param float par The security's 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()