Ratio-Adjusted Summation Index (RASI)
Install and import#
npm install fintech-algorithmsimport { calculate } from "fintech-algorithms/market-breadth-and-internals/mcclellan-family/ratio-adjusted-summation-index-rasi";Signature#
calculate(records, cutoff)RASI: the summation index built on the ratio-adjusted oscillator. Scaling A−D by 1000/(A+D) makes each input invariant when advances and declines grow together, so issue-count growth does not dominate the scale. Threshold levels remain historical practice, not universal rules.
Parameters#
| Name | Type | Notes |
|---|---|---|
records | BreadthRecord[] | Session records carrying session_sequence, revision, available_at, event_type, source_evidence_state, the six series identity fields (venue_id, universe_id, methodology_id, calendar_id, volume_unit, volume_adjustment_basis), and the advances and declines counts the ratio adjustment consumes. |
cutoff | string | Point-in-time bound. Revisions arriving after the cutoff are ignored rather than applied, so the series is exactly what was computable at that moment. Breadth data is revised routinely, and a cumulative line silently rebuilt from revised inputs is not the line anyone traded. |
Returns#
{ status, reason_codes, points, latest_oscillator, latest_index_value, ignored_future_records, seed_policy, initial_index }
status is resolved, incomplete, ambiguous, or unsupported; only a resolved result carries points. Each point holds its session date, the transformed input, both EMA states, the oscillator, the cumulative index value, and a warm-up status of warming_fast, warming_slow or ready — the first oscillator appears at observation 39. seed_policy is sma_19_39 and initial_index is the accumulator's declared starting constant, 0.0.
Warm-up#
The first 39 observations positions are warm-up status: warming_fast, then warming_slow. Every point carries a warm-up status. Under the sma_19_39 seed policy the 19-period EMA resolves first and the 39-period EMA second, so the first oscillator and the first summation-index step both appear at observation 39.
Errors#
- When evidence is missing or inconsistent: no record at the cutoff, a gap in the session sequence, a duplicate or non-contiguous revision, a cancelled session, a source not yet ready, or a break in series identity — returned as a non-resolved status with reason_codes; not thrown
- When a record is malformed: a timestamp not ending in Z, a non-positive session_sequence, a negative revision, an empty identity field, a non-finite or negative count, or advances + declines equal to zero, which leaves the ratio undefined — throws ValueError
Complexity: time O(n log n) for n records: sessions and per-session revisions are sorted before the head revision is taken, then the EMA recursion is a single linear pass,
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#
[
{
"session_date": "2026-01-02",
"session_sequence": 1,
"effective_at": "2026-01-02T21:00:00Z",
"available_at": "2026-01-02T21:20:00Z",
"revision": 0,
"event_type": "upsert",
"source_evidence_state": "ready",
"venue_id": "SYNTH-X",
"universe_id": "SYNTH-STABLE-200",
"methodology_id": "close-vs-comparable-prior-close-v1",
"calendar_id": "SYNTH-WEEKDAY",
"volume_unit": "shares",
"volume_adjustment_basis": "reported-unadjusted",
"advances": 100
}
]"2026-04-01T00:00:00Z"Call#
calculate(records, cutoff)Returns#
object with 4 fields: status, latest_oscillator, latest_index_value, ignored_future_records
{
"status": "resolved",
"latest_oscillator": null,
"latest_index_value": null,
"ignored_future_records": 0
}Other exports#
This module also exports
transformRecord, calculateValues. 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#
Calculation flow#
Ratio-Adjusted Summation Index (RASI) calculation flow
flowchart TD
A["Records available at knowledge cutoff"] --> B{"Contiguous, unique, ready evidence?"}
B -->|No| C["Withhold path and report reason"]
B -->|Yes| D["Apply Ratio-Adjusted Summation Index (RASI) input transform"]
D --> E["SMA-19 fast seed and 10% Trend"]
D --> F["SMA-39 slow seed and 5% Trend"]
E --> G{"Both states ready?"}
F --> G
G -->|No| H["Warm-up diagnostics"]
G -->|Yes| I["Fast minus slow oscillator"]
I --> J["Add to declared cumulative state"]
J --> K["Provenance and current regime"]
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#
- Calculating the McClellan Oscillator — McClellan Financial Publications; Tom McClellan
- Ratio Adjusted Summation Index — McClellan Financial Publications; Tom McClellan
- The McClellan Oscillator and Summation Index — McClellan Financial Publications
- A-D definition — Nasdaq, Inc.
- Evidence reconciliation