Repository navigation
feat(strategies): add funding-capture and basis model - #951
collinsezedike merged 2 commits into
Conversation
|
@Miraclechukwuemeka is attempting to deploy a commit to the Collins' projects Team on Vercel. A member of the Team first needs to authorize it. |
|
@Miraclechukwuemeka Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits. You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀 |
Add FundingRate and Position types to types.ts, consuming the existing FixedPointDecimal model rather than introducing a parallel rate type. Implement two pure functions in funding.ts: - accrueFunding(position, fundingRate, elapsedSeconds): computes funding payment on the short leg using integer-only bigint arithmetic (notional × rate × elapsed / STROOPS_PER_UNIT). Positive rate → short receives; negative rate → short pays. - computeBasis(spot, derivativePrice): returns spot − derivative as a FixedPointDecimal, positive in backwardation, negative in contango. Both functions return FixedPointDecimal with no floating-point anywhere in the computation path. Sign conventions are documented in JSDoc. Export accrueFunding, computeBasis, FundingRate, and Position from the package index. Add 25 unit tests in funding.test.ts covering: - Sign conventions (positive, negative, zero rate) - Linearity with respect to elapsed and notional - Full 7-decimal precision preservation - Integer truncation for sub-stroop results - RangeError on negative elapsedSeconds - All four acceptance criteria from the issue All 61 tests pass (25 new + 36 existing). Closes drydocs#927
c21d37c to
ff91084
Compare
collinsezedike
left a comment
There was a problem hiding this comment.
@Miraclechukwuemeka thank you for the funding-capture and basis model. I verified the accrual keeps every step in bigint stroops, that the single division by STROOPS_PER_UNIT leaves notional × ratePerSecond × elapsedSeconds exact, that a negative elapsedSeconds raises, and that computeBasis returns the spot-minus-derivative delta at full precision.
I rebased the branch onto main and fixed three things before landing. The branch declared its own Position interface in types.ts, and portfolio.ts already exports a different Position, so index.ts re-exported the name twice and the package failed to typecheck with TS2308. I renamed the funding one to FundingPosition. The two new files also carried ten em dashes in comments, which I rewrote to comply with the repository's writing rules. Prettier then reformatted three over-long lines.
packages/strategies is at 11 files and 218 tests, with funding.ts fully covered. Merging now.
|
@Miraclechukwuemeka your work is merged into |
Summary
Add
accrueFunding()andcomputeBasis()topackages/strategies, modelling funding payments on the short leg and the spot-versus-derivative basis so strategies can account for carry over a simulation.Changes
packages/strategies/src/types.tsFundingRateinterface,{ ratePerSecond: FixedPointDecimal }, reusing the existingFixedPointDecimalmodel rather than a parallel rate type.FundingPositioninterface,{ notional: FixedPointDecimal }, holding the absolute short-leg size. Named to avoid colliding with the portfolio's ownPosition.packages/strategies/src/funding.ts(new file)accrueFunding(position, fundingRate, elapsedSeconds)returnsnotional × ratePerSecond × elapsed / STROOPS_PER_UNITas aFixedPointDecimal. Entirely bigint arithmetic, no floats.computeBasis(spot, derivativePrice)returnsspot - derivativePriceas aFixedPointDecimal. Positive means backwardation, negative means contango.packages/strategies/src/index.ts./funding.packages/strategies/src/funding.test.ts(new file)RangeErroron negativeelapsedSecondsAcceptance criteria
Test plan
pnpm lintandpnpm typecheckpass across the workspacepnpm --filter @meridian/strategies testpasses, 11 files and 218 testspackages/strategiescoverage passes its thresholds, withfunding.tsfully coveredprettier --checkpasses on the new filesCloses #927