fintech-algorithms

Cash-Dividend Total-Return Adjustment

From Price Drop to Exact Return

Install and import

bash
npm install fintech-algorithms
ts
import { calculate } from "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/cash-dividend-total-return-adjustment";

Signature

calculate(data)

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

data
{
  "asOf": "2026-01-09T23:00:00Z",
  "returnVariant": "gross",
  "priceCurrency": "USD",
  "anchorBasis": "latest_raw_close",
  "specialDistributionPolicy": "exclude",
  "observations": [
    {
      "date": "2026-01-02",
      "close": 100,
      "availableAt": "2026-01-02T21:01:00Z"
    },
    {
      "date": "2026-01-05",
      "close": 102,
      "availableAt": "2026-01-05T21:01:00Z"
    },
    {
      "date": "2026-01-06",
      "close": 99,
      "availableAt": "2026-01-06T21:01:00Z"
    }
  ],
  "eventRevisions": [
    {
      "eventId": "SYNTH-DIV-A",
      "revision": 1,
      "status": "confirmed",
      "classification": "ordinary",
      "exDate": "2026-01-06",
      "grossDividend": 2.5,
      "dividendCurrency": "USD",
      "withholdingRate": 0.15,
      "fxRateToPriceCurrency": 1,
      "fxObservedAt": null,
      "availableAt": "2026-01-05T15:00:00Z",
      "sourceId": "SYNTHETIC-ACTION-FEED"
    },
    {
      "eventId": "SYNTH-DIV-A",
      "revision": 2,
      "status": "confirmed",
      "classification": "ordinary",
      "exDate": "2026-01-06",
      "grossDividend": 3,
      "dividendCurrency": "USD",
      "withholdingRate": 0.15,
      "fxRateToPriceCurrency": 1,
      "fxObservedAt": null,
      "availableAt": "2026-01-05T18:00:00Z",
      "sourceId": "SYNTHETIC-ACTION-FEED"
    },
    {
      "eventId": "SYNTH-SPECIAL-B",
      "revision": 1,
      "status": "confirmed",
      "classification": "special",
      "exDate": "2026-01-08",
      "grossDividend": 3,
      "dividendCurrency": "USD",
      "withholdingRate": 0.15,
      "fxRateToPriceCurrency": 1,
      "fxObservedAt": null,
      "availableAt": "2026-01-07T18:00:00Z",
      "sourceId": "SYNTHETIC-ACTION-FEED"
    }
  ]
}

Call

calculate(data)

Returns

object with 11 fields: methodology, returnVariant, priceCurrency, asOf, anchor, adjustedPrices, cumulativeFactors, eventAdjustments, …

{
  "methodology": "backward_adjusted_ex_date_close_total_return",
  "returnVariant": "gross",
  "priceCurrency": "USD",
  "asOf": "2026-01-09T23:00:00Z",
  "anchor": {
    "basis": "latest_raw_close",
    "date": "2026-01-09",
    "rawClose": 100
  },
  "adjustedPrices": [97.058823529412, 99, 99, 101, 98, 100],
  "cumulativeFactors": [0.970588235294, 0.970588235294, 1, 1, 1, 1],
  "eventAdjustments": [
    {
      "exDate": "2026-01-06",
      "exIndex": 2,
      "eventIds": ["SYNTH-DIV-A"],
      "selectedRevisions": [2],
      "sourceIds": ["SYNTHETIC-ACTION-FEED"],
      "priorClose": 102,
      "exDateClose": 99,
      "grossDividendPriceCurrency": 3,
      "effectiveDividend": 3,
      "backwardFactor": 0.970588235294,
      "factorAppliesTo": "indices < 2"
    }
  ],
  "returnLinks": [
    {
      "date": "2026-01-05",
      "priceReturn": 0.02,
      "totalReturn": 0.02,
      "effectiveDividend": 0
    },
    {
      "date": "2026-01-06",
      "priceReturn": -0.029411764706,
      "totalReturn": 0,
      "effectiveDividend": 3
    },
    {
      "date": "2026-01-07",
      "priceReturn": 0.020202020202,
      "totalReturn": 0.020202020202,
      "effectiveDividend": 0
    }
  ],
  "excludedEvents": [
    {
      "eventId": "SYNTH-CANCELLED-C",
      "selectedRevision": 2,
      "reason": "cancelled"
    },
    {
      "eventId": "SYNTH-SPECIAL-B",
      "selectedRevision": 1,
      "reason": "special_excluded_by_policy"
    }
  ],
  "rounding": {
    "internal": "unrounded IEEE-754 binary64",
    "serializedDecimalPlaces": 12,
    "factorCompounding": "multiply unrounded factors, round only serialized output"
  }
}

Diagrams

Cash-Dividend Total-Return Adjustment — article hero
Cash-Dividend Total-Return Adjustment — failure guard
Cash-Dividend Total-Return Adjustment — worked example

Calculation flow

Revision-aware total-return calculation
flowchart LR
    A["Raw closes and event revisions"] --> B["Validate order, prices, timestamps, and currencies"]
    B --> C["Select latest revision available by as-of"]
    C --> D{"Confirmed and eligible?"}
    D -->|No| E["Exclude with reason"]
    D -->|Yes| F["Resolve ex-date, class, FX, and withholding"]
    F --> G{"Cash below prior close?"}
    G -->|No| H["Reject undefined case"]
    G -->|Yes| I["Calculate return link and ex-date-close factor"]
    I --> J["Compound unrounded factors backward"]
    J --> K["Emit anchor, links, sources, revisions, and rounding"]
Point-in-time event revision lifecycle
stateDiagram-v2
    [*] --> Unavailable
    Unavailable --> Available: publication reaches as-of
    Available --> Selected: highest available revision
    Selected --> Eligible: confirmed and policy included
    Selected --> Excluded: cancelled or policy excluded
    Eligible --> Applied: ex-date and inputs resolved
    Applied --> Audited
    Excluded --> Audited
    Available --> Available: later revision retained

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

  • R1 - S&P DJI Index Mathematics Methodology
  • R2 - FR Global Equity Corporate Action Methodology
  • R3 - Apple July 30, 2020 Form 8-K filing detail
  • R4 - Apple Reports Third Quarter Results, Exhibit 99.1
  • R5 - Apple Dividend History
  • R6 - RFC 3339 and RFC 9557