Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion dist/advanced.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

13 changes: 9 additions & 4 deletions dist/advanced.js
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,10 @@
* 8. Insolvency check
* 9. Investment growth (per-item rates, fees, performance fees)
*/
import { CadenceMultiplier } from './defaults';
import { calculateTax } from './tax';
import { calculateWithdrawal, } from './withdrawal';
import { getLogger } from './logger';
import { CadenceMultiplier } from './defaults.js';
import { calculateTax } from './tax.js';
import { calculateWithdrawal, } from './withdrawal.js';
import { getLogger } from './logger.js';
// =============================================================================
// Helper Functions
// =============================================================================
Expand Down Expand Up @@ -705,6 +705,11 @@ export function runAdvancedProjection(scenario, overrideReturns) {
shortfall_withdrawals: shortfallWithdrawals,
black_swan_loss: yearBlackSwanLoss,
withdrawal_event: withdrawalEvent,
// v0.4 additions: deterministic advanced projection still uses the flat
// legacy inflation rate; asset_returns is null because per-class
// multi-asset mode is not active in this code path.
inflation_this_year: inflation_enabled ? inflation_pct / 100 : 0,
asset_returns: null,
};
timeline.push(row);
}
Expand Down
2 changes: 1 addition & 1 deletion dist/backtest.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 7 additions & 3 deletions dist/backtest.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { getLogger } from './logger';
import { getLogger } from './logger.js';
// ---------------------------------------------------------------------------
// Historical Backtest — Shiller Data (real total stock returns, 1871-2024)
// ---------------------------------------------------------------------------
Expand Down Expand Up @@ -179,7 +179,11 @@ const SHILLER_DATA = [
*/
export function runHistoricalBacktest(scenario, projectionFn) {
const log = getLogger();
const span = scenario.end_age - scenario.current_age;
// v0.4 (ADR-027/031): force-disable stochastic features for backtests.
// Historical windows already contain real-world volatility and inflation;
// layering stochastic samplers would double-count.
const baseScenario = Object.assign(Object.assign({}, scenario), { inflation_model: 'Flat', longevity_model: 'Fixed', return_distribution_kind: 'LogNormal', asset_classes: [] });
const span = baseScenario.end_age - baseScenario.current_age;
// Guard: span must be at least 1
if (span < 1) {
return { periods: [], successRate: 0 };
Expand Down Expand Up @@ -220,7 +224,7 @@ export function runHistoricalBacktest(scenario, projectionFn) {
// ADR-027: backtests already include real historical crashes — layering a
// synthetic Black Swan event would double-count. Force-disable it on a
// per-window scenario clone.
const periodScenario = JSON.parse(JSON.stringify(scenario));
const periodScenario = JSON.parse(JSON.stringify(baseScenario));
periodScenario.black_swan_enabled = false;
// Run projection with historical returns
const result = projectionFn(periodScenario, returns);
Expand Down
62 changes: 62 additions & 0 deletions dist/claiming-optimizers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/**
* Social Security, Pension, and Annuity Claiming Optimizers (ADR-036 / CONTRACT-019)
*
* Three grid-search optimizers that sweep over claiming ages and evaluate the
* full scenario at each candidate to maximize a user-chosen metric.
*
* No new runtime dependencies.
*/
import type { Scenario, TimelineRow, Metrics, ClaimingOptimizerResult } from './types';
export type ProjectionFn = (scenario: Scenario, overrideReturns?: number[]) => {
timeline: TimelineRow[];
metrics: Metrics;
};
export type MonteCarloFn = (scenario: Scenario, projFn: ProjectionFn, options?: {
runs?: number;
seed?: number;
budgetMs?: number;
}) => {
probability_no_shortfall: number;
median_terminal: number;
terminal_distribution: number[];
runs_completed: number;
};
export interface ClaimingOptimizerOptions {
metric?: 'terminal_real' | 'mc_success_pct';
mc_runs?: number;
mc_seed?: number;
}
/**
* SSA actuarial adjustment factors by claiming age.
* FRA = 67 (1.00). Early claiming reduces; delayed credits increase.
* Source: 2025 SSA published rates.
*/
export declare const SSA_ADJUSTMENT_FACTORS: Record<number, number>;
/**
* Approximate annuity payout rates by age and sex.
* Expressed as annual payout per $100,000 of purchase price.
* Based on approximate UK/US published annuity rate snapshots (2025 vintage).
*/
export declare const ANNUITY_RATE_TABLE: Array<{
age: number;
male: number;
female: number;
}>;
/**
* Grid search over ages 62-70 to find the optimal SS claiming age.
* At each candidate age, clones the scenario, sets the SS income source's
* start_age, adjusts the benefit amount by the SSA factor, and evaluates.
*/
export declare function optimizeSsClaiming(scenario: Scenario, projFn: ProjectionFn, mcFn?: MonteCarloFn, options?: ClaimingOptimizerOptions): ClaimingOptimizerResult;
/**
* Grid search over ages 55-75 to find the optimal pension claiming age.
* Uses pension_early_factor_pct and pension_late_factor_pct from the scenario.
*/
export declare function optimizePensionClaiming(scenario: Scenario, projFn: ProjectionFn, mcFn?: MonteCarloFn, options?: ClaimingOptimizerOptions): ClaimingOptimizerResult;
/**
* Grid search over ages current_age to retirement_age to find the optimal
* annuity purchase timing. At each candidate age, a portion of the portfolio
* (annuity_purchase_pct) is used to buy an annuity at the rate for that age.
*/
export declare function optimizeAnnuityTiming(scenario: Scenario, projFn: ProjectionFn, mcFn?: MonteCarloFn, options?: ClaimingOptimizerOptions): ClaimingOptimizerResult;
//# sourceMappingURL=claiming-optimizers.d.ts.map
1 change: 1 addition & 0 deletions dist/claiming-optimizers.d.ts.map

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading