From 0597ac74757e223c17a6477ff49d69a559168279 Mon Sep 17 00:00:00 2001 From: "Somhairle H. Marisol" Date: Tue, 22 Sep 2026 00:19:09 +0800 Subject: Add real AKShare NAV-date probe slice (3d-12) --- src/FundLab.Api/Persistence.fs | 20 ++++++++++++++++---- 1 file changed, 16 insertions(+), 4 deletions(-) (limited to 'src/FundLab.Api/Persistence.fs') diff --git a/src/FundLab.Api/Persistence.fs b/src/FundLab.Api/Persistence.fs index 7a7ab32..6028b7c 100644 --- a/src/FundLab.Api/Persistence.fs +++ b/src/FundLab.Api/Persistence.fs @@ -59,6 +59,18 @@ module ConfirmationPolicy = let candidate = if local.TimeOfDay >= cutoffTimeOfDay then date.AddDays 1 else date rollToWeekday candidate + /// Calendar date used to bucket events (cash flows, holdings) on the returns + /// timeline. Shares the FUND_LAB_TEST_TRADE_DATE anchor with tradeDateFor so a + /// pinned suite does not drift when the host crosses midnight; production (no + /// pin) is exactly the Shanghai calendar date of the moment. + let eventDateFor (moment: DateTimeOffset) : DateOnly = + match Environment.GetEnvironmentVariable("FUND_LAB_TEST_TRADE_DATE") with + | value when not (String.IsNullOrWhiteSpace value) -> + match DateOnly.TryParseExact(value, "yyyy-MM-dd", CultureInfo.InvariantCulture, DateTimeStyles.None) with + | true, anchored -> anchored + | _ -> shanghaiDate moment + | _ -> shanghaiDate moment + type NavQuote = { NavDate: DateOnly Nav: decimal @@ -4867,7 +4879,7 @@ type FundRepository(connectionString: string) = match this.GetFund fundId with | None -> None | Some fund -> - let today = ConfirmationPolicy.shanghaiDate DateTimeOffset.UtcNow + let today = ConfirmationPolicy.eventDateFor DateTimeOffset.UtcNow let deposits = this.GetCapitalDeposits fundId let orders = this.GetSubscriptionOrders fundId let redemptions = this.GetRedemptionOrders fundId @@ -4902,7 +4914,7 @@ type FundRepository(connectionString: string) = |> List.map (fun observation -> observation.NavDate)) |> Set.ofList - let creationDate = ConfirmationPolicy.shanghaiDate fund.CreatedAt + let creationDate = ConfirmationPolicy.eventDateFor fund.CreatedAt let dividendCredited = dividends @@ -4926,7 +4938,7 @@ type FundRepository(connectionString: string) = else let eventDates = [ yield creationDate - yield! deposits |> List.map (fun deposit -> ConfirmationPolicy.shanghaiDate deposit.CreatedAt) + yield! deposits |> List.map (fun deposit -> ConfirmationPolicy.eventDateFor deposit.CreatedAt) yield! orders |> List.map (fun order -> order.TradeDate) yield! redemptions |> List.map (fun order -> order.TradeDate) yield! dividendCredited |> List.map (fun record -> record.NavDate) ] @@ -4964,7 +4976,7 @@ type FundRepository(connectionString: string) = for date in dates do for deposit in deposits do - if ConfirmationPolicy.shanghaiDate deposit.CreatedAt = date then + if ConfirmationPolicy.eventDateFor deposit.CreatedAt = date then availableCash <- availableCash + deposit.Amount cumulativeDeposits <- cumulativeDeposits + deposit.Amount -- cgit v1.2.3