portfolio_risk
eigenkit.algorithms.portfolio_risk
PortfolioRiskEstimator
Bases: BaseQuantumEstimator
Quantum estimator of portfolio risk.
It estimates the Value at Risk (VaR) and the Conditional Value at Risk (CVaR) of
a portfolio. The estimator can use IQAE to estimate the tail
probability on a quantum circuit. The oracle for IQAE is built from the fitted
return distribution with amplitude encoding.
Note
This is not a standard scikit-learn regressor. The risk at a confidence
level comes from estimate() and var_at(), which take confidence levels
and not feature vectors, and the estimator has no meaningful scikit-learn
score(). It inherits only from
BaseQuantumEstimator.
Not financial advice
The estimates come from a model fitted to the price history you pass in, and they carry no guarantee. They are not investment advice.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
n_qubits
|
int
|
The total number of qubits, including the ancilla. The loss
distribution is discretised into |
6
|
epsilon
|
float
|
The additive precision of the IQAE estimate of the tail probability. |
0.01
|
alpha
|
float
|
The failure probability of IQAE. The confidence level is
|
0.05
|
horizon_days
|
int
|
The investment horizon, in trading days, used to scale daily
log-returns to the target horizon. The default is |
1
|
provider
|
ProviderSpec
|
The backend that Note The Grover operator built internally uses the adjoint of an
|
'numpy'
|
n_shots
|
int
|
The number of shots per IQAE round. The default is |
100
|
random_state
|
int | None
|
The seed that makes the results reproducible. |
42
|
n_bisection_steps
|
int
|
The number of binary-search steps used to locate the
VaR with quantum estimates of the tail probability. With |
0
|
measure_tail_probability
|
bool
|
When |
True
|
distribution
|
str
|
The model of the loss distribution that
|
'gaussian'
|
Example
import numpy as np
from eigenkit.algorithms import PortfolioRiskEstimator
rng = np.random.default_rng(0)
returns = rng.normal(0.0005, 0.02, size=(250, 3))
prices = 100 * np.exp(np.cumsum(returns, axis=0))
estimator = PortfolioRiskEstimator(
n_qubits=5, provider="numpy", random_state=0
)
estimator.fit(prices, weights=np.array([0.5, 0.3, 0.2]))
risk = estimator.estimate(confidence_level=0.95)
print(risk.var) # 0.0237: at most a 2.37% loss on 95% of days
print(risk.cvar) # 0.0262: the average loss on the worst 5%
print(risk.tail_probability) # 0.0659: the IQAE estimate of the tail mass
distribution_params
property
Summary statistics of the fitted return distribution.
The value is None if fit() has not been called. Otherwise it always contains "mu" (the mean) and "sigma" (the standard deviation) of
the scaled log-returns, whatever the distribution model. For "t", the
degrees of freedom are not stored here, because they are an intermediate
result of the maximum-likelihood fit and not part of the state of the
estimator.
is_fitted
property
Whether fit() has completed successfully.
estimate(confidence_level=0.95, *, _seed_seq=None)
Estimate the VaR and CVaR at confidence_level.
The VaR and CVaR come from the discretised loss distribution. When
n_bisection_steps > 0, the VaR is refined by a bisection that uses IQAE.
Otherwise, the classical quantiles of the bins are used. Unless
measure_tail_probability=False, a final IQAE run estimates P(loss ≥ VaR),
for checking and diagnostics.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confidence_level
|
float
|
The probability level of the risk measures, for example
|
0.95
|
_seed_seq
|
SeedSequence | None
|
A private override of the random seed, used by |
None
|
Returns:
| Type | Description |
|---|---|
PortfolioRiskResult
|
Raises:
| Type | Description |
|---|---|
RuntimeError
|
If |
ValueError
|
If the selected provider cannot compile the oracle for the tail that IQAE needs. |
fit(X, y=None, *, weights=None)
Fit the return distribution to historical price data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
A 2-D array of shape |
required |
y
|
ndarray | None
|
Ignored, because this estimator is unsupervised. It is present for compatibility with the scikit-learn interface. |
None
|
weights
|
ndarray | None
|
A 1-D array of portfolio weights that sum to 1. If it is not given, all assets have equal weights. |
None
|
Raises:
| Type | Description |
|---|---|
ValueError
|
If |
predict(X)
Not supported. Use var_at() instead.
The estimator base class requires a predict method. In scikit-learn,
predict takes samples from the same feature space that fit received, but
the risk at a confidence level is a different question, which var_at()
answers.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
X
|
ndarray
|
Ignored. |
required |
Raises:
| Type | Description |
|---|---|
NotImplementedError
|
Always. The message points to |
var_at(confidence_levels)
Return the VaR at each confidence level.
This is the array version of estimate(). It runs IQAE once for each level and
returns only the var of each result.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
confidence_levels
|
ndarray
|
A 1-D array of confidence levels in |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
An array of VaR values, as fractions of the portfolio value lost, with one value per level. |
Raises:
| Type | Description |
|---|---|
ValueError
|
If the argument is not 1-D after a single column is squeezed. |
NotFittedError
|
If |
Warns:
| Type | Description |
|---|---|
UserWarning
|
If any level is below |
Warning
Each level runs IQAE once, so n levels need n separate quantum
circuits. For a single risk measure, call estimate() instead.
PortfolioRiskResult
dataclass
Bases: ValueEquality
Outcome of a PortfolioRiskEstimator run.
The result is read-only. Assigning to a field raises FrozenInstanceError, so
a mistyped = (instead of ==) cannot change a result. This type holds no
arrays, so nothing else needs protecting.
Results compare by value. They are not hashable, so that all result types behave in the same way: the types that hold arrays cannot be hashed both correctly and efficiently.
Attributes:
| Name | Type | Description |
|---|---|---|
var |
float
|
The Value at Risk (VaR) at the requested |
cvar |
float
|
The Conditional Value at Risk (CVaR), also called Expected Shortfall, at the same confidence level. |
tail_probability |
float
|
The IQAE point estimate of |
confidence_interval |
tuple[float, float]
|
The |
iqae_result |
IQAEResult | None
|
The full |