lmi-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[lmi-commits] [lmi] master 5965057 3/7: Avoid writing the 1984-era 7702


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 5965057 3/7: Avoid writing the 1984-era 7702 rate literally
Date: Wed, 10 Feb 2021 09:42:00 -0500 (EST)

branch: master
commit 59650575661943fb5e125674c8d6d6343f7f69a3
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Avoid writing the 1984-era 7702 rate literally
    
    Now that the 7702 interest rate is no longer a constant, the original
    1984 rate must not be written literally anywhere. Examined every
    occurrence of /\.0[46][^0-9]/ and /[46]%/ to make sure nothing was
    missed in commit 7930f69291 of 20201229T0001Z. Abstracted such interest
    rates in the few cases found (one unit test, and several comments) even
    though they're of no material import. Changed local variables' names in
    another unit test because the GLP and GSP rates are not necessarily
    "4" or "6" percent since 2021 because of H.R. 6800.
---
 gpt_server.cpp          |  2 +-
 gpt_test.cpp            | 12 ++++++------
 ihs_basicval.cpp        |  4 ++--
 ihs_irc7702.cpp         |  4 ++--
 interest_rates.cpp      | 19 ++++++++++---------
 irc7702_tables_test.cpp | 10 ++++++----
 mec_server.cpp          |  2 +-
 7 files changed, 28 insertions(+), 25 deletions(-)

diff --git a/gpt_server.cpp b/gpt_server.cpp
index 6646e06..6f162e3 100644
--- a/gpt_server.cpp
+++ b/gpt_server.cpp
@@ -193,7 +193,7 @@ gpt_state test_one_days_gpt_transactions
         ,stratified.minimum_tiered_spread_for_7702()
         );
 
-    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(.04, guar_int) - 
spread);
+    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(iglp(), guar_int) - 
spread);
     std::vector<double> Mly7702iGlp(input.years_to_maturity());
     assign
         (Mly7702iGlp
diff --git a/gpt_test.cpp b/gpt_test.cpp
index db0518a..6750852 100644
--- a/gpt_test.cpp
+++ b/gpt_test.cpp
@@ -237,14 +237,14 @@ class gpt_test
 
 void gpt_test::initialize(int issue_age)
 {
-    static double const i_m_4 = i_upper_12_over_12_from_i<double>()(iglp());
-    static double const i_m_6 = i_upper_12_over_12_from_i<double>()(igsp());
+    static double const i12glp = i_upper_12_over_12_from_i<double>()(iglp());
+    static double const i12gsp = i_upper_12_over_12_from_i<double>()(igsp());
     q_m = sample_q(issue_age);
     int const length = lmi::ssize(q_m);
-    glp_ic               .assign(length,     i_m_4);
-    glp_ig               .assign(length,     i_m_4);
-    gsp_ic               .assign(length,     i_m_6);
-    gsp_ig               .assign(length,     i_m_6);
+    glp_ic               .assign(length,     i12glp);
+    glp_ig               .assign(length,     i12glp);
+    gsp_ic               .assign(length,     i12gsp);
+    gsp_ig               .assign(length,     i12gsp);
     prem_load_target     .assign(length,  0.03    );
     prem_load_excess     .assign(length,  0.02    );
     policy_fee_monthly   .assign(length,  5.0     );
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index e297d4d..e883234 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -408,8 +408,8 @@ void BasicValues::Init7702()
     // (optionally) rounding monthly COI rates.
     MlyDcvqc = round_coi_rate()(Mly7702qc);
 
-    // Monthly guar net int for 7702, with 4 or 6% min, is
-    //   greater of {4%, 6%} and annual guar int rate
+    // Monthly guar net int for 7702 is
+    //   greater of {iglp(), igsp()} and annual guar int rate
     //   less 7702 spread
     // TODO ?? TAXATION !! We need to subtract other things too, e.g. comp 
(sometimes)...
     //   transformed to monthly (simple subtraction?).
diff --git a/ihs_irc7702.cpp b/ihs_irc7702.cpp
index d456f08..9fd23bb 100644
--- a/ihs_irc7702.cpp
+++ b/ihs_irc7702.cpp
@@ -437,7 +437,7 @@ void Irc7702::InitCommFns()
         gsp_naar_disc_rate = GSPic;
         }
 
-    // Commutation functions using 4% min i: both options 1 and 2
+    // Commutation functions using min i = iglp(): both options 1 and 2
     CommFns[Opt1Int4Pct].reset
         (::new ULCommFns
             (Qc
@@ -460,7 +460,7 @@ void Irc7702::InitCommFns()
         );
     DEndt[Opt2Int4Pct] = CommFns[Opt2Int4Pct]->aDomega();
 
-    // Commutation functions using 6% min i: always option 1
+    // Commutation functions using min i = igsp(): always option 1
     CommFns[Opt1Int6Pct].reset
         (::new ULCommFns
             (Qc
diff --git a/interest_rates.cpp b/interest_rates.cpp
index 282107a..e65f13d 100644
--- a/interest_rates.cpp
+++ b/interest_rates.cpp
@@ -882,16 +882,17 @@ void InterestRates::Initialize7702Rates()
 
 // §7702 prescribes the interest basis for all §7702 and §7702A
 // calculations as the interest rate actually guaranteed in the
-// contract, or a statutory rate if greater. The statutory rate is 4%
-// for GLP and 6% for GSP. It is 4% for all §7702A calculations,
-// except that the necessary premium for guideline contracts is
-// defined in terms of the guideline limit.
+// contract, or a statutory rate if greater. The statutory rate is
+// iglp() and igsp() for GLP and GSP, and iglp() for all §7702A
+// calculations except that the necessary premium for guideline
+// contracts is defined in terms of the guideline limit.
 
 // The §7702 net rate is determined in two steps. First, the
 // guaranteed interest rate is determined from the contract, and the
 // statutory rate is used instead if it is greater. This operation is
 // performed separately for all periods with different guaranteed
-// rates [DEFRA Blue Book, page 648]. For example, if the guaranteed
+// rates [DEFRA Blue Book, page 648]. For example, using the original
+// 1984 statutory rates (4% for GLP and 6% for GSP), if the guaranteed
 // rate is 4.5% for five years and 3.5% thereafter, then the GLP
 // interest rate is 4.5% for five years and 4.0% thereafter, while the
 // GSP rate is always 6.0%. For products such as pure variable UL that
@@ -1043,8 +1044,8 @@ void InterestRates::Initialize7702Rates()
 // really belongs here, not in class BasicValues. TAXATION !! Resolve this.
 
 {
-    // Monthly guar net int for 7702, with 4 or 6% min, is
-    //   greater of {4%, 6%} and annual guar int rate
+    // Monthly guar net int for 7702 is
+    //   greater of {iglp(), igsp()} and annual guar int rate
     //   less 7702 spread
     // TAXATION !! Resolve this:
     // TODO ?? We need to subtract other things too, e.g. comp (sometimes)...
@@ -1099,7 +1100,7 @@ void InterestRates::Initialize7702Rates()
         }
 */
 
-    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(.04, guar_int) - 
SpreadFor7702_);
+    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(iglp(), guar_int) - 
SpreadFor7702_);
     Mly7702iGlp.assign(Length, iglp());
     std::transform
         (guar_int.begin()
@@ -1122,7 +1123,7 @@ void InterestRates::Initialize7702Rates()
         ,i_upper_12_over_12_from_i<double>()
         );
 
-    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(.06, guar_int) - 
SpreadFor7702_);
+    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(igsp(), guar_int) - 
SpreadFor7702_);
     Mly7702iGsp.assign(Length, igsp());
     std::transform
         (guar_int.begin()
diff --git a/irc7702_tables_test.cpp b/irc7702_tables_test.cpp
index 3927ef3..6a92e11 100644
--- a/irc7702_tables_test.cpp
+++ b/irc7702_tables_test.cpp
@@ -454,9 +454,10 @@ static double const ss_ol_7pp[100] =
 
 void Test_Corridor_and_7PP()
 {
+    double constexpr iglp = 0.04;
     std::vector<double> const naar_discount
         (100
-        ,i_upper_12_over_12_from_i<double>()(0.04)
+        ,i_upper_12_over_12_from_i<double>()(iglp)
         );
     irc7702_tables z
         (mce_2001cso
@@ -476,11 +477,12 @@ void Test_Corridor_and_7PP()
 
     // In the last year, the OL formula reduces to:
     //   NSP[omega-1] = vq * (i/delta) + vp
-    //   (0.30285 / 1.04) * (0.04 / ln(1.04)) + (1 - 0.30285) / 1.04
+    //   =     (0.30285  / (1.0 + iglp)) * (iglp / ln((1.0 + iglp)))
+    //   + (1 - 0.30285) / (1.0 + iglp)
     BOOST_TEST(materially_equal(0.30285, z.q_[99], 0.0));
     double ol_nsp99 =
-          (       z.q_[99]  / 1.04) * (0.04 / std::log(1.04))
-        +  (1.0 - z.q_[99]) / 1.04
+          (       z.q_[99]  / (1.0 + iglp)) * (iglp / std::log((1.0 + iglp)))
+        +  (1.0 - z.q_[99]) / (1.0 + iglp)
         ;
     BOOST_TEST(materially_equal(ol_corr[99], 1.0 / ol_nsp99, DBL_EPSILON));
 
diff --git a/mec_server.cpp b/mec_server.cpp
index 609e74e..109c959 100644
--- a/mec_server.cpp
+++ b/mec_server.cpp
@@ -176,7 +176,7 @@ mec_state test_one_days_7702A_transactions
         ,stratified.minimum_tiered_spread_for_7702()
         );
 
-    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(.04, guar_int) - 
spread);
+    // ET !! Mly7702iGlp = i_upper_12_over_12_from_i(max(iglp(), guar_int) - 
spread);
     std::vector<double> Mly7702iGlp(input.years_to_maturity());
     assign
         (Mly7702iGlp



reply via email to

[Prev in Thread] Current Thread [Next in Thread]