From b05e728ae23d088ca6c9ecccf6ed00d2ab6f3839 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 22 Sep 2026 08:07:00 +0800 Subject: Add bond full milestone: profile probe, coupon/accrual rules, ledger and point-in-time valuation (3d-29) --- src/FundLab.Api/BondQuoteProbe.fs | 45 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) (limited to 'src/FundLab.Api/BondQuoteProbe.fs') diff --git a/src/FundLab.Api/BondQuoteProbe.fs b/src/FundLab.Api/BondQuoteProbe.fs index 311dec5..b01ff18 100644 --- a/src/FundLab.Api/BondQuoteProbe.fs +++ b/src/FundLab.Api/BondQuoteProbe.fs @@ -17,8 +17,42 @@ type BondQuote = AccruedInterest: decimal option Date: DateOnly option MaturityDate: DateOnly option + ParValue: decimal option + IssuePrice: decimal option + ValueDate: DateOnly option + ListingDate: DateOnly option + PublishDate: DateOnly option + PayInterestDay: string option + CouponRate: decimal option + CouponRateExplain: string option + BondExpireYears: string option + Rating: string option + DataStatus: string option } +module BondQuote = + open FundLab.Domain + + /// Best-effort conversion of a quote into pricing terms. Requires the value + /// date, maturity and coupon rate; when any is missing the caller gets None + /// rather than a fabricated coupon. Exchange convertible bonds pay annually + /// (a single 付息日), so the frequency defaults to 1. + let tryTerms (quote: BondQuote) : BondTerms option = + match quote.ValueDate, quote.MaturityDate, quote.CouponRate with + | Some valueDate, Some maturityDate, Some couponRate -> + Some( + BondTerms.create + (defaultArg quote.ParValue 100m) + couponRate + 1 + valueDate + maturityDate + 10m + 0 + 0m + ) + | _ -> None + /// Read-only probe that returns the current quote for a bond code. /// /// Like INavDateProbe there is no synthetic fallback: a failed probe surfaces as @@ -70,6 +104,17 @@ type AkshareBondQuoteProbe(collector: IMarketDataCollector) = AccruedInterest = payload.AccruedInterest Date = payload.Date MaturityDate = payload.MaturityDate + ParValue = payload.ParValue + IssuePrice = payload.IssuePrice + ValueDate = payload.ValueDate + ListingDate = payload.ListingDate + PublishDate = payload.PublishDate + PayInterestDay = payload.PayInterestDay + CouponRate = payload.CouponRate + CouponRateExplain = payload.CouponRateExplain + BondExpireYears = payload.BondExpireYears + Rating = payload.Rating + DataStatus = payload.DataStatus } cache.[normalized] <- quote -- cgit v1.2.3