Generated file. Source:
docs/ROS_logic.mdEdit the source document and runnpm run docs:syncto refresh this published copy.
ROS Logic¶
This file documents the current ROS calculation engine implementation.
Status¶
- Scope: current
ROSengine and the shared annual-accumulation family - Implementation status: active in production code
- Code path:
annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.tsros.ts: src/app/domain/bond-engine/strategies/ros.ts- Test path:
ros.strategy.test.ts: tests/ros.strategy.test.tsannual-accumulation.strategy.test.ts: tests/annual-accumulation.strategy.test.tsexcel-accumulation-alignment.test.ts: tests/excel-accumulation-alignment.test.ts- Visual diagrams:
- ROS_interest_flow_diagram.md - Flow diagrams and algorithm visualization
Product Rules¶
- Bond:
ROS - Duration:
6 years - Year
1rate:5.00% - Years
2-6rate:inflation + 2.00% - Capitalization: yearly
- Interest payout: only on redemption
- Early redemption cost:
2 złper bond - Exchange price used on rollover: catalog-driven; the production catalog currently stores
99.90, while the workbook-aligned regression scenario uses an explicit override of100 - Bond unit price:
100 zł - Tax rate:
19% - Availability: only for investors receiving
800+
Strategy Family¶
ROS is a specialization of the shared annual-accumulation family.
It configures:
strategyId = annual-accumulation-roscycleLengthYears = 6- rate resolver:
cycleYear === 1->5.00%cycleYear >= 2->inflation + 2.00%
Runtime Model¶
The engine models:
- yearly capitalization inside the active
ROSbatch - tax only on redemption
- rollover after natural maturity
- residual cash parked on a non-interest-bearing cash account (unlike non-capitalizing bonds)
For ROS, workbook alignment depends on carrying the residue on that separate account. Since ROS is capitalizing, this account does not earn monthly interest to prevent incorrect OKO balance reporting.
Natural Redemption And Rollover¶
At natural maturity:
tax = (grossValue - principal) * 0.19
netRedemption = grossValue - tax
nextBondCount = floor(netRedemption / exchangePrice)
residue = netRedemption - nextBondCount * exchangePrice
residue goes to the residual cash account and continues to grow monthly.
Final Early Redemption¶
If the simulation ends before year 6:
earlyCost = bondCount * 2 zł
taxableProfit = max(0, grossValue - principal - earlyCost)
tax = taxableProfit * 0.19
netLiquidation = grossValue - earlyCost - tax
Public Result Semantics¶
The ROS public result includes:
bondValuecashAccountBalance- yearly tax and early-redemption postings
- purchase and redemption histories
Covered Tests¶
Current automated ROS tests cover:
- first-year fixed
5.00% - switch to
inflation + 2.00% - natural
6-yearmaturity - early redemption after
1,2, and5years - rollover after natural maturity
- residual cash-account balance after rollover
- public result contract
- Excel alignment across
12yearly checkpoints
Change Rules¶
If ROS logic changes, update together:
annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.ts- annual_accumulation_logic.md
ros.ts: src/app/domain/bond-engine/strategies/ros.tsros.strategy.test.ts: tests/ros.strategy.test.tsexcel-accumulation-alignment.test.ts: tests/excel-accumulation-alignment.test.ts- ROS_logic.md