summaryrefslogtreecommitdiff
path: root/src/FundLab.Api/MarketData.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 08:07:00 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 08:07:00 +0800
commitb05e728ae23d088ca6c9ecccf6ed00d2ab6f3839 (patch)
tree4846648aa87263742c1181c189287b53c3bf84de /src/FundLab.Api/MarketData.fs
parent27a85d9070abd000245b2a2e6460ddf9fd5eb97e (diff)
downloadfund-lab-b05e728ae23d088ca6c9ecccf6ed00d2ab6f3839.tar.gz
Add bond full milestone: profile probe, coupon/accrual rules, ledger and point-in-time valuation (3d-29)
Diffstat (limited to 'src/FundLab.Api/MarketData.fs')
-rw-r--r--src/FundLab.Api/MarketData.fs67
1 files changed, 58 insertions, 9 deletions
diff --git a/src/FundLab.Api/MarketData.fs b/src/FundLab.Api/MarketData.fs
index e621740..152ffd7 100644
--- a/src/FundLab.Api/MarketData.fs
+++ b/src/FundLab.Api/MarketData.fs
@@ -49,6 +49,17 @@ type MarketDataBondQuotePayload =
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
}
type MarketDataStockQuotePayload =
@@ -379,17 +390,44 @@ module MarketData =
let! name = optionalString quoteProperty "name"
let! priceProperty = requiredProperty quoteProperty "price"
let! price = optionalDecimal "price" priceProperty
- let! cleanPrice =
- optionalProperty quoteProperty "clean_price"
- |> Result.bind (function Some property -> optionalDecimal "clean_price" property | None -> Ok None)
- let! accruedInterest =
- optionalProperty quoteProperty "accrued_interest"
- |> Result.bind (function Some property -> optionalDecimal "accrued_interest" property | None -> Ok None)
- let! date =
- optionalProperty quoteProperty "date"
- |> Result.bind (function Some property -> optionalIsoDate "date" property | None -> Ok None)
+ let optionalDecimalField fieldName =
+ optionalProperty quoteProperty fieldName
+ |> Result.bind (function
+ | Some property -> optionalDecimal fieldName property
+ | None -> Ok None)
+
+ let optionalDateField fieldName =
+ optionalProperty quoteProperty fieldName
+ |> Result.bind (function
+ | Some property -> optionalIsoDate fieldName property
+ | None -> Ok None)
+
+ let optionalStringField fieldName =
+ optionalProperty quoteProperty fieldName
+ |> Result.bind (function
+ | Some property when property.ValueKind = JsonValueKind.Null -> Ok None
+ | Some property when property.ValueKind = JsonValueKind.String ->
+ let value = property.GetString()
+ if String.IsNullOrWhiteSpace value then Ok None else Ok(Some value)
+ | Some _ -> Error(sprintf "payload property '%s' must be null or a string" fieldName)
+ | None -> Ok None)
+
+ let! cleanPrice = optionalDecimalField "clean_price"
+ let! accruedInterest = optionalDecimalField "accrued_interest"
+ let! date = optionalDateField "date"
let! maturityProperty = requiredProperty quoteProperty "maturity_date"
let! maturityDate = optionalIsoDate "maturity_date" maturityProperty
+ let! parValue = optionalDecimalField "par_value"
+ let! issuePrice = optionalDecimalField "issue_price"
+ let! valueDate = optionalDateField "value_date"
+ let! listingDate = optionalDateField "listing_date"
+ let! publishDate = optionalDateField "publish_date"
+ let! payInterestDay = optionalStringField "pay_interest_day"
+ let! couponRate = optionalDecimalField "coupon_rate"
+ let! couponRateExplain = optionalStringField "coupon_rate_explain"
+ let! bondExpireYears = optionalStringField "bond_expire_years"
+ let! rating = optionalStringField "rating"
+ let! dataStatus = optionalStringField "data_status"
return
{
@@ -403,6 +441,17 @@ module MarketData =
AccruedInterest = accruedInterest
Date = date
MaturityDate = maturityDate
+ ParValue = parValue
+ IssuePrice = issuePrice
+ ValueDate = valueDate
+ ListingDate = listingDate
+ PublishDate = publishDate
+ PayInterestDay = payInterestDay
+ CouponRate = couponRate
+ CouponRateExplain = couponRateExplain
+ BondExpireYears = bondExpireYears
+ Rating = rating
+ DataStatus = dataStatus
}
}
with