fintech-algorithms

Stock-Dividend Adjustment

Convert Price and Quantity Bases Without Inventing Value

Install and import

bash
npm install fintech-algorithms
ts
import { calculate } from "fintech-algorithms/corporate-actions-and-security-master-data/complex-distributions/stock-dividend-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
{
  "method": "backward_post_event_same_class",
  "securityId": "SYNTH-CLASS-A",
  "asOf": "2026-02-04T12:00:00Z",
  "anchorAt": "2026-02-03T21:00:00Z",
  "volumePolicy": "adjust_to_anchor_basis",
  "events": [
    {
      "eventId": "SD-001",
      "subjectSecurityId": "SYNTH-CLASS-A",
      "distributedSecurityId": "SYNTH-CLASS-A",
      "exAt": "2026-01-15T14:30:00Z",
      "recordDate": "2026-01-15",
      "payableDate": "2026-01-20",
      "revisions": [
        {
          "publishedAt": "2026-01-05T18:00:00Z",
          "status": "confirmed",
          "rateNewSharesPerOld": 0.1,
          "sourceId": "SYNTH-NOTICE-1"
        }
      ]
    },
    {
      "eventId": "SD-002",
      "subjectSecurityId": "SYNTH-CLASS-A",
      "distributedSecurityId": "SYNTH-CLASS-A",
      "exAt": "2026-02-03T14:30:00Z",
      "recordDate": "2026-01-30",
      "payableDate": "2026-02-02",
      "revisions": [
        {
          "publishedAt": "2026-01-20T18:00:00Z",
          "status": "confirmed",
          "rateNewSharesPerOld": 0.15,
          "sourceId": "SYNTH-NOTICE-2-R1"
        },
        {
          "publishedAt": "2026-01-25T18:00:00Z",
          "status": "confirmed",
          "rateNewSharesPerOld": 0.2,
          "sourceId": "SYNTH-NOTICE-2-R2"
        }
      ]
    }
  ],
  "observations": [
    {
      "at": "2026-01-02T21:00:00Z",
      "availableAt": "2026-01-02T21:00:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "price": 50,
      "shares": 200,
      "volume": 80
    },
    {
      "at": "2026-02-02T21:00:00Z",
      "availableAt": "2026-02-02T21:00:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "price": 55,
      "shares": 220,
      "volume": 90
    },
    {
      "at": "2026-02-03T14:30:00Z",
      "availableAt": "2026-02-03T14:30:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "price": 46,
      "shares": 264,
      "volume": 100
    }
  ]
}

Call

calculate(data)

Returns

object with 9 fields: method, securityId, asOf, anchorAt, volumePolicy, appliedEvents, unavailableEventIds, cancelledEventIds, …

{
  "method": "backward_post_event_same_class",
  "securityId": "SYNTH-CLASS-A",
  "asOf": "2026-02-04T12:00:00Z",
  "anchorAt": "2026-02-03T21:00:00Z",
  "volumePolicy": "adjust_to_anchor_basis",
  "appliedEvents": [
    {
      "eventId": "SD-001",
      "exAt": "2026-01-15T14:30:00Z",
      "revisionPublishedAt": "2026-01-05T18:00:00Z",
      "knownByExDate": true,
      "rateNewSharesPerOld": 0.1,
      "shareFactor": 1.1,
      "priceFactor": 0.909090909091,
      "sourceId": "SYNTH-NOTICE-1"
    },
    {
      "eventId": "SD-002",
      "exAt": "2026-02-03T14:30:00Z",
      "revisionPublishedAt": "2026-01-25T18:00:00Z",
      "knownByExDate": true,
      "rateNewSharesPerOld": 0.2,
      "shareFactor": 1.2,
      "priceFactor": 0.833333333333,
      "sourceId": "SYNTH-NOTICE-2-R2"
    }
  ],
  "unavailableEventIds": [],
  "cancelledEventIds": [],
  "rows": [
    {
      "at": "2026-01-02T21:00:00Z",
      "availableAt": "2026-01-02T21:00:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "rawPrice": 50,
      "adjustedPrice": 37.878787878788,
      "rawShares": 200,
      "adjustedShares": 264,
      "rawVolume": 80,
      "adjustedVolume": 105.6,
      "cumulativeShareFactor": 1.32,
      "appliedEventIds": ["SD-001", "SD-002"]
    },
    {
      "at": "2026-02-02T21:00:00Z",
      "availableAt": "2026-02-02T21:00:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "rawPrice": 55,
      "adjustedPrice": 45.833333333333,
      "rawShares": 220,
      "adjustedShares": 264,
      "rawVolume": 90,
      "adjustedVolume": 108,
      "cumulativeShareFactor": 1.2,
      "appliedEventIds": ["SD-002"]
    },
    {
      "at": "2026-02-03T14:30:00Z",
      "availableAt": "2026-02-03T14:30:05Z",
      "sourceId": "SYNTH-CLOSES-V1",
      "rawPrice": 46,
      "adjustedPrice": 46,
      "rawShares": 264,
      "adjustedShares": 264,
      "rawVolume": 100,
      "adjustedVolume": 100,
      "cumulativeShareFactor": 1,
      "appliedEventIds": []
    }
  ]
}

Other exports

This module also exports settleEntitlement, roundOutput. Every module additionally exports run as an alias of its primary function, and a meta object carrying its catalog id, domain, family, shape and article URL.

Diagrams

Stock-Dividend Adjustment — article hero
Stock-Dividend Adjustment — failure guard
Stock-Dividend Adjustment — worked example

Calculation flow

Revision selection and adjustment flow
flowchart LR
    A["Raw event revisions"] --> B["Keep publishedAt not later than asOf"]
    B --> C["Choose latest unique revision"]
    C --> D{"Status and class valid?"}
    D -->|Cancelled| E["Report cancellation"]
    D -->|Wrong class| F["Reject method"]
    D -->|Confirmed same class| G{"Observation before exAt?"}
    G -->|No| H["Keep new-basis row"]
    G -->|Yes| I["Compound factor"]
    I --> J["Divide price"]
    I --> K["Multiply shares"]
    I --> L["Adjust or preserve volume"]
    J --> M["Audited output"]
    K --> M
    L --> M
Event evidence lifecycle
stateDiagram-v2
    [*] --> Unavailable
    Unavailable --> Announced: first publication
    Announced --> Confirmed: authoritative terms
    Announced --> Cancelled: source cancellation
    Confirmed --> Effective: exAt reached
    Confirmed --> Revised: later publication
    Revised --> Confirmed: terms replace prior revision
    Revised --> Cancelled: later cancellation
    Effective --> Restated: later correction selected by current asOf
    Effective --> Historical: earlier asOf retains earlier evidence
    Cancelled --> [*]
    Restated --> [*]
    Historical --> [*]

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 - NVIDIA 2021 stock-split announcement filed with the SEC — NVIDIA Corporation
  • R2 - NVIDIA 2021 Stock Split FAQ — NVIDIA Corporation
  • R3 - FINRA Rule 11140 — Financial Industry Regulatory Authority
  • R4 - Nasdaq Daily List File Format and Specifications — Nasdaq
  • R5 - FTSE Russell Corporate Actions and Events Guide for Market Capitalisation Weighted Indices — FTSE Russell, LSEG
  • R6 - S&P DJI Index Mathematics Methodology — S&P Dow Jones Indices
  • Evidence classification