summaryrefslogtreecommitdiff
path: root/tests/FundLab.Domain.Tests/DomainTests.fs
diff options
context:
space:
mode:
Diffstat (limited to 'tests/FundLab.Domain.Tests/DomainTests.fs')
-rw-r--r--tests/FundLab.Domain.Tests/DomainTests.fs48
1 files changed, 48 insertions, 0 deletions
diff --git a/tests/FundLab.Domain.Tests/DomainTests.fs b/tests/FundLab.Domain.Tests/DomainTests.fs
index ff5245e..63bcab2 100644
--- a/tests/FundLab.Domain.Tests/DomainTests.fs
+++ b/tests/FundLab.Domain.Tests/DomainTests.fs
@@ -748,6 +748,54 @@ module RebalancePolicyTests =
Assert.All(diffs, fun diff -> Assert.Equal(RebalancePolicy.Hold, diff.Action))
[<Fact>]
+ let ``weight rows expose current percent and proposed buy`` () =
+ let targets = [ target "000001" 60.00m; target "000002" 40.00m ]
+ let positions = [ position "000001" 5000.00m 1000m 1000m (Some 5m) ]
+
+ let rows: RebalancePolicy.RebalanceWeightRow list =
+ RebalancePolicy.weightRows targets positions 7000.00m
+ |> unwrap
+
+ let row = rows |> List.find (fun item -> item.InstrumentCode = "000001")
+
+ Assert.Equal(60.00m, row.TargetPercent)
+ Assert.Equal(5000.00m, row.CurrentValue)
+ Assert.Equal(41.66m, row.CurrentPercent)
+ Assert.Equal(RebalancePolicy.Buy, row.Action)
+ Assert.Equal(2200.00m, row.DeltaAmount)
+ Assert.Equal(None, row.DeltaUnits)
+
+ [<Fact>]
+ let ``weight rows propose a sell clamped to available units`` () =
+ let targets = [ target "000001" 50.00m; target "000002" 50.00m ]
+ let positions = [ position "000001" 1000.00m 400m 400m (Some 2.5m) ]
+
+ let rows: RebalancePolicy.RebalanceWeightRow list =
+ RebalancePolicy.weightRows targets positions 0m
+ |> unwrap
+
+ let row = rows |> List.find (fun item -> item.InstrumentCode = "000001")
+
+ Assert.Equal(100.00m, row.CurrentPercent)
+ Assert.Equal(RebalancePolicy.Sell, row.Action)
+ Assert.Equal(-500.00m, row.DeltaAmount)
+ Assert.Equal(200.00000000m, row.DeltaUnits.Value)
+
+ [<Fact>]
+ let ``weight rows hold when the drift is within the one cent tolerance`` () =
+ let targets = [ target "000001" 100.00m ]
+ let positions = [ position "000001" 199.99m 100m 100m (Some 1.9999m) ]
+
+ let rows: RebalancePolicy.RebalanceWeightRow list =
+ RebalancePolicy.weightRows targets positions 0.01m
+ |> unwrap
+
+ let row = rows |> List.find (fun item -> item.InstrumentCode = "000001")
+
+ Assert.Equal(RebalancePolicy.Hold, row.Action)
+ Assert.Equal(0.01m, row.DeltaAmount)
+
+ [<Fact>]
let ``idempotency keys are deterministic per plan run and code`` () =
let planId = Guid "7c9e6679-7425-40de-944b-e07fc1f90ae7"
let runDate = DateOnly(2026, 9, 21)