Delisting Return Reconstruction
Separate Observed Proceeds from Estimates
Install and import
npm install fintech-algorithmsimport { calculate } from "fintech-algorithms/corporate-actions-and-security-master-data/identity-continuity/delisting-return-reconstruction";Signature
calculate(input)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
{
"asOf": "2026-04-17T12:00:00Z",
"baseCurrency": "USD",
"previousRegularObservation": {
"securityId": "SYNTH-OLD-A",
"price": "48",
"currency": "USD",
"tradingAt": "2026-04-10T20:00:00Z",
"observedAt": "2026-04-10T20:00:00Z",
"sourceAt": "2026-04-10T20:01:00Z",
"availableAt": "2026-04-10T20:05:00Z",
"sourceId": "SYNTH-PRICES"
},
"lastRegularObservation": {
"securityId": "SYNTH-OLD-A",
"price": "50",
"currency": "USD",
"tradingAt": "2026-04-14T20:00:00Z",
"observedAt": "2026-04-14T20:00:00Z",
"sourceAt": "2026-04-14T20:01:00Z",
"availableAt": "2026-04-14T20:05:00Z",
"sourceId": "SYNTH-PRICES"
},
"event": {
"eventId": "SYNTH-EVENT-001",
"reason": "merger",
"effectiveAt": "2026-04-15T13:30:00Z",
"observedAt": "2026-04-01T14:00:00Z",
"sourceAt": "2026-04-01T14:01:00Z",
"availableAt": "2026-04-01T14:05:00Z",
"sourceId": "SYNTH-EVENTS"
},
"proceedsStatus": "complete",
"proceeds": [
{
"kind": "cash",
"amountPerOldShare": "10",
"currency": "EUR",
"effectiveAt": "2026-04-15T13:30:00Z",
"observedAt": "2026-04-15T15:00:00Z",
"sourceAt": "2026-04-15T15:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-PAYMENTS",
"fxToBase": {
"fromCurrency": "EUR",
"toCurrency": "USD",
"rate": "1.1",
"rateAt": "2026-04-15T20:00:00Z",
"observedAt": "2026-04-15T20:00:00Z",
"sourceAt": "2026-04-15T20:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-FX"
}
},
{
"kind": "stock",
"quantityPerOldShare": "0.8",
"successorSecurityId": "SYNTH-NEW-B",
"valuationPrice": "52.5",
"priceCurrency": "USD",
"valuationAt": "2026-04-15T20:00:00Z",
"observedAt": "2026-04-15T20:00:00Z",
"sourceAt": "2026-04-15T20:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-SUCCESSOR-PRICE",
"fxToBase": {
"fromCurrency": "USD",
"toCurrency": "USD",
"rate": "1",
"rateAt": "2026-04-15T20:00:00Z",
"observedAt": "2026-04-15T20:00:00Z",
"sourceAt": "2026-04-15T20:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-FX-IDENTITY"
}
}
],
"deductions": [
{
"kind": "fee",
"amountPerOldShare": "0.2",
"currency": "USD",
"effectiveAt": "2026-04-15T13:30:00Z",
"observedAt": "2026-04-15T21:00:00Z",
"sourceAt": "2026-04-15T21:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-FEES",
"fxToBase": {
"fromCurrency": "USD",
"toCurrency": "USD",
"rate": "1",
"rateAt": "2026-04-15T20:00:00Z",
"observedAt": "2026-04-15T20:00:00Z",
"sourceAt": "2026-04-15T20:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-FX-IDENTITY"
}
},
{
"kind": "withholding",
"amountPerOldShare": "0.3",
"currency": "USD",
"effectiveAt": "2026-04-15T13:30:00Z",
"observedAt": "2026-04-15T21:00:00Z",
"sourceAt": "2026-04-15T21:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-WITHHOLDING",
"fxToBase": {
"fromCurrency": "USD",
"toCurrency": "USD",
"rate": "1",
"rateAt": "2026-04-15T20:00:00Z",
"observedAt": "2026-04-15T20:00:00Z",
"sourceAt": "2026-04-15T20:01:00Z",
"availableAt": "2026-04-16T00:00:00Z",
"sourceId": "SYNTH-FX-IDENTITY"
}
}
],
"researchImputation": null
}Call
calculate(input)Returns
object with 3 fields: observed, researchEstimate, diagnostics
{
"observed": {
"status": "complete",
"lastRegularReturn": "0.041666666667",
"terminalGrossValuePerOldShare": "53.000000000000",
"deductionsPerOldShare": "0.500000000000",
"terminalNetValuePerOldShare": "52.500000000000",
"terminalReturn": "0.050000000000",
"linkedReturn": "0.093750000000",
"proceedsBasis": "complete_observed",
"knownObservedGrossValuePerOldShare": null,
"knownObservedDeductionsPerOldShare": null,
"knownObservedNetValuePerOldShare": null
},
"researchEstimate": null,
"diagnostics": {
"eventId": "SYNTH-EVENT-001",
"eventReason": "merger",
"asOf": "2026-04-17T12:00:00Z",
"effectiveAt": "2026-04-15T13:30:00Z",
"lastRegularTradingAt": "2026-04-14T20:00:00Z",
"observedEvidenceAvailable": true,
"missingEvidence": [],
"withheldEvidence": [],
"knownProceedsEvidence": [
"deductions[0]",
"deductions[0].fxToBase",
"deductions[1]",
"deductions[1].fxToBase",
"proceeds[0]",
"proceeds[0].fxToBase"
],
"baseCurrency": "USD"
}
}Diagrams
Calculation flow
Evidence-gated calculation flow
flowchart TD
A["Price and event records"] --> B["Validate decimals, identity, currency, and clocks"]
B --> C{"Available at as-of time?"}
C -->|No| D["Not yet available; returns null"]
C -->|Yes| E{"Event effective?"}
E -->|No| F["Event not effective; terminal return null"]
E -->|Yes| G["Value known cash, stock, FX, fees, and withholding"]
G --> H{"Proceeds evidence state"}
H -->|Complete| I["Observed terminal and linked returns"]
H -->|Explicit zero| I
H -->|Partial| J["Known subtotal; returns null"]
H -->|Unknown| K["Missing proceeds; returns null"]
L["Documented research policy"] --> M["Research estimate branch"]
M -. "Never fills observed fields" .-> I
Point-in-time evidence lifecycle
stateDiagram-v2
[*] --> EventUnavailable
EventUnavailable --> EventKnown: event available
EventKnown --> EventEffective: effective time reached
EventEffective --> ProceedsUnknown: no terminal evidence
EventEffective --> ProceedsPartial: some observed legs
EventEffective --> ProceedsComplete: complete observed legs
EventEffective --> ZeroConfirmed: explicit zero evidence
ProceedsUnknown --> ProceedsPartial: first observed leg
ProceedsPartial --> ProceedsComplete: completeness established
ProceedsUnknown --> ResearchEstimate: documented policy
ProceedsPartial --> ResearchEstimate: documented policy
ResearchEstimate --> ResearchEstimate: later estimates remain labeled
ResearchEstimate --> ProceedsComplete: observed branch completes separately
ProceedsComplete --> [*]
ZeroConfirmed --> [*]
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.
References
- R1 - CRSPAccess US Stock and Index Databases Data Descriptions Guide
- R2 - CRSP US Stock and Indexes Databases Data Descriptions Guide
- R3 - Nasdaq Daily List Product Description
- R4 - SEC Exchange Delistings
- R5 - SEC Exchange Act Forms, Section 111.01
- Evidence boundary for historical examples