lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] master 986ba37 2/2: Rework 7702 interest-rate formul


From: Greg Chicares
Subject: [lmi-commits] [lmi] master 986ba37 2/2: Rework 7702 interest-rate formulas
Date: Thu, 11 Mar 2021 10:52:49 -0500 (EST)

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

    Rework 7702 interest-rate formulas
---
 i7702.cpp | 90 ++++++++++++++++++++++++++++++++++++++++++---------------------
 1 file changed, 60 insertions(+), 30 deletions(-)

diff --git a/i7702.cpp b/i7702.cpp
index 279583b..45b45df 100644
--- a/i7702.cpp
+++ b/i7702.cpp
@@ -33,52 +33,83 @@
 /// Here's how lmi determines §7702 and §7702A interest rates.
 ///
 /// All these variables are vectors that may vary by year, except
-/// statutory rates marked as scalar.
+/// that statutory rates are always scalar.
 ///
-/// "max" means the year-by-year maximum: e.g.,
+/// Several rates must be considered:
+///
+/// A: statutory rates (concrete values A0 and A1 described below)
+/// B: contractual guarantees
+/// C: initial short-term guarantees
+/// D: asset-based charges
+/// E: NAAR discount
+///
+/// and several account-paths for each of {B,C,D}:
+///
+/// gen: general account  (unloaned)
+/// sep: separate account (unloaned)
+/// flr: fixed loan rate
+/// vlr: variable loan rate
+///
+/// Let "max" mean the year-by-year maximum of vectors: e.g.,
 ///   max({1 2 3}, {0 2 4}) is {1 2 4}
 ///
+/// Then the general formula is the maximum of
+///   max(A, B, C) - D
+/// along each account-path, i.e.
+///   max
+///     (max(A, Bgen, Cgen) - Dgen
+///     ,max(A, Bsep, Csep) - Dsep
+///     ,max(A, Bflr, Cflr) - Dflr
+///     ,max(A, Bvlr, Cvlr) - Dvlr
+///     )
+/// where A is chosen from {A0, A1} as appropriate,
+/// and the particular formulas are
+///   ic_usual  max(A0, B, C)
+///   ic_glp    max(A0, B   ) - D
+///   ic_gsp    max(A1, B, C) - D
+/// where C and D are taken as zero if omitted.
+///
+/// All ig are zero iff E uniformly equals zero; otherwise each is
+/// the greater of its ic counterpart and E:
+///   ig_usual  max(ic_usual, E)
+///   ig_glp    max(ic_glp,   E)
+///   ig_gsp    max(ic_gsp,   E)
+///
+/// Notes on input rates
+///
 /// A: statutory rates (always scalar)
 ///   A0: all but GSP (e.g., 4% as of 1984)
 ///   A1: GSP only (A0 + 2% in current statute)
 ///
 /// B: contractual guarantees
-///   B0: unloaned gen acct (specified by contract)
-///   B1: loaned, fixed rate (max net = charged - credited)
-///   B2: loaned, variable rate (max net, ascertainable from contract)
-///   B3: sep acct (generally 0%, so no effect on Bmax)
-///   Bmax: max(B0, B1, B2, B3)
+///   Bgen: unloaned general acct (specified by contract)
+///   Bsep: separate acct (generally 0%, thus without effect)
+///   Bflr: loaned, fixed rate (max net = charged - credited)
+///   Bvlr: loaned, variable rate (max net, ascertainable from contract)
 ///
 /// C: initial short-term guarantees
-///   good product design generally creates none
-///   therefore, always zero in practice for lmi
+///   good product design usually avoids creating any
+///   variable loan rate may cause Cvlr to be nonzero
+///   always zero in practice for lmi (which doesn't yet implement VLR)
 ///
 /// D: asset-based charges
 ///   lowest value each year, if dependent on assets, premiums, etc.
 ///
 /// E: NAAR discount (given here as i, the annual rate of interest)
-///   almost always specified in contract as B0 upper 12 / 12
-///     which should be rounded up, if at all
-///     if it was rounded down, B0 governs instead
-///   but some policies do not discount NAAR, in which case
-///     but E uniformly equals zero
-///   therefore, assert that either E=0 or E materially equals B0
-///
-/// ic_usual  max(A0, Bmax, C   )
-/// ig_usual  max(A0, B0,   C, E)
-/// ic_glp    max(A0, Bmax      ) - D
-/// ig_glp    max(A0, B0,      E) - D
-/// ic_gsp    max(A1, Bmax, C   ) - D
-/// ig_gsp    max(A1, B0,   C, E) - D
-///   but all ig* are zero if E uniformly equals zero
+///   often specified in contract as Bgen upper 12 / 12
+///     for 7702, must be rounded up, if at all
+///     if it was rounded down, Bgen governs instead
+///   but some policies do not discount NAAR
+///     in which case E uniformly equals zero
+///   lmi therefore asserts that either E=0 or E materially equals Bgen
 ///
 /// Exhaustive list of use cases:
-///   {GLP, GSP, CVAT NSP, §7702A NSP, 7PP, and DCV}
-/// All but {GLP, GSP} use "usual" rates.
+///   {GLP; GSP; CVAT NSP and corridor; §7702A NSP; 7PP; DCV}
+/// All but {GLP; GSP} use "usual" rates.
 ///
 /// Discussion
 ///
-/// Interest rates should be rounded up, if at all; lmi doesn't
+/// 7702 interest rates should be rounded up, if at all; lmi doesn't
 /// round them at all.
 ///
 /// ig may actually exceed ic; for example:
@@ -95,7 +126,7 @@
 /// must be ignored for 7PP and for the §7702 as well as §7702A NSPs
 /// because those quantities are net premiums. DCV calculations deduct
 /// actual charges during monthly processing, and credit interest at
-/// the ic_usual rate, which ignores D, because those charges must not
+/// the ic_usual rate, which ignores D because those charges must not
 /// be double-counted; thus, DCV correctly reflects any dependence of
 /// such charges on asset or premium tiers, which D cannot do.
 ///
@@ -105,11 +136,11 @@
 /// for §7702 purposes. Yet it's simple to follow lmi's more careful
 /// interpretation, which most often produces materially the same
 /// result. If a contract specifies E as the monthly equivalent of
-/// any rate other than B0, that's presumably just a mistake.
+/// any rate other than Bgen, that's presumably just a mistake.
 ///
 /// Present shortcomings of the code in this file:
 ///   [first change names to follow scheme above, adding new ones]
-///   formulas are too simplistic:
+///   implementation is too simplistic:
 ///     igross: max(A0, Bmax)
 ///     iglp:   max(A0, Bmax) - D
 ///     igsp:   max(A1, Bmax) - D
@@ -118,7 +149,6 @@
 ///     A1 ignored: must reflect +2% for GSP
 ///       and that 2% extra should be parameterized
 ///     use contractual rates if greater
-///   separate-account-only charges: deduct only from B3?
 
 i7702::i7702
     (product_database   const& database



reply via email to

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