Skip to content

Commit 3818f02

Browse files
author
MarkBaker
committed
Group #2, Treasury Bill functions
1 parent 5ad1675 commit 3818f02

File tree

3 files changed

+218
-92
lines changed

3 files changed

+218
-92
lines changed

src/PhpSpreadsheet/Calculation/Financial.php

+20-92
Original file line numberDiff line numberDiff line change
@@ -2006,6 +2006,10 @@ public static function SYD($cost, $salvage, $life, $period)
20062006
*
20072007
* Returns the bond-equivalent yield for a Treasury bill.
20082008
*
2009+
* @Deprecated 1.18.0
2010+
*
2011+
* @see Use the bondEquivalentYield() method in the Financial\TreasuryBill class instead
2012+
*
20092013
* @param mixed $settlement The Treasury bill's settlement date.
20102014
* The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
20112015
* @param mixed $maturity The Treasury bill's maturity date.
@@ -2016,37 +2020,21 @@ public static function SYD($cost, $salvage, $life, $period)
20162020
*/
20172021
public static function TBILLEQ($settlement, $maturity, $discount)
20182022
{
2019-
$settlement = Functions::flattenSingleValue($settlement);
2020-
$maturity = Functions::flattenSingleValue($maturity);
2021-
$discount = Functions::flattenSingleValue($discount);
2022-
2023-
// Use TBILLPRICE for validation
2024-
$testValue = self::TBILLPRICE($settlement, $maturity, $discount);
2025-
if (is_string($testValue)) {
2026-
return $testValue;
2027-
}
2028-
2029-
if (is_string($maturity = DateTime::getDateValue($maturity))) {
2030-
return Functions::VALUE();
2031-
}
2032-
2033-
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
2034-
++$maturity;
2035-
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
2036-
} else {
2037-
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
2038-
}
2039-
2040-
return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity);
2023+
return Financial\TreasuryBill::bondEquivalentYield($settlement, $maturity, $discount);
20412024
}
20422025

20432026
/**
20442027
* TBILLPRICE.
20452028
*
2046-
* Returns the yield for a Treasury bill.
2029+
* Returns the price per $100 face value for a Treasury bill.
2030+
*
2031+
* @Deprecated 1.18.0
2032+
*
2033+
* @see Use the price() method in the Financial\TreasuryBill class instead
20472034
*
20482035
* @param mixed $settlement The Treasury bill's settlement date.
2049-
* The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
2036+
* The Treasury bill's settlement date is the date after the issue date
2037+
* when the Treasury bill is traded to the buyer.
20502038
* @param mixed $maturity The Treasury bill's maturity date.
20512039
* The maturity date is the date when the Treasury bill expires.
20522040
* @param int $discount The Treasury bill's discount rate
@@ -2055,53 +2043,21 @@ public static function TBILLEQ($settlement, $maturity, $discount)
20552043
*/
20562044
public static function TBILLPRICE($settlement, $maturity, $discount)
20572045
{
2058-
$settlement = Functions::flattenSingleValue($settlement);
2059-
$maturity = Functions::flattenSingleValue($maturity);
2060-
$discount = Functions::flattenSingleValue($discount);
2061-
2062-
if (is_string($maturity = DateTime::getDateValue($maturity))) {
2063-
return Functions::VALUE();
2064-
}
2065-
2066-
// Validate
2067-
if (is_numeric($discount)) {
2068-
if ($discount <= 0) {
2069-
return Functions::NAN();
2070-
}
2071-
2072-
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
2073-
++$maturity;
2074-
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
2075-
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
2076-
// return date error
2077-
return $daysBetweenSettlementAndMaturity;
2078-
}
2079-
} else {
2080-
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
2081-
}
2082-
2083-
if ($daysBetweenSettlementAndMaturity > self::daysPerYear(DateTime::YEAR($maturity), 1)) {
2084-
return Functions::NAN();
2085-
}
2086-
2087-
$price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360));
2088-
if ($price <= 0) {
2089-
return Functions::NAN();
2090-
}
2091-
2092-
return $price;
2093-
}
2094-
2095-
return Functions::VALUE();
2046+
return Financial\TreasuryBill::price($settlement, $maturity, $discount);
20962047
}
20972048

20982049
/**
20992050
* TBILLYIELD.
21002051
*
21012052
* Returns the yield for a Treasury bill.
21022053
*
2054+
* @Deprecated 1.18.0
2055+
*
2056+
* @see Use the yield() method in the Financial\TreasuryBill class instead
2057+
*
21032058
* @param mixed $settlement The Treasury bill's settlement date.
2104-
* The Treasury bill's settlement date is the date after the issue date when the Treasury bill is traded to the buyer.
2059+
* The Treasury bill's settlement date is the date after the issue date
2060+
* when the Treasury bill is traded to the buyer.
21052061
* @param mixed $maturity The Treasury bill's maturity date.
21062062
* The maturity date is the date when the Treasury bill expires.
21072063
* @param int $price The Treasury bill's price per $100 face value
@@ -2110,35 +2066,7 @@ public static function TBILLPRICE($settlement, $maturity, $discount)
21102066
*/
21112067
public static function TBILLYIELD($settlement, $maturity, $price)
21122068
{
2113-
$settlement = Functions::flattenSingleValue($settlement);
2114-
$maturity = Functions::flattenSingleValue($maturity);
2115-
$price = Functions::flattenSingleValue($price);
2116-
2117-
// Validate
2118-
if (is_numeric($price)) {
2119-
if ($price <= 0) {
2120-
return Functions::NAN();
2121-
}
2122-
2123-
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
2124-
++$maturity;
2125-
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
2126-
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
2127-
// return date error
2128-
return $daysBetweenSettlementAndMaturity;
2129-
}
2130-
} else {
2131-
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
2132-
}
2133-
2134-
if ($daysBetweenSettlementAndMaturity > 360) {
2135-
return Functions::NAN();
2136-
}
2137-
2138-
return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity);
2139-
}
2140-
2141-
return Functions::VALUE();
2069+
return Financial\TreasuryBill::yield($settlement, $maturity, $price);
21422070
}
21432071

21442072
private static function bothNegAndPos($neg, $pos)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheet\Calculation\Financial;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7+
8+
class Helpers
9+
{
10+
public const DAYS_PER_YEAR_NASD = 0;
11+
public const DAYS_PER_YEAR_ACTUAL = 1;
12+
public const DAYS_PER_YEAR_360 = 2;
13+
public const DAYS_PER_YEAR_365 = 3;
14+
public const DAYS_PER_YEAR_360_EUROPEAN = 4;
15+
16+
/**
17+
* daysPerYear.
18+
*
19+
* Returns the number of days in a specified year, as defined by the "basis" value
20+
*
21+
* @param int|string $year The year against which we're testing
22+
* @param int|string $basis The type of day count:
23+
* 0 or omitted US (NASD) 360
24+
* 1 Actual (365 or 366 in a leap year)
25+
* 2 360
26+
* 3 365
27+
* 4 European 360
28+
*
29+
* @return int|string Result, or a string containing an error
30+
*/
31+
public static function daysPerYear($year, $basis = 0)
32+
{
33+
switch ($basis) {
34+
case self::DAYS_PER_YEAR_NASD:
35+
case self::DAYS_PER_YEAR_360:
36+
case self::DAYS_PER_YEAR_360_EUROPEAN:
37+
return 360;
38+
case self::DAYS_PER_YEAR_365:
39+
return 365;
40+
case self::DAYS_PER_YEAR_ACTUAL:
41+
return (DateTime::isLeapYear($year)) ? 366 : 365;
42+
}
43+
44+
return Functions::NAN();
45+
}
46+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<?php
2+
3+
namespace PhpOffice\PhpSpreadsheet\Calculation\Financial;
4+
5+
use PhpOffice\PhpSpreadsheet\Calculation\DateTime;
6+
use PhpOffice\PhpSpreadsheet\Calculation\Functions;
7+
8+
class TreasuryBill
9+
{
10+
/**
11+
* TBILLEQ.
12+
*
13+
* Returns the bond-equivalent yield for a Treasury bill.
14+
*
15+
* @param mixed $settlement The Treasury bill's settlement date.
16+
* The Treasury bill's settlement date is the date after the issue date
17+
* when the Treasury bill is traded to the buyer.
18+
* @param mixed $maturity The Treasury bill's maturity date.
19+
* The maturity date is the date when the Treasury bill expires.
20+
* @param int $discount The Treasury bill's discount rate
21+
*
22+
* @return float|string Result, or a string containing an error
23+
*/
24+
public static function bondEquivalentYield($settlement, $maturity, $discount)
25+
{
26+
$settlement = Functions::flattenSingleValue($settlement);
27+
$maturity = Functions::flattenSingleValue($maturity);
28+
$discount = Functions::flattenSingleValue($discount);
29+
30+
// Use TBILLPRICE for validation
31+
$testValue = self::price($settlement, $maturity, $discount);
32+
if (is_string($testValue)) {
33+
return $testValue;
34+
}
35+
36+
if (is_string($maturity = DateTime::getDateValue($maturity))) {
37+
return Functions::VALUE();
38+
}
39+
40+
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
41+
++$maturity;
42+
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
43+
} else {
44+
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
45+
}
46+
47+
return (365 * $discount) / (360 - $discount * $daysBetweenSettlementAndMaturity);
48+
}
49+
50+
/**
51+
* TBILLPRICE.
52+
*
53+
* Returns the price per $100 face value for a Treasury bill.
54+
*
55+
* @param mixed $settlement The Treasury bill's settlement date.
56+
* The Treasury bill's settlement date is the date after the issue date
57+
* when the Treasury bill is traded to the buyer.
58+
* @param mixed $maturity The Treasury bill's maturity date.
59+
* The maturity date is the date when the Treasury bill expires.
60+
* @param int $discount The Treasury bill's discount rate
61+
*
62+
* @return float|string Result, or a string containing an error
63+
*/
64+
public static function price($settlement, $maturity, $discount)
65+
{
66+
$settlement = Functions::flattenSingleValue($settlement);
67+
$maturity = Functions::flattenSingleValue($maturity);
68+
$discount = Functions::flattenSingleValue($discount);
69+
70+
if (is_string($maturity = DateTime::getDateValue($maturity))) {
71+
return Functions::VALUE();
72+
}
73+
74+
// Validate
75+
if (is_numeric($discount)) {
76+
if ($discount <= 0) {
77+
return Functions::NAN();
78+
}
79+
80+
if (Functions::getCompatibilityMode() === Functions::COMPATIBILITY_OPENOFFICE) {
81+
++$maturity;
82+
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
83+
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
84+
// return date error
85+
return $daysBetweenSettlementAndMaturity;
86+
}
87+
} else {
88+
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
89+
}
90+
91+
if ($daysBetweenSettlementAndMaturity > Helpers::daysPerYear(DateTime::YEAR($maturity), 1)) {
92+
return Functions::NAN();
93+
}
94+
95+
$price = 100 * (1 - (($discount * $daysBetweenSettlementAndMaturity) / 360));
96+
if ($price <= 0) {
97+
return Functions::NAN();
98+
}
99+
100+
return $price;
101+
}
102+
103+
return Functions::VALUE();
104+
}
105+
106+
/**
107+
* TBILLYIELD.
108+
*
109+
* Returns the yield for a Treasury bill.
110+
*
111+
* @param mixed $settlement The Treasury bill's settlement date.
112+
* The Treasury bill's settlement date is the date after the issue date when
113+
* the Treasury bill is traded to the buyer.
114+
* @param mixed $maturity The Treasury bill's maturity date.
115+
* The maturity date is the date when the Treasury bill expires.
116+
* @param int $price The Treasury bill's price per $100 face value
117+
*
118+
* @return float|mixed|string
119+
*/
120+
public static function yield($settlement, $maturity, $price)
121+
{
122+
$settlement = Functions::flattenSingleValue($settlement);
123+
$maturity = Functions::flattenSingleValue($maturity);
124+
$price = Functions::flattenSingleValue($price);
125+
126+
// Validate
127+
if (is_numeric($price)) {
128+
if ($price <= 0) {
129+
return Functions::NAN();
130+
}
131+
132+
if (Functions::getCompatibilityMode() == Functions::COMPATIBILITY_OPENOFFICE) {
133+
++$maturity;
134+
$daysBetweenSettlementAndMaturity = DateTime::YEARFRAC($settlement, $maturity) * 360;
135+
if (!is_numeric($daysBetweenSettlementAndMaturity)) {
136+
// return date error
137+
return $daysBetweenSettlementAndMaturity;
138+
}
139+
} else {
140+
$daysBetweenSettlementAndMaturity = (DateTime::getDateValue($maturity) - DateTime::getDateValue($settlement));
141+
}
142+
143+
if ($daysBetweenSettlementAndMaturity > 360) {
144+
return Functions::NAN();
145+
}
146+
147+
return ((100 - $price) / $price) * (360 / $daysBetweenSettlementAndMaturity);
148+
}
149+
150+
return Functions::VALUE();
151+
}
152+
}

0 commit comments

Comments
 (0)