[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master 718ef64 6/6: Enforce a minimum single premium
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master 718ef64 6/6: Enforce a minimum single premium for "corridor" strategy |
Date: |
Thu, 22 Apr 2021 11:57:26 -0400 (EDT) |
branch: master
commit 718ef646313d7207737a114361be06ffc845b544
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>
Enforce a minimum single premium for "corridor" strategy
See the preceding commit for the rationale.
Incidentally changed a nearby error message from
"for " << yare_input_.InsuredName
to
"for " << yare_input_.InsuredName
in case no name is entered, because a quoted empty string
...error message...for ''
is confusing, whereas
...error message...for insured ''
more clearly means that the insured's name is unspecified.
---
basic_values.hpp | 2 ++
ihs_avstrtgy.cpp | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++++++-
ihs_basicval.cpp | 2 ++
3 files changed, 60 insertions(+), 1 deletion(-)
diff --git a/basic_values.hpp b/basic_values.hpp
index 13d2381..12bed55 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -338,6 +338,8 @@ class LMI_SO BasicValues
oenum_modal_prem_type TgtPremType;
bool TgtPremFixedAtIssue;
currency TgtPremMonthlyPolFee;
+ oenum_min_single_prem_type MinSinglePremiumType;
+ double MinSinglePremiumMult;
currency CurrCoiTable0Limit;
currency CurrCoiTable1Limit;
e_actuarial_table_method CoiInforceReentry;
diff --git a/ihs_avstrtgy.cpp b/ihs_avstrtgy.cpp
index 83a445f..65e6542 100644
--- a/ihs_avstrtgy.cpp
+++ b/ihs_avstrtgy.cpp
@@ -30,6 +30,8 @@
#include "outlay.hpp"
#include <algorithm>
+#include <cmath> // ceil()
+#include <iomanip>
#include <utility>
/// Set specamt according to selected strategy in a non-solve year.
@@ -145,6 +147,59 @@ void AccountValue::PerformSpecAmtStrategy()
strategy = mce_sa_input_scalar;
}
currency z = CalculateSpecAmtFromStrategy(j, 0, explicit_value,
strategy);
+ if
+ ( 0 == j
+ && yare_input_.EffectiveDate == yare_input_.InforceAsOfDate
+ && oe_min_single_premium_corr_mult == MinSinglePremiumType
+ && mce_sa_corridor == strategy
+ && !Solving
+ )
+ {
+ // SOMEDAY !! Duplicated above--refactor.
+ currency annualized_pmt =
+ Outlay_->ee_premium_modes ()[0]
+ * Outlay_->ee_modal_premiums()[0]
+ + Outlay_->er_premium_modes ()[0]
+ * Outlay_->er_modal_premiums()[0]
+ ;
+ double special_spec_amt =
+ annualized_pmt
+ * GetCorridorFactor()[0]
+ / MinSinglePremiumMult
+ ;
+ // "0.01 + ": err on the conservative side for finicky users
+ double special_min_prem = std::ceil
+ (0.01 + MinSinglePremiumMult * m / (GetCorridorFactor()[0])
+ );
+ if(special_spec_amt < dblize(m))
+ {
+ alarum()
+ << std::fixed << std::setprecision(2)
+ << "For insured '"
+ << yare_input_.InsuredName
+ << "', premium "
+ << annualized_pmt
+ << " would correspond to a specified amount of "
+ << std::setprecision(12)
+ << special_spec_amt
+ << std::setprecision(2)
+ << ", which is premium "
+ << annualized_pmt
+ << " times corridor factor "
+ << GetCorridorFactor()[0]
+ << " divided by "
+ << MinSinglePremiumMult
+ << ", but "
+ << m
+ << " is the product's minimum specified amount."
+ << " If the client is willing to pay more, a premium of "
+ << std::setprecision(0)
+ << special_min_prem
+ << " would satisfy that product rule."
+ << std::flush
+ ;
+ }
+ }
DeathBfts_->set_specamt(std::max(m, z), j, 1 + j);
if
( j == InforceYear
@@ -159,7 +214,7 @@ void AccountValue::PerformSpecAmtStrategy()
<< inforce_specamt
<< " increased to the "
<< m
- << " minimum for '"
+ << " minimum for insured '"
<< yare_input_.InsuredName
<< "'."
<< std::flush
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 1b94fc1..4ec98fa 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -552,6 +552,8 @@ void BasicValues::SetPermanentInvariants()
LMI_ASSERT(round_gross_premium().c(TgtPremMonthlyPolFee) ==
TgtPremMonthlyPolFee);
// Assertion: see comments on GetModalPremTgtFromTable().
LMI_ASSERT(C0 == TgtPremMonthlyPolFee || oe_modal_table == TgtPremType);
+ database().query_into(DB_MinSinglePremiumType , MinSinglePremiumType);
+ database().query_into(DB_MinSinglePremiumMult , MinSinglePremiumMult);
database().query_into(DB_CurrCoiTable0Limit , CurrCoiTable0Limit);
database().query_into(DB_CurrCoiTable1Limit , CurrCoiTable1Limit);
LMI_ASSERT(C0 <= CurrCoiTable0Limit);
- [lmi-commits] [lmi] master updated (905df77 -> 718ef64), Greg Chicares, 2021/04/22
- [lmi-commits] [lmi] master d53539c 1/6: Rebuild 'custom_tools' early in 'hooks/pre-commit', Greg Chicares, 2021/04/22
- [lmi-commits] [lmi] master 60b5d97 2/6: Strenghen asserted preconditions, Greg Chicares, 2021/04/22
- [lmi-commits] [lmi] master 718ef64 6/6: Enforce a minimum single premium for "corridor" strategy,
Greg Chicares <=
- [lmi-commits] [lmi] master 8d6c2da 3/6: Transpose two arguments, Greg Chicares, 2021/04/22
- [lmi-commits] [lmi] master 88fbe0c 4/6: Overload calculate_premium(), Greg Chicares, 2021/04/22
- [lmi-commits] [lmi] master 37944d8 5/6: Add database entities for a minimum single premium, Greg Chicares, 2021/04/22