/* * public void SpouseDies(int holdings, int dead, int ratesLeft = 12 * 10, int ownDead = 999) * { * _holdingsDeadSpouse += holdings; //beholdningen opdateres i tilfælde af at personen allerede har modtaget en pension fra afdød ægtefælle (dette må være sjældne tilfælde). * _ratesLeftDeadSpouse = ratesLeft; //udbetales over 10 år med mindre udbetaling er påbegyndt, en unøjagtighed i tilfælde af pensioner fra flere afdøde ægtefæller * * int installment = 0; //årets samlede pensionsudbetaling * for (int m = Math.Min(dead, 0); m < Math.Min(ownDead, 12); m++) * { * } * * } */ private void ContributionRate(int contribution) { int growth = Convert.ToInt32(_holdingsRate * PensionSystem.InterestRateForecasted(12)); _holdingsRate += growth + contribution; //opdater personlig formue med rente og indbetaling PensionSystem.PensionfundRate.Contribution(growth + contribution); //orienter pensionsfund om vækst i beholdning }
public void InstallmentFactor() { for (int r = 0; r < _installmentFactor.Length; r++) { if (PensionSystem.InterestRateForecasted(12) == 0) { _installmentFactor[r] = r; //enhedsannuitet for given restløbetid. Bemærk r+1 fordi 0 betyder at der er en rate tilbage (den der er ved at blive udbetalt) } else { _installmentFactor[r] = (1 - Math.Pow(1 + PensionSystem.InterestRateForecasted(12), -(r + 1))) / PensionSystem.InterestRateForecasted(12); //enhedsannuitet for given restløbetid. Bemærk r+1 fordi 0 betyder at der er en rate tilbage (den der er ved at blive udbetalt) } } }
private void ReadMortalityRates() { double[] mortalityrates = new double[MAXAGE]; try { using (StreamReader sr = new StreamReader(_mortalityRatesFile)) { string line; while ((line = sr.ReadLine()) != null) { string[] cols = line.Split('\t'); int age = Convert.ToInt32(cols[1]); // if (Convert.ToInt32(cols[2]) == Program.year && age < MAXAGE) //hent kun dødsrater i det givne år for personer over 60 if (Convert.ToInt32(cols[2]) == 2010 && age < MAXAGE) //hent kun dødsrater i det givne år for personer over 60 { mortalityrates[age] += Convert.ToDouble(cols[3]) / 2d; //tag simpelt gennemsnit af raten for mænd og kvinder } } } } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); throw new Exception(); } decimal[] l = new decimal[MAXAGE * 12]; l[0] = 1; for (int a = 1; a < MAXAGE * 12; a++) { int y = a / 12; int m = a % 12; if (m == 0) //januar måned { l[a] = Convert.ToDecimal((1 - mortalityrates[y - 1])) * l[a - 12]; } else { l[a] = Convert.ToDecimal((1 - m / 12d * mortalityrates[y])) * l[y * 12]; } } for (int a = 0; a < MAXAGE * 12 - 1; a++) { _p[a] = Convert.ToDouble(l[a + 1] / l[a]); } double v = 1 / (1 + PensionSystem.InterestRateForecasted(12)); double[] L = new double[MAXAGE * 12]; for (int a = 0; a < MAXAGE * 12; a++) { L[a] = Convert.ToDouble(l[a] * Convert.ToDecimal(Math.Pow(v, a))); } for (int x = 0; x < _pensionAge * 12; x++) { double sum = 0; for (int y = _pensionAge * 12; y < MAXAGE * 12; y++) { sum += L[y] / L[x]; } _alphaB[x] = Math.Pow(v * sum, -1); } for (int x = 0; x < _pensionAge * 12; x++) { double sum = 0; for (int y = x; y < _pensionAge * 12; y++) { sum += L[y] / L[x]; } _alphaI[x] = v * sum * _alphaB[x]; } for (int x = _minPensionAge * 12; x < MAXAGE * 12; x++) { double sum = 0; for (int y = x; y < MAXAGE * 12; y++) { sum += L[y] / L[x]; } _gammaB[x - _minPensionAge * 12] = Math.Pow(v * sum, -1); } }
public int CalculateAdf(int bdf, int expected) { return(Convert.ToInt32((1 + PensionSystem.InterestRateForecasted(12)) * bdf - expected)); }
private void ReadMortalityRates() { double[] mortalityrates = new double[MAXAGE]; try { using (StreamReader sr = new StreamReader(_mortalityRatesFile)) { string line; while ((line = sr.ReadLine()) != null) { string[] cols = line.Split('\t'); int age = Convert.ToInt32(cols[1]); // if (Convert.ToInt32(cols[2]) == Program.year && age < MAXAGE) //hent kun dødsrater i det givne år if (Convert.ToInt32(cols[2]) == 2010 && age < MAXAGE) //hent kun dødsrater i det givne år for personer over 60 { mortalityrates[age] += Convert.ToDouble(cols[3]) / 2d; //tag simpelt gennemsnit af raten for mænd og kvinder } } } } catch (Exception e) { Console.WriteLine("The file could not be read:"); Console.WriteLine(e.Message); throw new Exception(); } decimal[] l = new decimal[MAXAGE * 12]; l[0] = 1; for (int a = 1; a < MAXAGE * 12; a++) { int y = a / 12; int m = a % 12; if (m == 0) //januar måned { l[a] = Convert.ToDecimal((1 - mortalityrates[y - 1])) * l[a - 12]; } else { l[a] = Convert.ToDecimal((1 - m / 12d * mortalityrates[y])) * l[y * 12]; } } for (int a = 0; a < MAXAGE * 12 - 1; a++) { _p[a] = Convert.ToDouble(l[a + 1] / l[a]); } double v = 1 / (1 + PensionSystem.InterestRateForecasted(12)); double[] L = new double[MAXAGE * 12]; for (int a = 0; a < MAXAGE * 12; a++) { L[a] = Convert.ToDouble(l[a] * Convert.ToDecimal(Math.Pow(v, a))); } for (int x = PensionSystem._minPensionAge * 12; x < MAXAGE * 12; x++) { double sum = 0; for (int y = x; y < MAXAGE * 12; y++) { sum += L[y] / L[x]; } _gammaB[x - PensionSystem._minPensionAge * 12] = Math.Pow(v * sum, -1); } #region beregn _beta for (int x = 0; x < PensionSystem._minPensionAge * 12 - 1; x++) { double sum = 0; for (int y = x + 1; y <= PensionSystem._minPensionAge * 12 - 1; y++) { sum += L[y] / L[x]; } _beta[x] = _qd[x] * sum; } for (int x = PensionSystem._minPensionAge * 12 - 1; x < MAXAGE * 12; x++) { _beta[x] = 0; //sættes til nul i perioden umiddelbart før pensionsalder og fremefter } #endregion beregn _beta #region beregn _alphaB for (int x = 0; x <= PensionSystem._pensionAge * 12 - 2; x++) { double sum1 = 0; for (int y = x; y <= PensionSystem._pensionAge * 12 - 2; y++) { sum1 += Math.Pow(v, y - x + 1) * _beta[y]; } double sum2 = 0; for (int y = PensionSystem._pensionAge * 12; y < MAXAGE * 12; y++) { sum2 += L[y] / L[PensionSystem._pensionAge * 12]; } sum2 *= Math.Pow(v, PensionSystem._minPensionAge * 12 - x + 1); _alphaB[x] = Math.Pow(_zeta * sum1 + sum2, -1); } { double sum = 0; for (int y = PensionSystem._minPensionAge * 12; y < MAXAGE * 12; y++) { sum += L[y] / L[PensionSystem._minPensionAge * 12]; } _alphaB[PensionSystem._minPensionAge * 12 - 1] = Math.Pow(v * v * sum, -1); } for (int x = PensionSystem._minPensionAge * 12; x < MAXAGE * 12; x++) { _alphaB[x] = 1; } #endregion beregn _alphaB #region beregn _alphaI for (int x = 0; x <= PensionSystem._pensionAge * 12 - 2; x++) { double sum1 = 0; for (int y = x; y <= PensionSystem._pensionAge * 12 - 1; y++) { sum1 += Math.Pow(v, y - x + 1); } double sum2 = 0; for (int y = x; y <= PensionSystem._pensionAge * 12 - 2; y++) { sum2 += Math.Pow(v, y - x + 1) * _beta[y]; } _alphaI[x] = _alphaB[x] * (sum1 - sum2); } _alphaI[PensionSystem._minPensionAge * 12 - 1] = _alphaB[PensionSystem._minPensionAge * 12 - 1] * v; for (int x = PensionSystem._minPensionAge * 12; x < MAXAGE * 12; x++) { _alphaI[x] = 1; } #endregion beregn _alphaI #region beregn _theta og _eta for (int x = 0; x < PensionSystem._minPensionAge * 12; x++) { double sum = 0; for (int y = x; y < PensionSystem._minPensionAge * 12; y++) { sum += L[y] / L[x]; } _theta[x] = v * sum; _eta[x] = Math.Pow(_theta[x], -1); } #endregion beregn _theta og _eta #region beregn _gamma for (int x = PensionSystem._minPensionAge * 12; x < MAXAGE * 12; x++) { double sum = 0; for (int y = x; y < MAXAGE * 12; y++) { sum += L[y] / L[x]; } _gamma[x - PensionSystem._minPensionAge * 12] = Math.Pow(v * sum, -1); } #endregion beregn _gamma }
public int Update(int age, int[] contributionRate, int[] contributionLivsrente, int startRate = -1, int startLivrente = -1, int dead = -1) { if (udvalgt && age == 65) { Console.WriteLine("65 år"); } int installment = 0; //årets samlede pensionsudbetaling int installmentLivrente = 0; for (int m = 0; m < 12; m++) { _livrenteDepotPrimoBx = PensionSystem.PensionfundLivrente.UpdateHoldings(age, _livrenteDepotUltimoAx, _dx, m); //beregn ny beholdning (Bx) if (m == 0) { w = _livrenteDepotPrimoBx; } if (udvalgt && m == 0 && age < 65) { int expected = PensionSystem.PensionfundLivrente.InstallmentExpected(age, m, _livrenteDepotPrimoBx, contributionLivsrente[m]); // Console.WriteLine("Forventet pension: " + expected); } #region ratepension if (startRate == m && _ratesLeft < 1) { _ratesLeft = 12 * 10; //aktiver ratepensionsudbetaling sæt udbetaling til at vare 10 år } ContributionRate(contributionRate[m]); //indbetal til ratepension installment += InstallmentRate(); //udbetal ratepension #endregion ratepension _activeLivrente |= startLivrente == m; //aktiver livrentepensionsudbetaling PensionSystem.PensionfundLivrente.Growth(w); //faktisk rente tilskrivning PensionSystem.PensionfundLivrente.Contribution(contributionLivsrente[m]); //orienter pensionsfund om indbetaling if (_activeLivrente /*&& installmentLivrente == 0*/ && _livrenteDepotPrimoBx > 0) { installmentLivrente = PensionSystem.PensionfundLivrente.CalculateInstallment(age, m, _livrenteDepotPrimoBx); //beregn livsrentepension, hvis aktiv } PensionSystem.PensionfundLivrente.Installment(installmentLivrente); //orienter pensionsfund om udbetaling w = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * w) + contributionLivsrente[m] - installmentLivrente; _livrenteDepotUltimoAx = Convert.ToInt32((1 + PensionSystem.InterestRateForecasted(12)) * _livrenteDepotPrimoBx) + contributionLivsrente[m] - installmentLivrente; installment += installmentLivrente; if (udvalgt && m == 0 && installmentLivrente > 0) { Console.WriteLine("Udbetaling, m=" + m + ", " + installmentLivrente + " Kr."); } if (dead == m) //personen dør denne måned { PensionSystem.PensionfundLivrente.PersonExit(w, m); PensionSystem.PensionfundRate.PersonExit(_holdingsRate, m); return(installment); } if (m == 11) { _dx = PensionSystem.PensionfundLivrente.CalculateDx(age, m, _livrenteDepotUltimoAx); //beregnes efter Ax } } return(installment); }
public int Update(int age, int[] contributionRate, int[] contributionLivsrente, int[] contributionInvalide, int startRate = -1, int startLivrente = -1, int startInvalideAldersPension = -1, int invalid = -1, int dead = -1) { double tmp = 0; if (udvalgt && age == 65) { Console.WriteLine("65 år"); } int installment = 0; //årets samlede pensionsudbetaling #region ratepension for (int m = 0; m < 12; m++) { if (startRate == m && _ratesLeft < 1) { _ratesLeft = 12 * 10; //aktiver ratepensionsudbetaling sæt udbetaling til at vare 10 år } ContributionRate(contributionRate[m]); //indbetal til ratepension installment += InstallmentRate(); //udbetal ratepension if (udvalgt && m == 0 && installment > 0) { Console.WriteLine("Ratepension, udbetalt (m=" + m + "): " + installment); } if (dead == m) //personen dør denne måned { PensionSystem.PensionfundRate.PersonExit(_holdingsRate, m); break; } // _dx = _livrenteDepotUltimoAx; } #endregion ratepension #region simpel livrente int installmentLivrente = 0; for (int m = 0; m < 12; m++) { _livrenteDepotPrimoBx = PensionSystem.PensionfundLivrente.UpdateHoldings(age, _livrenteDepotUltimoAx, _dx, m); //beregn ny beholdning (Bx) if (m == 0) { w = _livrenteDepotPrimoBx; } if (udvalgt && m == 0 && age < 65) { int expected = PensionSystem.PensionfundLivrente.InstallmentExpected(age, m, _livrenteDepotPrimoBx, contributionLivsrente[m]); // Console.WriteLine("Forventet pension: " + expected); } _activeLivrente |= startLivrente == m; //aktiver livrentepensionsudbetaling PensionSystem.PensionfundLivrente.Growth(w); //faktisk rente tilskrivning PensionSystem.PensionfundLivrente.Contribution(contributionLivsrente[m]); //orienter pensionsfund om indbetaling if (_activeLivrente /*&& installmentLivrente == 0*/ && _livrenteDepotPrimoBx > 0) { installmentLivrente = PensionSystem.PensionfundLivrente.CalculateInstallment(age, m, _livrenteDepotPrimoBx); //beregn livsrentepension, hvis aktiv } PensionSystem.PensionfundLivrente.Installment(installmentLivrente); //orienter pensionsfund om udbetaling w = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * w) + contributionLivsrente[m] - installmentLivrente; _livrenteDepotUltimoAx = Convert.ToInt32((1 + PensionSystem.InterestRateForecasted(12)) * _livrenteDepotPrimoBx) + contributionLivsrente[m] - installmentLivrente; installment += installmentLivrente; // if (udvalgt && installmentLivrente > 0) // Console.WriteLine("Udbetaling livrente, m=" + m + ", " + installmentLivrente + " Kr."); if (dead == m) //personen dør denne måned { PensionSystem.PensionfundLivrente.PersonExit(w, m); break; } if (m == 11) { _dx = PensionSystem.PensionfundLivrente.CalculateDx(age, m, _livrenteDepotUltimoAx); //beregnes efter Ax } } #endregion simpel livrente #region simpel livrente med invalidepension int installmentInvalide = 0; for (int m = 0; m < 12; m++) { #region selve invalidepensionen if (_invalid) { invalid = -1; //kan kun blive invalid een gang } _invalid |= invalid == m; //aktiver invalidepension if (_invalid && age >= PensionSystem._pensionAge) { _invalid = false; //når du når pensionsalderen behandles du ikke længere som invalid, men som pensionist _activeInvalideAlders = true; } if (_invalid) { _ddf = PensionSystem.PensionfundInvalide.CalculateDdf(age, m, _adf, _expectedPension, invalid == m); //indvalidebeholdning primo før bonus _bdf = PensionSystem.PensionfundInvalide.CalculateBdf(m, _ddf); //indvalidebeholdning, justeret m. bonus int fd = Math.Min(99999989, PensionSystem.PensionfundInvalide.CalculateFd(age, m, _bdf)); //udbetaling _adf = PensionSystem.PensionfundInvalide.CalculateAdf(_bdf, fd); //indvalidebeholdning ultimo if (m == 0) { _wdf = _bdf; } PensionSystem.PensionfundInvalide.Growth(_wdf); //rentetilskrivning PensionSystem.PensionfundInvalide.Installment(fd); //orienter pensionsfund om udbetaling _wdf = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * _wdf - fd); } #endregion selve invalidepensionen #region opsparingssikring int fdi = 0; if (_invalid) { _ddi = PensionSystem.PensionfundInvalide.CalculateDdi(age, m, _latestContribution, _adi, invalid == m); //indvalidebeholdning primo før bonus _bdi = PensionSystem.PensionfundInvalide.CalculateBdi(m, _ddi); //indvalidebeholdning, justeret m. bonus fdi = PensionSystem.PensionfundInvalide.CalculateFdi(age, m, _bdi); //"udbetaling" _adi = PensionSystem.PensionfundInvalide.CalculateAdi(_bdi, fdi); //indvalidebeholdning ultimo if (m == 0) { _wdi = _bdi; } PensionSystem.PensionfundInvalide.Growth(_wdi); //rentetilskrivning // PensionSystem.PensionfundInvalide.Installment(fdi); //orienter pensionsfund om "udbetaling" _wdi = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * _wdi - fdi); } #endregion opsparingssikring #region alderspension og pensionsindbetaling _activeInvalideAlders |= startInvalideAldersPension == m; //aktiver alderspension _invalideDepotPrimoBx = PensionSystem.PensionfundInvalide.UpdateHoldings(_dxInvalide, m); //beregn ny beholdning (Bx) int expected = 0; if (age < 65) { if (_invalid) { expected = PensionSystem.PensionfundInvalide.InstallmentExpected(age, m, _invalideDepotPrimoBx, fdi); } else { expected = PensionSystem.PensionfundInvalide.InstallmentExpected(age, m, _invalideDepotPrimoBx, contributionInvalide[m]); } } if (udvalgt && m == 0 && age < 65) { Console.WriteLine("Forventet invalide pension: " + expected + " (" + m + ")"); // Console.WriteLine("Invalide alderspension, beholdning primo (Bx): " + _invalideDepotPrimoBx + " (" + m + ")"); } if (m == 0) { wi = _invalideDepotPrimoBx; } PensionSystem.PensionfundInvalide.Growth(wi); //faktisk rente tilskrivning if (_invalid) { ;//PensionSystem.PensionfundInvalide.Contribution(fdi); //orienter pensionsfund om indbetaling } else { PensionSystem.PensionfundInvalide.Contribution(contributionInvalide[m]); //orienter pensionsfund om indbetaling } if (contributionInvalide[m] > 0) { _latestContribution = contributionInvalide[m]; //anvendes til bestemmelse af opsparingssikring ved invaliditet } if (_activeInvalideAlders && _invalideDepotPrimoBx > 0) { installmentInvalide = PensionSystem.PensionfundInvalide.CalculateInstallment(age, m, _invalideDepotPrimoBx); //beregn livsrentepension, hvis aktiv } PensionSystem.PensionfundInvalide.Installment(installmentInvalide); //orienter pensionsfund om udbetaling if (_invalid) { wi = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * wi) + fdi; } else { wi = Convert.ToInt32((1 + PensionSystem.InterestRate(12)) * wi) + contributionInvalide[m] - installmentInvalide; } double pidf, pidi; if (_invalid || (contributionInvalide[m] <= 0 && _timeSinceLastInvalideContribution++ > 3) || _activeInvalideAlders) //hvis der ikke er indbetalt til invalidepension i 3 måneder, stoppes dækning og præmier { pidf = 0; pidi = 0; } else { _timeSinceLastInvalideContribution = 0; pidf = PensionSystem.PensionfundInvalide.CalculatePidf(age, m, _invalideDepotPrimoBx, contributionInvalide[m]); //pidf skal dække pensionsudbetaling for invalide pidi = PensionSystem.PensionfundInvalide.CalculatePidi(age, m, contributionInvalide[m]); //pidi skal dække pensionsindbetaling for invalide tmp += pidi; } if (_invalid) { _invalideDepotUltimoAx = Convert.ToInt32((1 + PensionSystem.InterestRateForecasted(12)) * _invalideDepotPrimoBx + fdi); } else { _invalideDepotUltimoAx = Convert.ToInt32((1 + PensionSystem.InterestRateForecasted(12)) * _invalideDepotPrimoBx + contributionInvalide[m] - installmentInvalide - pidf - pidi); } installment += installmentInvalide; #endregion alderspension og pensionsindbetaling if (udvalgt /*&& m == 0*/ && installmentInvalide > 0) { Console.WriteLine("Udbetaling invalide, m=" + m + ", " + installmentInvalide + " Kr."); } _expectedPension = expected; //anvendes ved invalidering if (dead == m) //personen dør denne måned { PensionSystem.PensionfundInvalide.PersonExit(age, m, wi); //pensionsbeholdning slettes fra pensionskasse. break; } _dxInvalide = PensionSystem.PensionfundInvalide.CalculateDx(age, m, _invalideDepotUltimoAx, _activeInvalideAlders); if (m == 11) { PensionSystem.PensionfundInvalide.RegisterDx(_dxInvalide); PensionSystem.PensionfundInvalide.RegisterDx(_ddf); PensionSystem.PensionfundInvalide.RegisterDx(_ddi); } } #endregion simpel livrente med invalidepension return(installment); }