BondYTMCalculator::getApproxBondYTM()   B
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 33
Code Lines 22

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 33
rs 8.8571
cc 1
eloc 22
nc 1
nop 0
1
<?php
2
3
namespace FinanCalc\Calculators {
4
5
    use FinanCalc\Interfaces\Calculator\BondCalculatorAbstract;
6
    use FinanCalc\Utils\Lambdas;
7
    use FinanCalc\Utils\MathFuncs;
8
9
    /**
10
     * Class BondYTMCalculator
11
     * @package FinanCalc\Calculators
12
     */
13
    class BondYTMCalculator extends BondCalculatorAbstract
14
    {
15
16
        // market value of the bond = 'P'
17
        protected $bondMarketValue;
18
19
        // INHERITED MEMBERS
20
        // face value of the bond = 'F'
21
        // $bondFaceValue;
22
23
        // coupon rate of the bond per annum = 'c'
24
        // $bondAnnualCouponRate;
25
26
        // number of years to the maturity of the bond
27
        // $bondYearsToMaturity;
28
29
        // frequency of bond payments (expressed in a divisor of 12 months ~ 1 year)
30
        // e.g.: divisor 2 means semi-annual payments
31
        // $bondPaymentFrequency;
32
33
        // props returned by the getResultAsArray method by default
34
        protected $propResultArray = [
35
            "bondFaceValue",
36
            "bondMarketValue",
37
            "bondAnnualCouponRate",
38
            "bondYearsToMaturity",
39
            "bondPaymentFrequency",
40
            "bondApproxYTM" => "approxBondYTM"
41
        ];
42
43
        /**
44
         * @param $bondFaceValue
45
         * @param $bondMarketValue
46
         * @param $bondAnnualCouponRate
47
         * @param $bondYearsToMaturity
48
         * @param $bondPaymentFrequency
49
         */
50
        public function __construct(
51
            $bondFaceValue,
52
            $bondMarketValue,
53
            $bondAnnualCouponRate,
54
            $bondYearsToMaturity,
55
            $bondPaymentFrequency = 1
56
        ) {
57
            $this->setBondFaceValue($bondFaceValue);
58
            $this->setBondMarketValue($bondMarketValue);
59
            $this->setBondAnnualCouponRate($bondAnnualCouponRate);
60
            $this->setBondYearsToMaturity($bondYearsToMaturity);
61
            $this->setBondPaymentFrequency($bondPaymentFrequency);
62
        }
63
64
        /**
65
         * @param $bondMarketValue
66
         */
67
        public function setBondMarketValue($bondMarketValue)
68
        {
69
            $this->setProperty("bondMarketValue", $bondMarketValue, Lambdas::checkIfPositive());
70
        }
71
72
        /**
73
         * @return mixed
74
         */
75
        public function getBondMarketValue()
76
        {
77
            return $this->bondMarketValue;
78
        }
79
80
        /**
81
         * @return string
82
         */
83
        public function getApproxBondYTM()
84
        {
85
            // we need to calculate the coupon payment C = F*(c/payment frequency)
86
            $couponPayment =
87
                MathFuncs::mul(
88
                    $this->bondFaceValue,
89
                    MathFuncs::div(
90
                        $this->bondAnnualCouponRate,
91
                        $this->bondPaymentFrequency
92
                    )
93
                );
94
95
            // we use a formula to approximate the YTM = (C+(F-P)/n)/((F+P)/2)
96
            $approxYTM =
97
                MathFuncs::div(
98
                    MathFuncs::add(
99
                        $couponPayment,
100
                        MathFuncs::div(
101
                            MathFuncs::sub(
102
                                $this->bondFaceValue,
103
                                $this->bondMarketValue),
104
                            $this->getBondNoOfPayments()
105
                        )
106
                    ),
107
                    MathFuncs::div(
108
                        MathFuncs::add(
109
                            $this->bondFaceValue,
110
                            $this->bondMarketValue
111
                        ),
112
                        2));
113
114
            return $approxYTM;
115
        }
116
117
        // TODO – add a method for precise bond YTM calculation by means of a polynomial equation
118
    }
119
}
120