fintech-algorithms
Using a coding agent? Give it the skill: npx skills add IslamBaraka90/Fintech-Algorithms-Library What it does →

Bonus-Issue EPS Restatement

Install and import#

bash
npm install fintech-algorithms
ts
import { bonusIssueEpsRestatement } from "fintech-algorithms/earnings-and-per-share-analytics/earnings-and-share-foundations/bonus-issue-eps-restatement";

Signature#

bonusIssueEpsRestatement(input)

Restates weighted-average ordinary shares and basic EPS for bonus issues, multiplying each period by the (existing + bonus) / existing factor of every event effective after that period's basis date. All arithmetic runs in 50-significant-digit decimal with half-even rounding and the money figures come back as exact decimal strings. A contract failure is rethrown as an Error whose message begins EPS calculation failed: .

Parameters#

NameTypeNotes
input{ events: Array<{ event_id, effective_date, existing_shares, bonus_shares, no_additional_consideration, event_is_effective }>, periods: Array<{ period_id, basis_date, basis_is_uniform, earnings_available_to_ordinary_shareholders, weighted_average_ordinary_shares, is_final }> }events and periods are both required and must be non-empty arrays. Each event needs a unique truthy event_id, an effective_date in YYYY-MM-DD form that is strictly later than the previous event's, existing_shares and bonus_shares as positive integer strings, and both no_additional_consideration and event_is_effective set to true. Each period needs a basis_date, basis_is_uniform set to true, and canonical decimal strings for earnings_available_to_ordinary_shareholders and weighted_average_ordinary_shares, the latter strictly positive. is_final is optional and defaults to false. There are no numeric tuning parameters and nothing else is defaulted.

Returns#

{ topic_id, state, periods, all_final }

state is always calculated. periods follows the input order and each row carries period_id, applied_event_ids, factor_numerator, factor_denominator, earnings, pre_restatement_shares, restated_shares, pre_restatement_basic_eps, restated_basic_eps and is_final. The factor is an exact reduced fraction reported as two integer strings, and every share and EPS figure is a decimal string. all_final is true only when every period row is final.

Errors#

  • When existing_shares or bonus_shares is not a positive integer string, for instance an existing_shares of 0 — throws Error
  • When an event_id repeats or the effective_date values are not strictly increasing, an event is not marked effective and free of additional consideration, a date is not a real YYYY-MM-DD value, weighted_average_ordinary_shares is not positive, or basis_is_uniform is not true — throws Error

Complexity: time O(e * p) for e events and p periods, space O(e + p).

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#

input
{
  "events": [
    {
      "event_id": "SYN-BONUS-1",
      "effective_date": "2025-03-15",
      "bonus_shares": "1",
      "existing_shares": "4",
      "no_additional_consideration": true,
      "event_is_effective": true
    },
    {
      "event_id": "SYN-BONUS-2",
      "effective_date": "2025-09-01",
      "bonus_shares": "1",
      "existing_shares": "10",
      "no_additional_consideration": true,
      "event_is_effective": true
    }
  ],
  "periods": [
    {
      "period_id": "SYN-2024",
      "period_start": "2024-01-01",
      "period_end": "2024-12-31",
      "basis_date": "2024-12-31",
      "basis_is_uniform": true,
      "earnings_available_to_ordinary_shareholders": "24000000",
      "weighted_average_ordinary_shares": "10000000",
      "is_final": true
    },
    {
      "period_id": "SYN-2025-Q3",
      "period_start": "2025-01-01",
      "period_end": "2025-09-30",
      "basis_date": "2025-03-15",
      "basis_is_uniform": true,
      "earnings_available_to_ordinary_shareholders": "-3300000",
      "weighted_average_ordinary_shares": "12500000",
      "is_final": false
    }
  ]
}

Call#

bonusIssueEpsRestatement(input)

Returns#

object with 4 fields: topic_id, state, periods, all_final

{
  "topic_id": "D46-F01-A06",
  "state": "calculated",
  "periods": [
    {
      "period_id": "SYN-2024",
      "applied_event_ids": ["SYN-BONUS-1", "SYN-BONUS-2"],
      "factor_numerator": "11",
      "factor_denominator": "8",
      "earnings": "24000000",
      "pre_restatement_shares": "10000000",
      "restated_shares": "13750000",
      "pre_restatement_basic_eps": "2.4",
      "restated_basic_eps": "1.7454545454545454545454545454545454545454545454545",
      "is_final": true
    },
    {
      "period_id": "SYN-2025-Q3",
      "applied_event_ids": ["SYN-BONUS-2"],
      "factor_numerator": "11",
      "factor_denominator": "10",
      "earnings": "-3300000",
      "pre_restatement_shares": "12500000",
      "restated_shares": "13750000",
      "pre_restatement_basic_eps": "-0.264",
      "restated_basic_eps": "-0.24",
      "is_final": false
    }
  ],
  "all_final": false
}

Diagrams#

Bonus-Issue EPS Restatement — bonus factor anatomy

Calculation flow#

Bonus-issue EPS restatement flow
flowchart LR
  A["Validated bonus event"] --> B{"No additional consideration?"}
  B -- "No" --> X["Use transaction-specific method"]
  B -- "Yes" --> C["Factor = (existing + bonus) ÷ existing"]
  P["Uniform period basis date"] --> D["Select later effective events"]
  C --> D
  D --> E["Multiply exact factors"]
  E --> F["Restated shares = source shares × factor"]
  G["Preserve earnings numerator"] --> H["Restated EPS = earnings ÷ restated shares"]
  F --> H
  H --> I["Round displays and emit lineage"]

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#

  • IAS 33 Earnings per Share
  • Statement No. 128, Earnings per Share
  • Filed 10% common stock dividend example
  • Research limits

The rest of the Earnings and Share Foundations family#