lmi-commits
[Top][All Lists]
Advanced

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

[lmi-commits] [lmi] valyuta/004 883dc0a 2/3: Store policy fees as curren


From: Greg Chicares
Subject: [lmi-commits] [lmi] valyuta/004 883dc0a 2/3: Store policy fees as currency
Date: Mon, 14 Dec 2020 10:40:01 -0500 (EST)

branch: valyuta/004
commit 883dc0ab9c0241588f0a39d2b00e6e0ff4c9d121
Author: Gregory W. Chicares <gchicares@sbcglobal.net>
Commit: Gregory W. Chicares <gchicares@sbcglobal.net>

    Store policy fees as currency
    
    Rounded amounts on all bases as they arise, replacing the separate
    final step that used to be required.
    
    Changed the unit test's "extra" policy fee from $0.60 to $0.50, to
    emphasize that midpoint fees must be rounded even if all their
    components were exactly representable in floating point.
---
 basicvalues.cpp         |  4 +--
 ihs_basicval.cpp        | 14 ++++-----
 ledger_variant_init.cpp |  2 +-
 loads.cpp               | 84 +++++++++++++++++++++++++++++++------------------
 loads.hpp               | 49 +++++++++++++++--------------
 loads_impl.hpp          | 77 ++++++++++++++++++++++++---------------------
 loads_test.cpp          | 57 ++++++++++++++++-----------------
 7 files changed, 159 insertions(+), 128 deletions(-)

diff --git a/basicvalues.cpp b/basicvalues.cpp
index 056e677..e83093b 100644
--- a/basicvalues.cpp
+++ b/basicvalues.cpp
@@ -209,7 +209,7 @@ currency BasicValues::GetModalTgtPrem
                 )[a_year]
         );
     z *= MortalityRates_->MonthlyCoiRates(mce_gen_curr)[a_year];
-    z += Loads_->monthly_policy_fee(mce_gen_curr)[a_year];
+    z += Loads_->monthly_policy_fee(mce_gen_curr)[a_year].d();
 //    z += AdbRate;
 //    z *= 1.0 + WpRate;
     z /= 1.0 - Loads_->target_premium_load(mce_gen_curr)[a_year];
@@ -279,7 +279,7 @@ currency BasicValues::GetModalTgtSpecAmt
     z *= 1.0 - Loads_->target_premium_load(mce_gen_curr)[0];
 //    z /= WpRate;
 //    z -= AdbRate;
-    z -= Loads_->monthly_policy_fee(mce_gen_curr)[0];
+    z -= Loads_->monthly_policy_fee(mce_gen_curr)[0].d();
     z /= MortalityRates_->MonthlyCoiRates(mce_gen_curr)[0];
     z *=
         (   1.0
diff --git a/ihs_basicval.cpp b/ihs_basicval.cpp
index a0cfc73..8300489 100644
--- a/ihs_basicval.cpp
+++ b/ihs_basicval.cpp
@@ -554,9 +554,9 @@ void BasicValues::Init7702()
             ,yare_input_.SpecifiedAmount[0] + yare_input_.TermRiderAmount
             ,yare_input_.SpecifiedAmount[0] + yare_input_.TermRiderAmount
             ,effective_dbopt_7702(yare_input_.DeathBenefitOption[0], 
Effective7702DboRop)
-            ,Loads_->annual_policy_fee    (mce_gen_curr)
-            ,Loads_->monthly_policy_fee   (mce_gen_curr)
-            ,Loads_->specified_amount_load(mce_gen_curr)
+            ,doubleize(Loads_->annual_policy_fee  (mce_gen_curr))
+            ,doubleize(Loads_->monthly_policy_fee (mce_gen_curr))
+            ,Loads_->specified_amount_load        (mce_gen_curr)
             ,SpecAmtLoadLimit
             ,local_mly_charge_add
             ,local_adb_limit
@@ -1225,9 +1225,9 @@ std::pair<double,double> BasicValues::approx_mly_ded
         mly_ded += r * std::min(specamt.d(), SpecAmtLoadLimit);
         }
 
-    mly_ded += Loads_->monthly_policy_fee(mce_gen_curr)[year];
+    mly_ded += Loads_->monthly_policy_fee(mce_gen_curr)[year].d();
 
-    double ann_ded = Loads_->annual_policy_fee(mce_gen_curr)[year];
+    double ann_ded = Loads_->annual_policy_fee(mce_gen_curr)[year].d();
 
     if(yare_input_.WaiverOfPremiumBenefit)
         {
@@ -1277,7 +1277,7 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
     ,currency termamt
     ) const
 {
-    if(0.0 != Loads_->annual_policy_fee(mce_gen_curr)[year])
+    if(C0 != Loads_->annual_policy_fee(mce_gen_curr)[year])
         {
         return {0.0, 0.0};
         }
@@ -1317,7 +1317,7 @@ std::pair<double,double> BasicValues::approx_mly_ded_ex
         }
 
     // Paid by er.
-    er_ded += Loads_->monthly_policy_fee(mce_gen_curr)[year];
+    er_ded += Loads_->monthly_policy_fee(mce_gen_curr)[year].d();
 
     if(yare_input_.WaiverOfPremiumBenefit)
         {
diff --git a/ledger_variant_init.cpp b/ledger_variant_init.cpp
index fc1dcec..4f0608b 100644
--- a/ledger_variant_init.cpp
+++ b/ledger_variant_init.cpp
@@ -112,7 +112,7 @@ void LedgerVariant::Init
         ;
 
     InitTgtPremHiLoadRate = 
bv.Loads_->target_premium_load_maximum_premium_tax()[bv.yare_input_.InforceYear];
-    InitMlyPolFee         = bv.Loads_->monthly_policy_fee(GenBasis_)           
 [bv.yare_input_.InforceYear];
+    InitMlyPolFee         = bv.Loads_->monthly_policy_fee(GenBasis_)           
 [bv.yare_input_.InforceYear].d();
 
     FullyInitialized = true;
 }
diff --git a/loads.cpp b/loads.cpp
index 4ddf8cb..f18adf7 100644
--- a/loads.cpp
+++ b/loads.cpp
@@ -35,6 +35,35 @@
 #include "oecumenic_enumerations.hpp"
 #include "premium_tax.hpp"
 
+namespace
+{
+void query_into
+    (product_database const& database
+    ,e_database_key          key
+    ,std::vector<currency>&  v
+    ,round_to<double> const& round_minutiae
+    )
+{
+    std::vector<double> z;
+    database.query_into(key, z);
+    v = round_minutiae.c(z);
+}
+
+void assign_midpoint
+    (std::vector<currency>      & out
+    ,std::vector<currency> const& in_0
+    ,std::vector<currency> const& in_1
+    ,round_to<double>      const& round_minutiae
+    )
+{
+    std::vector<double> const v0 = doubleize(in_0);
+    std::vector<double> const v1 = doubleize(in_1);
+    std::vector<double>       z;
+    ::assign_midpoint(z, v0, v1);
+    out = round_minutiae.c(z);
+}
+} // Unnamed namespace.
+
 /// Ctor for production branch.
 
 Loads::Loads(BasicValues& V)
@@ -57,12 +86,12 @@ Loads::Loads(BasicValues& V)
         ,V.round_minutiae()
         ,V.yare_input_.ExtraCompensationOnPremium
         ,V.yare_input_.ExtraCompensationOnAssets
-        ,V.yare_input_.ExtraMonthlyCustodialFee
+        ,V.round_minutiae().c(V.yare_input_.ExtraMonthlyCustodialFee)
         ,V.GetGuarSpecAmtLoadTable()
         ,V.GetCurrSpecAmtLoadTable()
         );
     Allocate(length);
-    Initialize(V.database());
+    Initialize(V.database(), details);
     Calculate(details);
 }
 
@@ -115,13 +144,15 @@ void Loads::Allocate(int length)
 
 /// Set various data members from product database.
 
-void Loads::Initialize(product_database const& database)
+void Loads::Initialize(product_database const& database, load_details const& 
details)
 {
+    round_to<double> const& r = details.round_minutiae_;
+
     database.query_into(DB_LoadRfdProportion , 
refundable_sales_load_proportion_   );
     database.query_into(DB_DacTaxPremLoad    , dac_tax_load_                   
    );
 
-    database.query_into(DB_GuarMonthlyPolFee , monthly_policy_fee_   
[mce_gen_guar]);
-    database.query_into(DB_GuarAnnualPolFee  , annual_policy_fee_    
[mce_gen_guar]);
+    query_into(database, DB_GuarMonthlyPolFee, monthly_policy_fee_   
[mce_gen_guar], r);
+    query_into(database, DB_GuarAnnualPolFee , annual_policy_fee_    
[mce_gen_guar], r);
     database.query_into(DB_GuarSpecAmtLoad   , 
specified_amount_load_[mce_gen_guar]);
     database.query_into(DB_GuarAcctValLoad   , 
separate_account_load_[mce_gen_guar]);
     database.query_into(DB_GuarPremLoadTgt   , target_premium_load_  
[mce_gen_guar]);
@@ -129,8 +160,8 @@ void Loads::Initialize(product_database const& database)
     database.query_into(DB_GuarPremLoadTgtRfd, target_sales_load_    
[mce_gen_guar]);
     database.query_into(DB_GuarPremLoadExcRfd, excess_sales_load_    
[mce_gen_guar]);
 
-    database.query_into(DB_CurrMonthlyPolFee , monthly_policy_fee_   
[mce_gen_curr]);
-    database.query_into(DB_CurrAnnualPolFee  , annual_policy_fee_    
[mce_gen_curr]);
+    query_into(database, DB_CurrMonthlyPolFee, monthly_policy_fee_   
[mce_gen_curr], r);
+    query_into(database, DB_CurrAnnualPolFee , annual_policy_fee_    
[mce_gen_curr], r);
     database.query_into(DB_CurrSpecAmtLoad   , 
specified_amount_load_[mce_gen_curr]);
     database.query_into(DB_CurrAcctValLoad   , 
separate_account_load_[mce_gen_curr]);
     database.query_into(DB_CurrPremLoadTgt   , target_premium_load_  
[mce_gen_curr]);
@@ -143,6 +174,8 @@ void Loads::Initialize(product_database const& database)
 
 void Loads::Calculate(load_details const& details)
 {
+    round_to<double> const& r = details.round_minutiae_;
+
     premium_tax_load_.assign(details.length_, details.premium_tax_load_);
 
     for(int j = mce_gen_curr; j != mc_n_gen_bases; ++j)
@@ -275,6 +308,7 @@ void Loads::Calculate(load_details const& details)
     // consistent with this constraint.
 
     monthly_policy_fee_[mce_gen_curr] += details.VectorExtraPolFee_;
+
     for(int j = 0; j < details.length_; ++j)
         {
         if
@@ -299,8 +333,8 @@ void Loads::Calculate(load_details const& details)
 
     if(details.NeedMidpointRates_)
         {
-        assign_midpoint(monthly_policy_fee_   [mce_gen_mdpt], 
monthly_policy_fee_   [mce_gen_guar], monthly_policy_fee_   [mce_gen_curr]);
-        assign_midpoint(annual_policy_fee_    [mce_gen_mdpt], 
annual_policy_fee_    [mce_gen_guar], annual_policy_fee_    [mce_gen_curr]);
+        assign_midpoint(monthly_policy_fee_   [mce_gen_mdpt], 
monthly_policy_fee_   [mce_gen_guar], monthly_policy_fee_   [mce_gen_curr], r);
+        assign_midpoint(annual_policy_fee_    [mce_gen_mdpt], 
annual_policy_fee_    [mce_gen_guar], annual_policy_fee_    [mce_gen_curr], r);
         assign_midpoint(specified_amount_load_[mce_gen_mdpt], 
specified_amount_load_[mce_gen_guar], specified_amount_load_[mce_gen_curr]);
         assign_midpoint(separate_account_load_[mce_gen_mdpt], 
separate_account_load_[mce_gen_guar], separate_account_load_[mce_gen_curr]);
         assign_midpoint(target_premium_load_  [mce_gen_mdpt], 
target_premium_load_  [mce_gen_guar], target_premium_load_  [mce_gen_curr]);
@@ -310,18 +344,6 @@ void Loads::Calculate(load_details const& details)
         assign_midpoint(target_total_load_    [mce_gen_mdpt], 
target_total_load_    [mce_gen_guar], target_total_load_    [mce_gen_curr]);
         assign_midpoint(excess_total_load_    [mce_gen_mdpt], 
excess_total_load_    [mce_gen_guar], excess_total_load_    [mce_gen_curr]);
         }
-
-    // Round policy fees. No known product specifies any policy fee
-    // in fractional cents. However, if the monthly policy fee is
-    // $3.25 (current) and $5.00 (guaranteed), the midpoint shouldn't
-    // be $4.125, because subtracting that from the account value
-    // would make it a non-integral number of cents.
-
-    for(int j = mce_gen_curr; j < mc_n_gen_bases; ++j)
-        {
-        monthly_policy_fee_ [j] = details.round_minutiae_(monthly_policy_fee_ 
[j]);
-        annual_policy_fee_  [j] = details.round_minutiae_(annual_policy_fee_  
[j]);
-        }
 }
 
 /// Amortize premium tax.
@@ -351,26 +373,28 @@ void Loads::AmortizePremiumTax(load_details const&)
 
 Loads::Loads(product_database const& database, bool NeedMidpointRates)
 {
+    round_to<double> const& r {2, r_to_nearest};
+
     monthly_policy_fee_   .resize(mc_n_gen_bases);
     target_premium_load_  .resize(mc_n_gen_bases);
     excess_premium_load_  .resize(mc_n_gen_bases);
     specified_amount_load_.resize(mc_n_gen_bases);
 
-    database.query_into(DB_GuarMonthlyPolFee, monthly_policy_fee_   
[mce_gen_guar]);
-    database.query_into(DB_GuarPremLoadTgt  , target_premium_load_  
[mce_gen_guar]);
-    database.query_into(DB_GuarPremLoadExc  , excess_premium_load_  
[mce_gen_guar]);
-    database.query_into(DB_GuarSpecAmtLoad  , 
specified_amount_load_[mce_gen_guar]);
+    query_into(database, DB_GuarMonthlyPolFee, monthly_policy_fee_   
[mce_gen_guar], r);
+    database.query_into(DB_GuarPremLoadTgt   , target_premium_load_  
[mce_gen_guar]);
+    database.query_into(DB_GuarPremLoadExc   , excess_premium_load_  
[mce_gen_guar]);
+    database.query_into(DB_GuarSpecAmtLoad   , 
specified_amount_load_[mce_gen_guar]);
 
-    database.query_into(DB_CurrMonthlyPolFee, monthly_policy_fee_   
[mce_gen_curr]);
-    database.query_into(DB_CurrPremLoadTgt  , target_premium_load_  
[mce_gen_curr]);
-    database.query_into(DB_CurrPremLoadExc  , excess_premium_load_  
[mce_gen_curr]);
-    database.query_into(DB_CurrSpecAmtLoad  , 
specified_amount_load_[mce_gen_curr]);
+    query_into(database, DB_CurrMonthlyPolFee, monthly_policy_fee_   
[mce_gen_curr], r);
+    database.query_into(DB_CurrPremLoadTgt   , target_premium_load_  
[mce_gen_curr]);
+    database.query_into(DB_CurrPremLoadExc   , excess_premium_load_  
[mce_gen_curr]);
+    database.query_into(DB_CurrSpecAmtLoad   , 
specified_amount_load_[mce_gen_curr]);
 
     // This ctor ignores tabular specified-amount loads.
 
     if(NeedMidpointRates)
         {
-        assign_midpoint(monthly_policy_fee_   [mce_gen_mdpt], 
monthly_policy_fee_   [mce_gen_guar], monthly_policy_fee_   [mce_gen_curr]);
+        assign_midpoint(monthly_policy_fee_   [mce_gen_mdpt], 
monthly_policy_fee_   [mce_gen_guar], monthly_policy_fee_   [mce_gen_curr], r);
         assign_midpoint(target_premium_load_  [mce_gen_mdpt], 
target_premium_load_  [mce_gen_guar], target_premium_load_  [mce_gen_curr]);
         assign_midpoint(excess_premium_load_  [mce_gen_mdpt], 
excess_premium_load_  [mce_gen_guar], excess_premium_load_  [mce_gen_curr]);
         assign_midpoint(specified_amount_load_[mce_gen_mdpt], 
specified_amount_load_[mce_gen_guar], specified_amount_load_[mce_gen_curr]);
diff --git a/loads.hpp b/loads.hpp
index a61da7a..9c9633b 100644
--- a/loads.hpp
+++ b/loads.hpp
@@ -24,6 +24,7 @@
 
 #include "config.hpp"
 
+#include "currency.hpp"
 #include "mc_enum_type_enums.hpp"
 
 #include <vector>
@@ -49,16 +50,16 @@ class Loads
     // termination, the refund applies only to the sales load.
     std::vector<double> const& refundable_sales_load_proportion() const;
 
-    std::vector<double> const& monthly_policy_fee    (mcenum_gen_basis) const;
-    std::vector<double> const& annual_policy_fee     (mcenum_gen_basis) const;
-    std::vector<double> const& specified_amount_load (mcenum_gen_basis) const;
-    std::vector<double> const& separate_account_load (mcenum_gen_basis) const;
-    std::vector<double> const& target_premium_load   (mcenum_gen_basis) const;
-    std::vector<double> const& excess_premium_load   (mcenum_gen_basis) const;
-    std::vector<double> const& target_sales_load     (mcenum_gen_basis) const;
-    std::vector<double> const& excess_sales_load     (mcenum_gen_basis) const;
-    std::vector<double> const& target_total_load     (mcenum_gen_basis) const;
-    std::vector<double> const& excess_total_load     (mcenum_gen_basis) const;
+    std::vector<currency> const& monthly_policy_fee    (mcenum_gen_basis) 
const;
+    std::vector<currency> const& annual_policy_fee     (mcenum_gen_basis) 
const;
+    std::vector<double>   const& specified_amount_load (mcenum_gen_basis) 
const;
+    std::vector<double>   const& separate_account_load (mcenum_gen_basis) 
const;
+    std::vector<double>   const& target_premium_load   (mcenum_gen_basis) 
const;
+    std::vector<double>   const& excess_premium_load   (mcenum_gen_basis) 
const;
+    std::vector<double>   const& target_sales_load     (mcenum_gen_basis) 
const;
+    std::vector<double>   const& excess_sales_load     (mcenum_gen_basis) 
const;
+    std::vector<double>   const& target_total_load     (mcenum_gen_basis) 
const;
+    std::vector<double>   const& excess_total_load     (mcenum_gen_basis) 
const;
 
     std::vector<double> const& premium_tax_load           () const;
     std::vector<double> const& amortized_premium_tax_load () const;
@@ -75,23 +76,23 @@ class Loads
     Loads() = default; // Ctor for unit testing.
 
     void Allocate(int length);
-    void Initialize(product_database const&);
+    void Initialize(product_database const&, load_details const&);
     void Calculate(load_details const&);
 
-    void AmortizePremiumTax(load_details const& details);
+    void AmortizePremiumTax(load_details const&);
 
     std::vector<double> refundable_sales_load_proportion_;
 
-    std::vector<std::vector<double>> monthly_policy_fee_;
-    std::vector<std::vector<double>> annual_policy_fee_;
-    std::vector<std::vector<double>> specified_amount_load_;
-    std::vector<std::vector<double>> separate_account_load_;
-    std::vector<std::vector<double>> target_premium_load_;
-    std::vector<std::vector<double>> excess_premium_load_;
-    std::vector<std::vector<double>> target_sales_load_;
-    std::vector<std::vector<double>> excess_sales_load_;
-    std::vector<std::vector<double>> target_total_load_;
-    std::vector<std::vector<double>> excess_total_load_;
+    std::vector<std::vector<currency>> monthly_policy_fee_;
+    std::vector<std::vector<currency>> annual_policy_fee_;
+    std::vector<std::vector<double>>   specified_amount_load_;
+    std::vector<std::vector<double>>   separate_account_load_;
+    std::vector<std::vector<double>>   target_premium_load_;
+    std::vector<std::vector<double>>   excess_premium_load_;
+    std::vector<std::vector<double>>   target_sales_load_;
+    std::vector<std::vector<double>>   excess_sales_load_;
+    std::vector<std::vector<double>>   target_total_load_;
+    std::vector<std::vector<double>>   excess_total_load_;
 
     std::vector<double> premium_tax_load_;
     std::vector<double> amortized_premium_tax_load_;
@@ -111,13 +112,13 @@ Loads::refundable_sales_load_proportion() const
     return refundable_sales_load_proportion_;
 }
 
-inline std::vector<double> const&
+inline std::vector<currency> const&
 Loads::monthly_policy_fee(mcenum_gen_basis b) const
 {
     return monthly_policy_fee_[b];
 }
 
-inline std::vector<double> const&
+inline std::vector<currency> const&
 Loads::annual_policy_fee(mcenum_gen_basis b) const
 {
     return annual_policy_fee_[b];
diff --git a/loads_impl.hpp b/loads_impl.hpp
index 7fd9a88..5cb3154 100644
--- a/loads_impl.hpp
+++ b/loads_impl.hpp
@@ -24,6 +24,7 @@
 
 #include "config.hpp"
 
+#include "currency.hpp"
 #include "oecumenic_enumerations.hpp"
 #include "round_to.hpp"
 
@@ -62,8 +63,12 @@ class product_database;
 /// charge--it is expressed annually, converted to monthly in the
 /// implementation, and then must be rounded.
 ///
-/// round_minutiae_: Rounding function-object used for policy fees,
-/// which generally are an integral number of cents.
+/// round_minutiae_: Rounding function-object used for policy fees.
+/// No known product specifies any policy fee in fractional cents.
+/// However, if the monthly policy fee is $3.25 (current) and $5.00
+/// (guaranteed), the midpoint mustn't be $4.125, because subtracting
+/// that from the account value would make it a non-integral number
+/// of cents.
 ///
 /// VectorExtraCompLoad_: Input extra load per dollar of premium.
 ///
@@ -85,23 +90,23 @@ class product_database;
 struct load_details
 {
     load_details
-        (int                        length
-        ,bool                       AmortizePremLoad
-        ,double                     premium_tax_load
-        ,double                     maximum_premium_tax_load_rate
-        ,double                     minimum_premium_tax_load_rate
-        ,double                     premium_tax_rate
-        ,double                     premium_tax_amortization_rate
-        ,int                        premium_tax_amortization_period
-        ,oenum_asset_charge_type    asset_charge_type
-        ,bool                       NeedMidpointRates
-        ,round_to<double>    const& round_interest_rate
-        ,round_to<double>    const& round_minutiae
-        ,std::vector<double> const& VectorExtraCompLoad
-        ,std::vector<double> const& VectorExtraAssetComp
-        ,std::vector<double> const& VectorExtraPolFee
-        ,std::vector<double> const& TabularGuarSpecAmtLoad
-        ,std::vector<double> const& TabularCurrSpecAmtLoad
+        (int                          length
+        ,bool                         AmortizePremLoad
+        ,double                       premium_tax_load
+        ,double                       maximum_premium_tax_load_rate
+        ,double                       minimum_premium_tax_load_rate
+        ,double                       premium_tax_rate
+        ,double                       premium_tax_amortization_rate
+        ,int                          premium_tax_amortization_period
+        ,oenum_asset_charge_type      asset_charge_type
+        ,bool                         NeedMidpointRates
+        ,round_to<double>      const& round_interest_rate
+        ,round_to<double>      const& round_minutiae
+        ,std::vector<double>   const& VectorExtraCompLoad
+        ,std::vector<double>   const& VectorExtraAssetComp
+        ,std::vector<currency> const& VectorExtraPolFee
+        ,std::vector<double>   const& TabularGuarSpecAmtLoad
+        ,std::vector<double>   const& TabularCurrSpecAmtLoad
         )
         :length_                          {length}
         ,AmortizePremLoad_                {AmortizePremLoad}
@@ -122,23 +127,23 @@ struct load_details
         ,TabularCurrSpecAmtLoad_          {TabularCurrSpecAmtLoad}
         {}
 
-    int                        length_;
-    bool                       AmortizePremLoad_;
-    double                     premium_tax_load_;
-    double                     maximum_premium_tax_load_rate_;
-    double                     minimum_premium_tax_load_rate_;
-    double                     premium_tax_rate_;
-    double                     premium_tax_amortization_rate_;
-    int                        premium_tax_amortization_period_;
-    oenum_asset_charge_type    asset_charge_type_;
-    bool                       NeedMidpointRates_;
-    round_to<double>    const& round_interest_rate_;
-    round_to<double>    const& round_minutiae_;
-    std::vector<double> const& VectorExtraCompLoad_;
-    std::vector<double> const& VectorExtraAssetComp_;
-    std::vector<double> const& VectorExtraPolFee_;
-    std::vector<double> const  TabularGuarSpecAmtLoad_;
-    std::vector<double> const  TabularCurrSpecAmtLoad_;
+    int                          length_;
+    bool                         AmortizePremLoad_;
+    double                       premium_tax_load_;
+    double                       maximum_premium_tax_load_rate_;
+    double                       minimum_premium_tax_load_rate_;
+    double                       premium_tax_rate_;
+    double                       premium_tax_amortization_rate_;
+    int                          premium_tax_amortization_period_;
+    oenum_asset_charge_type      asset_charge_type_;
+    bool                         NeedMidpointRates_;
+    round_to<double>      const& round_interest_rate_;
+    round_to<double>      const& round_minutiae_;
+    std::vector<double>   const& VectorExtraCompLoad_;
+    std::vector<double>   const& VectorExtraAssetComp_;
+    std::vector<currency> const  VectorExtraPolFee_;
+    std::vector<double>   const  TabularGuarSpecAmtLoad_;
+    std::vector<double>   const  TabularCurrSpecAmtLoad_;
 };
 
 #endif // loads_impl_hpp
diff --git a/loads_test.cpp b/loads_test.cpp
index 329f286..39bbd12 100644
--- a/loads_test.cpp
+++ b/loads_test.cpp
@@ -67,7 +67,7 @@ struct LoadsTest
         {}
 
     void Allocate  () {loads_.Allocate(details_.length_);}
-    void Initialize() {loads_.Initialize(database_);}
+    void Initialize() {loads_.Initialize(database_, details_);}
     void Calculate () {loads_.Calculate(details_);}
 
     void Reinitialize();
@@ -83,26 +83,26 @@ struct LoadsTest
 
 void LoadsTest::Reinitialize()
 {
-    loads_.refundable_sales_load_proportion_    = std::vector<double>(length, 
0.50000);
-    loads_.dac_tax_load_                        = std::vector<double>(length, 
0.00500);
-
-    loads_.monthly_policy_fee_   [mce_gen_guar] = std::vector<double>(length, 
8.00000);
-    loads_.annual_policy_fee_    [mce_gen_guar] = std::vector<double>(length, 
2.00000);
-    loads_.specified_amount_load_[mce_gen_guar] = std::vector<double>(length, 
0.00003);
-    loads_.separate_account_load_[mce_gen_guar] = std::vector<double>(length, 
0.00130);
-    loads_.target_premium_load_  [mce_gen_guar] = std::vector<double>(length, 
0.04000);
-    loads_.excess_premium_load_  [mce_gen_guar] = std::vector<double>(length, 
0.03000);
-    loads_.target_sales_load_    [mce_gen_guar] = std::vector<double>(length, 
0.30000);
-    loads_.excess_sales_load_    [mce_gen_guar] = std::vector<double>(length, 
0.15000);
-
-    loads_.monthly_policy_fee_   [mce_gen_curr] = std::vector<double>(length, 
5.25000);
-    loads_.annual_policy_fee_    [mce_gen_curr] = std::vector<double>(length, 
1.00000);
-    loads_.specified_amount_load_[mce_gen_curr] = std::vector<double>(length, 
0.00002);
-    loads_.separate_account_load_[mce_gen_curr] = std::vector<double>(length, 
0.00110);
-    loads_.target_premium_load_  [mce_gen_curr] = std::vector<double>(length, 
0.02000);
-    loads_.excess_premium_load_  [mce_gen_curr] = std::vector<double>(length, 
0.01000);
-    loads_.target_sales_load_    [mce_gen_curr] = std::vector<double>(length, 
0.10000);
-    loads_.excess_sales_load_    [mce_gen_curr] = std::vector<double>(length, 
0.05000);
+    loads_.refundable_sales_load_proportion_    = std::vector<double>  
(length, 0.50000);
+    loads_.dac_tax_load_                        = std::vector<double>  
(length, 0.00500);
+
+    loads_.monthly_policy_fee_   [mce_gen_guar] = 
std::vector<currency>(length, currency(8.00000));
+    loads_.annual_policy_fee_    [mce_gen_guar] = 
std::vector<currency>(length, currency(2.00000));
+    loads_.specified_amount_load_[mce_gen_guar] = std::vector<double>  
(length, 0.00003);
+    loads_.separate_account_load_[mce_gen_guar] = std::vector<double>  
(length, 0.00130);
+    loads_.target_premium_load_  [mce_gen_guar] = std::vector<double>  
(length, 0.04000);
+    loads_.excess_premium_load_  [mce_gen_guar] = std::vector<double>  
(length, 0.03000);
+    loads_.target_sales_load_    [mce_gen_guar] = std::vector<double>  
(length, 0.30000);
+    loads_.excess_sales_load_    [mce_gen_guar] = std::vector<double>  
(length, 0.15000);
+
+    loads_.monthly_policy_fee_   [mce_gen_curr] = 
std::vector<currency>(length, currency(5.25000));
+    loads_.annual_policy_fee_    [mce_gen_curr] = 
std::vector<currency>(length, currency(1.00000));
+    loads_.specified_amount_load_[mce_gen_curr] = std::vector<double>  
(length, 0.00002);
+    loads_.separate_account_load_[mce_gen_curr] = std::vector<double>  
(length, 0.00110);
+    loads_.target_premium_load_  [mce_gen_curr] = std::vector<double>  
(length, 0.02000);
+    loads_.excess_premium_load_  [mce_gen_curr] = std::vector<double>  
(length, 0.01000);
+    loads_.target_sales_load_    [mce_gen_curr] = std::vector<double>  
(length, 0.10000);
+    loads_.excess_sales_load_    [mce_gen_curr] = std::vector<double>  
(length, 0.05000);
 }
 
 void LoadsTest::TestVectorLengths(char const* file, int line)
@@ -158,8 +158,9 @@ void LoadsTest::TestCalculations(char const* file, int line)
 {
     INVOKE_BOOST_TEST(materially_equal(0.500000, 
loads_.refundable_sales_load_proportion()[0]), file, line);
 
-    INVOKE_BOOST_TEST(materially_equal(6.920000, loads_.monthly_policy_fee    
(mce_gen_mdpt)[0]), file, line);
-    INVOKE_BOOST_TEST(materially_equal(1.500000, loads_.annual_policy_fee     
(mce_gen_mdpt)[0]), file, line);
+    // (8.00 + 5.25 + 0.50) / 2 = 13.75 / 2 = 6.875, rounded to cents
+    INVOKE_BOOST_TEST(currency(688, raw_cents{}) == loads_.monthly_policy_fee 
(mce_gen_mdpt)[0] , file, line);
+    INVOKE_BOOST_TEST(currency(150, raw_cents{}) == loads_.annual_policy_fee  
(mce_gen_mdpt)[0] , file, line);
     INVOKE_BOOST_TEST(materially_equal(0.000625, loads_.specified_amount_load 
(mce_gen_mdpt)[0]), file, line);
     // 12 bp and 19 bp, both converted to monthly, then added together.
     INVOKE_BOOST_TEST(materially_equal(0.0002581402795930, 
loads_.separate_account_load (mce_gen_mdpt)[0]), file, line);
@@ -193,11 +194,11 @@ int test_main(int, char*[])
 {
     round_to<double> round_interest_rate(0, r_not_at_all);
     round_to<double> round_minutiae     (2, r_to_nearest);
-    std::vector<double> extra_comp_load  (length, 0.0170);
-    std::vector<double> extra_asset_comp (length, 0.0019);
-    std::vector<double> extra_policy_fee (length, 0.6000);
-    std::vector<double> guar_specamt_load(length, 0.0007);
-    std::vector<double> curr_specamt_load(length, 0.0005);
+    std::vector<double>   extra_comp_load  (length, 0.0170);
+    std::vector<double>   extra_asset_comp (length, 0.0019);
+    std::vector<currency> extra_policy_fee (length, currency(50, raw_cents{}));
+    std::vector<double>   guar_specamt_load(length, 0.0007);
+    std::vector<double>   curr_specamt_load(length, 0.0005);
 
     load_details details
         (length                 // length_



reply via email to

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