fuggers_py.portfolio

Portfolio construction, aggregation, attribution, and analytics outputs.

.. py:module:: fuggers_py.portfolio

Fixed-income portfolio analytics and typed public result surfaces.

The package exposes the main portfolio container, typed holdings and classification helpers, and the analytics surfaces for risk, spreads, yield, liquidity, ETF, benchmark, contribution, bucketing, stress, and quote-output aggregation workflows. Values are expressed using the library’s fixed-income conventions: prices are typically percent-of-par, spreads and rates are raw decimals unless a *_bps or *_pct field states otherwise, and portfolio analytics are settled on the valuation date passed to each helper.

.. py:function:: aggregate_key_rate_profile(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio key-rate DV01 profile.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.KeyRateProfile``

.. py:class:: AggregatedAttribution(assumptions, income_return, rate_return, spread_return, total_return, benchmark_income_return=None, benchmark_rate_return=None, benchmark_spread_return=None, benchmark_total_return=None, active_income_return=None, active_rate_return=None, active_spread_return=None, active_total_return=None, duration_by_sector=None, spread_by_sector=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.AggregatedAttribution

Aggregated income, rate, and spread attribution outputs.

.. py:method:: AggregatedAttribution.from_portfolios(portfolio, *, curve, settlement_date, assumptions=None, benchmark=None) :module: fuggers_py.portfolio :classmethod:

  Build aggregated attribution from one or two portfolios.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.contribution.types.AggregatedAttribution\``

.. py:class:: ActiveWeight(name, portfolio_weight, benchmark_weight, active_weight) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.ActiveWeight

Active weight for a single holding or bucket.

.. py:property:: ActiveWeight.value :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active weight.

.. py:method:: ActiveWeight.as_dict() :module: fuggers_py.portfolio

  Return a mapping-style representation.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`dict\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\` \| \:py\:class\:\`str\`\]`

.. py:class:: ActiveWeights(entries, dimension=’holding’) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.ActiveWeights

Collection of active weights keyed by name.

.. py:method:: ActiveWeights.keys() :module: fuggers_py.portfolio

  Return the active-weight names.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: ActiveWeights.values() :module: fuggers_py.portfolio

  Return the active-weight values.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~decimal.Decimal\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: ActiveWeights.items() :module: fuggers_py.portfolio

  Return ``(name, active_weight)`` pairs.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\`\]\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: ActiveWeights.get(key, default=None) :module: fuggers_py.portfolio

  Return the active weight for ``key`` or ``default``.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\` \| \:py\:obj\:\`None\``

.. py:method:: ActiveWeights.by_name(name) :module: fuggers_py.portfolio

  Return the matching entry if present.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.ActiveWeight\` \| \:py\:obj\:\`None\``

.. py:property:: ActiveWeights.portfolio_weights :module: fuggers_py.portfolio :type: dict[str, ~decimal.Decimal]

  Return portfolio weights by name.

.. py:property:: ActiveWeights.benchmark_weights :module: fuggers_py.portfolio :type: dict[str, ~decimal.Decimal]

  Return benchmark weights by name.

.. py:property:: ActiveWeights.net_active_weight :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the signed sum of active weights.

.. py:method:: ActiveWeights.to_dict() :module: fuggers_py.portfolio

  Return a plain dictionary of active weights.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`dict\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\`\]`

.. py:function:: analyze_etf_basket(portfolio) :module: fuggers_py.portfolio

Return a high-level basket analysis for the portfolio.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.basket.BasketAnalysis``

.. py:class:: AnalyticsConfig(settlement_date=None, weighting_method=WeightingMethod.DIRTY_VALUE, key_rate_tenors=(Tenor(length=3, unit=<TenorUnit.MONTHS: ‘M’>), Tenor(length=6, unit=<TenorUnit.MONTHS: ‘M’>), Tenor(length=1, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=2, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=3, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=5, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=7, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=10, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=20, unit=<TenorUnit.YEARS: ‘Y’>), Tenor(length=30, unit=<TenorUnit.YEARS: ‘Y’>)), default_currency=Currency.<bound method Currency.name of <Currency.USD: ‘USD’>>) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.config.AnalyticsConfig

Configuration for portfolio analytics aggregation.

The config controls the settlement date used for accrued interest, the weighting basis used for portfolio averages, and the key-rate tenors used when building tenor profiles.

.. py:function:: approximate_sec_yield(net_investment_income, net_assets) :module: fuggers_py.portfolio

Return the historical SEC-yield approximation as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: arbitrage_opportunity(portfolio, *, curve, settlement_date, shares_outstanding, market_price, liabilities=Decimal(‘0’), transaction_cost_bps=Decimal(‘0’)) :module: fuggers_py.portfolio

Evaluate ETF creation or redemption arbitrage against NAV.

The result compares market price to NAV after estimated transaction costs and flags whether create or redeem is the better direction.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.nav.PremiumDiscountPoint``

.. py:class:: AttributionInput(income_horizon_years=Decimal(‘1’), rate_change_bps=Decimal(‘0’), spread_change_bps=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.AttributionInput

Assumptions used to scale attribution return estimates.

.. py:method:: AttributionInput.aggregate(portfolio, *, curve, settlement_date, benchmark=None) :module: fuggers_py.portfolio

  Aggregate attribution using these assumptions.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.contribution.types.AggregatedAttribution\``

.. py:class:: BasketAnalysis(num_positions, sector_counts, total_quantity) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.basket.BasketAnalysis

High-level ETF basket summary.

.. py:property:: BasketAnalysis.security_count :module: fuggers_py.portfolio :type: int

  Return the number of securities in the basket.

.. py:class:: BasketComponent(name, quantity, clean_price, dirty_price, market_value, dirty_value, accrued_interest, weight, sector=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.basket.BasketComponent

One component in a creation basket.

.. py:class:: BasketFlowSummary(component_count, total_quantity, securities_market_value, securities_dirty_value, accrued_interest, cash_component, liabilities_component, total_basket_value, shares_outstanding, creation_unit_shares) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.basket.BasketFlowSummary

Creation-basket cash-flow summary in currency units.

.. py:property:: BasketFlowSummary.basket_per_share :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the basket value per ETF share.

.. py:class:: BenchmarkComparison(risk, duration, yields, spread, active_weights, sector, rating) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.BenchmarkComparison

Complete portfolio-versus-benchmark comparison output.

.. py:property:: BenchmarkComparison.active_dirty_pv :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active dirty PV.

.. py:property:: BenchmarkComparison.active_duration :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active duration.

.. py:property:: BenchmarkComparison.active_dv01 :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active DV01.

.. py:property:: BenchmarkComparison.active_current_yield :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active current yield.

.. py:property:: BenchmarkComparison.active_z_spread :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active Z-spread.

.. py:property:: BenchmarkComparison.active_ytm :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active YTM.

.. py:property:: BenchmarkComparison.active_ytw :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active YTW.

.. py:property:: BenchmarkComparison.active_oas :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active OAS.

.. py:property:: BenchmarkComparison.sector_active_weights :module: fuggers_py.portfolio :type: ~fuggers_py.portfolio.benchmark.comparison.ActiveWeights

  Return the sector active weights.

.. py:property:: BenchmarkComparison.rating_active_weights :module: fuggers_py.portfolio :type: ~fuggers_py.portfolio.benchmark.comparison.ActiveWeights

  Return the rating active weights.

.. py:attribute:: BenchmarkMetrics :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.benchmark.comparison.BenchmarkComparison

.. py:function:: best_case(results) :module: fuggers_py.portfolio

Return the best-case stress result, if any.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult` | :py:obj:`None``

.. py:class:: BucketContribution(name, portfolio_value, benchmark_value, active_value, portfolio_weight=Decimal(‘0’), benchmark_weight=Decimal(‘0’), active_weight=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.BucketContribution

Portfolio-versus-benchmark contribution for a bucket.

.. py:property:: BucketContribution.value :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the active value.

.. py:attribute:: BucketMetrics :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.types.BucketResult

.. py:class:: BucketResult(label, clean_pv, dirty_pv, dv01, weight=Decimal(‘0’), market_value=Decimal(‘0’), average_ytm=None, average_duration=None, average_spread=None, holding_count=0) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.BucketResult

Aggregate metrics for a single portfolio bucket.

.. attribute:: label

  Bucket name.

.. attribute:: clean_pv, dirty_pv

  Aggregated clean and dirty present values in currency units.

.. attribute:: dv01

  Bucket DV01 in currency units per 1 bp.

.. attribute:: weight

  Bucket weight relative to the portfolio total, as a raw decimal.

.. attribute:: market_value

  Clean market value proxy used by the bucketing helpers.

.. attribute:: average_ytm, average_duration, average_spread

  Dirty-value-weighted averages, or ``None`` when no metric is available.

.. attribute:: holding_count

  Number of holdings assigned to the bucket.

.. py:class:: Bucketing(portfolio) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.bucketing.Bucketing

Convenience wrapper for portfolio bucketing helpers.

.. py:method:: Bucketing.bucket_dv01(curve, settlement_date, buckets=((‘0-2Y’, 0.0, 2.0), (‘2-5Y’, 2.0, 5.0), (‘5-10Y’, 5.0, 10.0), (‘10Y+’, 10.0, None))) :module: fuggers_py.portfolio

  Return maturity buckets with PV-weighted averages.

  Each bucket is keyed by the supplied maturity definition and includes
  clean PV, dirty PV, DV01, and dirty-value-weighted averages.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`list\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.types.BucketResult\`\]`

.. py:function:: bucket_by_classifier(portfolio, classifier_name) :module: fuggers_py.portfolio

Bucket holdings by a named classifier or custom field.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.ClassifierDistribution``

.. py:function:: bucket_by_country(portfolio) :module: fuggers_py.portfolio

Bucket holdings by country.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`list`\ \[:py:class:`~fuggers_py.portfolio.types.holding.Holding`]]`

.. py:function:: bucket_by_currency(portfolio) :module: fuggers_py.portfolio

Bucket holdings by currency.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`list`\ \[:py:class:`~fuggers_py.portfolio.types.holding.Holding`]]`

.. py:function:: bucket_by_custom_field(portfolio, field_name) :module: fuggers_py.portfolio

Bucket holdings by a custom field name.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.CustomDistribution``

.. py:function:: bucket_by_issuer(portfolio) :module: fuggers_py.portfolio

Bucket holdings by issuer.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`list`\ \[:py:class:`~fuggers_py.portfolio.types.holding.Holding`]]`

.. py:function:: bucket_by_maturity(portfolio, *, settlement_date, buckets=((‘0-2Y’, 0.0, 2.0), (‘2-5Y’, 2.0, 5.0), (‘5-10Y’, 5.0, 10.0), (‘10Y+’, 10.0, None))) :module: fuggers_py.portfolio

Bucket holdings by time to maturity in years.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.MaturityDistribution``

.. py:function:: bucket_by_rating(portfolio) :module: fuggers_py.portfolio

Bucket holdings by credit rating.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.RatingDistribution``

.. py:function:: bucket_by_region(portfolio) :module: fuggers_py.portfolio

Bucket holdings by region.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\dict`\ \[:py:class:`str`, :py:class:`list`\ \[:py:class:`~fuggers_py.portfolio.types.holding.Holding`]]`

.. py:function:: bucket_by_sector(portfolio) :module: fuggers_py.portfolio

Bucket holdings by sector.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.SectorDistribution``

.. py:function:: calculate_attribution(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Compatibility alias for :func:attribution_summary.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.PortfolioAttribution``

.. py:function:: calculate_credit_metrics(portfolio) :module: fuggers_py.portfolio

Compatibility alias for :func:calculate_credit_quality.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.CreditQualityMetrics``

.. py:function:: calculate_credit_quality(portfolio) :module: fuggers_py.portfolio

Return portfolio credit-quality metrics with typed risk fields.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.CreditQualityMetrics``

.. py:function:: calculate_distribution_yield(annual_distribution, market_price) :module: fuggers_py.portfolio

Return distribution yield as decimal, percent, and basis points.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.DistributionYield``

.. py:function:: calculate_etf_nav(portfolio, *, curve, settlement_date, shares_outstanding=Decimal(‘1’), liabilities=Decimal(‘0’)) :module: fuggers_py.portfolio

Return ETF NAV per share.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: calculate_etf_nav_metrics(portfolio, *, curve, settlement_date, shares_outstanding=Decimal(‘1’), liabilities=Decimal(‘0’), market_price=None) :module: fuggers_py.portfolio

Return the full ETF NAV and per-share risk summary.

The output includes total NAV, NAV per share, indicative NAV, per-share DV01 and CS01, and optional premium/discount data when a market price is supplied.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.nav.EtfNavMetrics``

.. py:function:: calculate_inav(portfolio, *, curve, settlement_date, shares_outstanding=Decimal(‘1’)) :module: fuggers_py.portfolio

Return ETF indicative NAV per share.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: calculate_liquidity_metrics(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the standard liquidity metrics.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.liquidity.LiquidityMetrics``

.. py:function:: calculate_migration_risk(portfolio) :module: fuggers_py.portfolio

Return the BBB and BB crossover risk for the portfolio.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.MigrationRisk``

.. py:function:: calculate_nav_breakdown(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio NAV split into clean, dirty, and cash components.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.NavBreakdown``

.. py:function:: calculate_portfolio_analytics(portfolio, *, curve, settlement_date, config=None) :module: fuggers_py.portfolio

Return the full portfolio analytics summary.

The returned object includes the portfolio-level metrics computed by :class:~fuggers_py.portfolio.analytics.base.PortfolioAnalytics.

.. py:function:: calculate_risk_metrics(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the standard portfolio rate-risk metrics.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.RiskMetrics``

.. py:function:: calculate_sec_yield(input_data, net_assets=None) :module: fuggers_py.portfolio

Return either standardized SEC yield or the legacy approximation.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.sec.SecYield` | :py:class:`~decimal.Decimal``

.. py:function:: calculate_spread_metrics(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the standard portfolio spread metrics.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.SpreadMetrics``

.. py:function:: calculate_yield_metrics(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the standard portfolio yield metrics.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.risk.YieldMetrics``

.. py:class:: CashPosition(amount, currency, label=’cash’, fx_rate=Decimal(‘1’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.cash.CashPosition

A cash holding denominated in a portfolio currency.

The amount is treated as the position’s market value. The optional FX rate is only used when translating the cash amount into the portfolio’s base currency.

.. py:method:: CashPosition.market_value() :module: fuggers_py.portfolio

  Return the cash amount as market value.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:property:: CashPosition.base_currency_value :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the cash amount translated by ``fx_rate``.

.. py:class:: Classification(sector=None, rating=None, seniority=None, country=None, currency=None, issuer=None, region=None, custom_fields=) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.classification.Classification

Optional cross-sectional classification data for a holding.

The fields are used for bucketing, active-weight analysis, and custom portfolio aggregation. A field may be left unset when the information is not available at holding creation time.

.. py:class:: ClassifierDistribution(classifier_name, entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.ClassifierDistribution

Distribution keyed by a named classification dimension.

.. py:function:: compare_portfolios(portfolio, benchmark, curve, settlement_date) :module: fuggers_py.portfolio

Compare a portfolio with a benchmark on risk, yield, and spread.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.benchmark.comparison.BenchmarkComparison``

.. py:class:: ComplianceCheck(name, passed, value, limit, description, severity) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.ComplianceCheck

Single ETF compliance check result.

.. py:class:: ComplianceSeverity(value) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.ComplianceSeverity

Severity of an ETF compliance check.

.. py:class:: Contribution(portfolio) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.Contribution

Convenience wrapper for portfolio contribution helpers.

.. py:method:: Contribution.by_position(curve, settlement_date) :module: fuggers_py.portfolio

  Return holding-level attribution for the portfolio.

.. py:method:: Contribution.aggregate(curve, settlement_date, *, assumptions=None) :module: fuggers_py.portfolio

  Return aggregated contribution and return decomposition.

.. py:class:: CreationBasket(components, flow_summary) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.basket.CreationBasket

Ordered ETF creation basket and its flow summary.

.. py:method:: CreationBasket.by_name(name) :module: fuggers_py.portfolio

  Return the basket component with ``name`` if present.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.etf.basket.BasketComponent\` \| \:py\:obj\:\`None\``

.. py:property:: CreationBasket.component_count :module: fuggers_py.portfolio :type: int

  Return the number of basket components.

.. py:property:: CreationBasket.basket_per_share :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the basket value per ETF share.

.. py:attribute:: CreditMetrics :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.risk.CreditQualityMetrics

.. py:class:: CreditQualityMetrics(distribution, sector_distribution, average_score, average_rating, investment_grade_weight, high_yield_weight, default_weight, unrated_weight, bbb_weight, bb_weight, crossover_weight, quality_tiers, migration_risk) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.CreditQualityMetrics

Portfolio credit-quality distribution and migration risk.

.. py:class:: CreditRating(value) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.rating.CreditRating

Issuer credit rating buckets.

.. py:method:: CreditRating.score() :module: fuggers_py.portfolio

  Return an ordinal score where lower numbers indicate stronger credit.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`int\``

.. py:class:: Cs01Contributions(entries, total=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.Cs01Contributions

Holding CS01 contributions.

.. py:function:: cs01_contributions(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Compatibility alias for :func:spread_contributions.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.Cs01Contributions``

.. py:function:: cs01_per_share(portfolio, *, curve, settlement_date, shares_outstanding=Decimal(‘1’)) :module: fuggers_py.portfolio

Return ETF CS01 per share in currency units per 1 bp.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:class:: CustomDistribution(field_name, entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.CustomDistribution

Distribution keyed by a user-defined field name.

.. py:class:: DaysToLiquidate(days, liquidity_score, liquidation_fraction=Decimal(‘1’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.liquidity.DaysToLiquidate

Estimated days to liquidate at a given liquidation fraction.

.. py:class:: DistributionYield(distribution_yield, annual_distribution, market_price, distribution_yield_pct, distribution_yield_bps) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.DistributionYield

Distribution yield expressed as raw decimal, percent, and bps.

.. py:property:: DistributionYield.yield_pct :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the distribution yield in percentage points.

.. py:method:: DistributionYield.as_decimal() :module: fuggers_py.portfolio

  Return the raw decimal distribution yield.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:function:: duration_contributions(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return duration contributions weighted by dirty PV.

Each holding contribution is its duration multiplied by its dirty-value weight in the portfolio.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.DurationContributions``

.. py:function:: duration_difference_by_sector(portfolio, benchmark, *, curve, settlement_date) :module: fuggers_py.portfolio

Return sector-level duration differences versus benchmark.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.SectorAttribution``

.. py:class:: DurationComparison(portfolio_duration, benchmark_duration, active_duration) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.DurationComparison

Portfolio, benchmark, and active duration values.

.. py:class:: DurationContributions(entries, total=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.DurationContributions

Holding duration contributions.

.. py:function:: dv01_contributions(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return holding DV01 contributions.

The contribution amount is the holding-level DV01 returned by the analytics layer.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.Dv01Contributions``

.. py:function:: dv01_per_share(portfolio, *, curve, settlement_date, shares_outstanding=Decimal(‘1’)) :module: fuggers_py.portfolio

Return ETF DV01 per share in currency units per 1 bp.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:class:: Dv01Contributions(entries, total=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.Dv01Contributions

Holding DV01 contributions.

.. py:class:: EtfPricer() :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.pricing.EtfPricer

Aggregate bond quote outputs into ETF-style analytics.

.. py:method:: EtfPricer.price(etf_id, holdings, quote_outputs, *, shares_outstanding) :module: fuggers_py.portfolio

  Aggregate holding-level outputs into an ETF analytics record.

  The pricer sums value-weighted risk outputs across holdings and returns
  an ETF-style analytics record with NAV, per-share metrics, and
  aggregation counts.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.calc.output.EtfAnalyticsOutput\``

.. py:function:: estimate_days_to_liquidate(portfolio, *, curve, settlement_date, liquidation_fraction=Decimal(‘1’)) :module: fuggers_py.portfolio

Estimate days to liquidate for the portfolio.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.liquidity.DaysToLiquidate``

.. py:function:: estimate_income_returns(portfolio, *, curve, settlement_date, horizon_years=None, assumptions=None) :module: fuggers_py.portfolio

Estimate income return over the provided horizon as a raw decimal.

The estimate is the portfolio current yield multiplied by the horizon in years.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: estimate_rate_returns(portfolio, *, curve, settlement_date, rate_change_bps=None, assumptions=None) :module: fuggers_py.portfolio

Estimate rate return from a parallel move in raw decimal terms.

The result is a first-order estimate based on portfolio DV01 and the requested rate shock.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: estimate_spread_returns(portfolio, *, curve, settlement_date, spread_change_bps=None, assumptions=None) :module: fuggers_py.portfolio

Estimate spread return from a spread move in raw decimal terms.

The result is a first-order estimate based on portfolio CS01 and the requested spread shock.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: estimate_tracking_error(benchmark, curve, settlement_date) :module: fuggers_py.portfolio

Estimate tracking error from active risk and holding dispersion.

The result combines active duration, active spread, and a simple dispersion term derived from active weights.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.benchmark.tracking.TrackingErrorEstimate``

.. py:function:: estimate_yield_from_holdings(portfolio, *, curve, settlement_date, gross_expense_ratio=Decimal(‘0’), fee_waiver_ratio=Decimal(‘0’)) :module: fuggers_py.portfolio

Estimate gross and net yield after expenses from holdings.

The gross yield is based on the portfolio YTM, then adjusted by the input expense and fee-waiver ratios to produce a net-yield estimate.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.sec.ExpenseMetrics``

.. py:class:: EtfComplianceReport(weights_sum_to_one, issuer_limit_ok, checks) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.EtfComplianceReport

Summary of ETF compliance checks.

.. py:property:: EtfComplianceReport.passed :module: fuggers_py.portfolio :type: bool

  Return ``True`` when all checks pass.

.. py:method:: EtfComplianceReport.by_name(name) :module: fuggers_py.portfolio

  Return the named compliance check if present.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.etf.sec.ComplianceCheck\` \| \:py\:obj\:\`None\``

.. py:class:: EtfNavMetrics(total_nav, shares_outstanding, nav_per_share, dv01_per_share, cs01_per_share, securities_value, cash_value, accrued_interest, liabilities, inav=None, market_price=None, premium_discount=None, premium_discount_dollars=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.nav.EtfNavMetrics

ETF NAV, iNAV, and per-share risk metrics.

.. py:property:: EtfNavMetrics.premium_discount_pct :module: fuggers_py.portfolio :type: ~decimal.Decimal | None

  Return the premium or discount in percent.

.. py:property:: EtfNavMetrics.premium_discount_bps :module: fuggers_py.portfolio :type: ~decimal.Decimal | None

  Return the premium or discount in basis points.

.. py:method:: EtfNavMetrics.is_premium() :module: fuggers_py.portfolio

  Return ``True`` when a premium/discount value is available and positive.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`bool\``

.. py:method:: EtfNavMetrics.is_discount() :module: fuggers_py.portfolio

  Return ``True`` when a premium/discount value is available and negative.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`bool\``

.. py:method:: EtfNavMetrics.abs_premium_discount() :module: fuggers_py.portfolio

  Return the absolute premium or discount in percent.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\` \| \:py\:obj\:\`None\``

.. py:function:: etf_compliance_checks(*, holdings_weight_sum, max_issuer_weight=None) :module: fuggers_py.portfolio

Evaluate a small set of ETF compliance checks.

The checks are intentionally simple: holdings weights should sum to one, and the issuer limit must stay within the provided bound when supplied.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.sec.EtfComplianceReport``

.. py:class:: ExpenseMetrics(gross_yield, net_yield, gross_expense_ratio, net_expense_ratio, fee_waiver_ratio, annual_income_estimate, annual_expense_amount, net_assets) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.ExpenseMetrics

Yield and expense metrics estimated from holdings.

.. py:property:: ExpenseMetrics.expense_drag :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the yield drag from expenses.

.. py:property:: ExpenseMetrics.yield_before_expenses :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the gross yield.

.. py:property:: ExpenseMetrics.yield_after_expenses :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the net yield.

.. py:class:: FallenAngelRisk(bbb_weight, market_value_at_risk, holdings_count) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.FallenAngelRisk

Weight and market value at risk from BBB holdings.

.. py:property:: FallenAngelRisk.weight :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the BBB weight.

.. py:class:: Holding(instrument, quantity=Decimal(‘1’), clean_price=None, market_value=None, accrued_interest=None, analytics=None, label=None, id=None, classification=None, rating_info=None, sector_info=None, seniority_info=None, liquidity_score=None, custom_fields=, fx_rate=Decimal(‘1’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.holding.Holding

A bond holding with optional valuation and classification metadata.

The holding stores the instrument, position size, optional pricing inputs, and optional classification metadata used for portfolio aggregation. When a clean price is present, market value is derived from the price and quantity unless an explicit market value is provided.

.. py:property:: Holding.par_amount :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the par amount carried by the holding.

.. py:property:: Holding.market_price :module: fuggers_py.portfolio :type: ~decimal.Decimal | None

  Return the clean market price as a percent-of-par value.

.. py:property:: Holding.currency :module: fuggers_py.portfolio :type: ~fuggers_py.core.types.Currency

  Return the holding currency, preferring explicit classification.

.. py:method:: Holding.name() :module: fuggers_py.portfolio

  Return a stable display name for the holding.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`str\``

.. py:property:: Holding.market_value_amount :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the clean market value in currency units.

  If an explicit market value is present it is used directly; otherwise
  the clean price is multiplied by the par amount.

.. py:property:: Holding.dirty_market_value :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the dirty market value in currency units.

  Accrued interest is added on a par-amount basis so the result is a
  dirty value consistent with dirty-PV aggregation.

.. py:property:: Holding.base_currency_value :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the clean market value translated by ``fx_rate``.

.. py:method:: Holding.weight_in_portfolio(total_market_value) :module: fuggers_py.portfolio

  Return the clean-value weight of the holding within a portfolio.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:class:: HoldingAnalytics(name, market_value, dirty_value, clean_value, accrued_value, duration, convexity, dv01, ytm=None, ytw=None, ytc=None, current_yield=None, best_yield=None, z_spread=None, oas=None, g_spread=None, i_spread=None, asw=None, best_spread=None, spread_duration=None, cs01=None, modified_duration=None, effective_duration=None, macaulay_duration=None, effective_convexity=None, key_rate_profile=, liquidity_score=None, weighted_average_life=None, coupon=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.holding.HoldingAnalytics

Per-holding analytics expressed in currency and raw-decimal units.

The currency fields are value terms for the individual holding. Yield, spread, duration, convexity, and key-rate fields use the library’s raw decimal convention unless the field name explicitly says otherwise.

.. py:class:: HoldingAttribution(name, pv_pct, dv01_pct, duration_contribution) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.HoldingAttribution

Holding-level PV and DV01 attribution.

.. py:method:: HoldingAttribution.as_dict() :module: fuggers_py.portfolio

  Return a mapping-style representation.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`dict\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\` \| \:py\:class\:\`str\`\]`

.. py:class:: HoldingBuilder(instrument=None, quantity=Decimal(‘1’), clean_price=None, market_value=None, accrued_interest=None, analytics=None, label=None, id=None, classification=None, rating_info=None, sector_info=None, seniority_info=None, liquidity_score=None, custom_fields=, fx_rate=Decimal(‘1’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.holding.HoldingBuilder

Mutable builder for :class:Holding instances.

.. py:method:: HoldingBuilder.with_instrument(instrument) :module: fuggers_py.portfolio

  Set the underlying instrument.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_quantity(quantity) :module: fuggers_py.portfolio

  Set the par amount or share quantity.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_par_amount(par_amount) :module: fuggers_py.portfolio

  Compatibility alias for :meth:`with_quantity`.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_clean_price(clean_price) :module: fuggers_py.portfolio

  Set the clean price as a percent-of-par value.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_market_price(market_price) :module: fuggers_py.portfolio

  Compatibility alias for :meth:`with_clean_price`.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_market_value(market_value) :module: fuggers_py.portfolio

  Set the clean market value in currency units.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_accrued_interest(accrued_interest) :module: fuggers_py.portfolio

  Set accrued interest in currency units.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_analytics(analytics) :module: fuggers_py.portfolio

  Attach precomputed analytics.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_label(label) :module: fuggers_py.portfolio

  Set the display label.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_id(value) :module: fuggers_py.portfolio

  Set the stable identifier used as a fallback name.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_classification(classification) :module: fuggers_py.portfolio

  Attach classification metadata.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_rating_info(rating_info) :module: fuggers_py.portfolio

  Attach rating metadata.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_sector_info(sector_info) :module: fuggers_py.portfolio

  Attach sector metadata.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_seniority_info(seniority_info) :module: fuggers_py.portfolio

  Attach seniority metadata.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_liquidity_score(liquidity_score) :module: fuggers_py.portfolio

  Set the liquidity score as a raw decimal.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.with_fx_rate(fx_rate) :module: fuggers_py.portfolio

  Set the base-currency FX conversion rate.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.HoldingBuilder\``

.. py:method:: HoldingBuilder.build() :module: fuggers_py.portfolio

  Create the immutable holding.

  :raises ValueError: If no instrument has been set.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.Holding\``

.. py:class:: HoldingContribution(name, amount, metric, value_key, weight=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.HoldingContribution

Contribution for a single holding.

.. py:property:: HoldingContribution.contribution :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the raw contribution amount.

.. py:property:: HoldingContribution.duration_contribution :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the duration contribution when this metric is duration.

.. py:property:: HoldingContribution.dv01_contribution :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the DV01 contribution when this metric is DV01.

.. py:property:: HoldingContribution.spread_contribution :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the spread contribution when this metric is CS01.

.. py:property:: HoldingContribution.cs01_contribution :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the CS01 contribution alias.

.. py:method:: HoldingContribution.as_dict() :module: fuggers_py.portfolio

  Return a mapping-style representation.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`dict\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\` \| \:py\:class\:\`str\`\]`

.. py:class:: KeyRateProfile(entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.KeyRateProfile

Key-rate DV01 profile keyed by tenor string.

.. py:property:: KeyRateProfile.total_dv01 :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the sum of all tenor contributions.

.. py:method:: KeyRateProfile.by_tenor(tenor) :module: fuggers_py.portfolio

  Return the contribution for ``tenor`` if present.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\` \| \:py\:obj\:\`None\``

.. py:function:: key_rate_shift_impact(portfolio, *, curve, settlement_date, tenor_shocks_bps) :module: fuggers_py.portfolio

Return the dirty-PV change for tenor-specific key-rate shocks.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: key_rate_shift_result(portfolio, *, curve, settlement_date, tenor_shocks_bps, scenario_name=None) :module: fuggers_py.portfolio

Return a typed result for a key-rate shift scenario.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult``

.. py:class:: KeyRateShiftScenario(name, tenor_shocks_bps) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.KeyRateShiftScenario

Collection of tenor-specific basis-point shocks.

.. py:property:: KeyRateShiftScenario.tenor_shifts :module: fuggers_py.portfolio :type: tuple[~fuggers_py.portfolio.stress.scenarios.TenorShift, …]

  Return the tenor shocks as typed objects.

.. py:method:: KeyRateShiftScenario.from_tenor_shifts(name, shifts) :module: fuggers_py.portfolio :classmethod:

  Build a scenario from typed tenor shifts.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.stress.scenarios.KeyRateShiftScenario\``

.. py:function:: liquidity_distribution(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the liquidity bucket distribution.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.liquidity.LiquidityDistribution``

.. py:class:: LiquidityBucket(label, min_score, max_score, weight, dirty_pv, holding_count) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.liquidity.LiquidityBucket

A liquidity-score bucket with dirty-PV weight.

.. py:class:: LiquidityDistribution(entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.liquidity.LiquidityDistribution

Ordered liquidity buckets keyed by label.

.. py:method:: LiquidityDistribution.keys() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: LiquidityDistribution.values() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.liquidity.LiquidityBucket\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: LiquidityDistribution.items() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~fuggers\_py.portfolio.liquidity.LiquidityBucket\`\]\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:property:: LiquidityDistribution.total_weight :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the sum of bucket weights.

.. py:property:: LiquidityDistribution.total_dirty_pv :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the sum of bucket dirty PV.

.. py:class:: LiquidityMetrics(liquidity_score, bid_ask_spread, days_to_liquidate, distribution) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.liquidity.LiquidityMetrics

Portfolio liquidity summary and bucket distribution.

.. py:class:: MaturityBucket(label, start_years, end_years) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.maturity.MaturityBucket

A half-open maturity bucket measured in years.

.. py:method:: MaturityBucket.contains(years_to_maturity) :module: fuggers_py.portfolio

  Return ``True`` when ``years_to_maturity`` falls inside the bucket.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`bool\``

.. py:class:: MaturityDistribution(entries, bucket_definition) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.MaturityDistribution

Distribution keyed by maturity bucket labels.

.. py:class:: MigrationRisk(fallen_angel_risk, rising_star_risk, fallen_angel, rising_star) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.MigrationRisk

Combined fallen-angel and rising-star migration risk.

.. py:property:: MigrationRisk.crossover_weight :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the combined BBB and BB crossover weight.

.. py:class:: NavBreakdown(clean_pv, dirty_pv, accrued, market_value, dirty_market_value, cash_value) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.NavBreakdown

Portfolio NAV components in currency units.

.. py:function:: parallel_shift_impact(portfolio, *, curve, settlement_date, bump_bps, scenario_name=None) :module: fuggers_py.portfolio

Compatibility alias for :func:rate_shock_impact.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult``

.. py:function:: partial_dv01s(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Compatibility alias for :func:aggregate_key_rate_profile.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.results.KeyRateProfile``

.. py:class:: Portfolio(positions, currency) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.portfolio.Portfolio

A currency-denominated collection of positions and cash.

.. attribute:: positions

  The portfolio holdings, stored in input order.

.. attribute:: currency

  Base reporting currency for portfolio-level analytics.

.. py:method:: Portfolio.new(positions, currency) :module: fuggers_py.portfolio :classmethod:

  Build a portfolio from a mutable position list.

  The input list is converted to an immutable tuple so later analytics
  see a stable position order.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.Portfolio\``

.. py:method:: Portfolio.total_quantity() :module: fuggers_py.portfolio

  Return the sum of quantity-bearing position quantities.

  Cash positions are ignored because they do not carry a par quantity.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:method:: Portfolio.holdings() :module: fuggers_py.portfolio

  Return the raw holdings tuple, including cash positions.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.Holding\` \| \:py\:class\:\`\~fuggers\_py.portfolio.types.cash.CashPosition\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: Portfolio.investable_holdings() :module: fuggers_py.portfolio

  Return the bond holdings, excluding cash positions.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.types.holding.Holding\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: Portfolio.cash_positions() :module: fuggers_py.portfolio

  Return the cash positions in the portfolio.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.types.cash.CashPosition\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: Portfolio.total_market_value() :module: fuggers_py.portfolio

  Return total market value in the portfolio's base currency units.

  Bond holdings contribute clean market value while cash contributes its
  face amount. The result is therefore a clean, portfolio-level value
  proxy rather than a dirty PV.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:class:: PortfolioAnalytics(portfolio) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.analytics.base.PortfolioAnalytics

Evaluate portfolio holdings into typed analytics outputs.

The object is a thin wrapper around the portfolio plus the analytics helpers that derive per-position and portfolio-level metrics.

.. py:method:: PortfolioAnalytics.position_metrics(curve, settlement_date, *, config=None, spread_curve=None, oas_calculator=None) :module: fuggers_py.portfolio

  Return per-position analytics for the portfolio.

  :type curve: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.core.traits.YieldCurve\` \| \:py\:obj\:\`None\``
  :param curve: Valuation curve used for discounting and risk calculations.
  :type settlement_date: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.core.types.Date\``
  :param settlement_date: Settlement or valuation date that anchors accrued interest and
                          year-fraction conventions.
  :type config: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.config.AnalyticsConfig\` \| \:py\:obj\:\`None\``
  :param config: Optional analytics configuration. When omitted, the portfolio
                 currency and settlement date are used to build a default config.
  :type spread_curve: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.core.traits.YieldCurve\` \| \:py\:obj\:\`None\``
  :param spread_curve: Optional curve used for spread calculations when it differs from
                       the valuation curve.
  :type oas_calculator: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.measures.spreads.oas.OASCalculator\` \| \:py\:obj\:\`None\``
  :param oas_calculator: Optional spread calculator override.

  :returns: One analytics record per position in portfolio order.
  :rtype: list[PositionAnalytics]

.. py:method:: PortfolioAnalytics.metrics(curve, settlement_date, *, config=None, spread_curve=None, oas_calculator=None) :module: fuggers_py.portfolio

  Return portfolio-level aggregated analytics.

  The totals and weighted averages are reported in the portfolio's base
  currency and raw-decimal risk units. The weighting basis follows the
  active analytics configuration.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.PortfolioMetrics\``

.. py:class:: PortfolioAnalyzer() :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.analytics.quote_outputs.PortfolioAnalyzer

Aggregate bond quote outputs into portfolio analytics.

.. py:method:: PortfolioAnalyzer.analyze(portfolio_id, positions, quote_outputs, *, reference_data=None) :module: fuggers_py.portfolio

  Aggregate positions into portfolio-level market value and risk.

  Holdings without a quote are skipped. Risk metrics are value weighted
  by dirty value, and the output includes sector and rating breakdowns
  when reference data is supplied.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.calc.output.PortfolioAnalyticsOutput\``

.. py:class:: PortfolioAttribution(entries, total_pv_pct=Decimal(‘0’), total_dv01_pct=Decimal(‘0’), total_duration_contribution=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.PortfolioAttribution

Sequence of holding-level attribution records.

.. py:method:: PortfolioAttribution.by_name(name) :module: fuggers_py.portfolio

  Return the named holding attribution if present.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.contribution.types.HoldingAttribution\` \| \:py\:obj\:\`None\``

.. py:class:: PortfolioBenchmark(portfolio, benchmark) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.PortfolioBenchmark

Pair a portfolio with its benchmark for repeated comparisons.

.. py:method:: PortfolioBenchmark.compare(curve, settlement_date) :module: fuggers_py.portfolio

  Return the portfolio-versus-benchmark comparison.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.BenchmarkComparison\``

.. py:method:: PortfolioBenchmark.active_weights(curve, settlement_date) :module: fuggers_py.portfolio

  Return active holding weights.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.ActiveWeights\``

.. py:method:: PortfolioBenchmark.active_weights_by_holding(curve, settlement_date) :module: fuggers_py.portfolio

  Return active holding weights with holding dimension metadata.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.ActiveWeights\``

.. py:method:: PortfolioBenchmark.active_weights_by_sector(curve, settlement_date) :module: fuggers_py.portfolio

  Return active sector weights.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.ActiveWeights\``

.. py:method:: PortfolioBenchmark.active_weights_by_rating(curve, settlement_date) :module: fuggers_py.portfolio

  Return active rating weights.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.benchmark.comparison.ActiveWeights\``

.. py:method:: PortfolioBenchmark.aggregated_attribution(curve, settlement_date, *, assumptions=None) :module: fuggers_py.portfolio

  Return aggregated attribution for the paired portfolio and benchmark.

.. py:method:: PortfolioBenchmark.duration_difference_by_sector(curve, settlement_date) :module: fuggers_py.portfolio

  Return sector duration differences.

.. py:method:: PortfolioBenchmark.spread_difference_by_sector(curve, settlement_date) :module: fuggers_py.portfolio

  Return sector spread differences.

.. py:method:: PortfolioBenchmark.overweight_underweight_counts(curve, settlement_date) :module: fuggers_py.portfolio

  Return overweight and underweight active-weight counts.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`dict\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`int\`\]`

.. py:method:: PortfolioBenchmark.largest_active_positions(curve, settlement_date, *, limit=5) :module: fuggers_py.portfolio

  Return the largest active positions by absolute active weight.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`list\`\\ \\\[\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~decimal.Decimal\`\]\]`

.. py:method:: PortfolioBenchmark.tracking_error_estimate(curve, settlement_date) :module: fuggers_py.portfolio

  Return the heuristic tracking error estimate.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:class:: PortfolioBuilder(currency=None, _positions=) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.portfolio.PortfolioBuilder

Incrementally assemble a :class:Portfolio.

.. py:method:: PortfolioBuilder.with_currency(currency) :module: fuggers_py.portfolio

  Set the portfolio reporting currency.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.PortfolioBuilder\``

.. py:method:: PortfolioBuilder.add_position(position) :module: fuggers_py.portfolio

  Append a position and infer currency from it if needed.

  If the builder does not yet have a currency, it adopts the position's
  currency on the first appended item.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.PortfolioBuilder\``

.. py:method:: PortfolioBuilder.add_holding(holding) :module: fuggers_py.portfolio

  Compatibility alias for :meth:`add_position`.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.PortfolioBuilder\``

.. py:method:: PortfolioBuilder.add_positions(positions) :module: fuggers_py.portfolio

  Append multiple positions to the builder.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.PortfolioBuilder\``

.. py:method:: PortfolioBuilder.build() :module: fuggers_py.portfolio

  Create the immutable portfolio.

  :raises ValueError: If no currency has been set or inferred.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.portfolio.Portfolio\``

.. py:class:: PortfolioMetrics(clean_pv, dirty_pv, accrued, duration, convexity, dv01, weights, currency, current_yield=Decimal(‘0’), ytm=Decimal(‘0’), ytw=Decimal(‘0’), ytc=Decimal(‘0’), best_yield=Decimal(‘0’), z_spread=Decimal(‘0’), oas=Decimal(‘0’), g_spread=None, i_spread=None, asw=None, best_spread=Decimal(‘0’), spread_duration=Decimal(‘0’), cs01=Decimal(‘0’), liquidity_score=Decimal(‘0’), key_rate_profile=, total_market_value=Decimal(‘0’), total_dirty_market_value=Decimal(‘0’), total_accrued_interest=Decimal(‘0’), cash_value=Decimal(‘0’), holding_count=0, priced_count=0, coverage_count=0, modified_duration=Decimal(‘0’), effective_duration=Decimal(‘0’), macaulay_duration=Decimal(‘0’), effective_convexity=Decimal(‘0’), weighted_average_maturity=Decimal(‘0’), weighted_average_coupon=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.PortfolioMetrics

Portfolio-level weighted metrics and totals.

All spread and rate values are raw decimals unless a name explicitly says bps or pct elsewhere in the API. PV and cash fields are currency amounts, while the weights and bucket shares are raw decimals.

.. py:class:: PortfolioPosition(instrument_id, quantity) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.analytics.quote_outputs.PortfolioPosition

Quantity held in a single instrument.

.. py:attribute:: Position :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.types.holding.Holding

.. py:attribute:: PositionAnalytics :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.types.holding.HoldingAnalytics

.. py:class:: PremiumDiscountPoint(nav_per_share, market_price, shares_outstanding, premium_discount, premium_discount_dollars, estimated_edge_per_share, estimated_edge_bps, direction, is_actionable) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.nav.PremiumDiscountPoint

Premium/discount evaluation point with actionable edge data.

.. py:property:: PremiumDiscountPoint.premium_discount_pct :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the premium or discount in percent.

.. py:property:: PremiumDiscountPoint.premium_discount_bps :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the premium or discount in basis points.

.. py:class:: PremiumDiscountStats(premium_discount, premium_discount_bps, premium_discount_pct) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.nav.PremiumDiscountStats

Portfolio premium or discount relative to NAV.

.. py:property:: PremiumDiscountStats.premium_discount_dollars :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the per-share premium or discount in currency units.

.. py:property:: PremiumDiscountStats.is_premium :module: fuggers_py.portfolio :type: bool

  Return ``True`` when the market price is above NAV.

.. py:property:: PremiumDiscountStats.is_discount :module: fuggers_py.portfolio :type: bool

  Return ``True`` when the market price is below NAV.

.. py:function:: premium_discount(nav, market_price) :module: fuggers_py.portfolio

Compatibility alias for :func:premium_discount_stats.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.nav.PremiumDiscountStats``

.. py:function:: premium_discount_stats(nav, market_price) :module: fuggers_py.portfolio

Return ETF premium or discount statistics.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.etf.nav.PremiumDiscountStats``

.. py:class:: QualityTiers(investment_grade, high_yield, distressed, defaulted, unrated) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.QualityTiers

Normalized credit-quality tier weights.

.. py:attribute:: RateScenario :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.stress.scenarios.RateShockScenario

.. py:function:: rate_shock_impact(portfolio, *, curve, settlement_date, bump_bps, scenario_name=None) :module: fuggers_py.portfolio

Return the dirty-PV change for a parallel rate shock in bps.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult``

.. py:class:: RateShockScenario(name, bump_bps) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.RateShockScenario

Parallel rate shock measured in basis points.

.. py:class:: RatingBucket(label, ratings) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.RatingBucket

A named set of credit ratings used for bucketing.

.. py:class:: RatingComparison(portfolio_weights, benchmark_weights, active_weights) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.RatingComparison

Portfolio, benchmark, and active rating weights.

.. py:class:: RatingDistribution(entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.RatingDistribution

Distribution keyed by credit rating label.

.. py:class:: RatingInfo(rating, agency=None, outlook=None) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.rating.RatingInfo

Rating metadata from an agency or internal source.

.. py:class:: RiskComparison(portfolio_dirty_pv, benchmark_dirty_pv, active_dirty_pv, portfolio_dv01, benchmark_dv01, active_dv01) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.RiskComparison

Portfolio, benchmark, and active dirty PV and DV01 values.

.. py:class:: RiskMetrics(duration, modified_duration, effective_duration, macaulay_duration, best_duration, convexity, effective_convexity, dv01, cs01) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.RiskMetrics

Portfolio rate-risk metrics expressed in raw-decimal units.

.. py:class:: RisingStarRisk(bb_weight, market_value_potential, holdings_count) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.RisingStarRisk

Weight and market value potential from BB holdings.

.. py:property:: RisingStarRisk.weight :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the BB weight.

.. py:function:: run_stress_scenario(portfolio, *, curve, settlement_date, scenario) :module: fuggers_py.portfolio

Run a single stress scenario and return its result.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult``

.. py:function:: run_stress_scenarios(portfolio, *, curve, settlement_date, scenarios) :module: fuggers_py.portfolio

Run a list of stress scenarios and return a summary.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.stress.scenarios.StressSummary``

.. py:class:: Sector(value) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.sector.Sector

High-level issuer sector classification.

.. py:class:: SectorAttribution(entries, metric, portfolio_total, benchmark_total, active_total) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.contribution.types.SectorAttribution

Bucketed attribution results keyed by sector.

.. py:method:: SectorAttribution.keys() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: SectorAttribution.values() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`\~fuggers\_py.portfolio.contribution.types.BucketContribution\`\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:method:: SectorAttribution.items() :module: fuggers_py.portfolio

  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`tuple\`\\ \\\[\:py\:class\:\`str\`\, \:py\:class\:\`\~fuggers\_py.portfolio.contribution.types.BucketContribution\`\]\, \:py\:data\:\`...\<Ellipsis\>\`\]`

.. py:property:: SectorAttribution.total_active :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the total active contribution.

.. py:class:: SectorComparison(portfolio_weights, benchmark_weights, active_weights) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.SectorComparison

Portfolio, benchmark, and active sector weights.

.. py:class:: SectorDistribution(entries) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.results.SectorDistribution

Distribution keyed by sector label.

.. py:class:: SectorInfo(sector, issuer=None, country=None, region=None, subsector=None) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.sector.SectorInfo

Sector metadata attached to a bond or issuer.

.. py:class:: SecYield(sec_30_day_yield, unsubsidized_yield, net_investment_income, average_shares_outstanding, max_offering_price, gross_expenses=None, fee_waivers=None, as_of_date=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.SecYield

Standardized SEC yield output and related inputs.

.. py:method:: SecYield.fee_waiver_impact() :module: fuggers_py.portfolio

  Return the yield impact of fee waivers when available.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\` \| \:py\:obj\:\`None\``

.. py:class:: SecYieldInput(net_investment_income, average_shares_outstanding, max_offering_price, gross_expenses=None, fee_waivers=None, as_of_date=None) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.etf.sec.SecYieldInput

Inputs for the standardized SEC-yield calculation.

.. py:class:: Seniority(value) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.seniority.Seniority

Issuer seniority classification.

.. py:class:: SeniorityInfo(seniority, secured=False) :module: fuggers_py.portfolio :canonical: fuggers_py.reference.bonds.types.seniority.SeniorityInfo

Seniority metadata attached to a bond or issuer.

.. py:class:: SpreadComparison(portfolio_z_spread, benchmark_z_spread, active_z_spread, portfolio_oas, benchmark_oas, active_oas) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.SpreadComparison

Portfolio, benchmark, and active spread metrics.

.. py:function:: spread_contributions(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return holding CS01 contributions.

The contribution amount is the holding-level CS01 returned by the analytics layer.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.Cs01Contributions``

.. py:function:: spread_difference_by_sector(portfolio, benchmark, *, curve, settlement_date) :module: fuggers_py.portfolio

Return sector-level spread differences versus benchmark.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.SectorAttribution``

.. py:function:: spread_shock_impact(portfolio, *, curve, settlement_date, bump_bps) :module: fuggers_py.portfolio

Return the dirty-PV change for a parallel spread shock in bps.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: spread_shock_result(portfolio, *, curve, settlement_date, bump_bps, scenario_name=None) :module: fuggers_py.portfolio

Return a typed result for a parallel spread shock.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult``

.. py:attribute:: SpreadContributions :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.contribution.types.Cs01Contributions

.. py:class:: SpreadMetrics(z_spread, oas, g_spread, i_spread, asw, best_spread, spread_duration, cs01) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.SpreadMetrics

Portfolio spread metrics expressed as raw decimals.

.. py:attribute:: SpreadScenario :module: fuggers_py.portfolio

alias of :py:class:~fuggers_py.portfolio.stress.scenarios.SpreadShockScenario

.. py:class:: SpreadShockScenario(name, bump_bps) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.SpreadShockScenario

Parallel spread shock measured in basis points.

.. py:function:: standard_scenarios() :module: fuggers_py.portfolio

Return the standard set of illustrative stress scenarios.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\list`\ \[:py:class:`~fuggers_py.portfolio.stress.scenarios.StressScenario`]`

.. py:class:: Stress(portfolio) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.Stress

Convenience wrapper around portfolio stress helpers.

.. py:method:: Stress.parallel_shift(curve, settlement_date, *, bump_bps) :module: fuggers_py.portfolio

  Return the dirty-PV change for a parallel rate shift in bps.

.. py:function:: stress_scenarios(portfolio, *, curve, settlement_date, scenarios) :module: fuggers_py.portfolio

Compatibility alias for :func:run_stress_scenarios.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.stress.scenarios.StressSummary``

.. py:class:: StressResult(base_dirty_pv, stressed_dirty_pv, actual_change, dv01_approximation, scenario_name=None, breakdown=) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.StressResult

Result of a stress scenario against portfolio dirty PV.

.. attribute:: base_dirty_pv

  Unstressed dirty present value.

.. attribute:: stressed_dirty_pv

  Dirty present value after applying the scenario.

.. attribute:: actual_change

  Signed PV change, where negative values indicate a loss.

.. attribute:: dv01_approximation

  First-order approximation of the change, in the same currency units.

.. attribute:: scenario_name

  Optional label for the scenario.

.. attribute:: breakdown

  Optional per-position or per-tenor change breakdown.

.. py:class:: StressScenario(name) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.StressScenario

Base class for a named stress scenario.

.. py:class:: StressSummary(results) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.StressSummary

Mapping of scenario names to stress results.

.. py:method:: StressSummary.from_results(results) :module: fuggers_py.portfolio :classmethod:

  Normalize a collection of stress results into a summary.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.stress.scenarios.StressSummary\``

.. py:property:: StressSummary.scenario_count :module: fuggers_py.portfolio :type: int

  Return the number of scenarios in the summary.

.. py:property:: StressSummary.aggregate_change :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the sum of all scenario PV changes.

.. py:property:: StressSummary.worst_loss :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the most negative PV change.

.. py:property:: StressSummary.best_gain :module: fuggers_py.portfolio :type: ~decimal.Decimal

  Return the most positive PV change.

.. py:method:: StressSummary.best_case() :module: fuggers_py.portfolio

  Return the scenario with the largest PV change.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.StressResult\` \| \:py\:obj\:\`None\``

.. py:method:: StressSummary.worst_case() :module: fuggers_py.portfolio

  Return the scenario with the smallest PV change.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~fuggers\_py.portfolio.types.StressResult\` \| \:py\:obj\:\`None\``

.. py:function:: summarize_results(results) :module: fuggers_py.portfolio

Normalize stress results into a :class:StressSummary.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.stress.scenarios.StressSummary``

.. py:class:: TenorShift(tenor, bump_bps) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.stress.scenarios.TenorShift

A single key-rate tenor shock in basis points.

.. py:function:: total_cs01(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return portfolio CS01 in currency units per 1 bp.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: total_dv01(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return portfolio DV01 in currency units per 1 bp.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:class:: TrackingErrorEstimate(estimate, duration_component=Decimal(‘0’), spread_component=Decimal(‘0’), dispersion_component=Decimal(‘0’)) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.tracking.TrackingErrorEstimate

Heuristic tracking-error estimate and its components.

The estimate is a heuristic decimal value, not a statistically fitted tracking-error model.

.. py:method:: TrackingErrorEstimate.as_decimal() :module: fuggers_py.portfolio

  Return the tracking-error estimate as a decimal.


  :rtype: :sphinx_autodoc_typehints_type:`\:py\:class\:\`\~decimal.Decimal\``

.. py:function:: active_weights(portfolio, benchmark, curve, settlement_date) :module: fuggers_py.portfolio

Return active holding weights for portfolio minus benchmark.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.benchmark.comparison.ActiveWeights``

.. py:function:: aggregated_attribution(portfolio, *, curve, settlement_date, assumptions=None, benchmark=None) :module: fuggers_py.portfolio

Return aggregated income, rate, and spread attribution.

When a benchmark is supplied, active attribution fields are populated as portfolio minus benchmark.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.contribution.types.AggregatedAttribution``

.. py:function:: benchmark_comparison(portfolio, benchmark, curve, settlement_date) :module: fuggers_py.portfolio

Compatibility alias for :func:compare_portfolios.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.benchmark.comparison.BenchmarkComparison``

.. py:function:: weighted_asw(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio asset-swap spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal` | :py:obj:`None``

.. py:function:: weighted_best_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the dirty-value-weighted best duration.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_best_spread(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio best spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_best_yield(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio best yield as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_bid_ask_spread(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the dirty-value-weighted bid/ask spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_convexity(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return portfolio convexity as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_current_yield(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio current yield as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return portfolio duration as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_effective_convexity(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio effective convexity as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_effective_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio effective duration as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_g_spread(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio G-spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal` | :py:obj:`None``

.. py:function:: weighted_i_spread(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio I-spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal` | :py:obj:`None``

.. py:function:: weighted_liquidity_score(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio liquidity score as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_macaulay_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio Macaulay duration as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_modified_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio modified duration as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_oas(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio OAS as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_spread_duration(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio spread duration as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_spreads(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio Z-spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_ytc(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio yield to call as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_ytm(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio yield to maturity as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_ytw(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio yield to worst as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:function:: weighted_z_spread(portfolio, *, curve, settlement_date) :module: fuggers_py.portfolio

Return the portfolio Z-spread as a raw decimal.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~decimal.Decimal``

.. py:class:: WeightingMethod(value) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.types.weighting.WeightingMethod

Weighting basis used for portfolio-level aggregation.

.. py:function:: worst_case(results) :module: fuggers_py.portfolio

Return the worst-case stress result, if any.

:rtype: :sphinx_autodoc_typehints_type:\:py\:class\:\~fuggers_py.portfolio.types.StressResult` | :py:obj:`None``

.. py:class:: YieldComparison(portfolio_current_yield, benchmark_current_yield, active_current_yield, portfolio_ytm, benchmark_ytm, active_ytm, portfolio_ytw, benchmark_ytw, active_ytw) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.benchmark.comparison.YieldComparison

Portfolio, benchmark, and active yield metrics.

.. py:class:: YieldMetrics(ytm, ytw, ytc, current_yield, best_yield) :module: fuggers_py.portfolio :canonical: fuggers_py.portfolio.risk.YieldMetrics

Portfolio yield metrics expressed as raw decimals.