Skip to content

[SDK] Add capital allocation across composed strategy members #1198

Closed

Description

@collinsezedike

Summary

Given a composition and a total starting capital, compute and apply each member's allocated capital as fixed-point decimals, with a deterministic rule for the residual so the parts always sum exactly to the total.

Motivation

runBacktest takes a single initialCash (packages/strategies/src/backtest/runner.ts:44-58). A composition has to split Scenario.startingCapital across members by weight without losing or inventing value. Fixed-point division does not divide evenly, so a naive split strands dust that is never assigned, and the engine's accounting identity rejects any run where value appears or disappears (packages/strategies/src/portfolio.ts:204-216).

Proposed Solution

  • Add an allocateCapital(total, weights) function in packages/strategies/src/composition/ returning per-member amounts as FixedPointDecimal, using largest-remainder apportionment so the parts sum exactly to total.
  • Validate weights up front: non-negative, at least one positive. Normalize the vector to the whole.
  • Order the remainder distribution by member id so a fixed input always yields the same allocation.
  • The composition's init consumes the allocation. When a member exits mid-run, its freed capital returns to cash and is not silently reassigned to another member.

Scope

Field Value
Area SDK
Protocol affected None
Network testnet
Breaking change? No

Alternatives Considered

  • Pro-rata with floating-point division. Rejected, because money paths never use floats, and float rounding would break the accounting identity.
  • Let each member draw cash on demand instead of a fixed allocation. Rejected, because it makes the run depend on call order and hides the split.

Acceptance Criteria

  • Allocation of any total across any valid weight vector sums exactly to the total, with no residual.
  • Invalid weights (negative, or all zero) are rejected with a typed error.
  • Allocation is deterministic for a fixed input.
  • Tests cover uneven splits where rounding is non-trivial.
  • pnpm --filter @meridian/strategies test and npx tsc --noEmit pass.

Additional Context

Depends on the composition interface, #1197. Part of the Meridian Strategies initiative.

Star the repo

Please star this repository before picking up this issue. It is a small ask that meaningfully helps the project reach more people.

Activity

  1. added
    enhancementNew feature or request
    mediumRequires familiarity with the Meridian codebase or relevant tooling; expect 4–8 hours
    sdkInvolves Blend or DeFindex SDK helpers in packages/stellar-sdk-helpers
    on Oct 19, 2026
  2. Ivenkili commented on Oct 19, 2026

    @Ivenkili

    @Ivenkili has applied to work on this issue as part of the Stellar Wave Program's 10th wave.

    Hey maintainer can i work on this

    ℹ️ Repo Maintainers: To accept this application, review their application or assign @Ivenkili to this issue.

  3. liutingqiu commented on Oct 20, 2026

    @liutingqiu
    Contributor

    @liutingqiu has applied to work on this issue as part of the Stellar Wave Program's 10th wave.

    I'll add allocateCapital(total, weights) in packages/strategies/src/composition/, returning per-member FixedPointDecimal amounts via largest-remainder apportionment. It will validate weights up front (non-negative, at least one positive), normalize the vector to the whole, and distribute the remainder ordered by member id so a fixed input always yields the same allocation and the parts sum exactly to total. Then I'll wire the composition's init to consume the allocation, with freed capital from a mid-run member exit returning to cash rather than being reassigned.

    Tests I'll add: even split, uneven split where naive division strands dust (asserting exact sum), single positive weight, zero weights mixed with positives, and the negative case of all-zero or negative weights rejecting. I'll also add a determinism test asserting identical output across repeated calls with shuffled input order.

    I've merged PRs #1175 and #1176 in drydocs/meridian and 65 merged PRs in Sottara-Labs/sottara, so the fixed-point and accounting-identity conventions here are familiar. ETA same or next day.

    ℹ️ Repo Maintainers: To accept this application, review their application or assign @liutingqiu to this issue.

  4. barnabasolutayo-lgtm commented on Oct 20, 2026

    @barnabasolutayo-lgtm

    @barnabasolutayo-lgtm has applied to work on this issue as part of the Stellar Wave Program's 10th wave.

    Please Maintainer, assign this ssue to me. Thank you so much

    ℹ️ Repo Maintainers: To accept this application, review their application or assign @barnabasolutayo-lgtm to this issue.

  5. drips-wave commented on Oct 20, 2026

    @drips-wave

    Congratulations, @liutingqiu! 🎉 Your application was accepted by the repo's maintainers, and the issue is due on October 22, 2026.

    🧑‍💻 @liutingqiu: Please resolve the issue such that the repo's maintainers have enough time to review your contribution before the due date. You'll earn Points for completing the issue on-time, which will make you eligible for a share of the Stellar Wave Program's reward pool.

    Warning

    When opening a PR, please link it to this issue to ensure it gets tracked accurately. Points are awarded when this issue is marked as completed by the maintainer.

    🤠 Repo maintainers: Please keep an eye on the contributor's progress and review their work before the due date. You can manage this issue, including adjusting its complexity and points, here.

    🌊 Happy Wave 🌊

  6. grantfox-oss commented on Oct 20, 2026

    @grantfox-oss

    🎉 This issue has been marked as completed on GrantFox!

    @liutingqiu's PR #1210 was approved and merged by @collinsezedike.

    🏆 @liutingqiu: You earned 35 FoxPoints for this contribution! Your current tier: Explorer (105 total points). Track your full progress on GrantFox.

    👏 Great work, @liutingqiu! Keep contributing to drydocs.

  7. drips-wave commented on Oct 20, 2026

    @drips-wave

    This issue has been completed by @liutingqiu as part of the Stellar Wave Program's 10th Wave 🥳

    😎 @liutingqiu: You earned 200 Points for completing this issue! Once the Wave's rewards are finalized, you'll be eligible for a percentage of the Wave's reward pool based on the percentage of total points you've earned. Learn more here. You can also Leave a review to share your experience working on this issue.

    🧑‍💻 Repo maintainers: How'd the contributor do? Leave a review to share your experience working with them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

Stellar WaveIssues in the Stellar wave programenhancementNew feature or requestmediumRequires familiarity with the Meridian codebase or relevant tooling; expect 4–8 hourssdkInvolves Blend or DeFindex SDK helpers in packages/stellar-sdk-helpers

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions