CRSP Cumulative Price Adjustment
Respect the Vendor Basis, Sign, and Gaps
Install and import#
npm install fintech-algorithmsimport { calculate } from "fintech-algorithms/corporate-actions-and-security-master-data/adjustment-factors/crsp-cumulative-price-adjustment";Signature#
calculate(input)The CRSP cumulative adjustment-factor convention, which is what academic finance means by an adjusted price. Reproducing published research requires this convention specifically, not a plausible equivalent.
Parameters#
| Name | Type | Notes |
|---|---|---|
input | { crspConvention: string; crspSourceVersion: string; packageSecurityKey: string; crspBaseDate: string; crspGapPolicy: string; roundingDecimals: number; crspFactorEvents: FactorEvent[]; records: Record[] } | crspConvention and crspSourceVersion pin which vintage of the convention is being applied — CRSP has revised it, and results differ. crspGapPolicy decides what happens across missing observations, and roundingDecimals fixes the rounding so the same input reproduces bit-for-bit. |
Returns#
{ crspConvention, crspBaseDate, crspPriceFormula, crspFactorEvents, crspFactorChangeDates, records, … }
Adjusted records together with the exact formula and factor-change dates applied — the provenance a replication needs in order to be checkable.
Errors#
- When the convention or source version is unrecognised — throws
Complexity: time O(n + e),
space O(n).
Worked example#
verified This is the worked example published in the article, replayed by the test suite on every run. The output cannot drift.
Input#
{
"crspConvention": "CRSPAccess-ts_print-cumfacpr-archived",
"crspSourceVersion": "Archived CRSP Stock and Index Data Description Guide convention; synthetic extract v1",
"packageSecurityKey": "SYNTHETIC-SECURITY-001",
"crspBaseDate": "2024-06-10",
"crspGapPolicy": "stop-at-unknown-exchange",
"roundingDecimals": 6,
"crspFactorEvents": [
{
"crspExdt": "2024-06-10",
"crspFacpr": 1,
"syntheticLabel": "Synthetic 2-for-1 split-like CRSP event"
}
],
"records": [
{
"date": "2024-06-06",
"crspPrc": 120,
"crspCumfacpr": 0.5,
"crspPriceKind": "trade",
"coverageStatus": "observed"
},
{
"date": "2024-06-07",
"crspPrc": -123,
"crspCumfacpr": 0.5,
"crspPriceKind": "bid_ask_average",
"coverageStatus": "observed"
},
{
"date": "2024-06-10",
"crspPrc": 60,
"crspCumfacpr": 1,
"crspPriceKind": "trade",
"coverageStatus": "observed"
}
]
}Call#
calculate(input)Returns#
object with 10 fields: crspConvention, crspSourceVersion, packageSecurityKey, crspBaseDate, crspGapPolicy, crspPriceFormula, crspFactorEvents, crspFactorChangeDates, …
{
"crspConvention": "CRSPAccess-ts_print-cumfacpr-archived",
"crspSourceVersion": "Archived CRSP Stock and Index Data Description Guide convention; synthetic extract v1",
"packageSecurityKey": "SYNTHETIC-SECURITY-001",
"crspBaseDate": "2024-06-10",
"crspGapPolicy": "stop-at-unknown-exchange",
"crspPriceFormula": "CRSP adjusted price = CRSP PRC * CRSP CUMFACPR",
"crspFactorEvents": [
{
"crspExdt": "2024-06-10",
"crspFacpr": 1,
"syntheticLabel": "Synthetic 2-for-1 split-like CRSP event"
}
],
"crspFactorChangeDates": ["2024-06-10"],
"roundingDecimals": 6,
"records": [
{
"date": "2024-06-06",
"crspPrc": 120,
"crspCumfacpr": 0.5,
"crspAdjustedPrice": 60,
"crspAdjustedMagnitude": 60,
"crspRecoveredPrc": 120,
"crspPriceKind": "trade",
"coverageStatus": "observed",
"status": "CRSP_ADJUSTED_TRADE"
},
{
"date": "2024-06-07",
"crspPrc": -123,
"crspCumfacpr": 0.5,
"crspAdjustedPrice": -61.5,
"crspAdjustedMagnitude": 61.5,
"crspRecoveredPrc": -123,
"crspPriceKind": "bid_ask_average",
"coverageStatus": "observed",
"status": "CRSP_ADJUSTED_BID_ASK_AVERAGE"
},
{
"date": "2024-06-10",
"crspPrc": 60,
"crspCumfacpr": 1,
"crspAdjustedPrice": 60,
"crspAdjustedMagnitude": 60,
"crspRecoveredPrc": 60,
"crspPriceKind": "trade",
"coverageStatus": "observed",
"status": "CRSP_ADJUSTED_TRADE"
}
]
}Diagrams#
Calculation flow#
Archived CRSPAccess cumulative-price calculation flow
flowchart LR
A["Archived CRSPAccess row"] --> B{"CRSP coverage state"}
B -->|Observed| C{"CRSP price kind"}
B -->|Unknown-exchange gap| G["CRSP factor gap: missing"]
B -->|Post-delisting unpriced| D["CRSP delisting state: missing"]
C -->|Trade or bid/ask average| E["CRSP PRC × CRSP CUMFACPR"]
C -->|Zero missing sentinel| M["CRSP price missing"]
E --> F["Signed CRSP result + magnitude + reverse check"]
CRSP evidence and result lifecycle
stateDiagram-v2
[*] --> VersionScoped
VersionScoped --> BaseAnchored: CRSP base row has CUMFACPR 1.0
BaseAnchored --> Calculable: observed CRSP price and positive factor
BaseAnchored --> Missing: zero price, factor gap, or unpriced delisting
Calculable --> Derived: CRSP PRC multiplied by CRSP CUMFACPR
Derived --> Audited: sign, magnitude, source, and reverse check retained
Missing --> Audited: reason retained without imputation
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#
- CRSP Stock and Index Data Description Guide, CRSPAccess
- CRSP Programmer's Guide
- Important Notice: CRSP US Stock & Indexes Databases Flat File Format 2.0 (CIZ)
- CRSP Policies & Statements
- Historical-example evidence decision