Skip to content

AllocationSnapshot

qcs.AllocationSnapshot

Bases: BaseModel

Snapshot of a portfolio's allocation.

This class provides a structure for storing information about a portfolio's currency, positions, and other optional data.

Parameters:

Name Type Description Default
currency str

The currency in which the portfolio amounts are denominated. Should be a 3-letter currency code.

required
positions List[Position]

A list of Position objects representing the individual investments in the portfolio. Use either size or allocation for all positions. Can be also given as {"ticker": str, "size": float}

Position properties: ticker : str size : float - size of the position in units of the financial instrument allocation : float - allocation of the position in the portfolio currency Other optional properties (used for optimization): locked : bool (default False) turnover : float - position turnover constraint (default -1.0, ignored) long_short : Literal["long_only", "long_short", "short_only"] - Long/short constraint (default "long_only") expected_return : float (default 0.0)

required
benchmark AllocationSnapshot | None = None

An optional AllocationSnapshot object to be used as a benchmark.

required
reference_market AllocationSnapshot | None = None

An optional AllocationSnapshot object to be used as a reference_market. Used in Black-Litterman and IPERF calculations.

required
pricing_context PricingContext | None = None

An optional PricingContext object to be used for pricing.

required

Methods:

Name Description
pivot_view

Create a pivot view instance

optimize

Optimize

apply_position_constraints

Apply position constraints

are_constraints_feasible

Check if the position and portfolio constraints are feasible

bl_returns

Calculate Black-Litterman returns

build_portfolio_constraints

Build portfolio constraints

check_portfolio_constraints

Check portfolio constraints

efficient_frontier

Calculate efficient frontier

get_historical_returns

Get historical returns

get_market_implied_returns

Get market implied returns

top_factors

Get top replication factors

Examples:

>>> positions = [
...     {"ticker": "EUR", "size": 100.0},
...     {"ticker": "EQUITY_1", "size": 200.0},
... ]
>>> portfolio_snapshot = AllocationSnapshot(
...     currency="USD", positions=positions
... )
>>> print(portfolio_snapshot.currency)
'USD'
>>> benchmark_snapshot = AllocationSnapshot(currency="EUR", positions=[...])
>>> portfolio_snapshot.benchmark = benchmark_snapshot

apply_position_constraints(context, position_constraints)

Applies position constraints to the positions of allocation snapshot. Returns a new AllocationSnapshot with the position constraints applied. Overwrites the 'lock' or 'long_short' or 'turnover' properties of the positions, but only if they are specified in the constraint and affected by the filter.

Parameters:

Name Type Description Default
context Context

The context which contains the local_db with assets

required
position_constraints List[PositionConstraint]

The position constraints to be applied to the snapshot.

required

Returns:

Type Description
AllocationSnapshot

A new AllocationSnapshot with the position constraints applied.

Examples:

>>> snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> context = Context(date="2023-03-31", horizon="1m", local_db=local_db)
>>> position_constraints = [PositionConstraint(
...     type="lock", filter=lambda asset: asset.type == "EQT"
... )]
>>> new_snapshot = snapshot.apply_position_constraints(
...     context, position_constraints
... )

are_constraints_feasible(context, portfolio_constraints=None)

Checks if the portfolio constraints and position constraints are feasible. It doesn't take into account the optimizer constraint. Can be run before running full optimization.

Parameters:

Name Type Description Default
context Context
required
portfolio_constraints List(PortfolioConstraint) | None
None

Returns:

Type Description
bool

True if the portfolio constraints are feasible, False otherwise.

Examples:

>>> if not snapshot.are_portfolio_constraints_feasible(
...     context, portfolio_constraints=portfolio_constraints
... ):
...     raise ValueError("Portfolio constraints are not feasible")

bl_returns(context, views, confidences, matrix_p, tau=0.3, uncertainty_method='jay_walters')

This method calculates the Black-Litterman returns. Prior estimate of return should be given in the allocation snapshot positions, in the expected_return field. The context, views, confidences, and picking matrix should be given as arguments.

Parameters:

Name Type Description Default
context Context

The context in which the Black-Litterman calculation is performed.

required
views List[float]

The views on the market. Vector Q

required
confidences List[float]

The confidences in the views. Vector representing diag(Ω)

required
matrix_p List[List[float]]

The picking matrix P.

required
tau float

Market uncertainty. Default is 0.3.

0.3
uncertainty_method str

The uncertainty method. Options include "jay_walters", "idzorek". Default is "jay_walters".

'jay_walters'

Returns:

Type Description
AllocationSnapshot

Allocation snapshot with posterior returns calculated using Black Litterman. The posterior returns are provided in expected_return field in snapshot.positions.

Examples:

>>> snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> context = Context(date="2023-03-31", horizon="1m", local_db=local_db)
>>> snapshot_with_posterior_returns = snapshot.bl_returns(
...     context=context,
...     views=[0.02, 0.1],
...     confidences=[0.3, 0.9],
...     matrix_p=[[1, 0, 0], [0, 1, 1]],
... )

build_portfolio_constraints(context, constraints)

Builds specific portfolio constraints based on the given constraints and context.

Parameters:

Name Type Description Default
context Context

The context which contains the local_db with assets

required
constraints List[Constraint]

The constraints to be used for building the portfolio.

required

Returns:

Type Description
List[PortfolioConstraint]

A list of portfolio constraints, with exposure_coefficients for this snapshot

Examples:

>>> snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> context = Context(date="2023-03-31", horizon="1m", local_db=my_local_db)
>>> constraints = [Constraint(
...     type="limit_max",
...     value=0.5,
...     filter=lambda asset: asset.type == "EQT"
... )]
>>> portfolio_constraints = snapshot.build_portfolio_constraints(
...     context, constraints
... )

check_portfolio_constraints(portfolio_constraints, context=None, epsilon=1e-06)

Checks if the portfolio constraints are met for the allocation snapshot.

Parameters:

Name Type Description Default
portfolio_constraints List[PortfolioConstraint]

The portfolio constraints to be checked for the snapshot.

required
context Context | None

Required if snapshot positions are given in sizes.

None
epsilon float

The epsilon value to use for the check. Default is 1e-6.

1e-06

Returns:

Type Description
Tuple[bool, List[Dict[str, Any]]]

A tuple containing a boolean indicating whether the constraints are met and a list of breached constraints.

Examples:

>>> snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> portfolio_constraints = [PortfolioConstraint(
...     exposure_coefficients=[0.5, 0.5], limit_min=0.5, limit_max=0.5
... )]
>>> constraints_met, breached_constraints = (
...     snapshot.check_portfolio_constraints(portfolio_constraints)
... )

efficient_frontier(context, portfolio_constraints=None, optimizer_constraints=None, cost_function='markowitz', volatility_ladder=(0.05, 0.2, 0.05))

Get the optimization efficient frontier for the allocation snapshot.

Same inputs as the optimize method, with additional input of volatility ladder.

Parameters:

Name Type Description Default
context Context

The context in which the optimization is performed.

required
portfolio_constraints List(PortfolioConstraint) | None

The list of portfolio constraints.

None
optimizer_constraints List[OptimizerConstraint] | None

The list of optimizer constraints.

None
cost_function str

The cost function to use for optimization. Options include "robust_mean_variance", "markowitz". Default is "markowitz".

'markowitz'
volatility_ladder Tuple[float, float, float]

The volatility ladder (min, max, step) to use for efficient frontier calculation. Default is (0.05, 0.20, 0.05).

(0.05, 0.2, 0.05)

Returns:

Type Description
dict

The efficient frontier data.

Examples:

>>> context = Context(date=date.today(), horizon="1d", local_db=local_db)
>>> efficient_frontier_data = portfolio_snapshot.efficient_frontier(
...     context,
...     portfolio_constraints=portfolio_constraints,
...     volatility_ladder=(0.05, 0.20, 0.05)
... )

get_historical_returns(context, window)

Calculates historical returns for the positions within the allocation snapshot over a specified window.

Parameters:

Name Type Description Default
context Context

The context which contains the local_db with assets and histories.

required
window Literal['1m', '2m', '3m', '6m', '1y']

The time window over which historical returns are calculated.

required

Returns:

Type Description
AllocationSnapshot

A new AllocationSnapshot instance with expected_return updated for each position based on historical performance.

Examples:

>>> snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> historical_returns_snapshot = snapshot.get_historical_returns(
...     context=context, window="1m"
... )
>>> print(historical_returns_snapshot.positions[0].expected_return)

get_market_implied_returns(context, implied_perf_exponent)

Calculates market implied returns for the positions within the allocation snapshot. Snapshot should contain pricing_context and reference_market.

Parameters:

Name Type Description Default
context Context

The context which contains the local_db with assets and histories.

required
implied_perf_exponent int

The exponent of the implied performance. k=1 Markowitz, k=3 Robust mean variance

required

Returns:

Type Description
AllocationSnapshot

A new AllocationSnapshot instance with expected_return updated for each position based on the market implied returns.

Examples:

>>> pricing_context = {"risk_free_rate": 0.03}
>>> reference_market = {
>>>     "currency": "USD",
>>>     "positions": [{"ticker": "GBP", "allocation": 100.0}],
>>> }
>>> snapshot = AllocationSnapshot(
...     currency="USD",
...     positions=positions,
...     pricing_context=pricing_context,
...     reference_market=reference_market
... )
>>> snapshot_with_returns = snapshot.get_market_implied_returns(
...     context=context, implied_perf_exponent=3
... )
>>> print(snapshot_with_returns.positions[0].expected_return)

optimize(context, portfolio_constraints=None, optimizer_constraints=None, cost_function='min_tracking_error')

Optimize the allocation snapshot.

This function optimizes the allocation snapshot based on the given context, cost function, and DAE matrix.

Parameters:

Name Type Description Default
context Context

The context in which the optimization is performed.

required
portfolio_constraints List(PortfolioConstraint) | None

The list of portfolio constraints.

None
optimizer_constraints List[OptimizerConstraint] | None

The list of optimizer constraints.

None
cost_function str

The cost function to use for optimization. Options include "min_tracking_error", "robust_mean_variance", "markowitz", "risk_parity", "min_variance", "max_diversification", "min_scr". Default is "min_tracking_error".

'min_tracking_error'

Returns:

Type Description
AllocationSnapshot

The optimized allocation snapshot.

Examples:

>>> context = Context(date=date.today(), horizon="1d", local_db=local_db)
>>> optimized_snapshot = portfolio_snapshot.optimize(
...     context, portfolio_constraints=portfolio_constraints
... )

pivot_view(context, pivot_fields)

Create a pivot view of the allocation snapshot.

Take the current allocation snapshot and create a pivot view based on the provided context and pivot fields. The pivot view can be used to analyze the portfolio data in different drilldown levels.

Parameters:

Name Type Description Default
context Context

The context in which the pivot view is created, containing date, horizon, local database and possibly other relevant settings for risk analysis.

required
pivot_fields List[str]

A list of fields to pivot on. Asset fields like type, country, ticker.

required

Returns:

Type Description
AllocationSnapshotPivotView

An instance of AllocationSnapshotPivotView containing the pivoted data.

Examples:

>>> context = Context(date=date.today(), horizon="1d", local_db=local_db)
>>> pivot_fields = ["sector", "country"]
>>> pivot_view = portfolio_snapshot.pivot_view(context, pivot_fields)

top_factors(context, factors, max_size=None, replication_method='enhanced_stepwise', epsilon=0.01, trace=None)

Calculates the top factors which can replicate the portfolio tickers using the given factors. Outputs the factors and the R^2 values.

Parameters:

Name Type Description Default
context Context

The context which contains the local_db with assets

required
factors List[str]

The tickers used for replication.

required
max_size int

The maximum number of factors to include in the top factors. Default is None.

None
replication_method ReplicationMethod

Method used for replication. Options include "enhanced_stepwise", "forward", "backward", "stepwise", "adaptive_stepwise", "r_statistics". Default is "enhanced_stepwise".

'enhanced_stepwise'
epsilon float

Epsilon value for replication. Default is 0.01.

0.01
trace bool

If true, then method returns additional output with trace

None

Returns:

Type Description
Tuple[List[str], List[float]]

A tuple containing the top factors and the R^2 values.

Examples:

>>> top_factors, r2 = snapshot.top_factors(
...     context,
...     factors,
...     replication_method="enhanced_stepwise",
...     epsilon=0.01
... )

qcs.Position

Bases: BaseModel

Single position in a portfolio. All positions in portfolio must use either size or allocation.

Parameters:

Name Type Description Default
ticker str

The ticker representing the asset or financial instrument.

required
size float

The size of the position in units of the financial instrument.

required
allocation

The allocation of the position in the portfolio currency.

required
locked bool

Indicates if the position is locked, preventing it from being optimized. Defaults to False.

required
turnover float

The turnover constraint for the position. Defaults to -1.0, i.e. ignored.

required
long_short Literal['long_only', 'long_short', 'short_only']

Specifies the long/short constraint for the position. Defaults to "long_only".

required
expected_return float

The expected return value for the position, in decimal. Defaults to 0.0.

required

Examples:

>>> position = Position(ticker="AAPL", size=50)

qcs.PricingContext

Bases: BaseModel

Pricing context for AllocationSnapshot

Specify either risk_aversion or risk_free_rate

Parameters:

Name Type Description Default
risk_aversion float

The risk aversion coefficient

required
risk_free_rate float

The risk-free rate

required

qcs.AllocationSnapshotPivotView

Bases: BaseModel

Represents a pivot view of an allocation snapshot.

This model holds the data necessary to represent a pivot view of an allocation snapshot, including the snapshot itself, the context in which the pivot is viewed, and the fields on which the pivot is made.

Parameters:

Name Type Description Default
allocation_snapshot AllocationSnapshot

The allocation snapshot that is being pivoted.

required
context Context

The context in which the pivot view is created, containing date, horizon, local database and possibly other relevant settings for risk analysis.

required
pivot_fields List[str]

A list of fields to pivot on. Asset fields like type, country, ticker.

required

Methods:

Name Description
get_risks

Get risk analysis drilldown as a pandas DataFrame.

Examples:

>>> positions = [
...     {"ticker": "EUR", "size": 100.0},
...     {"ticker": "EQUITY_1", "size": 200.0},
... ]
>>> portfolio_snapshot = AllocationSnapshot(currency="USD", positions=positions)
>>> context = Context(date=date.today(), horizon="1d", local_db=my_local_db)
>>> pivot_fields = ["sector", "country"]
>>> portfolio_snapshot.pivot_view(
...     context=context,
...     pivot_fields=pivot_fields
... )

get_risks(fields)

Get risk analysis drilldown as a pandas DataFrame.

This method calls an external risk service to obtain risk indicators for the current allocation snapshot and pivot view based on the specified fields / indicators.

It might take some time to compute.

Parameters:

Name Type Description Default
fields List[str]

A list of risk indicator fields to retrieve, e.g. MAV, MRGVAR[Q=99], \\div(STD,MAV).

required

Returns:

Type Description
DataFrame

A DataFrame containing the risk analysis drilldown.

Raises:

Type Description
HTTPError

If the request to the backend fails with an HTTP error.

Timeout

If the request to the backend times out.

RequestException

For other request-related errors.

Examples:

>>> fields = ["MAV", "\\div(MRGSTD,MAV#)", "\\div(MRGVAR[Q=99],MAV#)"]
>>> risks_df = pivot_view.get_risks(fields)