Compliance & Audit API¶
Audit Trail¶
audit
¶
Immutable audit trail for algorithm executions.
Provides append-only logging of every algorithm run with full provenance: timestamp, user, algorithm name, parameters, input hash, result, and wall-clock duration. Default storage is SQLite in WAL mode; optional Postgres backend via psycopg2.
Typical usage::
store = AuditStore.from_sqlite("/path/to/audit.db")
entry = AuditEntry(
user="quant_desk_1",
algorithm="quantum_var",
params={"confidence": 0.99, "n_qubits": 6},
input_hash="sha256:abc123...",
result={"var_95": 0.042},
duration_ms=1523.7,
)
store.log(entry)
# Query and export
results = store.query(algorithm="quantum_var", start="2026-01-01")
store.export_csv(results, "audit_q1.csv")
AuditEntry
dataclass
¶
Single audit log entry.
Parameters¶
user : str
Identifier of the user / service account that triggered the run.
algorithm : str
Name of the algorithm executed (e.g. "quantum_var").
params : dict[str, Any]
Algorithm hyper-parameters as a JSON-serialisable dict.
input_hash : str
Deterministic hash of the input data (use :func:compute_input_hash).
result : dict[str, Any]
Algorithm outputs as a JSON-serialisable dict.
duration_ms : float
Wall-clock duration in milliseconds.
entry_id : str
UUID assigned automatically if not provided.
timestamp : str
ISO-8601 UTC timestamp, auto-generated when omitted.
AuditStore
¶
Append-only audit log backed by SQLite or Postgres.
Use the factory class-methods :meth:from_sqlite or
:meth:from_postgres to obtain an instance.
from_sqlite(path=':memory:')
classmethod
¶
Create a store backed by a SQLite database in WAL mode.
Parameters¶
path : str | Path
File-system path for the database, or ":memory:" for an
in-memory database (useful for tests).
from_postgres(dsn)
classmethod
¶
log(entry)
¶
get(entry_id)
¶
Retrieve a single entry by its ID, or None if not found.
query(*, start=None, end=None, algorithm=None, user=None, limit=None)
¶
Query audit entries matching the given filters.
Parameters¶
start : str, optional ISO-8601 lower bound (inclusive) on timestamp. end : str, optional ISO-8601 upper bound (inclusive) on timestamp. algorithm : str, optional Exact algorithm name filter. user : str, optional Exact user name filter. limit : int, optional Maximum number of rows to return.
Returns¶
list[AuditEntry] Matching entries ordered by timestamp ascending.
query_filter(qf)
¶
Query using a :class:QueryFilter object.
count()
¶
Return total number of audit entries.
export_csv(entries, path=None)
¶
export_json(entries, path=None)
¶
close()
¶
Close the underlying database connection.
QueryFilter
dataclass
¶
Filter criteria for audit log queries.
All fields are optional; None means no filter on that field.
compute_input_hash(data)
¶
Return a sha256:<hex> hash of data for provenance tracking.
Model Validation¶
validation
¶
Model validation framework aligned with SR 11-7 (Fed) and SS1/23 (PRA).
Provides three core capabilities for quantitative model governance:
- Checklist generation -- auto-generates model documentation covering inputs, methodology, assumptions, and limitations per SR 11-7 / SS1/23.
- Champion-challenger -- compares a quantum (challenger) model against a classical (champion) model on the same problem set using paired t-tests, bootstrap confidence intervals, and effect-size metrics.
- Sensitivity analysis -- systematically perturbs key parameters and measures output change to assess model stability.
References¶
Federal Reserve SR 11-7, "Guidance on Model Risk Management" (2011). PRA SS1/23, "Model risk management principles for banks" (2023).
ModelDocumentation
dataclass
¶
Auto-generated model documentation for SR 11-7 / SS1/23.
This is the core artefact produced by :func:generate_checklist.
Attributes¶
model_name : str Canonical model name. model_version : str Semantic version string. model_tier : ModelTier Materiality tier. framework : ComplianceFramework Governing regulatory framework. owner : str Model owner / responsible party. methodology : str Description of the modelling methodology. inputs : list[ModelInput] Documented inputs. assumptions : list[ModelAssumption] Key assumptions. limitations : list[str] Known limitations. generated_at : str ISO-8601 timestamp of generation. checklist_items : dict[str, bool] Checklist items and their completion status. pnl_attribution : PnLAttribution | None Backtesting P&L attribution report, if available.
ChampionChallengerResult
dataclass
¶
Result of a champion-challenger comparison.
Attributes¶
champion_name : str
Name of the champion (baseline) model.
challenger_name : str
Name of the challenger model.
champion_scores : NDArray
Per-problem scores from the champion.
challenger_scores : NDArray
Per-problem scores from the challenger.
n_problems : int
Number of problems compared.
mean_champion : float
Mean score for the champion.
mean_challenger : float
Mean score for the challenger.
t_statistic : float
Paired t-test statistic.
p_value : float
Two-sided p-value from the paired t-test.
significant : bool
True if difference is statistically significant at alpha.
alpha : float
Significance level used.
bootstrap_ci : tuple[float, float]
Bootstrap confidence interval for mean difference.
cohens_d : float
Cohen's d effect size for the paired difference.
FullSensitivityReport
dataclass
¶
Aggregated sensitivity report across multiple parameters.
Attributes¶
results : list[SensitivityResult] Per-parameter results. most_sensitive : str Name of the parameter with the highest mean absolute change. ranking : list[tuple[str, float]] Parameters ranked by mean absolute change (descending).
generate_checklist(*, model_name, model_version, model_tier=ModelTier.TIER_2, framework=ComplianceFramework.BOTH, owner='', methodology='', inputs=None, assumptions=None, limitations=None, pnl_attribution=None)
¶
Generate an SR 11-7 / SS1/23 model documentation checklist.
Automatically assesses which checklist items are satisfied based on the supplied documentation artefacts.
Parameters¶
model_name : str
Canonical model name.
model_version : str
Semantic version string.
model_tier : ModelTier
Materiality tier (default TIER_2).
framework : ComplianceFramework
Which regulatory framework(s) to cover.
owner : str
Model owner / responsible party.
methodology : str
Description of the modelling methodology.
inputs : list[ModelInput] | None
Documented model inputs.
assumptions : list[ModelAssumption] | None
Model assumptions.
limitations : list[str] | None
Known model limitations.
pnl_attribution : PnLAttribution | None
Optional P&L attribution from backtesting.
Returns¶
ModelDocumentation Complete documentation object with auto-assessed checklist.
compare_champion_challenger(champion_scores, challenger_scores, *, champion_name='classical', challenger_name='quantum', alpha=0.05, n_bootstrap=10000, seed=None)
¶
Compare champion and challenger models on the same problem set.
Uses a paired t-test for statistical significance and bootstrap resampling for a confidence interval on the mean difference (challenger - champion).
Parameters¶
champion_scores : NDArray Scores from the champion model (one per problem). challenger_scores : NDArray Scores from the challenger model (one per problem). champion_name : str Label for the champion. challenger_name : str Label for the challenger. alpha : float Significance level (default 0.05). n_bootstrap : int Number of bootstrap resamples (default 10,000). seed : int | None Random seed for bootstrap reproducibility.
Returns¶
ChampionChallengerResult Full comparison statistics.
Raises¶
ValueError If arrays differ in length, are empty, or have fewer than 2 elements.
sensitivity_analysis(model_fn, base_params, perturbation_pcts=None, *, param_names=None)
¶
Run sensitivity analysis by perturbing each parameter independently.
For each selected parameter, the function evaluates the model at
base_value * (1 + pct) for every percentage in perturbation_pcts,
holding all other parameters at their base values.
Parameters¶
model_fn : Callable[..., float]
Model function that accepts keyword arguments from base_params
and returns a scalar output.
base_params : dict[str, float]
Baseline parameter values.
perturbation_pcts : array-like | None
Fractional perturbations to apply (e.g. [-0.10, -0.05, 0.05, 0.10]
for +/-5% and +/-10%). Defaults to
[-0.20, -0.10, -0.05, 0.05, 0.10, 0.20].
param_names : list[str] | None
Subset of parameter names to perturb. Defaults to all keys in
base_params.
Returns¶
FullSensitivityReport Aggregated report with per-parameter results and ranking.
Raises¶
ValueError If param_names contains a key not in base_params.
compute_pnl_attribution(actual_pnl, model_pnl)
¶
Compute backtesting P&L attribution.
Decomposes total P&L into model-explained and residual components.
Parameters¶
actual_pnl : NDArray Realised daily P&L series. model_pnl : NDArray Daily P&L predicted / attributed by the model.
Returns¶
PnLAttribution Attribution report.
Raises¶
ValueError If arrays have different lengths or are empty.
Explainability¶
explainability
¶
Explainability module for quantum portfolio optimization decisions.
Provides tools to decompose, attribute, and compare QUBO-based portfolio selections so that quantum optimization decisions can be understood, audited, and justified to stakeholders and regulators.
Features¶
- QUBO coefficient decomposition: identify strongest asset interactions
- Marginal contribution analysis: effect of removing each asset on objective
- SHAP-like attribution for QAOA/quantum optimizer decisions
- Comparison report: quantum selection rationale vs classical optimizer
- Visualization: heatmap of asset interaction strengths
QUBODecomposition
dataclass
¶
Result of decomposing a QUBO matrix into interpretable components.
Attributes¶
linear_terms : NDArray
Diagonal elements of Q — per-asset linear bias (shape (N,)).
interaction_matrix : NDArray
Off-diagonal interaction strengths (shape (N, N)), zeroed diagonal.
top_interactions : list[tuple[int, int, float]]
Strongest pairwise interactions sorted by absolute magnitude,
each entry is (asset_i, asset_j, strength).
asset_total_interaction : NDArray
Sum of absolute interaction strengths per asset (shape (N,)).
MarginalContribution
dataclass
¶
Marginal contribution of each asset to the QUBO objective.
Attributes¶
base_objective : float
Objective value with all selected assets present.
contributions : NDArray
Change in objective when each asset is removed (shape (N,)).
Positive means removing the asset increases the objective
(i.e., the asset was beneficial for minimization).
asset_rankings : list[int]
Asset indices sorted from most to least beneficial.
SHAPAttribution
dataclass
¶
SHAP-like attribution values for a quantum portfolio decision.
Uses a permutation-based approximation of Shapley values over the binary asset-selection vector.
Attributes¶
shapley_values : NDArray
Approximate Shapley value for each asset (shape (N,)).
base_value : float
Objective value with no assets selected (empty coalition).
selection : NDArray
The binary selection vector being explained.
ComparisonReport
dataclass
¶
Side-by-side comparison of quantum vs classical portfolio selections.
Attributes¶
quantum_selection : NDArray Binary vector of quantum-selected assets. classical_selection : NDArray Binary vector of classical-selected assets. quantum_objective : float QUBO objective value for the quantum solution. classical_objective : float QUBO objective value for the classical solution. agreement_mask : NDArray Boolean mask — True where both agree on inclusion/exclusion. agreement_ratio : float Fraction of assets where quantum and classical agree. quantum_unique : list[int] Asset indices selected only by quantum optimizer. classical_unique : list[int] Asset indices selected only by classical optimizer. quantum_marginals : MarginalContribution Marginal contribution analysis of quantum selection. classical_marginals : MarginalContribution Marginal contribution analysis of classical selection. summary : str Human-readable summary of differences.
decompose_qubo(Q, *, top_k=10, asset_labels=None)
¶
Decompose a QUBO matrix into linear and interaction components.
Parameters¶
Q : NDArray
Square QUBO matrix of shape (N, N).
top_k : int
Number of top interactions to return (by absolute magnitude).
asset_labels : list[str] | None
Optional human-readable labels (unused in computation, stored
for downstream visualization).
Returns¶
QUBODecomposition
marginal_contribution(Q, selection)
¶
Compute marginal contribution of each selected asset.
For each selected asset i, computes the change in QUBO objective
x^T Q x when asset i is removed from the selection.
Parameters¶
Q : NDArray
Square QUBO matrix, shape (N, N).
selection : NDArray
Binary selection vector, shape (N,).
Returns¶
MarginalContribution
shapley_attribution(Q, selection, *, n_permutations=100, seed=None)
¶
Compute SHAP-like Shapley values for a QUBO portfolio decision.
Uses a permutation-based Monte Carlo approximation of Shapley values. Each asset's Shapley value quantifies its average marginal contribution across all possible orderings of asset inclusion.
Parameters¶
Q : NDArray
Square QUBO matrix, shape (N, N).
selection : NDArray
Binary selection vector, shape (N,).
n_permutations : int
Number of random permutations to sample.
seed : int | None
Random seed for reproducibility.
Returns¶
SHAPAttribution
compare_selections(Q, quantum_selection, classical_selection, *, asset_labels=None)
¶
Compare quantum and classical portfolio selections.
Parameters¶
Q : NDArray
Square QUBO matrix, shape (N, N).
quantum_selection : NDArray
Binary selection vector from quantum optimizer.
classical_selection : NDArray
Binary selection vector from classical optimizer.
asset_labels : list[str] | None
Optional human-readable asset labels for the summary.
Returns¶
ComparisonReport