Skip to content

Contrib API

Optional modules for risk metrics, independent fit batches, and marginal models. Not part of the core copula API.

Install the optional marginal and risk dependencies before importing them:

pip install "pyscarcopula[contrib]"
from pyscarcopula.contrib.risk_metrics import risk_metrics
from pyscarcopula.contrib.parallel_fit import fit_independent
from pyscarcopula.contrib.marginal import MarginalModel

risk_metrics(..., n_jobs=...) is used for both rolling marginal fits and rolling copula/risk windows. n_jobs=-1 uses all available workers where the selected marginal model supports parallel fitting.

When more than one worker process is used, both risk_metrics and fit_independent default to one native thread per worker. An explicit n_threads value greater than one opts into nested parallelism. The resolved worker count, native thread count, multiprocessing start method, and ownership policy are available in result diagnostics.

When no native thread count is supplied anywhere, the result is always one thread, independently of environment variables. Each process owns a separate model and prepared evaluator. For n_jobs=1, rolling windows remain sequential and may reuse the caller's model; each fit invalidates transient prepared state before the next window.

See CPU Parallelism for oversubscription, reproducibility, and thread-safety guidance.

fit_independent

pyscarcopula.contrib.parallel_fit.fit_independent(copulas, datasets, *, method='mle', fit_kwargs=None, n_jobs=1, n_threads=None, mp_start_method=None)

Fit independent datasets/models, optionally in worker processes.

copulas may be one unfitted prototype, which is broadcast to every dataset, or one prototype per dataset. fit_kwargs follows the same rule and can therefore carry task-specific initial points or optimizer settings. Only constructor-level structural model parameters are copied; transient caches and previous fit state are intentionally excluded. Nonreal data and unknown or wrong-method fit keywords are rejected before any task executes. Failed optimizer results remain available in the batch; inspect their success flags before using a fitted model.

When n_jobs > 1, omitted n_threads resolves to 1. Passing an explicit larger value opts into nested process/thread parallelism and is recorded in batch.diagnostics.

IndependentFitBatch.models contains one independently reconstructed fitted model per task. No model, prepared evaluator, or transient fit cache is shared between tasks.

Nonreal observations and unknown or wrong-method fit_kwargs are rejected before any fit or worker process starts. This includes task-specific keyword dictionaries: an invalid later task prevents earlier tasks from running. Optimizer nonconvergence remains a returned result; inspect each batch.results[i].success before using its model. Whether an unsuccessful result is attached to model.fit_result follows that model's fit contract; the presence of fitted state alone does not establish convergence.

risk_metrics

pyscarcopula.contrib.risk_metrics.risk_metrics(copula, data, window_len, gamma=0.95, N_mc=100000, marginals_method='johnsonsu', method='mle', optimize_portfolio=True, portfolio_weight=None, n_jobs=1, n_threads=None, mp_start_method=None, rng=None, failure_policy='raise', **kwargs)

Rolling VaR/CVaR estimation with copula models.

Parameters:

Name Type Description Default
copula (BivariateCopula, GaussianCopula, StudentCopula, VineCopula)

or a fitted regular vine

required
data (T, dim) log-returns
required
window_len int
required
gamma float or list — confidence level(s)
0.95
N_mc int or list — MC sample sizes
100000
marginals_method str — 'normal', 'johnsonsu', etc.
'johnsonsu'
method str — 'mle', 'scar-tm-ou', 'scar-tm-jacobi', 'gas'

Ignored for multivariate elliptical copulas (GaussianCopula, StudentCopula), which always use their own MLE fit.

'mle'
optimize_portfolio bool
True
portfolio_weight (dim,) or None (equal weights)
None
n_jobs int

Number of parallel workers for rolling window computation. Default 1 (sequential). Use -1 for all CPU cores. Each worker processes a contiguous chunk of windows, so numba compilation overhead is paid once per worker.

1
n_threads int or None

Native threads used inside each fit. With n_jobs != 1, the safe default is one thread per worker. Passing a value greater than one explicitly opts into nested parallelism.

None
mp_start_method str or None

Multiprocessing start method. None uses the platform default.

None
rng int, np.random.Generator, np.random.SeedSequence, or None

Root randomness source. Independent child SeedSequences are spawned per rolling window, so parallel workers never share one Generator.

None
failure_policy ('raise', 'continue')

'raise' stops on a final unsuccessful copula fit or VaR/CVaR optimizer result, before prediction or consumption of that optimizer result. This includes iteration/evaluation limit exhaustion. Internal failed trials and successful model fallbacks do not count as final failure. The error identifies the stage and zero-based window end index. Parallel execution stops when the first failing chunk is observed; other chunks may already have run, and error order is not chronological. 'continue' keeps the previous behavior of using available fitted state and optimizer output regardless of success. A rejected refit may leave an older fitted state in use; an unfitted model can still raise. Exceptions propagate under both policies. Marginal fitting exposes no common success flag; its exceptions likewise propagate unchanged.

'raise'
**kwargs forwarded to copula.fit()
{}

Returns:

Name Type Description
dict res[gamma][N_mc] = {'var': ..., 'cvar': ..., 'weight': ...}

failure_policy="raise" is the default. A final unsuccessful copula fit stops that window before prediction can use older fitted state. A final unsuccessful SLSQP result stops before its VaR, CVaR or weights are consumed. Iteration/evaluation limit exhaustion counts as failure even when the returned candidate is finite. Internal rejected objective trials, unsuccessful restarts and successful model fallbacks do not count as final failure; for a vine, the final selected edge results determine overall fit success.

The exception identifies the stage and zero-based window end index. With multiple processes, the first error received stops collection and terminates remaining workers; other windows may already have run. This does not promise the chronologically earliest failing window or rollback of the caller's model.

failure_policy="continue" retains the previous handling of unsuccessful results: prediction uses the available fitted state and the portfolio step uses the returned optimizer candidate. In particular, a rejected refit can leave an older fitted state in use. A fresh model with no fitted state may still raise. Exceptions are never suppressed under either policy.

This policy checks final copula and portfolio results. Marginal fits return parameter arrays rather than a common success result, so hidden marginal optimizer convergence flags are not inspected; marginal exceptions propagate unchanged. The policy does not make unsupported marginal prediction modes available.

Nonreal input and unknown or wrong-owner fit keywords are rejected before marginal fitting or worker submission under both policies. Gaussian/Student models retain their documented MLE method override and receive the supplied optimizer/numerical settings, including resolved n_threads.

MarginalModel

pyscarcopula.contrib.marginal.MarginalModel

Base class for marginal distribution models.

create(name) staticmethod

Factory method.

fit_rolling(data, window_len, n_jobs=-1)

Rolling window fit. data: (T, dim). Returns: (T, dim, n_params).

ppf(u, params)

Inverse CDF. u: (N, dim), params: (dim, n_params). Returns: (N, dim).