Skip to content

Monte Carlo research

Import public experiment contracts, built-in models, distributions, metrics, and evaluation helpers from persistra.monte_carlo.

Contracts and results

persistra.monte_carlo.contracts

Public contracts for deterministic Monte Carlo experiments.

MonteCarloModel

Bases: Protocol

Structural contract for one-path generation from a managed random stream.

Distribution

Bases: Protocol

Structural contract for sampling only from a caller-managed generator.

PathMetric

Bases: Protocol

Structural contract for one named scalar outcome from one generated path.

PathEvaluator

Bases: Protocol

Structural contract for a bounded set of scalar outcomes from one path.

MonteCarloExperiment dataclass

Execution-independent identity and outputs for a Monte Carlo experiment.

MonteCarloExecution dataclass

Execution controls kept outside experiment identity.

MonteCarloResult dataclass

Paths, scalar outcomes, summaries, convergence, and provenance for one run.

path_array(path_id: int) -> NDArray[np.float64]

Return a defensive array copy for one retained path.

path_frame(path_id: int) -> pd.DataFrame

Return one retained path as an ordinary defensive pandas frame.

metric_frame() -> pd.DataFrame

Return a defensive copy of path-level scalar outcomes.

PathEvaluationResult dataclass

Bounded path-level evaluator outcomes and aggregate statistics.

freeze_portable_mapping(value: Mapping[str, Any], *, name: str, redact_api_keys: bool = False) -> Mapping[str, Any]

Copy and recursively freeze one portable JSON mapping.

require_integer(value: object, *, name: str, minimum: int | None = None) -> int

Return a normalized integer after enforcing an optional inclusive minimum.

_component_identity(component_name: str, version: str, parameters: Mapping[str, Any], *, name: str) -> None

_ordered_names(values: tuple[str, ...], *, name: str, allow_empty: bool = False) -> None

Execution and summaries

persistra.monte_carlo.runner

Deterministic batched execution for Monte Carlo experiments.

MonteCarloExecution dataclass

Execution controls kept outside experiment identity.

MonteCarloExperiment dataclass

Execution-independent identity and outputs for a Monte Carlo experiment.

MonteCarloResult dataclass

Paths, scalar outcomes, summaries, convergence, and provenance for one run.

path_array(path_id: int) -> NDArray[np.float64]

Return a defensive array copy for one retained path.

path_frame(path_id: int) -> pd.DataFrame

Return one retained path as an ordinary defensive pandas frame.

metric_frame() -> pd.DataFrame

Return a defensive copy of path-level scalar outcomes.

PathEvaluationResult dataclass

Bounded path-level evaluator outcomes and aggregate statistics.

PathEvaluator

Bases: Protocol

Structural contract for a bounded set of scalar outcomes from one path.

freeze_portable_mapping(value: Mapping[str, Any], *, name: str, redact_api_keys: bool = False) -> Mapping[str, Any]

Copy and recursively freeze one portable JSON mapping.

thaw_portable_mapping(value: Mapping[str, Any]) -> dict[str, Any]

Return a mutable JSON-compatible copy of one frozen mapping.

run_experiment(experiment: MonteCarloExperiment, execution: MonteCarloExecution | None = None, *, evaluator: PathEvaluator | None = None) -> MonteCarloResult

Run stable per-path random streams in bounded serial or threaded batches.

evaluate_paths(result: MonteCarloResult, evaluator: PathEvaluator) -> PathEvaluationResult

Evaluate every retained path without retaining heavyweight evaluator results.

_generate_path(experiment: MonteCarloExperiment, path_id: int, evaluator: PathEvaluator | None) -> tuple[NDArray[np.float64], dict[str, float]]

_finite_outcome(value: object, *, name: str) -> float

_metric_summary(metrics: pd.DataFrame, confidence_level: float) -> pd.DataFrame

_convergence(metrics: pd.DataFrame, checkpoints: tuple[int, ...]) -> pd.DataFrame

_manifest(experiment: MonteCarloExperiment, evaluator: PathEvaluator | None) -> Mapping[str, Any]

_evaluator_identity(evaluator: PathEvaluator) -> None

Models

persistra.monte_carlo.models

Focused built-in Monte Carlo path models.

MultivariateNormalReturns dataclass

Correlated simple or log returns with per-year mean and covariance.

GeometricBrownianMotion dataclass

Correlated positive price paths with per-year drift and covariance.

MovingBlockBootstrap dataclass

Joint moving-block resampling of complete historical return rows.

require_integer(value: object, *, name: str, minimum: int | None = None) -> int

Return a normalized integer after enforcing an optional inclusive minimum.

covariance_matrix(covariance: pd.DataFrame, labels: pd.Index, *, name: str, tolerance: float = 1e-12) -> pd.DataFrame

Return a defensive symmetric positive-semidefinite labeled covariance.

named_vector(values: pd.Series, *, name: str, positive: bool = False) -> pd.Series

Return a defensive finite vector with unique ordered string labels.

Calibration

persistra.monte_carlo.calibration

Pure explicit calibration helpers for Monte Carlo models.

GeometricBrownianMotion dataclass

Correlated positive price paths with per-year drift and covariance.

finite_scalar(value: object, *, name: str, positive: bool = False) -> float

Return one finite real scalar with an optional strict-positive requirement.

named_vector(values: pd.Series, *, name: str, positive: bool = False) -> pd.Series

Return a defensive finite vector with unique ordered string labels.

fit_geometric_brownian_motion(log_returns: pd.DataFrame, *, initial_prices: pd.Series, periods_per_year: float) -> GeometricBrownianMotion

Fit GBM after the caller has chosen log returns, sample, and annualization.

Distributions

persistra.monte_carlo.distributions

Built-in distributions that use only managed NumPy generators.

NormalDistribution dataclass

Univariate normal draws with explicit location and scale.

StudentTDistribution dataclass

Univariate shifted and scaled Student-t draws.

EmpiricalDistribution dataclass

Univariate sampling with replacement from explicit finite observations.

MultivariateNormalDistribution dataclass

Multivariate normal draws with strictly aligned labeled parameters.

covariance_matrix(covariance: pd.DataFrame, labels: pd.Index, *, name: str, tolerance: float = 1e-12) -> pd.DataFrame

Return a defensive symmetric positive-semidefinite labeled covariance.

finite_scalar(value: object, *, name: str, positive: bool = False) -> float

Return one finite real scalar with an optional strict-positive requirement.

named_vector(values: pd.Series, *, name: str, positive: bool = False) -> pd.Series

Return a defensive finite vector with unique ordered string labels.

sample_size(size: tuple[int, ...]) -> tuple[int, ...]

Validate one ordered NumPy sample shape.

Path metrics

persistra.monte_carlo.metrics

Built-in scalar outcomes for generated Monte Carlo paths.

TerminalLevel dataclass

Terminal value of one named path variable.

TerminalReturn dataclass

Simple terminal return from one explicit initial level.

PathVolatility dataclass

Annualized sample volatility of one path variable.

MaximumDrawdown dataclass

Maximum drawdown magnitude for levels or simple returns.

MinimumLevel dataclass

Minimum value reached by one named path variable.

ThresholdBreach dataclass

Indicator that one path variable crossed an explicit threshold.

finite_scalar(value: object, *, name: str, positive: bool = False) -> float

Return one finite real scalar with an optional strict-positive requirement.

_variable_name(variable: object) -> None

_variable_position(variable: str, variable_names: tuple[str, ...]) -> int

Portfolio evaluator

persistra.monte_carlo.portfolio

Bounded portfolio evaluation for Monte Carlo paths.

BacktestPolicies dataclass

Explicit missing-return and nontradeable-asset behavior.

BacktestTiming dataclass

Signal-to-decision and decision-to-holding timing policy.

PortfolioBacktestEvaluator dataclass

Evaluate return or price paths through the vectorized portfolio backtester.

finite_scalar(value: object, *, name: str, positive: bool = False) -> float

Return one finite real scalar with an optional strict-positive requirement.

backtest_portfolio(target_weights: PortfolioConstructionResult | pd.DataFrame, *, returns: pd.DataFrame | None = None, prices: pd.DataFrame | None = None, timing: BacktestTiming | None = None, policies: BacktestPolicies | None = None, transaction_cost_bps: float | pd.Series | pd.DataFrame = 0.0, buy_cost_bps: float | pd.Series | pd.DataFrame | None = None, sell_cost_bps: float | pd.Series | pd.DataFrame | None = None, missing_cost: MissingCostPolicy = 'error', market_impact: MarketImpactModel | None = None, liquidity: pd.DataFrame | None = None, shortable: pd.DataFrame | None = None, borrow_rates: float | pd.Series | pd.DataFrame = 0.0, borrow_policy: BorrowPolicy | None = None, fx_rates: pd.DataFrame | None = None, multi_currency: MultiCurrencyPolicy | None = None, corporate_actions: Sequence[CorporateAction] = (), return_adjustment: ReturnAdjustment = 'unadjusted', cash_returns: float | pd.Series = 0.0, tradeable: pd.DataFrame | None = None, benchmarks: Mapping[str, pd.DataFrame | pd.Series] | None = None, initial_equity: float = 1.0, tolerance: float = 1e-10) -> BacktestResult

Simulate rebalances to supplied targets over returns or prices.

Target row dates are signal-observation dates. BacktestTiming maps each observation to a decision date and first holding period. The default applies a target one period after its signal observation. Zero total lag is rejected unless the caller asserts that the signal was available before the assumed trade.

Trade costs may be scalar, asset-specific, or dated and asymmetric. Optional impact uses supplied liquidity, while borrow fees accrue separately on beginning short weights. Cash is the residual needed to make beginning weights sum to one; it can be greater than one after short sales or negative under net leverage. Returns, cash, holdings, and every cost component reconcile in the returned result.

Sourced corporate actions can add dividend cash, normalize unadjusted split returns, or replace a missing observation with a terminal return and liquidate the asset. Adjusted-return inputs explicitly suppress dividend and split application to prevent double counting.

A benchmark value can be a static weight series or a date-by-asset target panel. Static weights enter on the first strategy signal date and then drift. Panel benchmarks use the same timing and policies as the strategy. This supports explicit static and naive-signal comparisons without hiding their definitions.