# ---
# jupyter:
#   jupytext:
#     formats: ipynb,py:percent
#     text_representation:
#       extension: .py
#       format_name: percent
#       format_version: '1.3'
#       jupytext_version: 1.19.1
#   kernelspec:
#     display_name: Python 3
#     language: python
#     name: python3
# ---

# %% [markdown]
# # Portfolio summary analytics
#
# Build a small research portfolio and compute summary valuation, yield, risk,
# and spread outputs.

# %%
from __future__ import annotations

import sys
from dataclasses import replace
from decimal import Decimal
from pathlib import Path

root = Path.cwd()
if (root / "src").exists():
    sys.path.insert(0, str(root / "src"))
elif (root.parent / "src").exists():
    sys.path.insert(0, str(root.parent / "src"))

from fuggers_py.bonds.instruments import FixedBond  # noqa: E402
from fuggers_py.bonds.types import CreditRating, RatingInfo, Sector, SectorInfo, YieldCalculationRules  # noqa: E402
from fuggers_py.core import Currency, Date, Frequency  # noqa: E402
from fuggers_py.curves import DiscountCurveBuilder  # noqa: E402
from fuggers_py.portfolio import Classification, Holding, PortfolioBuilder, calculate_nav_breakdown, calculate_portfolio_analytics  # noqa: E402


# %% [markdown]
# ## Build the portfolio

# %%
reference_date = Date.from_ymd(2024, 1, 2)
curve = (
    DiscountCurveBuilder(reference_date=reference_date)
    .add_zero_rate(0.5, Decimal("0.030"))
    .add_zero_rate(2.0, Decimal("0.033"))
    .add_zero_rate(5.0, Decimal("0.038"))
    .add_zero_rate(10.0, Decimal("0.041"))
    .build()
)

def make_holding(label: str, years: int, coupon: str, price: str, sector: Sector, rating: CreditRating) -> Holding:
    bond = FixedBond.new(
        issue_date=reference_date,
        maturity_date=reference_date.add_years(years),
        coupon_rate=Decimal(coupon),
        frequency=Frequency.ANNUAL,
        currency=Currency.USD,
        rules=replace(YieldCalculationRules.us_corporate(), frequency=Frequency.ANNUAL),
    )
    return Holding(
        id=label,
        instrument=bond,
        quantity=Decimal("100"),
        clean_price=Decimal(price),
        label=label,
        classification=Classification(sector=sector, rating=rating, currency=Currency.USD),
        rating_info=RatingInfo(rating=rating),
        sector_info=SectorInfo(sector=sector),
    )


portfolio = (
    PortfolioBuilder()
    .with_currency(Currency.USD)
    .add_holding(make_holding("gov_short", 2, "0.0325", "99.5", Sector.GOVERNMENT, CreditRating.AA))
    .add_holding(make_holding("corp_bbb", 5, "0.0500", "101.0", Sector.CORPORATE, CreditRating.BBB))
    .add_holding(make_holding("corp_bb", 8, "0.0625", "98.0", Sector.INDUSTRIALS, CreditRating.BB))
    .build()
)


# %% [markdown]
# ## Summary metrics and NAV breakdown

# %%
summary = calculate_portfolio_analytics(portfolio, curve=curve, settlement_date=reference_date)
{
    "dirty_pv": summary.dirty_pv,
    "ytm": summary.ytm,
    "ytw": summary.ytw,
    "duration": summary.duration,
    "dv01": summary.dv01,
    "z_spread": summary.z_spread,
}

# %%
calculate_nav_breakdown(portfolio, curve=curve, settlement_date=reference_date)
