# ---
# 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]
# # Floating-rate notes with fixings
#
# Use a fixing store plus a projection curve to evaluate a live SOFR FRN.

# %%
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.indices import BondIndex, IndexConventions, IndexFixingStore, OvernightCompounding  # noqa: E402
from fuggers_py.bonds.instruments import FloatingRateNoteBuilder  # noqa: E402
from fuggers_py.bonds.types import RateIndex, YieldCalculationRules  # noqa: E402
from fuggers_py.core import Currency, Date, Frequency  # noqa: E402
from fuggers_py.curves import DiscountCurveBuilder  # noqa: E402


# %% [markdown]
# ## Build the fixing store and note definition

# %%
reference_date = Date.from_ymd(2024, 1, 10)
fixing_store = IndexFixingStore()
for offset, rate in enumerate(["0.0490", "0.0495", "0.0500", "0.0505", "0.0510", "0.0515", "0.0520"], start=0):
    fixing_store.add_fixing("SOFR", reference_date.add_days(-10 + offset), Decimal(rate))

index_definition = BondIndex(
    name="SOFR",
    rate_index=RateIndex.SOFR,
    currency=Currency.USD,
    fixing_store=fixing_store,
    conventions=IndexConventions(overnight_compounding=OvernightCompounding.COMPOUNDED),
)

frn = (
    FloatingRateNoteBuilder.new()
    .with_issue_date(reference_date.add_months(-3))
    .with_maturity_date(reference_date.add_years(2))
    .with_index(RateIndex.SOFR)
    .with_index_definition(index_definition)
    .with_frequency(Frequency.QUARTERLY)
    .with_rules(replace(YieldCalculationRules.us_treasury(), frequency=Frequency.QUARTERLY))
    .with_current_reference_rate(Decimal("0.0520"))
    .with_quoted_spread(Decimal("0.0025"))
    .build()
)


# %% [markdown]
# ## Inspect required fixings and accrued interest

# %%
accrual_start, accrual_end = frn.schedule().unadjusted_dates[:2]
required_fixings = frn.required_fixing_dates(accrual_start, accrual_end)
required_fixings[:5]

# %%
projection_curve = (
    DiscountCurveBuilder(reference_date=reference_date)
    .add_zero_rate(0.25, Decimal("0.0510"))
    .add_zero_rate(1.0, Decimal("0.0530"))
    .add_zero_rate(2.0, Decimal("0.0540"))
    .build()
)
frn.accrued_interest(reference_date, fixing_store=fixing_store, forward_curve=projection_curve)


# %% [markdown]
# ## Project future cash flows with mixed realized and projected rates

# %%
cashflows = frn.projected_cash_flows(
    projection_curve,
    settlement_date=reference_date,
    fixing_store=fixing_store,
)
[
    {
        "date": cashflow.date,
        "amount": cashflow.amount,
        "reference_rate": cashflow.reference_rate,
    }
    for cashflow in cashflows[:3]
]
