Repository navigation
Conversation
|
Warning Review limit reachedYou've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Next included review available in 41 minutes. View limit details
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #3959
Root cause
All four odd-period functions take the quasi-coupon period's normal length from
normal_length(
crates/functions/src/financial/securities.rs:321). It returns360/frequencyfor basis 2 and365/frequencyfor basis 3. Excel's values in the issue show two things this gets wrong:odd_last,securities.rs:464on main): Excel measures eachquasi-coupon period of an odd last period by its actual length under bases 2 and 3. The issue's
basis-2 example gives exactly the basis-1 price (100.157877308959). With NL = 360, GridCraft
gave 100.160017355362.
odd_first,securities.rs:371on main): Excel keeps NL =360/frequency(the COUPDAYS value) for a long first period. But it counts every wholequasi-coupon period after the one holding the issue date as NL days, which is exactly one
period. GridCraft counted actual days instead (181/180, 184/180, …). Solving the issue's example
for the single unknown Σ DCi/NLi gives 3.00555555555547, which is (180 + 180 + 181) / 180 to
within 1e-13. The accrued-days sum and DSC/E stay as they were. With this rule the price
matches Excel's 102.126937578431.
Fix
Two narrow changes in
securities.rs, both limited to bases 2 and 3:odd_last: NL is the quasi-period's actual length (end - start).odd_first: a quasi-period that starts after the issue date counts as NL days in Σ DCi/NLi.The period that holds the issue date still counts its actual days from issue.
Bases 0, 1 and 4 are unchanged. For basis 1 both rules are already true, so its results stay the
same, and the test checks the basis-1 control value.
Tests
New test
financial::tests::odd_periods_on_actual_day_bases_follow_excel(
crates/functions/src/financial/tests.rs):basis-1 control stays at 102.194911009281
Before the fix (on the branch made from upstream/main, test added, code unchanged):
With only the ODDFPRICE change taken out (the ODDLPRICE change still in):
With the fix:
Checks run (Windows)
cargo fmt -p gridcraft-functions: no changes outside the edited linescargo clippy -j 4 -p gridcraft-functions --all-targets -- -D warnings: cleancargo test -j 4 -p gridcraft-functions: 181 passed, 1 failed. The failure isengineering::tests::complex_numbers, which expects...+0.707106781186547iand gets...+0.707106781186548i. That test only exercises complex-number text, which this change doesnot touch. It is most likely a last-digit difference in the Windows maths library. I did not
re-run it on unmodified main.
Not run
cargo xtask ci(wasm, layers, assets) and other crates' testsI only had Excel values for the two basis-2 examples. The basis-3 behaviour follows the same
rule but has no Excel value to check against: the ODDLPRICE basis-3 result is only tested to
equal basis 1. Odd-first periods whose issue date falls inside a quasi-period, under bases 2 and
3, are also inferred rather than checked against Excel.