StockDividendDiscountModelCalculator   A
last analyzed

Complexity

Total Complexity 19

Size/Duplication

Total Lines 167
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 8
Bugs 2 Features 2
Metric Value
wmc 19
lcom 1
cbo 6
dl 0
loc 167
rs 10
c 8
b 2
f 2

10 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A setDividendDiscountModelType() 0 11 3
A setStockVIR() 0 4 1
A setStockAnnualDividendsValue() 0 4 1
B setStockAnnualDividendsGrowth() 0 23 5
A getDividendDiscountModelType() 0 4 1
A getStockVIR() 0 4 1
A getStockAnnualDividendsValue() 0 4 1
A getStockAnnualDividendsGrowth() 0 4 1
B getStockPresentValue() 0 31 4
1
<?php
2
3
namespace FinanCalc\Calculators {
4
5
    use Exception;
6
    use FinanCalc\Constants\StockDDMTypes;
7
    use FinanCalc\Interfaces\Calculator\CalculatorAbstract;
8
    use FinanCalc\Utils\Helpers;
9
    use FinanCalc\Utils\Lambdas;
10
    use FinanCalc\Utils\MathFuncs;
11
    use FinanCalc\Utils\Strings;
12
    use InvalidArgumentException;
13
14
    /**
15
     * Class StockDividendDiscountModelCalculator
16
     * @package FinanCalc\Calculators
17
     */
18
    class StockDividendDiscountModelCalculator extends CalculatorAbstract
19
    {
20
21
        /** @var  StockDDMTypes */
22
        // the type of the dividend discount model according to which the result will be calculated
23
        protected $dividendDiscountModelType;
24
        // stock's valuation interest rate
25
        protected $stockVIR;
26
        // absolute value of the stock's annual dividends
27
        protected $stockAnnualDividendsValue;
28
        // the rate by which the stock's annual dividends grow annually (i.e., a decimal number between 0 and 1)
29
        // this value applies only to the multiple growth dividend discount model
30
        protected $stockAnnualDividendsGrowth;
31
32
        // props returned by the getResultAsArray method by default
33
        protected $propResultArray = [
34
            "dividendDiscountModelType",
35
            "stockVIR",
36
            "stockAnnualDividendsValue",
37
            "stockAnnualDividendsGrowth",
38
            "stockPresentValue"
39
        ];
40
41
        /**
42
         * @param StockDDMTypes $dividendDiscountModelType
43
         * @param $stockVIR
44
         * @param $stockAnnualDividendValue
45
         * @param null $stockAnnualDividendsGrowth
46
         */
47
        public function __construct(
48
            StockDDMTypes $dividendDiscountModelType,
49
            $stockVIR,
50
            $stockAnnualDividendValue,
51
            $stockAnnualDividendsGrowth = null
52
        ) {
53
            $this->setDividendDiscountModelType($dividendDiscountModelType);
54
            $this->setStockVIR($stockVIR);
55
            $this->setStockAnnualDividendsValue($stockAnnualDividendValue);
56
            $this->setStockAnnualDividendsGrowth($stockAnnualDividendsGrowth);
57
        }
58
59
        /**
60
         * @param StockDDMTypes $dividendDiscountModelType
61
         */
62
        public function setDividendDiscountModelType(StockDDMTypes $dividendDiscountModelType)
63
        {
64
            if (
65
                $dividendDiscountModelType->getValue() == StockDDMTypes::ZERO_GROWTH
66
                &&
67
                $this->stockAnnualDividendsGrowth !== null
68
            ) {
69
                $this->stockAnnualDividendsGrowth = null;
70
            }
71
            $this->setProperty("dividendDiscountModelType", $dividendDiscountModelType);
72
        }
73
74
        /**
75
         * @param $stockVIR
76
         */
77
        public function setStockVIR($stockVIR)
78
        {
79
            $this->setProperty("stockVIR", $stockVIR, Lambdas::checkIfPositive());
80
        }
81
82
        /**
83
         * @param $stockAnnualDividendsValue
84
         */
85
        public function setStockAnnualDividendsValue($stockAnnualDividendsValue)
86
        {
87
            $this->setProperty("stockAnnualDividendsValue", $stockAnnualDividendsValue, Lambdas::checkIfPositive());
88
        }
89
90
        /**
91
         * @param $stockAnnualDividendsGrowth
92
         */
93
        public function setStockAnnualDividendsGrowth($stockAnnualDividendsGrowth)
94
        {
95
            $dividendDiscountModelType = $this->dividendDiscountModelType->getValue();
96
97
            if ($dividendDiscountModelType == StockDDMTypes::ZERO_GROWTH
98
                &&
99
                $stockAnnualDividendsGrowth !== null
100
            ) {
101
                throw new InvalidArgumentException(Strings::getString('message_cannot_set_growth_value_on_zero_growth_type'));
102
            }
103
104
            if ($dividendDiscountModelType == StockDDMTypes::MULTIPLE_GROWTH) {
105
                if (Helpers::checkIfPositiveNumberOrThrowAnException($stockAnnualDividendsGrowth)) {
106
                    Helpers::checkIfLeftOperandGreaterOrThrowAnException(
107
                        $this->stockVIR,
108
                        $stockAnnualDividendsGrowth,
109
                        Strings::getString('message_vir_must_be_higher_than_growth_value')
110
                    );
111
                }
112
            }
113
114
            $this->setProperty("stockAnnualDividendsGrowth", $stockAnnualDividendsGrowth);
115
        }
116
117
        /**
118
         * @return mixed
119
         */
120
        public function getDividendDiscountModelType()
121
        {
122
            return $this->dividendDiscountModelType;
123
        }
124
125
        /**
126
         * @return mixed
127
         */
128
        public function getStockVIR()
129
        {
130
            return $this->stockVIR;
131
        }
132
133
        /**
134
         * @return mixed
135
         */
136
        public function getStockAnnualDividendsValue()
137
        {
138
            return $this->stockAnnualDividendsValue;
139
        }
140
141
        /**
142
         * @return mixed
143
         */
144
        public function getStockAnnualDividendsGrowth()
145
        {
146
            return $this->stockAnnualDividendsGrowth;
147
        }
148
149
        /**
150
         * @return string
151
         * @throws Exception
152
         */
153
        public function getStockPresentValue()
154
        {
155
            switch ($this->dividendDiscountModelType->getValue()) {
156
                case StockDDMTypes::ZERO_GROWTH:
157
                    // PV = D/i
158
                    return MathFuncs::div(
159
                        $this->stockAnnualDividendsValue,
160
                        $this->stockVIR
161
                    );
162
                case StockDDMTypes::MULTIPLE_GROWTH:
163
                    if ($this->stockAnnualDividendsGrowth === null) {
164
                        throw new Exception(Strings::getString('message_must_set_growth_value'));
165
                    }
166
                    // PV = (D*(1+g))/(i-g)
167
                    return MathFuncs::mul(
168
                        $this->stockAnnualDividendsValue,
169
                        MathFuncs::div(
170
                            MathFuncs::add(
171
                                1,
172
                                $this->stockAnnualDividendsGrowth
173
                            ),
174
                            MathFuncs::sub(
175
                                $this->stockVIR,
176
                                $this->stockAnnualDividendsGrowth
177
                            )
178
                        )
179
                    );
180
            }
181
182
            return null;
183
        }
184
    }
185
}
186