Пример #1
0
 /**
  * @return string
  */
 public function getApproxBondYTM()
 {
     // we need to calculate the coupon payment C = F*(c/payment frequency)
     $couponPayment = MathFuncs::mul($this->bondFaceValue, MathFuncs::div($this->bondAnnualCouponRate, $this->bondPaymentFrequency));
     // we use a formula to approximate the YTM = (C+(F-P)/n)/((F+P)/2)
     $approxYTM = MathFuncs::div(MathFuncs::add($couponPayment, MathFuncs::div(MathFuncs::sub($this->bondFaceValue, $this->bondMarketValue), $this->getBondNoOfPayments())), MathFuncs::div(MathFuncs::add($this->bondFaceValue, $this->bondMarketValue), 2));
     return $approxYTM;
 }
Пример #2
0
 /**
  * @return string
  */
 public function getBondFairValue()
 {
     // we need to get the coupon rate per payment period = c/payment frequency
     $couponRateForPeriod = MathFuncs::div($this->bondAnnualCouponRate, $this->bondPaymentFrequency);
     // similarly, we need to calculate the VIR per payment period = i/payment frequency
     $VIRForPeriod = MathFuncs::div($this->bondVIR, $this->bondPaymentFrequency);
     // we also save the bond's number of payments to an auxillary variable
     $bondNoOfPayments = $this->getBondNoOfPayments();
     // next, we also need the present value of the unit annuity pertaining to the bond, in arrears
     $PVofUnitBondAnnuity = MathFuncs::div(MathFuncs::sub(1, Mathfuncs::pow(MathFuncs::div(1, MathFuncs::add(1, $VIRForPeriod)), $bondNoOfPayments)), $VIRForPeriod);
     // now we can use the formula to calculate the real value of the bond (i.e., the present value of its payments)
     // PV = F*[c*PVofUnitBondAnnuity+1/((1+i)^n)]
     $fairValue = MathFuncs::mul($this->bondFaceValue, MathFuncs::add(MathFuncs::mul($couponRateForPeriod, $PVofUnitBondAnnuity), MathFuncs::div(1, MathFuncs::pow(MathFuncs::add(1, $VIRForPeriod), $bondNoOfPayments))));
     return $fairValue;
 }
 /**
  * @return string
  */
 public function getRetentionRatio()
 {
     return MathFuncs::sub(1, $this->getPayoutRatio());
 }
Пример #4
0
 /**
  * @return string
  */
 public function getInterestAmount()
 {
     // n = P*i*t = IN/ID
     return MathFuncs::div($this->getInterestNumber(), $this->getInterestDivisor());
 }
Пример #5
0
 public function testRound()
 {
     $this->assertEquals("3.68", MathFuncs::round(3.675624));
 }
Пример #6
0
 /**
  * @param $checkedVariable
  * @param integer $expectedResult
  * @return bool|null
  */
 public static function checkNumberRelativityToZero($checkedVariable, $expectedResult)
 {
     if (is_numeric((string) $checkedVariable)) {
         return MathFuncs::comp($checkedVariable, "0.00") == $expectedResult;
     }
     return null;
 }
Пример #7
0
 /**
  * @return string [Value of the total amount that the payment represents as a string]
  */
 public function getTotalAmount()
 {
     return MathFuncs::add($this->principalAmount, $this->interestAmount);
 }
Пример #8
0
 /**
  * @param array $resultArray
  */
 private function processArray(array $resultArray)
 {
     $this->assertEquals("40000", $resultArray["debtPrincipal"]);
     $this->assertEquals("6", $resultArray["debtNoOfCompoundingPeriods"]);
     $this->assertEquals(MathFuncs::div($resultArray["debtPeriodLength"]["days"], TimeUtils::getDaysFromYears(1)), $resultArray["debtPeriodLength"]["years"]);
     $this->assertEquals(MathFuncs::div($resultArray["debtPeriodLength"]["days"], TimeUtils::getDaysFromMonths(1)), $resultArray["debtPeriodLength"]["months"]);
     $this->assertEquals(MathFuncs::div($resultArray["debtLength"]["days"], TimeUtils::getDaysFromYears(1)), $resultArray["debtLength"]["years"]);
     $this->assertEquals(MathFuncs::div($resultArray["debtLength"]["days"], TimeUtils::getDaysFromMonths(1)), $resultArray["debtLength"]["months"]);
     $this->assertEquals("0.12", $resultArray["debtInterest"]);
     $repayments = $resultArray["debtRepayments"];
     $INDIVIDUAL_REPAYMENT = "9729.03";
     $this->assertEquals("4929.03", round($repayments[1]["principalAmount"], 2));
     $this->assertEquals("4800.00", round($repayments[1]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[1]["totalAmount"], 2));
     $this->assertEquals("5520.51", round($repayments[2]["principalAmount"], 2));
     $this->assertEquals("4208.52", round($repayments[2]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[2]["totalAmount"], 2));
     $this->assertEquals("6182.97", round($repayments[3]["principalAmount"], 2));
     $this->assertEquals("3546.06", round($repayments[3]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[3]["totalAmount"], 2));
     $this->assertEquals("6924.93", round($repayments[4]["principalAmount"], 2));
     $this->assertEquals("2804.10", round($repayments[4]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[4]["totalAmount"], 2));
     $this->assertEquals("7755.92", round($repayments[5]["principalAmount"], 2));
     $this->assertEquals("1973.11", round($repayments[5]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[5]["totalAmount"], 2));
     $this->assertEquals("8686.63", round($repayments[6]["principalAmount"], 2));
     $this->assertEquals("1042.4", round($repayments[6]["interestAmount"], 2));
     $this->assertEquals($INDIVIDUAL_REPAYMENT, round($repayments[6]["totalAmount"], 2));
 }
Пример #9
0
 /**
  * @return int
  */
 public function getBondNoOfPayments()
 {
     // number of payments during the duration of the bond (up to the moment of its maturity)
     // is calculated from the number of years of the duration of the bond
     // multiplied by the number of payments per year (i.e., payment frequency)
     //, floored (to eliminate the last remaining incomplete due period)
     return intval(floor(MathFuncs::mul($this->bondYearsToMaturity, $this->bondPaymentFrequency)));
 }
Пример #10
0
 /**
  * @param AnnuityPaymentTypes $annuityPaymentType
  * @param AnnuityValueTypes $annuityValueType
  * @return null|string
  * @throws Exception
  */
 public function getAnnuityValue(AnnuityPaymentTypes $annuityPaymentType = null, AnnuityValueTypes $annuityValueType)
 {
     // if the number of the annuity's compounding periods
     // is set to zero, we're dealing with a perpetuity
     if (Helpers::checkIfZero($this->annuityNoOfCompoundingPeriods)) {
         // we cannot calculate FV of a perpetuity, we therefore return null
         // in case such a value is demanded
         if ($annuityValueType->getValue() == AnnuityValueTypes::FUTURE_VALUE) {
             return null;
         }
         // PV of a perpetuity = K/i
         return Helpers::roundMoneyForDisplay(MathFuncs::div($this->annuitySinglePaymentAmount, $this->annuityInterest));
     }
     // when the annuity is not a perpetuity, we first need to check that
     // the $annuityPaymentType is not null
     if (Helpers::checkIfNotNull($annuityPaymentType)) {
         // discount factor 'v = 1/(1+i)'
         $discountFactor = MathFuncs::div(1, MathFuncs::add(1, $this->annuityInterest));
         if ($annuityValueType->getValue() == AnnuityValueTypes::PRESENT_VALUE) {
             // PV numerator = 1-v^n
             $numerator = MathFuncs::sub(1, MathFuncs::pow($discountFactor, $this->annuityNoOfCompoundingPeriods));
         } elseif ($annuityValueType->getValue() == AnnuityValueTypes::FUTURE_VALUE) {
             // FV numerator = (1+i)^n-1
             $numerator = MathFuncs::sub(MathFuncs::pow(MathFuncs::add(1, $this->annuityInterest), $this->annuityNoOfCompoundingPeriods), 1);
         }
         if ($annuityPaymentType->getValue() == AnnuityPaymentTypes::IN_ADVANCE) {
             // in advance denom. = 1-v
             $denominator = MathFuncs::sub(1, $discountFactor);
         } elseif ($annuityPaymentType->getValue() == AnnuityPaymentTypes::IN_ARREARS) {
             // in arrears denom. = i
             $denominator = $this->annuityInterest;
         }
         if (isset($numerator) && isset($denominator)) {
             return MathFuncs::mul(MathFuncs::div($numerator, $denominator), $this->annuitySinglePaymentAmount);
         }
     }
     return null;
 }
Пример #11
0
 /**
  * @return mixed
  * @throws Exception
  */
 public static function getCurrentDayCountConvention()
 {
     $dayCountConventionIdentifier = Config::getConfigField('day_count_convention');
     $availableDayCountConventions = Config::getConfigField('available_day_count_conventions');
     if (is_array($availableDayCountConventions) && array_key_exists($dayCountConventionIdentifier, $availableDayCountConventions)) {
         $dayCountConvention = $availableDayCountConventions[$dayCountConventionIdentifier];
         if (self::isDayCountConventionValid($dayCountConvention)) {
             $dayCountConvention['days_in_a_month'] = MathFuncs::div($dayCountConvention['days_in_a_year'], 12);
             return $dayCountConvention;
         }
     }
     throw new Exception(ErrorMessages::getDayCountConventionNotDefinedMessage());
 }
Пример #12
0
 /**
  * @return string
  */
 public function getDiscountAmount()
 {
     // D = S*d*t
     return MathFuncs::mul($this->amountDue, MathFuncs::mul($this->annualDiscountRate, $this->getTimeInYears()));
 }
Пример #13
0
 /**
  * @return string
  * @throws Exception
  */
 public function toDays()
 {
     $yearsComponent = TimeUtils::getDaysFromYears($this->getYearsComponent());
     $monthsComponent = TimeUtils::getDaysFromMonths($this->getMonthsComponent());
     return MathFuncs::add(MathFuncs::add($yearsComponent, $monthsComponent), $this->getDaysComponent());
 }
Пример #14
0
 /**
  * @return string
  */
 public function getBondDuration()
 {
     // duration of the bond = sum of auxiliary values of all periods / bond present value
     // auxiliary value for a period = discounted cash flow in the period * number of the period
     $auxiliaryValue = 0;
     $i = 1;
     foreach ($this->getBondDiscountedCashFlows() as $discountedCashFlowEntry) {
         $auxiliaryValue = MathFuncs::add($auxiliaryValue, MathFuncs::mul($discountedCashFlowEntry, $i++));
     }
     $duration = MathFuncs::div($auxiliaryValue, $this->getBondPresentValue());
     return $duration;
 }
 /**
  * @return string
  * @throws Exception
  */
 public function getStockPresentValue()
 {
     switch ($this->dividendDiscountModelType->getValue()) {
         case StockDDMTypes::ZERO_GROWTH:
             // PV = D/i
             return MathFuncs::div($this->stockAnnualDividendsValue, $this->stockVIR);
         case StockDDMTypes::MULTIPLE_GROWTH:
             if ($this->stockAnnualDividendsGrowth === null) {
                 throw new Exception(Strings::getString('message_must_set_growth_value'));
             }
             // PV = (D*(1+g))/(i-g)
             return MathFuncs::mul($this->stockAnnualDividendsValue, MathFuncs::div(MathFuncs::add(1, $this->stockAnnualDividendsGrowth), MathFuncs::sub($this->stockVIR, $this->stockAnnualDividendsGrowth)));
     }
 }