tablepress
/
libraries
/
vendor
/
PhpSpreadsheet
/
Calculation
/
Financial
/
Securities
/
AccruedInterest.php
AccruedInterest.php in TablePress – Tables in WordPress made easy 3.4, at libraries/vendor/PhpSpreadsheet/Calculation/Financial/Securities/AccruedInterest.php
| 1 | <?php |
| 2 | |
| 3 | namespace TablePress\PhpOffice\PhpSpreadsheet\Calculation\Financial\Securities; |
| 4 | |
| 5 | use TablePress\PhpOffice\PhpSpreadsheet\Calculation\DateTimeExcel\YearFrac; |
| 6 | use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Exception; |
| 7 | use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Financial\Constants as FinancialConstants; |
| 8 | use TablePress\PhpOffice\PhpSpreadsheet\Calculation\Functions; |
| 9 | use TablePress\PhpOffice\PhpSpreadsheet\Shared\StringHelper; |
| 10 | |
| 11 | class AccruedInterest |
| 12 | { |
| 13 | public const ACCRINT_CALCMODE_ISSUE_TO_SETTLEMENT = true; |
| 14 | |
| 15 | public const ACCRINT_CALCMODE_FIRST_INTEREST_TO_SETTLEMENT = false; |
| 16 | |
| 17 | /** |
| 18 | * ACCRINT. |
| 19 | * |
| 20 | * Returns the accrued interest for a security that pays periodic interest. |
| 21 | * |
| 22 | * Excel Function: |
| 23 | * ACCRINT(issue,firstinterest,settlement,rate,par,frequency[,basis][,calc_method]) |
| 24 | * |
| 25 | * @param mixed $issue the security's issue date |
| 26 | * @param mixed $firstInterest the security's first interest date |
| 27 | * @param mixed $settlement The security's settlement date. |
| 28 | * The security settlement date is the date after the issue date |
| 29 | * when the security is traded to the buyer. |
| 30 | * @param mixed $rate The security's annual coupon rate |
| 31 | * @param mixed $parValue The security's par value. |
| 32 | * If you omit par, ACCRINT uses $1,000. |
| 33 | * @param mixed $frequency The number of coupon payments per year. |
| 34 | * Valid frequency values are: |
| 35 | * 1 Annual |
| 36 | * 2 Semi-Annual |
| 37 | * 4 Quarterly |
| 38 | * @param mixed $basis The type of day count to use. |
| 39 | * 0 or omitted US (NASD) 30/360 |
| 40 | * 1 Actual/actual |
| 41 | * 2 Actual/360 |
| 42 | * 3 Actual/365 |
| 43 | * 4 European 30/360 |
| 44 | * @param mixed $calcMethod Unused by PhpSpreadsheet, and apparently by Excel (https://exceljet.net/functions/accrint-function) |
| 45 | * |
| 46 | * @return float|string Result, or a string containing an error |
| 47 | */ |
| 48 | public static function periodic( |
| 49 | $issue, |
| 50 | $firstInterest, |
| 51 | $settlement, |
| 52 | $rate, |
| 53 | $parValue = 1000, |
| 54 | $frequency = FinancialConstants::FREQUENCY_ANNUAL, |
| 55 | $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD, |
| 56 | $calcMethod = self::ACCRINT_CALCMODE_ISSUE_TO_SETTLEMENT |
| 57 | ) { |
| 58 | $issue = Functions::flattenSingleValue($issue); |
| 59 | $firstInterest = Functions::flattenSingleValue($firstInterest); |
| 60 | $settlement = Functions::flattenSingleValue($settlement); |
| 61 | $rate = Functions::flattenSingleValue($rate); |
| 62 | $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue); |
| 63 | $frequency = Functions::flattenSingleValue($frequency) ?? FinancialConstants::FREQUENCY_ANNUAL; |
| 64 | $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; |
| 65 | |
| 66 | try { |
| 67 | $issue = SecurityValidations::validateIssueDate($issue); |
| 68 | $settlement = SecurityValidations::validateSettlementDate($settlement); |
| 69 | SecurityValidations::validateSecurityPeriod($issue, $settlement); |
| 70 | $rate = SecurityValidations::validateRate($rate); |
| 71 | $parValue = SecurityValidations::validateParValue($parValue); |
| 72 | SecurityValidations::validateFrequency($frequency); |
| 73 | $basis = SecurityValidations::validateBasis($basis); |
| 74 | } catch (Exception $e) { |
| 75 | return $e->getMessage(); |
| 76 | } |
| 77 | |
| 78 | $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis)); |
| 79 | if (!is_numeric($daysBetweenIssueAndSettlement)) { |
| 80 | // return date error |
| 81 | return StringHelper::convertToString($daysBetweenIssueAndSettlement); |
| 82 | } |
| 83 | $daysBetweenFirstInterestAndSettlement = Functions::scalar(YearFrac::fraction($firstInterest, $settlement, $basis)); |
| 84 | if (!is_numeric($daysBetweenFirstInterestAndSettlement)) { |
| 85 | // return date error |
| 86 | return StringHelper::convertToString($daysBetweenFirstInterestAndSettlement); |
| 87 | } |
| 88 | |
| 89 | return $parValue * $rate * $daysBetweenIssueAndSettlement; |
| 90 | } |
| 91 | |
| 92 | /** |
| 93 | * ACCRINTM. |
| 94 | * |
| 95 | * Returns the accrued interest for a security that pays interest at maturity. |
| 96 | * |
| 97 | * Excel Function: |
| 98 | * ACCRINTM(issue,settlement,rate[,par[,basis]]) |
| 99 | * |
| 100 | * @param mixed $issue The security's issue date |
| 101 | * @param mixed $settlement The security's settlement (or maturity) date |
| 102 | * @param mixed $rate The security's annual coupon rate |
| 103 | * @param mixed $parValue The security's par value. |
| 104 | * If you omit parValue, ACCRINT uses $1,000. |
| 105 | * @param mixed $basis The type of day count to use. |
| 106 | * 0 or omitted US (NASD) 30/360 |
| 107 | * 1 Actual/actual |
| 108 | * 2 Actual/360 |
| 109 | * 3 Actual/365 |
| 110 | * 4 European 30/360 |
| 111 | * |
| 112 | * @return float|string Result, or a string containing an error |
| 113 | */ |
| 114 | public static function atMaturity( |
| 115 | $issue, |
| 116 | $settlement, |
| 117 | $rate, |
| 118 | $parValue = 1000, |
| 119 | $basis = FinancialConstants::BASIS_DAYS_PER_YEAR_NASD |
| 120 | ) { |
| 121 | $issue = Functions::flattenSingleValue($issue); |
| 122 | $settlement = Functions::flattenSingleValue($settlement); |
| 123 | $rate = Functions::flattenSingleValue($rate); |
| 124 | $parValue = ($parValue === null) ? 1000 : Functions::flattenSingleValue($parValue); |
| 125 | $basis = Functions::flattenSingleValue($basis) ?? FinancialConstants::BASIS_DAYS_PER_YEAR_NASD; |
| 126 | |
| 127 | try { |
| 128 | $issue = SecurityValidations::validateIssueDate($issue); |
| 129 | $settlement = SecurityValidations::validateSettlementDate($settlement); |
| 130 | SecurityValidations::validateSecurityPeriod($issue, $settlement); |
| 131 | $rate = SecurityValidations::validateRate($rate); |
| 132 | $parValue = SecurityValidations::validateParValue($parValue); |
| 133 | $basis = SecurityValidations::validateBasis($basis); |
| 134 | } catch (Exception $e) { |
| 135 | return $e->getMessage(); |
| 136 | } |
| 137 | |
| 138 | $daysBetweenIssueAndSettlement = Functions::scalar(YearFrac::fraction($issue, $settlement, $basis)); |
| 139 | if (!is_numeric($daysBetweenIssueAndSettlement)) { |
| 140 | // return date error |
| 141 | return StringHelper::convertToString($daysBetweenIssueAndSettlement); |
| 142 | } |
| 143 | |
| 144 | return $parValue * $rate * $daysBetweenIssueAndSettlement; |
| 145 | } |
| 146 | } |
| 147 |