fintech-algorithms

Return-of-Capital Adjustment

Keep Price, Return, and Tax Views Separate

Install and import

bash
npm install fintech-algorithms
ts
import { calculate } from "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/return-of-capital-adjustment";

Signature

calculate(payload)

Worked example

executed Captured by running this function on the input its own test provides. Real output of real code — but not asserted against a published figure.

Input

payload
{
  "asOf": "2025-02-03T21:05:00Z",
  "revisions": [
    {
      "eventId": "SYN-ROC-2025-001",
      "revisionId": "SYN-ANNOUNCEMENT-R1",
      "revisionSequence": 1,
      "observedAt": "2025-01-20T14:00:00Z",
      "availableAt": "2025-01-20T14:02:00Z",
      "sourceId": "SYN-ISSUER-NOTICE",
      "status": "confirmed",
      "exAt": "2025-02-03T14:30:00Z",
      "sameDayOrdering": {
        "sequence": 1,
        "priorEventIds": []
      },
      "terms": {
        "eventCurrency": "USD",
        "grossCapitalReturnPerShare": "2.00000000",
        "withholdingPerShare": "0.10000000",
        "feesPerShare": "0.02000000"
      }
    }
  ],
  "referenceObservation": {
    "price": "25.00000000",
    "currency": "USD",
    "observedAt": "2025-01-31T21:00:00Z",
    "availableAt": "2025-01-31T21:00:05Z",
    "sourceId": "SYN-OFFICIAL-CLOSE"
  },
  "fxObservation": {
    "priceCurrencyPerEventCurrency": "1.00000000",
    "pair": "USD/USD",
    "anchorPolicy": "ON_OR_BEFORE_REFERENCE_OBSERVATION",
    "observedAt": "2025-01-31T21:00:00Z",
    "availableAt": "2025-01-31T21:00:00Z",
    "sourceId": "IDENTITY-FX"
  },
  "exObservation": {
    "price": "23.15000000",
    "currency": "USD",
    "observedAt": "2025-02-03T21:00:00Z",
    "availableAt": "2025-02-03T21:00:04Z",
    "sourceId": "SYN-OFFICIAL-CLOSE"
  },
  "taxIllustration": {
    "jurisdiction": "US_FEDERAL_INDIVIDUAL_TAXABLE_2025",
    "currency": "USD",
    "basisPerShareBefore": "1.50000000",
    "confirmedReturnOfCapitalPerShare": "1.20000000",
    "sourceId": "SYN-FINAL-ISSUER-TAX-CLASSIFICATION",
    "observedAt": "2025-02-03T20:00:00Z",
    "availableAt": "2025-02-03T20:05:00Z"
  }
}

Call

calculate(payload)

Returns

object with 8 fields: eventId, revisionId, state, applied, priceCurrency, marketDataAdjustment, investorReturnDiagnostics, usFederalTaxIllustration

{
  "eventId": "SYN-ROC-2025-001",
  "revisionId": "SYN-ANNOUNCEMENT-R1",
  "state": "confirmed",
  "applied": true,
  "priceCurrency": "USD",
  "marketDataAdjustment": {
    "referencePrice": "25.00000000",
    "grossDistributionInPriceCurrency": "2.00000000",
    "theoreticalExPrice": "23.00000000",
    "backwardHistoryFactor": "0.92000000",
    "forwardPostEventFactor": "1.08695652",
    "factorDirection": "multiply_pre_ex_history_by_backwardHistoryFactor",
    "theoreticalPriceIsObservedTrade": false
  },
  "investorReturnDiagnostics": {
    "rawPriceReturn": "-0.07400000",
    "grossTotalReturn": "0.00600000",
    "netCashReturn": "0.00120000"
  },
  "usFederalTaxIllustration": {
    "basisPerShareAfter": "0.30000000",
    "basisReductionPerShare": "1.20000000",
    "excessOverBasisPerShare": "0.00000000"
  }
}

Diagrams

Return-of-Capital Adjustment — article hero
Return-of-Capital Adjustment — failure guard
Return-of-Capital Adjustment — worked example

Calculation flow

Point-in-time calculation flow
flowchart LR
    A["Event revisions"] --> B{"availableAt <= asOf?"}
    P["Price and FX observations"] --> C{"observedAt <= availableAt <= asOf?"}
    B -- "No" --> X["Exclude future revision"]
    B -- "Yes" --> D["Latest knowable revision"]
    C -- "No" --> R["Reject"]
    C -- "Yes" --> V["Validate ex boundary and ordering"]
    D --> V
    V --> M["Gross market-data factor"]
    V --> T["Observed price / gross / net returns"]
    V --> U["Optional scoped US basis illustration"]
Revision lifecycle
stateDiagram-v2
    [*] --> Announced
    Announced --> Revised: corrected terms become available
    Announced --> Confirmed: terms remain effective
    Revised --> Confirmed: latest terms validated
    Announced --> Cancelled: cancellation becomes available
    Revised --> Cancelled: cancellation becomes available
    Confirmed --> Corrected: later quantitative evidence
    Corrected --> Confirmed: corrected revision selected
    Cancelled --> [*]

How it works

This page states the contract — how to call it correctly. The article explains the concept: why it works, and where it breaks.

Read the article →

References

  • FTSE Russell Corporate Actions and Events Guide for Non-Market Capitalisation Weighted Indices
  • IRS Publication 550 (2025), Investment Income and Expenses
  • Instructions for Form 8937 (12/2017)
  • Logility Supply Chain Solutions announces tax treatment of 2024 distributions
  • Evidence classification