summaryrefslogtreecommitdiff
path: root/src/FundLab.Api/MarketData.fs
diff options
context:
space:
mode:
authorSomhairle H. Marisol <[email protected]>2026-09-22 03:25:00 +0800
committerSomhairle H. Marisol <[email protected]>2026-09-22 03:25:00 +0800
commit7dd0e3f42105569b6e6ec02aeeec9b5a8bbd9dd3 (patch)
treed7374c1b4bb5308374c3386ac3768ac7209a6440 /src/FundLab.Api/MarketData.fs
parent8c01adf05f1428bf2ada49574b25529c064da884 (diff)
downloadfund-lab-7dd0e3f42105569b6e6ec02aeeec9b5a8bbd9dd3.tar.gz
Add real AKShare stock daily history probe slice (3d-19)
Diffstat (limited to 'src/FundLab.Api/MarketData.fs')
-rw-r--r--src/FundLab.Api/MarketData.fs69
1 files changed, 69 insertions, 0 deletions
diff --git a/src/FundLab.Api/MarketData.fs b/src/FundLab.Api/MarketData.fs
index 87ef145..82da1c9 100644
--- a/src/FundLab.Api/MarketData.fs
+++ b/src/FundLab.Api/MarketData.fs
@@ -59,6 +59,23 @@ type MarketDataStockQuotePayload =
Currency: string
}
+type MarketDataStockDailyBar =
+ {
+ BarDate: DateOnly
+ Close: decimal
+ Volume: decimal option
+ Amount: decimal option
+ }
+
+type MarketDataStockDailyPayload =
+ {
+ Source: string
+ SourceRevision: string
+ CollectedAt: DateTimeOffset
+ Code: string
+ Bars: MarketDataStockDailyBar list
+ }
+
type MarketDataInstrumentRecord =
{
Code: string
@@ -398,3 +415,55 @@ module MarketData =
}
with
| :? JsonException -> Error "payload must be valid JSON"
+
+ let private parseStockDailyBar root =
+ result {
+ let! dateText = requiredString root "date"
+ let! date = parseDate dateText
+ let! closeProperty = requiredProperty root "close"
+ let! close = parseDecimal "close" closeProperty
+ let! volumeProperty = requiredProperty root "volume"
+ let! volume = optionalDecimal "volume" volumeProperty
+ let! amountProperty = requiredProperty root "amount"
+ let! amount = optionalDecimal "amount" amountProperty
+
+ return
+ {
+ BarDate = date
+ Close = close
+ Volume = volume
+ Amount = amount
+ }
+ }
+
+ let parseStockDailyPayload (json: string) : Result<MarketDataStockDailyPayload, string> =
+ try
+ use document = JsonDocument.Parse(json)
+ let root = document.RootElement
+
+ result {
+ let! source, sourceRevision, collectedAt = validateEnvelope root "stock-daily"
+ let! instrumentProperty = requiredProperty root "instrument"
+ let! codeProperty = requiredString instrumentProperty "code"
+
+ if not (isFundCode codeProperty) then
+ return! Error "stock code must contain exactly six digits"
+
+ let! observationsProperty = requiredProperty root "observations"
+ let! barsProperty = requiredProperty root "observations"
+ let! bars = parseArray parseStockDailyBar barsProperty
+
+ if List.isEmpty bars then
+ return! Error "observations must not be empty"
+
+ return
+ {
+ Source = source
+ SourceRevision = sourceRevision
+ CollectedAt = collectedAt
+ Code = codeProperty
+ Bars = bars
+ }
+ }
+ with
+ | :? JsonException -> Error "payload must be valid JSON"