Skip to content

Generated file. Source: docs/TOS_logic.md Edit the source document and run npm run docs:sync to refresh this published copy.

TOS Logic

This file documents the current TOS calculation engine implementation.

Status

  • Scope: current TOS engine and the shared annual-accumulation strategy family it uses
  • Implementation status: active in production code
  • Code path:
  • annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.ts
  • tos.ts: src/app/domain/bond-engine/strategies/tos.ts
  • Test path:
  • tos.strategy.test.ts: tests/tos.strategy.test.ts
  • annual-accumulation.strategy.test.ts: tests/annual-accumulation.strategy.test.ts

Product Rules

  • Bond: TOS
  • Duration: 3 years
  • Annual rate: 4.65% fixed for the whole cycle
  • Capitalization: yearly
  • Interest payout: only on redemption
  • Early redemption cost: 3 zł per bond
  • Bond unit price: 100 zł
  • Tax rate: 19%

Strategy Family

TOS does not use the generic yearly calculator anymore.

It is implemented as the first specialization of a shared annual-accumulation family for bonds that:

  • capitalize annually
  • do not pay cash during the cycle
  • allow reinvestment only after redemption
  • may end with early redemption of unfinished batches

That family is intended to be reused later for:

  • EDO
  • ROS
  • ROD

State Model

The engine tracks:

  • cash
  • positions
  • purchaseEvents
  • yearSnapshots
  • yearlyResults

Each active position contains:

  • bonds
  • purchaseYear

Simulation Flow

The engine works on yearly steps.

For each year:

  1. Redeem positions that reached natural maturity (3 years).
  2. Add redeemed net cash to cash.
  3. Reinvest available cash into full new bonds if the horizon continues.
  4. If this is the final year, early-redeem all still-active positions.
  5. Build yearly carried-value and liquidation snapshots.

Natural Redemption

For a naturally redeemed batch:

  1. Start with nominal principal.
  2. Apply annual compounding for 3 years:
V1 = P * (1 + 0.0465)
V2 = V1 * (1 + 0.0465)
V3 = V2 * (1 + 0.0465)
  1. Compute gross profit:
grossProfit = V3 - P
  1. Compute tax:
tax = grossProfit * 0.19
  1. Add net redemption value to cash:
netRedemption = V3 - tax

Final Early Redemption

If the investment horizon ends before a batch reaches 3 years:

  1. Compute accumulated value for the current age in full years.
  2. Compute tax on total accrued gain.
  3. Subtract early redemption cost:
earlyCost = bondCount * 3 zł
  1. Add final net liquidation value to cash.

Reinvestment

TOS does not reinvest during a cycle.

Reinvestment may happen only after natural redemption, using:

reinvestedBondCount = floor(cash / 100)

Any remainder stays as cash.

The engine records:

  • initial allocation purchase event
  • each reinvestment purchase event
  • natural redemption events
  • final early redemption events

Snapshot Semantics

This is critical for UI consistency.

grossValue

For each year:

  • grossValue means year-end portfolio value before all taxes and costs realized so far
  • it includes:
  • carried portfolio value
  • taxes already realized in previous completed cycles
  • early-redemption costs already realized, if any

netValue

  • intermediate years:
  • netValue = carried portfolio value
  • no forced liquidation is applied
  • final year:
  • netValue = liquidationValue
  • all taxes and early redemption costs are fully settled

taxPaid

  • only tax actually realized in that year

earlyRedemptionCost

  • only cost actually realized in that year

Rounding Policy

Current implementation follows project policy:

  • internal calculations: 0.001 zł
  • final public values: 0.01 zł

Public Contract

The TOS public result includes:

  • yearly results
  • final totals
  • simulationDetails.strategy = "annual-accumulation-tos"
  • simulationDetails.purchaseEvents
  • simulationDetails.redemptionEvents

Mermaid Flow

flowchart TD
    A[Initial cash] --> B[Buy initial full bonds]
    B --> C[Year loop]
    C --> D{Any batch reached 3 years?}
    D -->|Yes| E[Natural redemption + tax]
    D -->|No| F[Keep active batches]
    E --> G[Add net cash]
    F --> G
    G --> H{More years left?}
    H -->|Yes| I[Buy new full bonds]
    H -->|No| J[Final settlement]
    I --> C
    J --> K[Early redeem unfinished batches]
    K --> L[Build final result]

Covered Tests

Current automated TOS tests cover:

  • full 3-year natural cycle
  • 1-year early redemption
  • 2-year early redemption
  • no reinvestment before maturity
  • reinvestment after natural redemption
  • yearly intermediate carried-value semantics
  • public result contract and strategy id
  • long-horizon large-principal stability
  • deterministic threshold scenarios
  • shared annual-accumulation invariant grid
  • shared annual-accumulation golden scenarios

Traceability

  • product duration, redemption, tax, reinvestment:
  • tos.strategy.test.ts: tests/tos.strategy.test.ts
  • shared carried-value vs liquidation semantics:
  • annual-accumulation.strategy.test.ts: tests/annual-accumulation.strategy.test.ts
  • purchase and redemption history retention:
  • tos.strategy.test.ts: tests/tos.strategy.test.ts
  • annual-accumulation.strategy.test.ts: tests/annual-accumulation.strategy.test.ts

Change Rules

If TOS logic changes, update together:

  • annual-accumulation.ts: src/app/domain/bond-engine/strategies/annual-accumulation.ts
  • annual_accumulation_logic.md
  • tos.ts: src/app/domain/bond-engine/strategies/tos.ts
  • tos.strategy.test.ts: tests/tos.strategy.test.ts
  • TOS_logic.md
  • init_prompt.md: ai/init_prompt.md