Generated file. Source:
docs/annual_accumulation_logic.mdEdit the source document and runnpm run docs:syncto refresh this published copy.
Annual Accumulation Strategy Family¶
This file documents the shared annual-accumulation engine used by bonds that:
- capitalize annually
- do not pay interest during the cycle
- reinvest only after redemption
- may finish with final early redemption of unfinished batches
Status¶
- Shared engine status: active in production code
- Current specializations:
TOSEDOROSROD
Code Path¶
annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.ts
Shared Responsibilities¶
The shared engine is responsible for:
- initial allocation into full bonds
- yearly state loop
- natural redemption handling
- reinvestment after redemption
- final early redemption
- yearly snapshots
- purchase history
- redemption history
- final public totals
Specializations should define only:
strategyId- cycle length in years
- annual rate resolution policy
The product-specific strategy factory exported from each specialization module is the single source of truth for:
- runtime strategy configuration
- test strategy configuration
- public strategy identifier
This is intentional. Tests should reuse these factories instead of duplicating inline strategy definitions.
Eligibility rules such as 800+ access for family bonds are intentionally out of scope for this engine family.
Those rules belong to bond selection and sanitization layers, not to financial calculation strategies.
Shared State¶
The engine tracks:
cash- active
positions purchaseEventsredemptionEventsyearSnapshotsyearlyResults
Each position contains:
bondspurchaseYear
Year Loop¶
For each year:
- Identify naturally maturing positions.
- Compute their gross value.
- Compute tax on realized profit.
- Add net redemption proceeds to cash.
- Reinvest available cash into full new bonds if the horizon continues.
- If the simulation ends, early-redeem all remaining active positions.
- Build:
- carried
grossValue - liquidation
netValueon final year
Shared Snapshot Semantics¶
Intermediate years¶
grossValue= carried portfolio value plus all taxes and costs already realized so farnetValue= carried portfolio value after already realized taxes and costs
Final year¶
grossValue= value before all taxes and early redemption costs from the whole simulationnetValue= actual liquidation value after final settlement
Shared History Contracts¶
Purchase events¶
Recorded for:
- initial allocation
- post-redemption reinvestment
Redemption events¶
Recorded for:
- natural maturity
- final early redemption
Invariants¶
The shared engine should always satisfy:
grossValue >= liquidationValuecash >= 0- final public
gross/nettotals match the last yearly snapshot after display rounding - reinvestment never happens before available cash reaches one full bond unit
Mermaid Overview¶
flowchart TD
A[Initial cash] --> B[Buy initial full bonds]
B --> C[Year loop]
C --> D[Natural redemption]
D --> E[Add net cash]
E --> F[Reinvest after redemption]
F --> G{Final year?}
G -->|No| C
G -->|Yes| H[Final early redemption of remaining batches]
H --> I[Build final yearly result]
Shared Tests¶
Shared-engine tests should validate:
- invariant grids
- final total consistency
- history retention
- golden reference scenarios for more than one specialization
Current test path:
annual-accumulation.strategy.test.ts: tests/annual-accumulation.strategy.test.ts
Proven Abstraction Scope¶
The shared family is now validated against three different real product shapes:
TOS- fixed annual rate
- short
3-yearcycle EDO- inflation-indexed annual rates
- long
10-yearcycle ROS- inflation-indexed annual rates
- shorter
6-yearfamily-bond cycle ROD- inflation-indexed annual rates
- longer
12-yearfamily-bond cycle - different family-bond margin than
ROS
This means the current abstraction has now been exercised on the full planned annual-accumulation family.
Change Rules¶
If the shared annual-accumulation engine changes, update together:
annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.ts- all specialization docs and tests that depend on it
- annual_accumulation_logic.md