An editable install from the repository root exposes six command names through
pyproject.toml. One of them is a legacy alias, so these
represent five workflow families:
| Command | Implementation | Intended use |
|---|---|---|
precompute-q-cache |
precompute_q_market_and_hedge_cache.py |
Create or validate exact Q-market and conditional-MC hedge caches |
portfolio-risk-analysis |
run_portfolio_risk_analysis.py |
Recommended end-to-end cap, behaviour and optional stress workflow |
crediting-future-profit-risk-analysis |
run_crediting_rate_capital_analysis.py |
Dynamic-only fixed-cap MLL-FPAR research study |
crediting-capital-analysis |
run_crediting_rate_capital_analysis.py |
Legacy alias for crediting-future-profit-risk-analysis; not a regulatory-capital calculation |
optimise-crediting-dynamic |
run_crediting_rate_optimisation.py |
Prepare exact caches, then run the strict one-modelpoint Dynamic Time-0 custom-CSM reader with secondary MLL-FPAR diagnostics |
optimise-crediting-lsmc |
run_crediting_rate_optimisation.py |
Prepare exact caches, then run the strict combined LSMC-policyholder optimiser |
Use python -m pip install -e ".[test]" once from the repository root. Direct
file execution is supported, but direct optimiser files remain strict cache
readers. The installed optimisation commands add the authorised cache-preflight
layer as well as making repository paths and package imports clearer.
This is the only script authorised to write
results/cache/q_market_paths or results/cache/q_hedge_prices.
Required run-specific inputs include --horizon-years and --n-paths; seed,
substeps, market stress, cap grid, allocation and cache roots are explicit or
portable defaults. The runner first validates an exact existing market entry,
creates it only when missing, and then does the same for the path-congruent
hedge surface. --market-only deliberately skips hedge preparation.
It does not choose approximate matches and does not overwrite a valid exact
entry. With --market-only, it prepares no conditional-MC hedge surface; this
is the appropriate cache boundary when a reader explicitly selects the labelled
moment_matched_bs pricing proxy.
This is the prepare-then-read orchestrator behind both installed optimisation
commands. It parses the selected optimiser's arguments, resolves the model-point
horizon and enumerates the exact samples required by that family. The Dynamic
Time-0 route hard-requires one modelpoint and one complete Q sample; the
Customer-LSMC route retains its separately declared sample roles. For every
distinct path-count/market-seed pair it invokes
precompute_q_market_and_hedge_cache.py with the same market inputs, substeps,
cache roots and horizon. With mc_conditional, it also supplies the optimiser's
complete cap grid so that the path-congruent hedge surface has the exact
required identity. With explicitly selected moment_matched_bs, it requests
only the exact market cache.
The precompute process validates reusable entries and creates only missing
ones. After every cache job succeeds, the orchestrator starts the requested
optimiser in a separate process and enforces --require-market-cache; for
mc_conditional it also enforces --require-hedge-cache. The optimiser itself
never gains cache-write authority. The LSMC command is dispatched through the
Bellman wrapper so that LSMC policyholder behaviour is enforced.
This is the read-only market-consistent portfolio valuation with statistical
dynamic behaviour. It values every model point on a shared Q scenario set and
aggregates with contract_weight.
Important options include:
- model-point, cost, behaviour and market input paths;
- evaluation path count and market/take-up/mortality seeds;
- fixed
--crediting-cap-ratedesign override; --hedge-pricing-methodand hedge cap-leg mode;- market/non-market stress choice;
- optional absolute portfolio contract count and fair-fee calculation;
- output/log/plot controls.
The exact Q market cache is always required. With mc_conditional, the exact
hedge cache is also required. Principal outputs are model-point results,
portfolio summary, aggregation reconciliation, run manifest, log and optional
figures.
This is the prepare-then-read Dynamic-only MLL future-profit-at-risk
orchestrator behind the canonical crediting-future-profit-risk-analysis
command. For every cap it invokes the authorised precompute runner to validate
or create only the exact required base market and hedge caches, then launches
run_portfolio_valuation.py for base, mortality, longevity, lapse-up and
lapse-down revaluations. Non-market stresses must preserve the base cache keys.
The command hard-codes dynamic Income Election and post-Election behaviour and
rejects any child output with lsmc_used=true. It never calls
run_portfolio_valuation_lsmc.py. Outputs include the reconciled stressed
custom-CSM values, stand-alone future-profit losses, permanent and approximate
mass-lapse amounts, correlated MLL-FPAR, FPAR-penalised CSM sensitivity,
CSM/MLL-FPAR ratio, selection result, manifest and plots.
The default and primary ranking is custom CSM. The explicit
--objective fpar_penalised_csm and --objective csm_to_fpar choices rank by
secondary research sensitivities instead. The dimensionless 6% factor in the
first sensitivity is an FPAR penalty weight, not a capital charge,
cost-of-capital rate or full Risk Margin. The MLL-FPAR amount is partial and
the mass-lapse leg is a model-point positive-value proxy rather than a
revaluation. crediting-capital-analysis, the old option names and
capital-named output columns remain compatibility aliases only.
The runner must not be used or described as an APRA capital calculation. APRA's actual boundary is set out in LPS 115 for the Insurance Risk Charge, LPS 112 for adjusted policy liabilities and capital base, and LPS 110 for the prescribed-capital and Prudential Capital Requirement framework. The runner also does not calculate an IFRS 17 CSM; its custom CSM is a repository profitability proxy.
This is the read-only portfolio valuation with the combined policyholder LSMC.
It fits annual Growth WAIT/START_NORMAL_INCOME and annual Income normal
Scheduled Income plus CONTINUE/FULL_SURRENDER decisions. The implementation
retains the internal transition labels START_INCOME_NOW and
FULL_WITHDRAWAL_NOW. Partial withdrawal is not part of the current optimal
action set. It requires exactly one model point.
The customer objective is the Q-expectation of income, surrender and finite
terminal-closeout cashflows discounted by today's Australian zero curve. The
fit contains no mortality or death benefit; configured mortality is restored
for actuarial and custom-CSM rollout. Whole-path cross-fitting estimates
continuation values inside one exact Q sample. The V11 rule is deployed directly on that
same sample: there is no separate validation/evaluation sample, policy-selection
gate, RMSE exercise buffer or fixed-policy substitution. Legacy sample flags
remain parseable
but are normalised to --n-train and the active training seeds.
The runner writes regression/action diagnostics, same-sample comparisons and
explicit oos_validation_used=false / oos_evaluation_used=false manifest
fields. A paired Dynamic benchmark is produced by default unless disabled.
Use this runner directly when one fixed cap and detailed LSMC diagnostics are the subject. Use the risk orchestrator for a multi-cap comparison with automatic cache preparation.
This is the primary portfolio orchestrator. For each cap and optional stress it:
- resolves the single exact training-and-valuation sample;
- invokes the authorised precompute runner for missing exact Q/hedge entries;
- runs Dynamic and LSMC valuations serially within each cap/stress pair;
- schedules independent pairs with bounded worker/BLAS concurrency;
- validates source, cache, sample and aggregation consistency;
- writes aggregate CSV, manifest, report and optional plots to a new timestamped run directory.
The default is a base-only 4%, 6%, 12% and 15% cap comparison on the one-point
proxy with one worker. The runner rejects multi-model-point input for the
customer-LSMC workflow. Such output is an illustrative method/design
sensitivity, not evidence about the full 48-point portfolio.
--stress-analysis is required to add the selected shock-and-revalue grid.
The outputs are expected values and model-point diagnostics, not a pathwise loss distribution or regulatory capital calculation.
This is the strict cache-reader implementation used by the canonical Dynamic-behaviour cap command. It values today the insurer's right to reset the annual cap under statistical Dynamic Policyholder behaviour. It hard-requires exactly one modelpoint and never calls Customer LSMC. Future cashflows are risk-neutral expected values discounted to Time 0 with the current curve.
The gas-storage formulation uses account value per initial premium as an endogenous inventory grid. Node continuation fits use an intercept, ATM one-year call value, reference-fund level and overnight rate. Each action-Q target is the realised annual 14-value Base/Stress custom-CSM payload plus the next value interpolated at that same path's realised next account value. The six-column action basis adds account value and squared account value.
Because MLL-FPAR is non-additive, the runner fits 21 predeclared additive
Base/Stress support policies plus one conditional-ratio heuristic, then ranks
the finished fixed-anchored payloads on the primary Time-0 custom-CSM score.
The standard hedge is the sold bull call spread. The current cap affects statistical behaviour through account value, guarantee moneyness and realised performance history; it is not inserted as an undocumented direct lapse coefficient.
This small strict cache-reader entry point enforces LSMC policyholder behaviour
and delegates to
optimize_crediting_rate_lsmc.py.
Use the wrapper when the policyholder response must be LSMC; use the
implementation module only for advanced research configuration.
The implementation fits an ordered policyholder follower and an insurer cap leader. Its fast default screens a coarse cap grid, then performs fresh cap-specific follower fits for selected fixed-cap finalists. The full action grid and broader comparators are opt-in.
The cap-randomised adaptive response surface is currently diagnostic only. Code blocks its deployment until joint leader/follower on-policy iteration and the complete three-seed component validation contract are implemented. A reported deployed result is therefore the validated fixed-cap follower, not the raw adaptive response-surface candidate.
optimize_crediting_rate_lsmc.py
is active because the public Bellman entry point delegates to it, but it is an
advanced implementation module rather than a separate recommended workflow.
Files beginning with _ are implementation helpers, not public commands:
_mc_analysis_inputs.pystrictly loads the predeclared Monte Carlo sample table;_run_layout.pycentralises child output-directory conventions;_run_logging.pyprovides consistent console/log formatting.
| Question | Start here |
|---|---|
| One fixed cap with statistical Dynamic behaviour | run_portfolio_valuation.py |
| One fixed cap with direct optimal-policyholder diagnostics | run_portfolio_valuation_lsmc.py |
| Dynamic versus direct LSMC V11 across caps and optional stresses | portfolio-risk-analysis |
| Fixed caps under Dynamic mortality/longevity/lapse MLL-FPAR | crediting-future-profit-risk-analysis |
| Time-0 custom-CSM value of annual cap flexibility under statistical Dynamic behaviour, with 6%-FPAR penalty and CSM/MLL-FPAR reported secondarily | optimise-crediting-dynamic |
| LSMC-follower cap research | optimise-crediting-lsmc |
| Prepare one known exact cache specification | precompute-q-cache |
| Debug an optimiser against already prepared exact caches | Direct optimiser implementation file |
- Run from a cloned repository without editing absolute paths; portable defaults
come from
repository_paths.py. - Prefer the installed optimisation commands when missing exact caches may need preparation; direct optimiser files are readers only.
- For Q valuation, never bypass exact market-cache validation.
- For
mc_conditional, never omit the congruent hedge cache or replace it with an implicit Black–Scholes estimate. - For Dynamic-customer Management LSMC, use exactly one modelpoint and the one complete Time-0 sample recorded in the manifest; do not reinterpret its action-cell diagnostics as a deployment rule.
- For the separate Customer-LSMC/Stackelberg route, follow its own declared sample and deployment restrictions.
- Check the custom-CSM and portfolio aggregation reconciliations before interpreting a result; do not reinterpret custom CSM as IFRS 17 CSM or MLL-FPAR as required capital.
- Treat one-point customer-LSMC runs as method/design sensitivities, not portfolio evidence, regardless of path count.
- Promote a figure to
results/document_figures/only from a completed, current-source, provenance-backed run.
For full workflow and cache semantics, see portfolio valuation and risk workflows. For the control equations and validation gates, see crediting-rate optimisation.