[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[lmi-commits] [5380] Mark some taxation issues
From: |
Greg Chicares |
Subject: |
[lmi-commits] [5380] Mark some taxation issues |
Date: |
Wed, 25 Jan 2012 15:19:23 +0000 |
Revision: 5380
http://svn.sv.gnu.org/viewvc/?view=rev&root=lmi&revision=5380
Author: chicares
Date: 2012-01-25 15:19:23 +0000 (Wed, 25 Jan 2012)
Log Message:
-----------
Mark some taxation issues
Modified Paths:
--------------
lmi/trunk/ihs_acctval.cpp
lmi/trunk/ihs_avmly.cpp
lmi/trunk/ihs_basicval.cpp
lmi/trunk/ihs_irc7702.cpp
lmi/trunk/ihs_irc7702.hpp
lmi/trunk/ihs_irc7702a.cpp
lmi/trunk/ihs_irc7702a.hpp
Modified: lmi/trunk/ihs_acctval.cpp
===================================================================
--- lmi/trunk/ihs_acctval.cpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_acctval.cpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -460,6 +460,7 @@
,InvariantValues().SpecAmt[0]
);
// It is at best superfluous to do this for every basis.
+ // TAXATION !! Don't do that then.
Irc7702_->Initialize7702
(InvariantValues().SpecAmt[0] + InvariantValues().TermSpecAmt[0]
,InvariantValues().SpecAmt[0] + InvariantValues().TermSpecAmt[0]
@@ -472,7 +473,7 @@
// This is notionally called once per *current*-basis run
// and actually called once per run, with calculations suppressed
- // for all other bases. TODO ?? How should we handle MEC-avoid
+ // for all other bases. TODO ?? TAXATION !! How should we handle MEC-avoid
// solves on bases other than current?
InvariantValues().InforceYear = yare_input_.InforceYear;
@@ -504,7 +505,8 @@
if(0 == InforceYear && 0 == InforceMonth)
{
// No need to initialize 'pmts_7702a' in this case.
- // This assumes the term rider can be treated as death benefit.
+ // TAXATION !! This assumes the term rider can be treated as death
benefit.
+ // TAXATION !! DATABASE !! That should be a database flag.
bfts_7702a.push_back
( InvariantValues().SpecAmt[0]
+ InvariantValues().TermSpecAmt[0]
@@ -520,6 +522,10 @@
,std::back_inserter(pmts_7702a)
);
// Specamt history starts at policy year zero and must be offset.
+ // TAXATION !! That's wrong, because contract-year history cannot
+ // generally be obtained from policy-year history by any integral
+ // offset; but doesn't LDB provide all the information required,
+ // if only it were used in preference to this?
int const offset = duration_ceiling
(yare_input_.EffectiveDate
,yare_input_.LastMaterialChangeDate
@@ -533,7 +539,7 @@
double lowest_death_benefit = yare_input_.InforceLeastDeathBenefit;
if(0 == InforceYear && 0 == InforceMonth)
{
- lowest_death_benefit = bfts_7702a.front();
+ lowest_death_benefit = bfts_7702a.front(); // TAXATION !! See
above--use input LDB instead.
}
Irc7702A_->Initialize7702A
(mce_run_gen_curr_sep_full != RunBasis_
@@ -545,11 +551,13 @@
,yare_input_.InforceContractYear
,yare_input_.InforceContractMonth
,yare_input_.InforceAvBeforeLastMc
- ,lowest_death_benefit
+ ,lowest_death_benefit // TAXATION !! See above--use input LDB instead.
,pmts_7702a
,bfts_7702a
);
+ // TAXATION !! Move this before 7702 and 7702A stuff, to make it
+ // harder to overlook.
daily_interest_accounting = contains
(yare_input_.Comments
,"idiosyncrasy_daily_interest_accounting"
@@ -587,7 +595,7 @@
{
// These inforce things belong in input struct.
// TODO ?? The list is not complete; others will be required:
- // payment history; surrender charges; DCV history?
+ // payment history; surrender charges; DCV history? TAXATION !! Resolve
this.
InforceYear = yare_input_.InforceYear ;
InforceMonth = yare_input_.InforceMonth ;
InforceAVGenAcct = yare_input_.InforceGeneralAccountValue ;
@@ -604,7 +612,7 @@
Month = InforceMonth;
CoordinateCounters();
- DB7702A = 0.0; // TODO ?? This seems silly.
+ DB7702A = 0.0; // TODO ?? TAXATION !! This seems
silly.
AVRegLn = InforceAVRegLn;
AVPrfLn = InforceAVPrfLn;
@@ -895,7 +903,7 @@
PremiumTax_->start_new_year();
// Skip this in an incomplete initial inforce year.
- // Premium tax should perhaps be handled similarly.
+ // TAXATION !! Premium tax should perhaps be handled similarly.
if(Year != InforceYear || 0 == InforceMonth)
{
Irc7702_ ->UpdateBOY7702();
@@ -1495,6 +1503,9 @@
*/
YearsTotLoadTgt = Loads_->target_total_load (GenBasis_)[Year];
YearsTotLoadExc = Loads_->excess_total_load (GenBasis_)[Year];
+ // TAXATION !! This '_lowest_premium_tax' approach needs to be
+ // reworked: there should be an option (at least) to use the
+ // current tax rates.
YearsTotLoadTgtLowestPremtax =
Loads_->target_premium_load_7702_lowest_premium_tax()[Year];
YearsTotLoadExcLowestPremtax =
Loads_->excess_premium_load_7702_lowest_premium_tax()[Year];
YearsPremLoadTgt = Loads_->target_premium_load (GenBasis_)[Year];
Modified: lmi/trunk/ihs_avmly.cpp
===================================================================
--- lmi/trunk/ihs_avmly.cpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_avmly.cpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -121,8 +121,9 @@
TxTakeWD();
TxTestGPT();
- // TODO ?? Doesn't this mean dumpins and 1035s get ignored?
+ // TODO ?? TAXATION !! Doesn't this mean dumpins and 1035s get ignored?
LMI_ASSERT(0.0 <= Dcv);
+ // TAXATION !! Is it really useful to comment the arguments here?
Irc7702A_->UpdateBft7702A
(Dcv
,DBReflectingCorr + TermDB // DB7702A
@@ -153,7 +154,7 @@
+ GetRefundableSalesLoad()
// + std::max(0.0, ExpRatReserve) // This would be added if it
existed.
);
-// TODO ?? Use CashValueFor7702() instead?
+// TODO ?? TAXATION !! Use CashValueFor7702() instead?
double max_necessary_premium = Irc7702A_->MaxNecessaryPremium
(Dcv
,AnnualTargetPrem
@@ -169,18 +170,22 @@
,kludge_account_value
);
- // Saved for monthly detail report only.
+ // Saved for monthly detail report only. TAXATION !! Then are
+ // these still needed...perhaps in order to report their values
+ // prior to accepting any payment?
NetMaxNecessaryPremium = Irc7702A_->DebugGetNetMaxNecPm ();
GrossMaxNecessaryPremium = Irc7702A_->DebugGetGrossMaxNecPm();
TxAscertainDesiredPayment();
TxLimitPayment(max_non_mec_premium);
+ // TAXATION !! This line recognizes a withdrawal for 7702A;
+ // shouldn't there be similar code here for GPT?
if(0 == Month)
{
Irc7702A_->UpdatePmt7702A
(Dcv
- ,-NetWD
+ ,-NetWD // TAXATION !! This should be gross, not net.
,false
,AnnualTargetPrem
,YearsTotLoadTgtLowestPremtax
@@ -557,13 +562,15 @@
// return;
// }
+// TAXATION !! This condition, or a similar one, guards several GPT calls,
+// but not all (ProcessAdjustableEvent(), e.g.); should this be made uniform?
// TODO ?? Perhaps this condition should be:
// if(!SolvingForGuarPremium && Solving || mce_run_gen_curr_sep_full ==
RunBasis_)
if(Solving || mce_run_gen_curr_sep_full == RunBasis_)
{
if(!SolvingForGuarPremium)
{
- double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+ double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
Irc7702_->ProcessGptPmt(Year, GrossPmts[Month], fake_cum_pmt);
}
// Limit external 1035 first, then internal, as necessary to avoid
@@ -603,13 +610,13 @@
DBReflectingCorr = 0.0;
TxSetDeathBft();
TxSetTermAmt();
- // TODO ?? Should 1035 exchanges be handled somewhere else?
+ // TODO ?? TAXATION !! Should 1035 exchanges be handled somewhere else?
HOPEFULLY(0.0 == Dcv);
Irc7702A_->Update1035Exch7702A
(Dcv
,NetPmts[Month]
,ActualSpecAmt + TermSpecAmt
-// ,DBReflectingCorr + TermDB
+// ,DBReflectingCorr + TermDB // TAXATION !! Alternate if 7702A benefit
is DB?
);
if(HoneymoonActive)
@@ -883,7 +890,10 @@
OldSA = ActualSpecAmt + TermSpecAmt;
OldDB = DBReflectingCorr + TermDB;
- // TODO ?? CVAT only?
+ // TODO ?? CVAT only? TAXATION !! Consider whether and how 7702A
+ // functions should be guarded generally, with due regard to the
+ // definitional test chosen. This function probably should be
+ // called for GPT as well as CVAT.
Irc7702A_->UpdateBOM7702A(Month);
}
@@ -1060,7 +1070,7 @@
ChangeSpecAmtBy(YearsSpecAmt - ActualSpecAmt);
- // TODO ?? Should 7702 or 7702A processing be done here?
+ // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
}
//============================================================================
@@ -1076,6 +1086,11 @@
80000 guar
if forceout needed, it will be higher for curr--OK
but position could be reversed for variable policy with bad curr performance
+
+TAXATION !! Revisit those issues. Furthermore, should forceout really
+vary by basis? Probably not if it shows up only in an "outlay" column
+that's shared by all bases...but then what about the variable scenario
+mentioned above?
*/
if(mce_gpt != DefnLifeIns_ || mce_run_gen_curr_sep_full != RunBasis_)
@@ -1127,6 +1142,7 @@
//
mcenum_dbopt_7702 const new_dbopt(effective_dbopt_7702(YearsDBOpt,
Equiv7702DBO3));
mcenum_dbopt_7702 const old_dbopt(effective_dbopt_7702(OldDBOpt ,
Equiv7702DBO3));
+ // TAXATION !! This may require revision if DB is treated as the 7702
benefit.
bool adj_event =
(
!materially_equal(OldSA, ActualSpecAmt + TermSpecAmt)
@@ -1136,7 +1152,8 @@
;
if(adj_event)
{
- // TODO ?? Perhaps we should pass 'A' of 'A+B-C' for validation.
+ // TODO ?? TAXATION !! Perhaps we should pass 'A' of 'A+B-C' for
validation.
+ // Or maybe not, because we can't match it if there was a plan change.
Irc7702_->ProcessAdjustableEvent
(Year
,DBReflectingCorr + TermDB
@@ -1150,7 +1167,7 @@
}
GptForceout = Irc7702_->Forceout();
- // TODO ?? On other bases, nothing is forced out, and payments aren't
limited.
+ // TODO ?? TAXATION !! On other bases, nothing is forced out, and payments
aren't limited.
process_distribution(GptForceout);
YearsTotalGptForceout += GptForceout;
@@ -1167,7 +1184,7 @@
Irc7702A_->InduceMaterialChange();
}
- // TODO ?? GPT--perform only if current basis?
+ // TODO ?? TAXATION !! GPT--perform only if current basis?
OldDBOpt = YearsDBOpt;
}
@@ -1231,7 +1248,7 @@
// illustration-reg guaranteed premium.
if(!SolvingForGuarPremium)
{
- double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+ double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
Irc7702_->ProcessGptPmt(Year, eepmt, fake_cum_pmt);
}
EeGrossPmts[Month] += eepmt;
@@ -1244,7 +1261,7 @@
// illustration-reg guaranteed premium.
if(!SolvingForGuarPremium)
{
- double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+ double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
Irc7702_->ProcessGptPmt(Year, erpmt, fake_cum_pmt);
}
ErGrossPmts[Month] += erpmt;
@@ -1277,7 +1294,7 @@
// illustration-reg guaranteed premium.
if(!SolvingForGuarPremium)
{
- double fake_cum_pmt = 0.0; // TODO ?? Needs work.
+ double fake_cum_pmt = 0.0; // TODO ?? TAXATION !! Needs work.
Irc7702_->ProcessGptPmt(Year, Dumpin, fake_cum_pmt);
}
EeGrossPmts[Month] += Dumpin;
@@ -1287,6 +1304,8 @@
}
//============================================================================
+// TAXATION !! Should this be called for gpt? or, if it's called,
+// should it assert that it has no effect?
void AccountValue::TxLimitPayment(double a_maxpmt)
{
// Subtract premium load from gross premium yielding net premium.
@@ -1294,7 +1313,7 @@
// This is needed only for current-basis or solve-basis runs.
// Otherwise we're doing too much work, and maybe doing things
// we shouldn't.
-// TODO ?? Clean this up, and put GPT limit here, on prem net of WD.
+// TODO ?? TAXATION !! Clean this up, and put GPT limit here, on prem net of
WD.
HOPEFULLY(materially_equal(GrossPmts[Month], EeGrossPmts[Month] +
ErGrossPmts[Month]));
@@ -1370,8 +1389,9 @@
);
LMI_ASSERT(0.0 <= Dcv);
- // TODO ?? Not correct yet--need to test pmt less deductible WD; and
- // shouldn't we deduct the *gross* WD?
+ // TODO ?? TAXATION !! Not correct yet--need to test pmt less deductible
WD; and
+ // shouldn't we deduct the *gross* WD? [Yes, if any fee is part of the
+ // WD, which it normally is.]
double amount_paid_7702A = a_pmt;
Irc7702A_->UpdatePmt7702A
(Dcv
@@ -1420,8 +1440,11 @@
// TODO ?? This thing isn't really the tax basis as it should be
// because we subtract all WDs without regard to taxability:
// if WDs exceed basis, 7702A calculations are incorrect.
+ // TAXATION !! Fix this. Nontaxable WDs are handled much like
+ // GPT forceouts. Generally, WDs are nontaxable up to basis for
+ // non-MECs, except for 7702(f)(7)(B-E).
TaxBasis += a_pmt;
- // TODO ?? Save ee and er bases separately e.g. for split dollar;
+ // TODO ?? TAXATION !! Save ee and er bases separately e.g. for split
dollar;
// call them EeTaxBasis and ErTaxBasis.
}
@@ -1575,12 +1598,16 @@
}
else
{
+ // TAXATION !! We could at least change this in xrc help elements:
// USER !! User documentation should explain that this
// includes any 7702-integrated term rider.
//
// Some products have loads that depend on the initial
// specified amount, which probably includes term; if it
// doesn't, then a new input field would need to be added.
+ //
+ // TAXATION !! Is this really desirable? INPUT !! Should we
+ // instead capture specamt as of issue date for this purpose?
z = yare_input_.SpecamtHistory.front();
}
SpecAmtLoadBase = std::max(z, NetPmts[Month] * YearsCorridorFactor);
@@ -1607,7 +1634,7 @@
// Set death benefit reflecting corridor and death benefit option.
void AccountValue::TxSetDeathBft(bool force_eoy_behavior)
{
- // TODO ?? Should 7702 or 7702A processing be done here?
+ // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
// If so, then this code may be useful:
// double prior_db_7702A = DB7702A;
// double prior_sa_7702A = ActualSpecAmt;
@@ -1689,6 +1716,7 @@
DBReflectingCorr = round_death_benefit()(DBReflectingCorr);
// This overrides the value assigned above. There's more than one
// way to interpret 7702A "death benefit"; this is just one.
+ // TAXATION !! DATABASE !! Offer a choice of interpretations.
DB7702A = DBReflectingCorr + TermDB;
DcvDeathBft = std::max
@@ -1701,7 +1729,7 @@
)
)
);
- // TODO ?? Should 7702 or 7702A processing be done here?
+ // TODO ?? TAXATION !! Should 7702 or 7702A processing be done here?
// If so, then this code may be useful:
/*
// Try moving this here...
@@ -2625,15 +2653,15 @@
}
CumPmts -= NetWD;
- TaxBasis -= NetWD;
+ TaxBasis -= NetWD; // TODO ?? TAXATION !! This should be gross, not
net; how about the line above and the line below?
CumWD += NetWD;
+ // TAXATION !! What about 7702A "amounts paid"?
if(Solving || mce_run_gen_curr_sep_full == RunBasis_)
{
if(!SolvingForGuarPremium)
{
double fake_cum_pmt = 0.0; // TODO ?? Needs work.
- // TODO ?? Should also use *gross* above in CumPmts etc.
double premiums_paid_increment = -GrossWD;
Irc7702_->ProcessGptPmt(Year, premiums_paid_increment,
fake_cum_pmt);
}
Modified: lmi/trunk/ihs_basicval.cpp
===================================================================
--- lmi/trunk/ihs_basicval.cpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_basicval.cpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -95,7 +95,7 @@
template std::string mc_str(mcenum_uw_basis);
//============================================================================
-// TODO ?? Not for general use--use for GPT server only. This is bad design.
+// TODO ?? Not for general use--use for GPT server only. This is bad design.
TAXATION !! Eliminate this.
BasicValues::BasicValues
(std::string const& a_ProductName
,mcenum_gender a_Gender
@@ -253,7 +253,8 @@
// determined by a strategy. This data member is used only by
// Init7702(), and is meaningful only when that function is called
// by GPTServerInit(); the value assigned here is overridden by a
- // downstream call to Irc7702::Initialize7702().
+ // downstream call to Irc7702::Initialize7702(). TAXATION !! So
+ // eliminate the member when it becomes unnecessary.
InitialTargetPremium = 0.0;
SetMaxSurvivalDur();
@@ -263,7 +264,7 @@
}
//============================================================================
-// TODO ?? Not for general use--use for GPT server only, for now--refactor
later
+// TODO ?? Not for general use--use for GPT server only, for now. TAXATION !!
refactor later
void BasicValues::GPTServerInit()
{
ProductData_.reset(new product_data(yare_input_.ProductName));
@@ -438,6 +439,9 @@
return z;
}
+// TAXATION !! Reconsider unconditional initialization.
+// TAXATION !! For 7702A, offer a choice: tables or first principles.
+
/// Initialize 7702 object.
///
/// This function is called unconditionally, even for CVAT cases that
@@ -502,7 +506,7 @@
// Monthly guar net int for 7702, with 4 or 6% min, is
// greater of {4%, 6%} and annual guar int rate
// less 7702 spread
- // TODO ?? We need to subtract other things too, e.g. comp (sometimes)...
+ // TODO ?? TAXATION !! We need to subtract other things too, e.g. comp
(sometimes)...
// transformed to monthly (simple subtraction?).
// These interest rates belong here because they're used by
// DCV calculations in the account value class as well as
@@ -510,6 +514,10 @@
std::vector<double> guar_int;
Database_->Query(guar_int, DB_GuarInt);
+// TAXATION !! Rework this. The intention is to make the 7702 interest
+// rate no less, at any duration, than the guaranteed loan rate--here,
+// the fixed rate charged on loans, minus the guaranteed loan spread
+// (if any).
/*
switch(yare_input_.LoanRateType)
{
@@ -609,7 +617,7 @@
// TODO ?? We should avoid reading the rate file again; but
// the GPT server doesn't initialize a MortalityRates object
- // that would hold those rates.
+ // that would hold those rates. TAXATION !! Rework this.
std::vector<double> local_mly_charge_add(Length, 0.0);
if(yare_input_.AccidentalDeathBenefit)
{
@@ -656,16 +664,16 @@
//============================================================================
void BasicValues::Init7702A()
{
- int magic = 0; // TODO ?? A kludge.
+ int magic = 0; // TODO ?? TAXATION !! A kludge.
Irc7702A_.reset
(new Irc7702A
(magic
,DefnLifeIns_
,DefnMaterialChange_
- ,false // TODO ?? Joint life: hardcoded for now.
+ ,false // TODO ?? TAXATION !! Joint life: hardcoded for now.
,yare_input_.AvoidMecMethod
- ,true // TODO ?? Use table for 7pp: hardcoded for now.
- ,true // TODO ?? Use table for NSP: hardcoded for now.
+ ,true // TODO ?? TAXATION !! Use table for 7pp: hardcoded for now.
+ ,true // TODO ?? TAXATION !! Use table for NSP: hardcoded for now.
,MortalityRates_->SevenPayRates()
,MortalityRates_->CvatNspRates()
,round_max_premium()
Modified: lmi/trunk/ihs_irc7702.cpp
===================================================================
--- lmi/trunk/ihs_irc7702.cpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702.cpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -40,6 +40,10 @@
#include <limits>
#include <numeric>
+// TAXATION !! Update this block comment, or simply delete it. The
+// client-server model is important, but not predominantly so. It is
+// no longer desirable to document basic C++ for C programmers here.
+//
// The corridor factor may as well reside on the client system: it's
// just a constant vector of 101 numbers. We make it available for
// any client that wants us to supply it.
@@ -76,28 +80,33 @@
return v;
}
- // Use 7702 int rate for DB discount in NAAR
+ // Use 7702 int rate for DB discount in NAAR. TAXATION !! Does it
+ // make sense to retain this?
bool g_UseIcForIg = true;
} // Unnamed namespace.
-// General concerns
+// TAXATION !! General concerns
//
-// flat extras
+// TAXATION !! Explain why flat extras are generally ignored.
//
-// off-anniversary processing
+// TAXATION !! Support off-anniversary adjustment events, though not
+// in illustrations.
//
-// signal forceouts
-// signal if gp limit becomes negative
+// TAXATION !! Are forceouts signalled properly by the server? in
illustrations?
//
-// always allow min pmt to keep contract in force
+// TAXATION !! Signal if gp limit becomes negative; always allow min pmt to
keep
+// contract in force.
//
-// maturity duration
+// TAXATION !! What if maturity duration is beyond age 100?
//
-// riders
+// TAXATION !! Are riders adequately supported?
//
-// need these in ctor?
+// TAXATION !! need this in ctor?
// ,double a_CumPmtYtd
+//
+// TAXATION !! 7702(f)(7)(B-E)
+// TAXATION !! Document these points in some more appropriate fashion:
// Server questions and answers:
// check each pmt? --no, admin system does that
// maintain current and last GSP, GLP --no, admin system does that
@@ -176,13 +185,13 @@
{
LMI_ASSERT(a_PresentSpecAmt <= a_PresentBftAmt);
LMI_ASSERT(0.0 <= a_TargetPremium);
- // TODO ?? Instead put these in initializer-list and write assertions?
+ // TODO ?? TAXATION !! Instead put these in initializer-list and write
assertions?
if(0 == InforceYear && 0 == InforceMonth)
{
PriorBftAmt = a_PresentBftAmt;
PriorSpecAmt = a_PresentSpecAmt;
- // TODO ?? Assert that this is <= least-bft arg?
- LeastBftAmtEver = a_PresentSpecAmt;
+ // TODO ?? TAXATION !! Assert that this is <= least-bft arg?
+ LeastBftAmtEver = a_PresentSpecAmt; // TAXATION !! Why not
a_LeastBftAmtEver?
PriorDBOpt = PresentDBOpt;
PresentGLP = 0.0;
PriorGLP = 0.0;
@@ -194,13 +203,15 @@
}
else
{
+ // TAXATION !! Why Prior from Prior here, but from Present above?
+ // and, below, from Present for dbopt?
PriorBftAmt = a_PresentBftAmt;
PriorSpecAmt = a_PresentSpecAmt;
LeastBftAmtEver = a_LeastBftAmtEver;
LMI_ASSERT(LeastBftAmtEver <= PriorBftAmt);
LMI_ASSERT(LeastBftAmtEver <= PresentBftAmt);
- PriorDBOpt = PresentDBOpt; // TODO ?? handle this (and some
others) in initializer-list instead
- // TODO ?? Must these be members? The arguments could be used here
instead.
+ PriorDBOpt = PresentDBOpt; // TODO ?? TAXATION !! handle this
(and some others) in initializer-list instead
+ // TODO ?? TAXATION !! Must these be members? The arguments could be
used here instead.
PresentGLP = InforceGLP;
PriorGLP = InforceGLP;
CumGLP = InforceCumGLP;
@@ -208,6 +219,7 @@
PriorGSP = InforceGSP;
GptLimit = std::max(CumGLP, PresentGSP);
CumPmts = a_InforceCumPremsPaid;
+// TAXATION !! Are these comments still useful?
// to handle inforce, we need to know:
// the quantity A in A+B-C (i.e. both GSP and GLP)
// CumGLP
@@ -229,6 +241,7 @@
)
{
// TODO ?? Duration and CumPmt args not yet used.
+// TAXATION !! Would Duration somehow be used for verification?
if(mce_gpt != Test7702)
{
return;
@@ -239,6 +252,7 @@
}
//============================================================================
+// TAXATION !! Update this block comment.
// Adjustable events processed here:
// actual changes in DB arising from:
// changes in SA
@@ -284,9 +298,11 @@
LMI_ASSERT(materially_equal(PresentSpecAmt, a_PriorSpecAmt));
LMI_ASSERT(PresentDBOpt == a_PriorDBOpt);
LMI_ASSERT(0.0 <= a_TargetPremium);
+ // TAXATION !! Update this block comment:
// Should be called only when something actually changed: either
// dbopt changed; or
// specamt changed, causing an actual change in bftamt.
+ // TAXATION !! ...or bft amt, if 7702 DB is defined as that
// For illustrations only, we assume:
// no changes in ratings
// no liberalizations in charges
@@ -312,6 +328,8 @@
// Apply A + B - C method for both GLP and GSP.
+// TAXATION !! The name should certainly be changed; should the
+// old behavior be retained conditionally?
// We changed our interpretation, but it'd be nice to preserve
// the old functionality, conditional on a behavior flag. And
// the name is poor: shouldn't it just be 'EndowmentBenefit'?
@@ -321,14 +339,14 @@
(a_Duration
,PresentBftAmt
,PresentSpecAmt
- ,PresentSpecAmt // LeastBftAmtEver
+ ,PresentSpecAmt // TAXATION !! LeastBftAmtEver
,PresentDBOpt
);
double c_level = CalculateGLP
(a_Duration
,PriorBftAmt
,PriorSpecAmt
- ,PriorSpecAmt // LeastBftAmtEver
+ ,PriorSpecAmt // TAXATION !! LeastBftAmtEver
,PriorDBOpt
);
PriorGLP = PresentGLP;
@@ -338,19 +356,20 @@
(a_Duration
,PresentBftAmt
,PresentSpecAmt
- ,PresentSpecAmt // LeastBftAmtEver
+ ,PresentSpecAmt // TAXATION !! LeastBftAmtEver
);
double c_single = CalculateGSP
(a_Duration
,PriorBftAmt
,PriorSpecAmt
- ,PriorSpecAmt // LeastBftAmtEver
+ ,PriorSpecAmt // TAXATION !! LeastBftAmtEver
);
PriorGSP = PresentGSP;
PresentGSP = PriorGSP + b_single - c_single;
// Test for negative guideline...then do what if negative?
// --refer to actuarial department (see specs)
- CumGLP = CumGLP + PresentGLP - PriorGLP;
+// TAXATION !! shouldn't that be handled here?
+ CumGLP = CumGLP + PresentGLP - PriorGLP; // TAXATION !! Eh? Because prior
GLP was already added?
GptLimit = std::max(CumGLP, PresentGSP);
}
@@ -376,8 +395,10 @@
{
Length = Qc.size();
// TODO ?? Assumes that endowment age is always 100--should pass as arg
instead.
+ // TAXATION !! Is the comment above correct? Maturity age is passed as an
argument.
LMI_ASSERT(Length == EndtAge - IssueAge);
+ // TAXATION !! "For now": a decade has passed...
// For now, always perform both GPT and CVAT calculations.
// GLP might be wanted for some purpose in a CVAT product.
// The extra overhead is not enormous.
@@ -389,7 +410,7 @@
InitPvVectors(Opt1Int6Pct);
// TODO ?? We can delete the commutation functions here, rather than in
// the dtor, to save some space. We defer doing so until the
- // program is complete.
+ // program is complete. TAXATION !! It would be better not to use
pointers--see header.
}
//============================================================================
@@ -464,7 +485,7 @@
{
// CVAT corridor
// TODO ?? Substandard: set last NSP to 1.0? ignore flats? set NSP[omega]
to 1?
- // --better to ignore susbstandard
+ // TAXATION !! --better to ignore susbstandard
CvatCorridor.resize(Length);
// ET !! CvatCorridor = CommFns[Opt1Int4Pct]->aD() /
CommFns[Opt1Int4Pct]->kM();
std::vector<double> denominator(CommFns[Opt1Int4Pct]->kM());
@@ -621,7 +642,7 @@
// ET !! PvNpfSglTgt[a_EIOBasis] = (1.0 - LoadTgt) * comm_fns.aD();
std::vector<double>& npf_sgl_tgt = PvNpfSglTgt[a_EIOBasis];
-// LMI_ASSERT(u_length == npf_sgl_tgt.size());
+// LMI_ASSERT(u_length == npf_sgl_tgt.size()); // TAXATION !! Expunge if
truly unwanted.
npf_sgl_tgt = LoadTgt;
LMI_ASSERT(u_length == npf_sgl_tgt.size());
std::transform(npf_sgl_tgt.begin(), npf_sgl_tgt.end(), npf_sgl_tgt.begin()
@@ -637,7 +658,7 @@
,std::multiplies<double>()
);
std::vector<double>& npf_lvl_tgt = PvNpfLvlTgt[a_EIOBasis];
-// LMI_ASSERT(u_length == npf_lvl_tgt.size());
+// LMI_ASSERT(u_length == npf_lvl_tgt.size()); // TAXATION !! Expunge if
truly unwanted.
npf_lvl_tgt = npf_sgl_tgt;
LMI_ASSERT(u_length == npf_lvl_tgt.size());
std::reverse(npf_lvl_tgt.begin(), npf_lvl_tgt.end());
@@ -648,13 +669,13 @@
// ET !! PvNpfSglExc[a_EIOBasis] = (1.0 - LoadExc) * comm_fns.aD();
std::vector<double>& npf_sgl_exc = PvNpfSglExc[a_EIOBasis];
-// LMI_ASSERT(u_length == npf_sgl_exc.size());
+// LMI_ASSERT(u_length == npf_sgl_exc.size()); // TAXATION !! Expunge if
truly unwanted.
npf_sgl_exc = LoadExc;
LMI_ASSERT(u_length == npf_sgl_exc.size());
std::transform(npf_sgl_exc.begin(), npf_sgl_exc.end(), npf_sgl_exc.begin()
,std::bind1st(std::minus<double>(), 1.0)
);
- LMI_ASSERT(u_length == npf_sgl_tgt.size());
+ LMI_ASSERT(u_length == npf_sgl_tgt.size()); // TAXATION !! Shouldn't this
be npf_sgl_exc?
LMI_ASSERT(u_length == comm_fns.aD().size());
std::transform
(npf_sgl_exc.begin()
@@ -664,7 +685,7 @@
,std::multiplies<double>()
);
std::vector<double>& npf_lvl_exc = PvNpfLvlExc[a_EIOBasis];
-// LMI_ASSERT(u_length == npf_lvl_exc.size());
+// LMI_ASSERT(u_length == npf_lvl_exc.size()); // TAXATION !! Expunge if
truly unwanted.
npf_lvl_exc = npf_sgl_exc;
LMI_ASSERT(u_length == npf_lvl_exc.size());
std::reverse(npf_lvl_exc.begin(), npf_lvl_exc.end());
@@ -675,7 +696,7 @@
// ET !! PvLoadDiffSgl[a_EIOBasis] = npf_sgl_exc - npf_sgl_tgt;
std::vector<double>& diff_sgl = PvLoadDiffSgl[a_EIOBasis];
-// LMI_ASSERT(u_length == diff_sgl.size());
+// LMI_ASSERT(u_length == diff_sgl.size()); // TAXATION !! Expunge if truly
unwanted.
diff_sgl.resize(Length);
LMI_ASSERT(u_length == diff_sgl.size());
LMI_ASSERT(u_length == npf_sgl_exc.size());
@@ -688,7 +709,7 @@
,std::minus<double>()
);
std::vector<double>& diff_lvl = PvLoadDiffLvl[a_EIOBasis];
-// LMI_ASSERT(u_length == diff_lvl.size());
+// LMI_ASSERT(u_length == diff_lvl.size()); // TAXATION !! Expunge if truly
unwanted.
diff_lvl.resize(Length);
LMI_ASSERT(u_length == diff_lvl.size());
std::reverse(diff_lvl.begin(), diff_lvl.end());
@@ -707,7 +728,7 @@
void Irc7702::Initialize7702
(double a_BftAmt
,double a_SpecAmt
- ,mcenum_dbopt_7702 a_DBOpt // TODO ?? Is there any reason why dbopt would
be changed here?
+ ,mcenum_dbopt_7702 a_DBOpt // TODO ?? TAXATION !! Is there any reason why
dbopt would be changed here?
,double a_TargetPremium
)
{
@@ -719,7 +740,7 @@
PriorSpecAmt = PresentSpecAmt;
PresentBftAmt = a_BftAmt;
PriorBftAmt = PresentBftAmt;
-// This:
+// TAXATION !! This:
// LeastBftAmtEver = PresentBftAmt;
// would appear correct: ...BftAmt assigned from ...BftAmt. However,
// as pointed out above, 'EndowmentBenefit' would be a better name,
@@ -748,6 +769,7 @@
}
else
{
+ // TAXATION !! Revisit this.
// TODO ?? None of this should be necessary, but this function
// is called for every basis, though it probably should be
// called only once, for basis 'mce_run_gen_curr_sep_full'.
@@ -773,6 +795,9 @@
// be OK because illustration systems confine most transactions
// to anniversaries and we envision that an admin system client
// will do this calculation itself.
+ // TAXATION !! Rewrite that comment. It is true that off-anniversary
+ // changes aren't handled at present, but the work done here would
+ // never be done at any other time.
CumGLP += PresentGLP;
GptLimit = std::max(CumGLP, PresentGSP);
}
@@ -890,6 +915,7 @@
LMI_ASSERT(0.0 != a_NetPmtFactorTgt);
LMI_ASSERT(0.0 != a_NetPmtFactorExc);
+ // TAXATION !! Deal with this:
// TODO ?? This implementation is correct only if target premium
// is fixed forever at issue; otherwise, distinct target premiums
// must be passed for each of the quantities A, B, and C. Should
@@ -926,19 +952,22 @@
;
}
+// TAXATION !! Deal with this stuff.
// Nothing past this point is intended for use by the GPT server
// General concerns outside the scope of the standalone server
//
-// combine txs on same date
+// combine txs on same date TAXATION !! isn't that up to the server?
//
-// track cum pmts - wds and forceouts
+// track cum pmts less wds and forceouts TAXATION !! is it necessary
+// to add code here to accumulate those debits?
//
-// current mort for substd
+// current mort for substd TAXATION !! is that outside the scope of this code?
//
-// set SA at issue to reflect dumpins and 1035s
+// set SA at issue to reflect dumpins and 1035s TAXATION !! That could be
+// done for option two, but is probably a mistake.
//
-// naming--SA vs SpecAmt, etc.
+// naming--SA vs SpecAmt, etc. TAXATION !! a grand renaming is desirable
//
/*
@@ -946,7 +975,7 @@
void Irc7702::InitSevenPayPrem()
{
// 7PP = MO / (N0-N7) (limit 7 to maturity year)
- // add flat extras to 7PP?
+ // TAXATION !! add flat extras to 7PP?
double denom = CFFourPctMin->N()[j];
if((7 + j) < q.size())
{
@@ -1007,7 +1036,7 @@
return CumPmts;
}
-// TODO ?? This should be a separate, standalone unit test.
+// TAXATION !! TODO ?? This should be a separate, standalone unit test.
#ifdef TESTING
#include "ihs_timer.hpp"
@@ -1031,6 +1060,7 @@
int main()
{
+// TAXATION !! Update or remove these timings.
// timing to construct Irc7702:
// RW: about 37 msec
// OS: about 93 msec; about 41 if we disable index checking
Modified: lmi/trunk/ihs_irc7702.hpp
===================================================================
--- lmi/trunk/ihs_irc7702.hpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702.hpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -49,7 +49,7 @@
// premium) and the bftamt (for death benefit), even though those two
// arguments may be equal.
-// TODO ?? Is this still true?
+// TODO ?? TAXATION !! Is this still true?
// No rounding is performed in this class. Round the values it calculates
// as needed, being sure to round conservatively if at all. Unrounded
// values are especially needed for the iterative specamt calculation.
@@ -94,7 +94,7 @@
,double a_InforceCumGLP
,double a_InforceGSP
,double a_InforceCumPremsPaid
- // TODO ?? Perhaps other arguments are needed for inforce.
+ // TODO ?? TAXATION !! Perhaps other arguments are needed for inforce.
);
~Irc7702();
@@ -110,7 +110,7 @@
,double& a_Pmt
,double& a_CumPmt
);
- // Returns forceout if any, else 0.0 .
+ // Returns forceout if any, else 0.0 . TAXATION !! But it's void.
void ProcessAdjustableEvent
(int a_Duration
,double a_NewBftAmt
@@ -174,6 +174,8 @@
(mcenum_dbopt_7702 a_DBOpt
);
+ // TAXATION !! Comments are unreliable (e.g., 7702 test may be
+ // neither CVAT nor GPT), and should be improved or removed.
mcenum_defn_life_ins const Test7702; // 7702 test: CVAT or GPT
int const IssueAge; // Issue age
int const EndtAge; // Endowment age
@@ -188,7 +190,7 @@
double PriorBftAmt;
double PresentSpecAmt;
double PriorSpecAmt;
- double LeastBftAmtEver;// Lowest bft amt since issue
date // TODO ?? NOT!
+ double LeastBftAmtEver;// Lowest bft amt since issue
date // TODO ?? TAXATION !! NOT!
mcenum_dbopt_7702 PresentDBOpt; // Present death benefit option
mcenum_dbopt_7702 PriorDBOpt; // Prior death benefit option
@@ -229,13 +231,18 @@
// Commutation functions
// TODO ?? Apparently the original reason for using smart pointers
// was to minimize stack usage in a 16-bit environment; clearly that
-// doesn't matter anymore.
+// doesn't matter anymore. TAXATION !! Don't do that then.
//
-// TODO ?? Consider using std::vector instead of array members.
+// TODO ?? TAXATION !! Consider using std::vector instead of array members.
boost::scoped_ptr<ULCommFns> CommFns [NumIOBases];
// After the Init- functions have executed, we can delete the
// rather sizeable ULCommFns objects, as long as we keep the
- // endowment-year value of D for each basis.
+ // endowment-year value of D for each basis. TAXATION !! But
+ // not if they're created on the stack. And the meaning of
+ // "sizeable" has changed since that comment was written; the
+ // object contains nine vectors of double, each of potential
+ // length 100, and 9 * 8 * 100 = 7200 bytes is negligible in
+ // the twenty-first century.
double DEndt [NumIOBases];
// GPT corridor factors for attained ages [IssueAge, 100]
@@ -249,16 +256,18 @@
std::vector<double> PvChgSpecAmt [NumIOBases];
std::vector<double> PvChgADD [NumIOBases];
std::vector<double> PvChgMort [NumIOBases];
- // TODO ?? Perhaps -Sgl/Lvl and -Tgt/Exc should be dimensions.
+ // TODO ?? TAXATION !! Perhaps -Sgl/Lvl and -Tgt/Exc should be dimensions.
std::vector<double> PvNpfSglTgt [NumIOBases];
std::vector<double> PvNpfLvlTgt [NumIOBases];
std::vector<double> PvNpfSglExc [NumIOBases];
std::vector<double> PvNpfLvlExc [NumIOBases];
-// TODO ?? Not necessary?
+// TODO ?? TAXATION !! Not necessary?
std::vector<double> PvLoadDiffSgl [NumIOBases];
std::vector<double> PvLoadDiffLvl [NumIOBases];
};
+// TAXATION !! Update this, and move it to a better location.
+//
// Implementation thoughts
//
// This class was designed to be instantiated by a C++ illustration
Modified: lmi/trunk/ihs_irc7702a.cpp
===================================================================
--- lmi/trunk/ihs_irc7702a.cpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702a.cpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -21,11 +21,11 @@
// $Id$
-// TODO ?? Make this a server app. Consider where to store DB, SA history.
+// TODO ?? TAXATION !! Make this a server app. Consider where to store DB, SA
history.
-// TODO ?? Do we need a separate function to handle withdrawals?
+// TODO ?? TAXATION !! Do we need a separate function to handle withdrawals?
-// TODO ?? Treat ROP increases as material changes exactly where needed.
+// TODO ?? TAXATION !! Treat ROP increases as material changes exactly where
needed.
#ifdef __BORLANDC__
# include "pchfile.hpp"
@@ -51,7 +51,7 @@
static int const months_per_year = 12 ;
static long double const years_per_month = 1.0L / 12.0L;
static int const statutory_max_endowment_age = 100 ;
-// TODO ?? Test period not limited to seven years for survivorship.
+// TODO ?? TAXATION !! Test period not limited to seven years for survivorship.
static int const usual_test_period_length = 7 ;
}
@@ -116,8 +116,9 @@
// Set flags for implementation choices. Assigning values here
// looks superfluous because it duplicates the initializer-list;
// they're grouped here to emphasize them for maintainers.
+ // TAXATION !! DATABASE !! Each should either be eliminated or moved to
the database.
InterpolateNspOnly = false;
- Exch1035IsMatChg = true; // TODO ?? Silly--remove.
+ Exch1035IsMatChg = true; // TODO ?? TAXATION !! Silly--remove.
CorrHidesIncr = false;
switch(DefnMaterialChange)
@@ -140,7 +141,7 @@
break;
case mce_later_of_increase_or_unnecessary_premium:
{
- // TODO ?? Not implemented yet.
+ // TODO ?? TAXATION !! Not implemented yet.
fatal_error()
<< "mce_later_of_increase_or_unnecessary_premium not
implemented."
<< LMI_FLUSH
@@ -216,14 +217,14 @@
double lowest_bft = *std::min_element(a_Bfts.begin(), a_Bfts.end());
// Allow Bfts to be zero for solves.
LMI_ASSERT(0.0 <= lowest_bft);
- // TODO ?? Should we assert that this equals 'a_LowestBft'?
+ // TODO ?? TAXATION !! Should we assert that this equals 'a_LowestBft'?
// If we can, then we don't need the latter as an argument.
Ignore = false;
if(a_Ignore || (mce_cvat != DefnLifeIns && mce_gpt != DefnLifeIns))
{
Ignore = true;
- // TODO ?? An early return here as a speed optimization is not yet
+ // TODO ?? TAXATION !! An early return here as a speed optimization is
not yet
// safe. Routines to print optional monthly calculation detail rely
// on sane values for some of the variables below. We could make
// those routines depend on the early return condition here, or
@@ -234,12 +235,12 @@
UnnecPremPaid = false;
IsMec = false;
- // TODO ?? I dislike this variable name because a contract can become a MEC
+ // TODO ?? TAXATION !! I dislike this variable name because a contract can
become a MEC
// at issue even when the variable's value is false.
if(a_MecAtIssue)
{
IsMec = true;
- // TODO ?? An early return here as a speed optimization is not yet
+ // TODO ?? TAXATION !! An early return here as a speed optimization is
not yet
// safe. Routines to print optional monthly calculation detail rely
// on sane values for some of the variables below. We could make
// those routines depend on the early return condition here, or
@@ -256,7 +257,7 @@
PolicyYear = a_PolicyYear;
PolicyMonth = a_PolicyMonth;
- // TODO ?? Not for survivorship.
+ // TODO ?? TAXATION !! Not for survivorship.
TestPeriodLen = months_per_year * usual_test_period_length;
TestPeriodDur = a_ContractMonth + months_per_year * a_ContractYear;
@@ -266,7 +267,7 @@
std::min(a_EndtAge, statutory_max_endowment_age)
- a_IssueAge
;
- // TODO ?? Do we really need '1 +'?
+ // TODO ?? TAXATION !! Do we really need '1 +'?
unsigned int max_dur = 1 + months_per_year * max_years;
Pmts.assign(max_dur, 0.0);
Bfts.assign(max_dur, 0.0);
@@ -274,11 +275,11 @@
LMI_ASSERT(a_Pmts.size() <= max_years);
for(unsigned int j = 0; j < a_Pmts.size(); ++j)
{
- // TODO ?? OK to treat premium history as annual?
+ // TODO ?? TAXATION !! OK to treat premium history as annual?
Pmts[j * months_per_year] = a_Pmts[j];
}
LMI_ASSERT(a_Bfts.size() <= max_years);
-// UpdateBft7702A() updates this, thus:
+// TAXATION !! UpdateBft7702A() updates this, thus:
// Bfts[TestPeriodDur] = current_bft;
// so should we make sure Bfts[TestPeriodDur] is zero here?
for(unsigned int j = 0; j < a_Bfts.size(); ++j)
@@ -291,10 +292,10 @@
CumPmts = std::accumulate(a_Pmts.begin(), a_Pmts.end(), 0.0);
- AssumedBft = a_LowestBft; // TODO ?? Is this needed? Is it not always
Bfts[0]?
+ AssumedBft = a_LowestBft; // TAXATION !! TODO ?? Is this needed? Is
it not always Bfts[0]?
LowestBft = a_LowestBft;
- // For now, make do with the data available. Ultimately, pass
+ // TAXATION !! For now, make do with the data available. Ultimately, pass
// duration of last material change as an argument.
double const z = std::floor
( ( PolicyYear + PolicyMonth / 12.0)
@@ -306,7 +307,7 @@
state_.B2_deduced_px7_rate = SevenPPRateVec[duration_of_last_mc];
SavedNecPrem = 0.0;
UnnecPrem = 0.0;
- SavedNSP = NSPVec[PolicyYear]; // TODO ?? Ignores interpolation.
+ SavedNSP = NSPVec[PolicyYear]; // TODO ?? TAXATION !! Ignores
interpolation.
state_.B3_deduced_nsp_rate = NSPVec[PolicyYear];
Determine7PP
@@ -381,6 +382,7 @@
// applying it irregularly is beyond the pale. We emulate this
// ill-advised behavior only as an exercise in matching
// another system. Do not use this for production.
+ // TAXATION !! Remove support for this misbegotten concept.
double NSPBeg = NSPVec[PolicyYear];
double NSPEnd = NSPVec[1 + PolicyYear];
double lo_decrement = NSPBeg * years_per_month;
@@ -419,7 +421,7 @@
}
// state_.Q4_cum_px7 and state_.Q5_cum_amt_pd are not updated here
- // even though this function modifies CumSevenPP. Perhaps that
+ // even though this function modifies CumSevenPP. TAXATION !! Perhaps that
// modification is a mistake: this function is called at the
// beginning of each policy year, but the premium limit applies
// to contract years.
@@ -634,7 +636,7 @@
}
else
{
- // TODO ?? For GPT, this is presumed valid but not yet tested.
+ // TODO ?? TAXATION !! For GPT, this is presumed valid but not yet
tested.
//
// Initially assume the result is less than target. If it
// turns out to be greater, then use a different formula.
@@ -717,6 +719,7 @@
(double a_DeemedCashValue
,double a_Payment
,bool a_ThisPaymentIsUnnecessary
+// TAXATION !! Eliminate these unused arguments?
,double // a_TargetPrem
,double // a_LoadTarget
,double // a_LoadExcess
@@ -728,7 +731,7 @@
return a_Payment;
}
-// TODO ?? Not necessarily true if we net out WD?
+// TODO ?? TAXATION !! Not necessarily true if we net out WD?
// LMI_ASSERT(0.0 <= a_Payment);
// As long as we're MEC testing, this function should be called whenever a
@@ -736,20 +739,20 @@
// called, the payment for the current duration should have its default
// value of zero.
//
- // TODO ?? But then how will we handle a WD? Separate function?
+ // TODO ?? TAXATION !! But then how will we handle a WD? Separate function?
//
// Changed anyway: called twice a month when there's a material change.
// LMI_ASSERT(0.0 == Pmts[TestPeriodDur]);
// During the test period (only), we accumulate premiums and compare
- // to the seven-pay limit. We store premium history for this period(or
longer?)
+ // to the seven-pay limit. We store premium history for this period (or
longer?)
// so that we can perform this comparison afresh in retrospect when
// Bfts decreases.
if(TestPeriodDur < TestPeriodLen)
{
// Reduce pmt to seven-pay limit if desired before recording it.
// This won't avoid a retrospective MEC if Bfts later decreases.
- // TODO ?? This is unnecessary now--premium limited in caller.
+ // TODO ?? TAXATION !! This is unnecessary now--premium limited in
caller.
/*
if(mce_reduce_prem == AvoidMec)
{
@@ -768,7 +771,7 @@
if(CumSevenPP < CumPmts)
{
IsMec = true;
-/* TODO ?? Reenable after testing.
+/* TODO ?? TAXATION !! Reenable after testing.
if(mce_reduce_prem == AvoidMec)
{
warning()
@@ -786,7 +789,7 @@
// Test for unnecessary premium, which we deem to be a material change
-// TODO ?? Under GPT always MatChg if (iff?) GLP increased or if pmt increases
ROP Bfts.
+// TODO ?? TAXATION !! Under GPT always MatChg if (iff?) GLP increased or if
pmt increases ROP Bfts.
if(mce_gpt == DefnLifeIns)
{
@@ -805,10 +808,10 @@
// Reduce pmt to necessary premium if desired before accepting it.
// This won't avoid a retrospective MEC if Bfts later decreases.
- // TODO ?? Anyway, why limit premium to necessary?
+ // TODO ?? TAXATION !! Anyway, why limit premium to necessary?
if(mce_reduce_prem == AvoidMec)
{
- // TODO ?? Not needed unless we try handling MEC avoidance here.
+ // TODO ?? TAXATION !! Not needed unless we try handling MEC avoidance
here.
/*
double max_necessary_prem = MaxNecessaryPremium
(a_DeemedCashValue
@@ -837,7 +840,7 @@
// never occur.
//
// However, a material change must be processed before any
- // unnecessary premium is accepted. This code defectively
+ // unnecessary premium is accepted. This code defectively [TAXATION !!
<-- Fix the defect then.]
// accepts it while raising a flag calling for the material
// change to be processed later. That's okay as long as a
// material change has just been processed--but in that case
@@ -887,15 +890,15 @@
//============================================================================
// record and test monthly Bfts
-// This function always returns zero, so it shouldn't return anything.
+// TAXATION !! This function always returns zero, so it shouldn't return
anything.
double Irc7702A::UpdateBft7702A
- (double // a_DeemedCashValue // TODO ?? Not used.
+ (double // a_DeemedCashValue // TODO ?? TAXATION !! Not used.
,double a_NewDB
,double a_OldDB
,bool a_IsInCorridor
,double a_NewSA
,double a_OldSA
- ,double // a_CashValue // TODO ?? Not used.
+ ,double // a_CashValue // TODO ?? TAXATION !! Not used.
)
{
if(Ignore || IsMec)
@@ -911,7 +914,7 @@
// I believe that the death benefit, unlike the premium, can be set more
// than once per month in the present code. I do not know whether or not
- // this can be avoided. TODO ?? Figure this out.
+ // this can be avoided. TODO ?? TAXATION !! Figure this out.
LMI_ASSERT(TestPeriodDur < static_cast<int>(Bfts.size()));
double current_bft = 0.0;
@@ -986,7 +989,7 @@
// One school of thought treats any Bft increase following any unnec prem
// as a MatChg.
#ifdef THIS_IS_NOT_DEFINED
- // TODO ?? Recognizing a MatChg wipes the slate clean: it is as though no
+ // TODO ?? TAXATION !! Recognizing a MatChg wipes the slate clean: it is
as though no
// unnecessary premium had ever been paid. So 'UnnecPremEver' is
// a nonsensical notion.
if(UnnecPremPaid && AssumedBft < current_bft)
@@ -997,14 +1000,14 @@
if(is_material_change)
{
-// Suppressed--see note above:
+// TAXATION !! Suppressed--see note above:
// LMI_ASSERT(AssumedBft < current_bft); // No decrease is a MC.
IsMatChg = true;
state_.D3_incr_is_mc = true;
/*
RedressMatChg
(a_DeemedCashValue
- ,0.0 // TODO ?? a_UnnecPrem
+ ,0.0 // TODO ?? TAXATION !! a_UnnecPrem
,0.0 // a_NecPrem
,a_CashValue
);
@@ -1019,15 +1022,15 @@
// recalculate 7pp and apply retroactively to beginning of 7 yr period
void Irc7702A::TestBftDecrease(double a_NewBft)
{
- // TODO ?? Is AssumedBft always equal to LowestBft?
+ // TODO ?? TAXATION !! Is AssumedBft always equal to LowestBft?
// Bfts reductions during any seven-year test period need to be tested.
// In addition, only for second-to-die (but not first-to-die) contracts,
// Bfts reductions have to be tested whenever they occur, even if it's
// outside any seven-year test period; but such testing covers only
// seven years in any event.
- // VERIFY Bfts decrease at end of period, and just beyond; also dur zero
- // VERIFY same with survivorship; also in last contract month
+ // TAXATION !! VERIFY Bfts decrease at end of period, and just beyond;
also dur zero
+ // TAXATION !! VERIFY same with survivorship; also in last contract month
if(!(IsSurvivorship || TestPeriodDur < TestPeriodLen))
{
return;
@@ -1041,7 +1044,7 @@
// Recalculate 7pp to reflect lower death benefit.
//
- // TODO ?? If the benefit decreases subsequent to a MatChg, then the 7pp
+ // TODO ?? TAXATION !! If the benefit decreases subsequent to a MatChg,
then the 7pp
// recalculation should use AV, NecPrem, and NSP as of the last MatChg.
Determine7PP
(a_NewBft
@@ -1054,7 +1057,7 @@
// Retest all premiums from beginning of test period.
//
- // TODO ?? We also need to test for unnecessary premium in retrospect.
+ // TODO ?? TAXATION !! We also need to test for unnecessary premium in
retrospect. [obsolete interpretation?]
//
// Recalculate CumSevenPP because SevenPP changed.
CumSevenPP = 0.0;
@@ -1133,7 +1136,7 @@
,double a_CashValue
)
{
-// TODO ?? I think all public functions in this class need this test:
+// TODO ?? TAXATION !! I think all public functions in this class need this
test:
if(Ignore || IsMec || !IsMaterialChangeInQueue())
{
return;
@@ -1148,11 +1151,11 @@
// 'SavedDCV' is used only for monthly trace.
SavedDCV = a_DeemedCashValue;
- // TODO ?? What if account value is less than zero here?
+ // TODO ?? TAXATION !! What if account value is less than zero here?
// Recalculate 7pp to reflect material change
Determine7PP
-// TODO ?? If MatChg due to unnec prem, should Bfts reflect any corridor
increase?
+// TODO ?? TAXATION !! If MatChg due to unnec prem, should Bfts reflect any
corridor increase?
// Yes.
(Bfts[TestPeriodDur] // a_Bft
,false // a_TriggeredByBftDecrease
@@ -1171,7 +1174,7 @@
(Pmts.begin()
,Pmts.begin() + TestPeriodDur
);
-// TODO ?? Is the latest payment still there?
+// TODO ?? TAXATION !! Is the latest payment still there?
// Start new 7 pay period
TestPeriodDur = 0;
@@ -1204,7 +1207,7 @@
//============================================================================
// update 7pp
-// Restructure this--too many TriggeredBy's
+// TAXATION !! Restructure this--too many TriggeredBy's
void Irc7702A::Determine7PP
(double a_Bft
,bool // a_TriggeredByBftDecrease
@@ -1216,7 +1219,7 @@
{
// We always treat payment of unnecessary premium as a material change
// So this test is unnecessary; so is the parm in the conditional.
- // TODO ?? NO LONGER TRUE.
+ // TODO ?? TAXATION !! NO LONGER TRUE.
if(a_TriggeredByUnnecPrem)
{
LMI_ASSERT(a_TriggeredByMatChg);
@@ -1227,7 +1230,7 @@
// Store new values for
// Saved7PPRate, SavedAVBeforeMatChg, SavedNecPrem, and SavedNSP
// iff 7pp recalculation due to material change. (But how could
- // a material change mutate 'Saved7PPRate'?)
+ // a material change mutate 'Saved7PPRate'?) [TAXATION !! rethink that]
// But leave those values undisturbed if triggered by Bfts decrease.
if(a_TriggeredByMatChg)
{
@@ -1238,7 +1241,7 @@
// premium was paid. Otherwise, the premium, which was all necessary,
// simply went into the AV. SavedNecPrem is used only to adjust
// the AV saved prior to a material change.
- // TODO ?? Is that rigorous?
+ // TODO ?? TAXATION !! Is that rigorous?
if(a_TriggeredByUnnecPrem)
{
SavedNecPrem = a_NecPrem;
@@ -1252,7 +1255,7 @@
{
// No material change--either we're initializing, or processing
// a Bfts decrease. NO...could be an inforce case.
-// TODO ?? expunge
+// TODO ?? TAXATION !! expunge
// LMI_ASSERT
// ( a_TriggeredByBftDecrease
// || (0 == PolicyYear && 0 == PolicyMonth)
@@ -1271,7 +1274,7 @@
// pass DCV as an argument; maybe we should drop the assertion. Note
// that 'SavedDCV', because of its limited purpose, isn't reliably
// initialized; I'm not sure we should promote that variable to a
-// first-class citizen by initializing it carefully.
+// first-class citizen by initializing it carefully. [TAXATION !! Address
this.]
LMI_ASSERT
( 0.0 == SavedAVBeforeMatChg
|| materially_equal(SavedDCV, SavedAVBeforeMatChg)
@@ -1280,7 +1283,7 @@
LMI_ASSERT(materially_equal(SevenPPRateVec[0], Saved7PPRate));
LMI_ASSERT(materially_equal(NSPVec[0], SavedNSP));
}
-/* TODO ?? Expunge this perhaps. Not sure what we should do if someone
+/* TODO ?? TAXATION !! Expunge this perhaps. Not sure what we should do if
someone
tries running an inforce case as of month 0, year 0.
// In either of these two cases--initialization or Bfts reduction--the
// a_AVBeforeMatChg and a_NecPrem arguments are not used, so give a
@@ -1313,7 +1316,7 @@
// worry about whether the denominator is zero. For instance, Bfts
// is allowed to be zero for solves.
double bft_adjustment = SavedAVBeforeMatChg / SavedNSP;
-// TODO ?? expunge
+// TODO ?? TAXATION !! expunge
// double bft_adjustment =
// (SavedAVBeforeMatChg + SavedNecPrem)
// / SavedNSP
@@ -1327,7 +1330,7 @@
{
SevenPP = 0.0;
}
-// TODO ?? AssumedBft should reflect any Bfts increase--AFTER the MatChg?
+// TODO ?? TAXATION !! AssumedBft should reflect any Bfts increase--AFTER the
MatChg?
}
//============================================================================
@@ -1340,7 +1343,7 @@
,Bfts.begin() + std::min(TestPeriodLen, TestPeriodDur)
);
LMI_ASSERT(Bfts.begin() <= last_bft_in_test_period);
-// This is harmful for inforce if inforce history is unreliable:
+// TAXATION !! This is harmful for inforce if inforce history is unreliable:
LowestBft = *std::min_element(Bfts.begin(), last_bft_in_test_period);
return LowestBft;
}
@@ -1349,13 +1352,13 @@
// determine lowest non-MEC spec amt
double Irc7702A::SAIncreaseToAvoidMec(bool a_TriggeredByUnnecPrem)
{
-// TODO ?? Specs say DB, but isn't this SA?
+// TODO ?? TAXATION !! Specs say DB, but isn't this SA?
double av = SavedAVBeforeMatChg;
if(a_TriggeredByUnnecPrem) // TODO ?? iff MatChg triggered by unnec prem?
{
av += SavedNecPrem;
}
- // Why aren't we using something like "SavedUnnecPrem" instead?
+ // TAXATION !! Why aren't we using something like "SavedUnnecPrem" instead?
double new_bft =
UnnecPrem / Saved7PPRate
+ av
@@ -1365,7 +1368,7 @@
// Specs say this formula is for Bfts increase to avoid MEC when unnec prem
// paid. Also need to handle case where prem exceeds 7pp. Also need to handle
// dumpins. Also need to handle Bfts decrease (complicated). Also need to
-// reflect new 7pp upon MatChg. TODO ?? Where should we do all this?
+// reflect new 7pp upon MatChg. TODO ?? TAXATION !! Where should we do all
this?
//
// Events that are MatChgs:
// 1035 exchange--but we treat that as a special case
@@ -1378,6 +1381,7 @@
return new_bft;
}
+// TAXATION !! Rewrite or remove this block comment:
/*
* // Entry points
*
Modified: lmi/trunk/ihs_irc7702a.hpp
===================================================================
--- lmi/trunk/ihs_irc7702a.hpp 2012-01-25 09:59:36 UTC (rev 5379)
+++ lmi/trunk/ihs_irc7702a.hpp 2012-01-25 15:19:23 UTC (rev 5380)
@@ -36,7 +36,7 @@
void LMI_SO TestIrc7702A();
-// TODO ?? Known defects:
+// TAXATION !! TODO ?? Known defects:
// need to handle withdrawals correctly;
// 7-pay premium strategy changes premium when spec amt changes;
// should optionally calculate factors e.g. 7pp, NSP from first principles.
@@ -57,9 +57,10 @@
,mcenum_mec_avoid_method a_AvoidMec
,bool a_Use7PPTable
,bool a_UseNSPTable
- ,std::vector<double> const& a_SevenPPRateVec// TODO ?? Assume table
passed, for now.
- ,std::vector<double> const& a_NSPVec // TODO ?? Assume table
passed, for now.
+ ,std::vector<double> const& a_SevenPPRateVec// TODO ?? TAXATION !!
Assume table passed, for now.
+ ,std::vector<double> const& a_NSPVec // TODO ?? TAXATION !!
Assume table passed, for now.
,round_to<double> const& a_RoundNonMecPrem
+// TAXATION !! Either use these arguments or eliminate them.
// ,unsigned int a_IssueAge
// ,double a_Face
// ,mcenum_dbopt_7702 a_DBOpt
@@ -68,13 +69,14 @@
// ,std::vector<double> const& a_PremLoad
// ,std::vector<double> const& a_PerKCharge
// ,std::vector<double> const& a_PolFee
-// probably other arguments are needed for reproposals
+// TAXATION !! probably other arguments are needed for reproposals
);
~Irc7702A();
+// TAXATION !! Move documentation of functions to '.cpp' file.
// This is notionally called once per *current*-basis run
// and actually called once per run, with calculations suppressed
- // for all other bases by setting Ignore (q.v.).
+ // for all other bases by setting Ignore (q.v.). TAXATION !! Is that good?
void Initialize7702A // set initial values at issue
(bool a_Ignore
,bool a_MecAtIssue
@@ -90,7 +92,7 @@
,std::vector<double> const& a_Bfts
);
// Always call at beginning of policy year
- // interpolate NSP; update cum 7pp
+ // interpolate NSP; update cum 7pp // TAXATION !! That interpolation is a
poor idea.
void UpdateBOY7702A
(int a_PolicyYear
);
@@ -124,7 +126,7 @@
// record and test monthly Bfts
// return min non-mec Bft if called for
double UpdateBft7702A
- (double // a_DeemedCashValue
+ (double // a_DeemedCashValue // TAXATION !! Is this argument useful?
,double a_NewDB
,double a_OldDB
,bool a_IsInCorridor
@@ -134,7 +136,7 @@
);
// Queue a material change for later handling.
void InduceMaterialChange();
- // TODO ?? Handle material change--always call right before monthly
deduction?
+ // TODO ?? TAXATION !! Handle material change--always call right before
monthly deduction?
void RedressMatChg
(double& a_DeemedCashValue
,double a_UnnecPrem
@@ -157,7 +159,7 @@
,double a_LoadExcess
,double a_CashValue
) const;
- // SOMEDAY !! Consider using accessors like Irc7702::RoundedGLP()
+ // TAXATION !! Consider using accessors like Irc7702::RoundedGLP()
// to encapsulate rounding within this class.
double GetPresent7pp() const {return SevenPP;}
bool IsMecAlready() const {return IsMec;}
@@ -172,7 +174,7 @@
// for other purposes. They may be changed or eliminated in future
// versions. I don't regard them as part of the public interface,
// although they physically happen to be so.
- // TODO ?? IOW, 'friend' would be better?
+ // TODO ?? TAXATION !! IOW, 'friend' would be better?
int DebugGetTestDur () const
{return TestPeriodDur - 1; /* we already incremented it */}
double DebugGet7ppRate () const
@@ -217,7 +219,7 @@
,double a_AVBeforeMatChg
,double a_NecPrem
);
- // TODO ?? Wouldn't this need to be public?
+ // TODO ?? TAXATION !! Wouldn't this need to be public?
double SAIncreaseToAvoidMec // determine lowest non-MEC spec amt
(bool a_TriggeredByUnnecPrem
);
@@ -226,9 +228,9 @@
mutable mec_state state_;
// NOTE: table lookup really means supplied via arguments ?
-// TODO ?? Need to calculate if not table lookup.
+// TODO ?? TAXATION !! Need to calculate if not table lookup.
- int magic; // TODO ?? Temporary kludge.
+ int magic; // TODO ?? TAXATION !! Temporary kludge.
mcenum_defn_life_ins DefnLifeIns;
mcenum_defn_material_change DefnMaterialChange;
@@ -240,7 +242,7 @@
bool InterpolateNspOnly;
bool const IsSurvivorship; // is policy multilife and not first to
die?
- mcenum_mec_avoid_method AvoidMec; // TODO ?? Document what this does.
+ mcenum_mec_avoid_method AvoidMec; // TODO ?? TAXATION !! Document what
this does.
bool const Use7PPTable; // get SevenPP from table, not calculation
bool const UseNSPTable; // get NSP from table, not calculation
@@ -250,11 +252,12 @@
round_to<double> RoundNonMecPrem;
// Note that death benefit and pmts may not have their usual meanings.
- // Pmts is premium net of deductible withdrawals.
+ // TAXATION !! [Explain why.]
+ // Pmts is premium net of deductible withdrawals. [TAXATION !! globally
prefer "nontaxable" to "deductible"]
// Bfts is SA, plus tax basis for ROP. The corridor is conservatively
// ignored to prevent the policy from becoming a MEC retroactively
// due to poor investment performance.
- // TODO ?? Maybe not--Bfts might be DB.
+ // TODO ?? TAXATION !! Maybe not--Bfts might be DB.
std::vector<double> Bfts; // "death benefit" for 7702A
std::vector<double> Pmts; // premium net of deductible
withdrawals
std::vector<double> MlyInterpNSP; // monthly interpolated NSP per $
@@ -279,7 +282,7 @@
int TestPeriodLen; // length (months) of test period
int TestPeriodDur; // duration (months) since beginning of
// current test period
- // We need policy year for table lookups, and month for NSP interpolation
+ // We need policy year for table lookups, and month for NSP interpolation
TAXATION !! eliminate interpolation
int PolicyYear; // duration since issue (full years)
int PolicyMonth; // duration since issue (months)
double AssumedBft; // death bft assumed in setting last
SevenPP
@@ -292,9 +295,11 @@
double SavedNSP; // interpolated NSP
double SavedDCV; // deemed cash value
+ // TAXATION !! Need these be 'mutable'?
mutable double NetNecessaryPrem; // maximum necessary premium, no loads
mutable double GrossNecessaryPrem; // max nec prem grossed up for prem
load
+// TAXATION !! Is this stuff useful? q and i might be, but the others?
// std::vector<double> const& q;
// std::vector<double> const& i;
// std::vector<double> const& PremLoad;
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [lmi-commits] [5380] Mark some taxation issues,
Greg Chicares <=