[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [lmi] master bcc8861 1/2: Eradicate weird minimum initial
From: |
Greg Chicares |
Subject: |
[lmi-commits] [lmi] master bcc8861 1/2: Eradicate weird minimum initial premium |
Date: |
Fri, 30 Nov 2018 19:38:28 -0500 (EST) |
branch: master
commit bcc88611275f63bd8c6ba6c673b49ac031fae2cc
Author: Gregory W. Chicares <address@hidden>
Commit: Gregory W. Chicares <address@hidden>
Eradicate weird minimum initial premium
This largely reverses the following commits, although git-revert
wouldn't cleanly reverse most of them:
6078c07b26cd889019edcdf03d290505c2288f0a
aa07e082345532bbdb4de97b291f0ea1f3735fb8
be5c6278d6fb43b47e9811be95268bc380f74c0d
254dae3f9b8c5c286a1e66fc05d42badeb99f762
ba457794c6693f3c8bdae9314d2a8ac22b5a8f6a
8f57302f49a2dbef1874091e1b6e77aa681b582a
---
account_value.hpp | 6 ---
basic_values.hpp | 2 -
basicvalues.cpp | 1 -
dbdict.cpp | 1 -
dbdict.hpp | 1 -
dbnames.hpp | 1 -
dbnames.xpp | 1 -
finra_header_lower.mst | 3 --
group_quote_pdf_gen_wx.cpp | 4 +-
ihs_acctval.cpp | 103 +--------------------------------------------
ihs_avmly.cpp | 30 -------------
ihs_basicval.cpp | 1 -
ledger_evaluator.cpp | 2 -
ledger_invariant.cpp | 2 -
ledger_invariant.hpp | 2 -
ledger_invariant_init.cpp | 2 -
ledger_text_formats.cpp | 2 -
rounding_document.cpp | 1 -
rounding_rules.cpp | 3 --
rounding_rules.hpp | 1 -
rounding_view.xrc | 12 ------
21 files changed, 3 insertions(+), 178 deletions(-)
diff --git a/account_value.hpp b/account_value.hpp
index f774f81..4fd71da 100644
--- a/account_value.hpp
+++ b/account_value.hpp
@@ -286,10 +286,6 @@ class LMI_SO AccountValue
double SurrChg () const;
double CSVBoost () const;
- double MinInitDumpin() const;
- double MinInitPrem() const;
- double ModalMinInitPremShortfall() const;
-
void set_list_bill_year_and_month();
void set_list_bill_premium();
@@ -361,8 +357,6 @@ class LMI_SO AccountValue
double Internal1035Amount;
double Dumpin;
- double InitAnnPlannedPrem_;
-
double MlyNoLapsePrem;
double CumNoLapsePrem;
bool NoLapseActive;
diff --git a/basic_values.hpp b/basic_values.hpp
index f9b1cc9..06476e8 100644
--- a/basic_values.hpp
+++ b/basic_values.hpp
@@ -190,7 +190,6 @@ class LMI_SO BasicValues
round_to<double> const& round_max_specamt () const {return
round_max_specamt_ ;}
round_to<double> const& round_min_premium () const {return
round_min_premium_ ;}
round_to<double> const& round_max_premium () const {return
round_max_premium_ ;}
- round_to<double> const& round_min_init_premium () const {return
round_min_init_premium_ ;}
protected:
double GetModalMinPrem
@@ -461,7 +460,6 @@ class LMI_SO BasicValues
round_to<double> round_max_specamt_ ;
round_to<double> round_min_premium_ ;
round_to<double> round_max_premium_ ;
- round_to<double> round_min_init_premium_ ;
};
inline int BasicValues::GetLength() const
diff --git a/basicvalues.cpp b/basicvalues.cpp
index 50e5f64..f5be04e 100644
--- a/basicvalues.cpp
+++ b/basicvalues.cpp
@@ -79,7 +79,6 @@ BasicValues::BasicValues(Input const& input)
,round_max_specamt_ {0, r_downward }
,round_min_premium_ {2, r_upward }
,round_max_premium_ {2, r_downward }
- ,round_min_init_premium_ {2, r_upward }
{
Init();
}
diff --git a/dbdict.cpp b/dbdict.cpp
index b291a9d..ce2efc2 100644
--- a/dbdict.cpp
+++ b/dbdict.cpp
@@ -356,7 +356,6 @@ void DBDictionary::ascribe_members()
ascribe("MinPremIntSpread" , &DBDictionary::MinPremIntSpread );
ascribe("SplitMinPrem" , &DBDictionary::SplitMinPrem );
ascribe("UnsplitSplitMinPrem" , &DBDictionary::UnsplitSplitMinPrem );
- ascribe("MinInitPremType" , &DBDictionary::MinInitPremType );
ascribe("TgtPremType" , &DBDictionary::TgtPremType );
ascribe("TgtPremTable" , &DBDictionary::TgtPremTable );
ascribe("TgtPremFixedAtIssue" , &DBDictionary::TgtPremFixedAtIssue );
diff --git a/dbdict.hpp b/dbdict.hpp
index 2b3f950..f04e951 100644
--- a/dbdict.hpp
+++ b/dbdict.hpp
@@ -340,7 +340,6 @@ class LMI_SO DBDictionary final
database_entity MinPremIntSpread ;
database_entity SplitMinPrem ;
database_entity UnsplitSplitMinPrem ;
- database_entity MinInitPremType ;
database_entity TgtPremType ;
database_entity TgtPremTable ;
database_entity TgtPremFixedAtIssue ;
diff --git a/dbnames.hpp b/dbnames.hpp
index a8eff0a..d2b9e79 100644
--- a/dbnames.hpp
+++ b/dbnames.hpp
@@ -450,7 +450,6 @@ enum e_database_key
,DB_MinPremIntSpread
,DB_SplitMinPrem
,DB_UnsplitSplitMinPrem
- ,DB_MinInitPremType
,DB_TgtPremType
,DB_TgtPremTable
,DB_TgtPremFixedAtIssue
diff --git a/dbnames.xpp b/dbnames.xpp
index b0e5399..e9a1937 100644
--- a/dbnames.xpp
+++ b/dbnames.xpp
@@ -296,7 +296,6 @@
{DB_MinPremIntSpread,DB_Topic_Premiums,"MinPremIntSpread","Interest spread
from general-account rate used to capitalize monthly deductions for minimum
premium calculation",}, \
{DB_SplitMinPrem,DB_Topic_Premiums,"SplitMinPrem","Split monthly-deductions
minimum premium by payor: 0=no, 1=yes",}, \
{DB_UnsplitSplitMinPrem,DB_Topic_Premiums,"UnsplitSplitMinPrem","Payment
strategies recombine split minimum premium: 0=no, 1=yes",}, \
-{DB_MinInitPremType,DB_Topic_Premiums,"MinInitPremType","Minimum initial
premium: 0=none, 1=custom calculation #1",}, \
{DB_TgtPremType,DB_Topic_Premiums,"TgtPremType","Target premium: 0=based on
monthly deductions, 1=7702A seven-pay premium, 2=read from table",}, \
{DB_TgtPremTable,DB_Topic_Premiums,"TgtPremTable","Annual target premium rates
per $1 (index in mortality table database)",}, \
{DB_TgtPremFixedAtIssue,DB_Topic_Premiums,"TgtPremFixedAtIssue","Target
premium set forever at issue: 0=no, 1=yes",}, \
diff --git a/finra_header_lower.mst b/finra_header_lower.mst
index eddc939..56024e7 100644
--- a/finra_header_lower.mst
+++ b/finra_header_lower.mst
@@ -34,9 +34,6 @@
{{Gender}} {{Smoker}} rates, Age {{Age}}<br>
{{/Composite}}
{{ContractNameCap}}: {{PolicyMktgName}}<br>
- {{#GroupCarveout}}
- Minimum Initial Premium: ${{InitMinPrem}}<br>
- {{/GroupCarveout}}
First Year Premium: ${{InitPrem}}<br>
{{^Composite}}
{{#UWTypeIsMedical}}
diff --git a/group_quote_pdf_gen_wx.cpp b/group_quote_pdf_gen_wx.cpp
index 1ffb818..7bc951c 100644
--- a/group_quote_pdf_gen_wx.cpp
+++ b/group_quote_pdf_gen_wx.cpp
@@ -560,7 +560,7 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger const&
ledger)
break;
case e_col_additional_premium:
{
- double const z = invar.EeModalMinimumPremium.at(year) +
invar.ModalMinimumDumpin;
+ double const z = invar.EeModalMinimumPremium.at(year);
rd.output_values[i] = '$' + ledger_format(z, f2);
if(is_composite)
{
@@ -580,7 +580,7 @@ void group_quote_pdf_generator_wx::add_ledger(Ledger const&
ledger)
break;
case e_col_total_premium:
{
- double const z = invar.ModalMinimumPremium.at(year) +
invar.ModalMinimumDumpin;
+ double const z = invar.ModalMinimumPremium.at(year);
rd.output_values[i] = '$' + ledger_format(z, f2);
if(is_composite)
{
diff --git a/ihs_acctval.cpp b/ihs_acctval.cpp
index e61da12..e07e2d3 100644
--- a/ihs_acctval.cpp
+++ b/ihs_acctval.cpp
@@ -624,7 +624,6 @@ void AccountValue::SetInitialValues()
YearlyTaxBasis.assign(BasicValues::GetLength(), 0.0);
MlyNoLapsePrem = 0.0;
CumNoLapsePrem = InforceCumNoLapsePrem;
- InitAnnPlannedPrem_ = 0.0;
// Initialize all elements of this vector to 'false'. Then, when
// the no-lapse criteria fail to be met, future values are right.
@@ -983,112 +982,12 @@ void AccountValue::InitializeSpecAmt()
if(0 == Year)
{
- mcenum_mode const er_mode = InvariantValues().ErMode[0].value();
- // 'ModalMinimumDumpin' and 'InitMinPrem' depend on 'InitTgtPrem'.
- InvariantValues().InitTgtPrem = AnnualTargetPrem;
- InvariantValues().ModalMinimumDumpin = MinInitDumpin() / er_mode;
- InvariantValues().InitMinPrem = MinInitPrem();
+ InvariantValues().InitTgtPrem = AnnualTargetPrem;
}
// TODO ?? Perform specamt strategy here?
}
-/// Minimum initial extra premium--zero for most products.
-///
-/// Motivation: to help ensure VUL suitability for products whose
-/// minimum premium alone would generate little if any account value.
-///
-/// Custom MinInitPremType #1: first-year payments must be at least
-/// the pay-as-you-go minimum premium (calculated elsewhere) plus half
-/// the target premium (calculated here, and rounded according to its
-/// own rule). This extra amount is defined only for new business; for
-/// inforce, it is impracticable to calculate because the target may
-/// have changed, and suitability is determined at issue anyway.
-///
-/// Because the result is twelve times a rounded value, it can be
-/// modalized without further rounding.
-
-double AccountValue::MinInitDumpin() const
-{
- if
- ( 0 == Year
- && 1 == database().query<int>(DB_MinInitPremType)
- && yare_input_.EffectiveDate == yare_input_.InforceAsOfDate
- )
- {
- double const target = InvariantValues().InitTgtPrem;
- return 12.0 * round_min_init_premium()(target / 24.0);
- }
- else
- {
- return 0.0;
- }
-}
-
-double AccountValue::MinInitPrem() const
-{
- if
- ( 0 == Year
- && 1 == database().query<int>(DB_MinInitPremType)
- && yare_input_.EffectiveDate == yare_input_.InforceAsOfDate
- )
- {
- mcenum_mode const er_mode = InvariantValues().ErMode[0].value();
- double const modal_min_prem = InvariantValues().ModalMinimumPremium[0];
- return MinInitDumpin() + modal_min_prem * er_mode;
- }
- else
- {
- return 0.0;
- }
-}
-
-/// Required modal increment to initial planned premium.
-///
-/// If the minimum is not otherwise satisfied, then employee payments
-/// must be increased to fulfill it.
-///
-/// First-year payments from all sources count toward satisfying the
-/// minimum, including dumpins and 1035 proceeds--which are amodal by
-/// their nature. This function is designed to support a product whose
-/// minimum premium reflects only the er mode; yet lmi permits ee and
-/// er modes to differ, so it is necessary to compare the first-year
-/// minimum to the first year's total planned premium, including any
-/// dumpin and 1035 exchange, and modalize any shortfall. Because 1035
-/// and dumpin amounts are arbitrary, modalization could yield a value
-/// in fractional cents; therefore, the result must be rounded up.
-///
-/// Alternative not pursued: The shortfall could be calculated on each
-/// payment date, taking into account the annual incidence of dumpins
-/// and 1035 exchanges. Thus, if the shortfall before a $40 dumpin is
-/// $100, and the ee pays quarterly, an increase of {0, 10, 25, 25}
-/// rather than a level $15 could be calculated. No strong rationale
-/// was found for this exquisite refinement.
-///
-/// Planned payments might be reduced to the guideline or non-MEC
-/// limit, in which case the minimum is deemed to be satisfied. This
-/// case should not arise with the contemplated product, whose minimum
-/// is designed to be lower than those limits.
-
-double AccountValue::ModalMinInitPremShortfall() const
-{
- if
- ( 0 == Year
- && 1 == database().query<int>(DB_MinInitPremType)
- && yare_input_.EffectiveDate == yare_input_.InforceAsOfDate
- )
- {
- mcenum_mode const ee_mode = InvariantValues().EeMode[0].value();
- double const z = material_difference(MinInitPrem(),
InitAnnPlannedPrem_);
- double const shortfall = std::max(0.0, z);
- return round_min_premium()(shortfall / ee_mode);
- }
- else
- {
- return 0.0;
- }
-}
-
/// Set duration at which list-bill premium is to be determined.
///
/// The year and month of determination correspond to the first
diff --git a/ihs_avmly.cpp b/ihs_avmly.cpp
index eecc7cb..00e04f0 100644
--- a/ihs_avmly.cpp
+++ b/ihs_avmly.cpp
@@ -1194,36 +1194,6 @@ void AccountValue::TxAscertainDesiredPayment()
LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] +
ErGrossPmts[Month]));
LMI_ASSERT(GrossPmts[Month] < 1.0e100);
- // On the issue date (which is always a modal payment date), store
- // annualized planned premium, including dumpin and 1035 proceeds,
- // and reflecting the payment strategies just applied (and premium
- // solves, on the final iteration). Of course, any planned premium
- // might be reduced to the guideline or non-MEC limit.
- if(0 == Year && 0 == Month)
- {
- InitAnnPlannedPrem_ =
- Dumpin
- + External1035Amount
- + Internal1035Amount
- + ee_mode * eepmt
- + er_mode * erpmt
- ;
- }
-
- if(0 == Year && ee_pay_this_month && 1 ==
database().query<int>(DB_MinInitPremType))
- {
- double z = ModalMinInitPremShortfall();
- // Illustration-reg guaranteed premium ignores GPT limit.
- if(!SolvingForGuarPremium)
- {
- Irc7702_->ProcessGptPmt(Year, z);
- }
- EeGrossPmts[Month] += z;
- GrossPmts [Month] += z;
- }
-
- LMI_ASSERT(materially_equal(GrossPmts[Month], EeGrossPmts[Month] +
ErGrossPmts[Month]));
-
if(0 == Year && 0 == Month)
{
// Illustration-reg guaranteed premium ignores GPT limit.
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index 385695b..6f850aa 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -799,7 +799,6 @@ void BasicValues::SetRoundingFunctors()
set_rounding_rule(round_max_specamt_ ,
RoundingRules_->datum("RoundMaxSpecamt" ));
set_rounding_rule(round_min_premium_ ,
RoundingRules_->datum("RoundMinPrem" ));
set_rounding_rule(round_max_premium_ ,
RoundingRules_->datum("RoundMaxPrem" ));
- set_rounding_rule(round_min_init_premium_ ,
RoundingRules_->datum("RoundMinInitPrem" ));
}
/// Establish maximum survivorship duration.
diff --git a/ledger_evaluator.cpp b/ledger_evaluator.cpp
index 756197c..c666e2f 100644
--- a/ledger_evaluator.cpp
+++ b/ledger_evaluator.cpp
@@ -480,9 +480,7 @@ format_map_t static_formats()
,{"InitPrem" , f2}
,{"InitSevenPayPrem" , f2}
,{"InitTgtPrem" , f2}
- ,{"InitMinPrem" , f2}
,{"ListBillPremium" , f2}
- ,{"ModalMinimumDumpin" , f2}
// >
// F1: zero decimals, commas
// > Format as a number with thousand separators and no decimal places
(#,###,###)
diff --git a/ledger_invariant.cpp b/ledger_invariant.cpp
index 9b7e3f5..5bc65bb 100644
--- a/ledger_invariant.cpp
+++ b/ledger_invariant.cpp
@@ -119,11 +119,9 @@ void LedgerInvariant::Alloc(int len)
ScalableScalars ["InitGSP" ] = &InitGSP ;
ScalableScalars ["InitGLP" ] = &InitGLP ;
ScalableScalars ["InitTgtPrem" ] = &InitTgtPrem ;
- ScalableScalars ["InitMinPrem" ] = &InitMinPrem ;
ScalableScalars ["ListBillPremium" ] = &ListBillPremium ;
ScalableScalars ["EeListBillPremium" ] = &EeListBillPremium ;
ScalableScalars ["ErListBillPremium" ] = &ErListBillPremium ;
- ScalableScalars ["ModalMinimumDumpin" ] = &ModalMinimumDumpin ;
ScalableScalars ["Dumpin" ] = &Dumpin ;
ScalableScalars ["External1035Amount" ] = &External1035Amount ;
ScalableScalars ["Internal1035Amount" ] = &Internal1035Amount ;
diff --git a/ledger_invariant.hpp b/ledger_invariant.hpp
index f722a8a..0e59895 100644
--- a/ledger_invariant.hpp
+++ b/ledger_invariant.hpp
@@ -144,11 +144,9 @@ class LMI_SO LedgerInvariant
double InitGSP;
double InitGLP;
double InitTgtPrem;
- double InitMinPrem;
double ListBillPremium;
double EeListBillPremium;
double ErListBillPremium;
- double ModalMinimumDumpin;
double Dumpin;
double External1035Amount;
double Internal1035Amount;
diff --git a/ledger_invariant_init.cpp b/ledger_invariant_init.cpp
index f078561..3be0942 100644
--- a/ledger_invariant_init.cpp
+++ b/ledger_invariant_init.cpp
@@ -219,11 +219,9 @@ void LedgerInvariant::Init(BasicValues const* b)
// GuarPrem = 0;
// InitSevenPayPrem =
// InitTgtPrem =
-// InitMinPrem =
// ListBillPremium =
// EeListBillPremium =
// ErListBillPremium =
-// ModalMinimumDumpin =
MaleProportion = b->yare_input_.MaleProportion;
NonsmokerProportion = b->yare_input_.NonsmokerProportion;
diff --git a/ledger_text_formats.cpp b/ledger_text_formats.cpp
index 5289bae..03989e2 100644
--- a/ledger_text_formats.cpp
+++ b/ledger_text_formats.cpp
@@ -693,7 +693,6 @@ void PrintRosterHeaders(std::string const& file_name)
,"SupplSpecAmt"
,"InitialTargetPremium"
,"ModalMinimumPremium"
- ,"ModalMinimumDumpin"
,"EeModalMinimumPremium"
,"ErModalMinimumPremium"
,"ListBillPremium"
@@ -778,7 +777,6 @@ void PrintRosterTabDelimited
<< Invar.value_str("TermSpecAmt" ,d) << '\t'
<< Invar.value_str("InitTgtPrem" ) << '\t'
<< Invar.value_str("ModalMinimumPremium" ,d) << '\t'
- << Invar.value_str("ModalMinimumDumpin" ) << '\t'
<< Invar.value_str("EeModalMinimumPremium",d) << '\t'
<< Invar.value_str("ErModalMinimumPremium",d) << '\t'
<< Invar.value_str("ListBillPremium" ) << '\t'
diff --git a/rounding_document.cpp b/rounding_document.cpp
index c9854f6..28c94b8 100644
--- a/rounding_document.cpp
+++ b/rounding_document.cpp
@@ -58,7 +58,6 @@ RoundingDocument::RoundingDocument()
values_["max_specamt" ] = &rounding_rules_.round_max_specamt_ ;
values_["min_premium" ] = &rounding_rules_.round_min_premium_ ;
values_["max_premium" ] = &rounding_rules_.round_max_premium_ ;
- values_["min_init_premium" ] = &rounding_rules_.round_min_init_premium_ ;
}
void RoundingDocument::ReadDocument(std::string const& filename)
diff --git a/rounding_rules.cpp b/rounding_rules.cpp
index 83e1fc4..1cbf03e 100644
--- a/rounding_rules.cpp
+++ b/rounding_rules.cpp
@@ -152,7 +152,6 @@ rounding_rules::rounding_rules()
,round_max_specamt_ (0, r_downward , "")
,round_min_premium_ (2, r_upward , "")
,round_max_premium_ (2, r_downward , "")
- ,round_min_init_premium_ (2, r_upward , "")
{
ascribe_members();
}
@@ -189,7 +188,6 @@ rounding_rules::rounding_rules(std::string const& filename)
LMI_ASSERT(r_not_at_all == round_max_specamt_ .style() || r_downward
== round_max_specamt_ .style());
LMI_ASSERT(r_not_at_all == round_min_premium_ .style() || r_upward
== round_min_premium_ .style());
LMI_ASSERT(r_not_at_all == round_max_premium_ .style() || r_downward
== round_max_premium_ .style());
- LMI_ASSERT(r_not_at_all == round_min_init_premium_ .style() || r_upward
== round_min_init_premium_ .style());
}
/// Member datum nominated by the given name.
@@ -224,7 +222,6 @@ void rounding_rules::ascribe_members()
ascribe("RoundMaxSpecamt" , &rounding_rules::round_max_specamt_ );
ascribe("RoundMinPrem" , &rounding_rules::round_min_premium_ );
ascribe("RoundMaxPrem" , &rounding_rules::round_max_premium_ );
- ascribe("RoundMinInitPrem" , &rounding_rules::round_min_init_premium_ );
}
/// Backward-compatibility serial number of this class's xml version.
diff --git a/rounding_rules.hpp b/rounding_rules.hpp
index 5906901..4c58e66 100644
--- a/rounding_rules.hpp
+++ b/rounding_rules.hpp
@@ -151,7 +151,6 @@ class LMI_SO rounding_rules final
rounding_parameters round_max_specamt_ ;
rounding_parameters round_min_premium_ ;
rounding_parameters round_max_premium_ ;
- rounding_parameters round_min_init_premium_ ;
};
void LMI_SO load(rounding_rules &, fs::path const&);
diff --git a/rounding_view.xrc b/rounding_view.xrc
index 7d7ac98..143cbec 100644
--- a/rounding_view.xrc
+++ b/rounding_view.xrc
@@ -316,18 +316,6 @@
<size>-1,-1</size>
</object>
</object>
- <object class="sizeritem">
-
<flag>wxALIGN_RIGHT|wxALIGN_CENTER_VERTICAL</flag>
- <object class="wxStaticText">
- <label>Minimum initial premium</label>
- </object>
- </object>
- <object class="sizeritem">
- <flag>wxALIGN_LEFT</flag>
- <object class="RoundingButtons"
name="min_init_premium">
- <size>-1,-1</size>
- </object>
- </object>
</object>
</object>
</object>