2013-01-20 11 views
7
w programie Excel

W ramach projektu Formula.js próbuję ponownie zaimplementować funkcję programu Excel w wersji ACCRINT (w języku JavaScript, ale język nie powinien mieć znaczenia). Próbuję znaleźć odpowiedni opis tego, jak powinien działać (szczególnie w odniesieniu do parametru first_interest), ale nie mógł znaleźć niczego.Jak zaimplementować program ACCRINT

Co ciekawe, Excel, arkusze kalkulacyjne Google, numery Apple, Gnumeric i OpenOffice nie zgadzają się co do sposobu wdrożenia, mimo że wszystkie trzy główne wersje programu Excel (Win, Mac, Web) wydają się ze sobą zgadzać. Na tej blog post można znaleźć trochę więcej kontekstu.

Dziesiątki przypadków testowych i moją obecną (wadliwą) implementację można znaleźć pod numerem here.

Każda pomoc będzie bardzo ceniona!

UPDATE: być jasne, że problem jest nie związane z day count convention, którą realizowanego przy użyciu David Wheeler pseudocode dla YEARFRAC, która sama została potwierdzona przez ponad 32 milionów testów, obejmujących wszystkie pięć opcji bazowych. Problem pochodzi z parametru first_interest, którego nikt nie rozumie. O ile nam wiadomo, ten parametr jest po prostu ignorowany przez wiele alternatywnych arkuszy kalkulacyjnych, w tym OpenOffice (jest to skomentowane w kodzie źródłowym). A ten parametr naprawdę zachowuje się w dziwny sposób. Jeśli używasz programu Excel i zmienisz jego wartość, zobaczysz, że zmieni on wyniki podane przez funkcję ACCRINT, ale w sposób, który wydaje się chaotyczny. Spróbuj zmienić datę first_interest na pełny wiek, a zobaczysz, że naliczone odsetki zmieniają się, ale nie za dużo. Naprawdę nie mogę tego zrozumieć. Jeśli ktoś może, jestem wszystkich uszy ...

+1

O nie! Dobre pytanie! Jak mam z tym pogodzić? (+1) –

Odpowiedz

0

Phil H od Quantitative Finance uznał ten .NET library, który zapewnia czyste implementacje pokój dla wszystkich finansowych Funkcje i wszystkie, z wyjątkiem dwóch, zdają się zdawać test (201 349 przypadków testowych). Należą do nich ACCRINT. Kod jest dostępny na licencji Creative Commons Uznanie autorstwa. Jest napisany w języku F #, ale jest całkiem jasne. Kod dla ACCRINT znajduje się w pliku bonds.fs. Spróbujemy przenieść ją na JavaScript i sprawdzić, czy otrzymamy takie same wyniki, jak Excel. Więcej na ten temat wkrótce ...

0

to w php (myślę): od this page

/** 
    * 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() 
+0

Dzięki za napiwek! –

+0

Niestety, ten kod nie uwzględnia częstotliwości ani daty pierwszego zainteresowania. –

Powiązane problemy