The governed definitions this build depends on. Read them first if a term is unfamiliar.
- PrimaryCumulative TICKCumulative TICK is a running total of Market TICK observations over a declared accumulation interval.
- PrerequisiteDowntickDowntick is a trade-price classification indicating a decrease from the applicable comparison price.
- PrerequisiteMarket TICK IndicatorThe Market TICK Indicator is the number of eligible issues trading on an uptick minus those trading on a downtick at a timestamp.
- PrerequisiteUptickUptick is a trade-price classification indicating an increase from the applicable comparison price.
- ImportantBreadth Scale FactorThe breadth scale factor multiplies a normalized issue-balance ratio into a declared reporting scale.
- ImportantCumulative Starting LevelThe declared initial constant from which a cumulative recurrence begins before accepted increments are added.
- ImportantCumulative StateA persisted running value updated by adding each newly accepted increment to the previous accumulated value.
The hidden decision
An intraday cumulative line can look smooth while silently jumping over a missing snapshot; the clock is part of the calculation.
Cumulative TICK answers one bounded question: what is the session-running balance of exchange issues last trading on upticks versus downticks? Its value is not a prediction. Its value is an auditable state whose inputs, time, units, and failure conditions are visible.
By the end, you will be able to calculate the method, reproduce its synthetic case, inspect its implementation trace, and decide when the output must be withheld.
Build the mental model
Sample one exchange universe on an exact timezone-bearing grid, subtract downtick from uptick issues at each sample, and accumulate from a session seed.
Instantaneous TICK is one cross-section. Cumulative TICK is a path-dependent sum whose identity includes interval, grid anchor, session, universe, and reset.
The highlighted family card is a scope boundary. Count breadth, volume composition, recursive pressure, intraday sampling, and causal divergence can all produce lines, but their units and state memories are not interchangeable.
Freeze the contract before calculating
The selected formulation is:
Sample one declared exchange universe every minute and reset the cumulative seed to zero at the regular-session open. Publication invariant: A sampling gap, session change, universe change, or non-monotone timestamp makes the cumulative tail incomplete.
The input table in the canonical README defines row fields and units. The parameter table distinguishes a sourced method from package choices such as equality behavior, seed, zero policy, sampling grid, normalized breadth scale, and event timestamp.
Glossary: TICK supports this bounded source role: tick is the number of issues on upticks minus issues on downticks at a point in the session; unchanged last trades are neutral. It does not override the limitations recorded in REFERENCES.md, and it does not establish historical performance.
Reproduce the synthetic result
Every observation below is synthetic. The arithmetic is author-derived:
| Exact one-minute window | TICK subtotal | Cumulative TICK |
|---|---|---|
| 09:30–09:35 | 300 | 300 |
| 09:36–09:41 | 140 | 440 |
| 09:42–09:47 | 220 | 660 |
| 09:48–09:53 | 160 | 820 |
| 09:54–09:59 | 220 | 1040 |
| 10:00–10:05 | 340 | 1380 |
Every adjacent timestamp is exactly 60 seconds apart and carries an explicit UTC offset. Removing the 09:54 observation creates a 120-second gap and changes the result to incomplete / sampling_gap rather than bridging the missing sample.
The expected output is:
{
"status": "resolved",
"value": 1380
}
The SVG is not a decorative output card. It isolates the algorithm's actual learning obstacle: the final cumulative value hides the sampling grid and any missing snapshot. Notice the labels and dashed or branched boundaries; color is supplementary.
Calculation flow
The Mermaid diagram renders from visuals/mermaid/calculation-flow.md and follows this pseudocode:
validate positive integer interval and one session
for each timezone-bearing snapshot:
require exact interval_seconds from the prior timestamp
tick = uptick_issues - downtick_issues
cumulative = cumulative + tick
return cumulative path or stop at the first grid defect
Validation comes first so bad evidence cannot mutate later state. That rule is especially important for recursive lines, timestamp grids, arming clocks, and right-side pivot confirmation.
Read the implementation
Python and TypeScript both:
- validate finite inputs and the topic's identity/clock rules;
- compute the named intermediate values;
- preserve the trace needed to audit the result; and
- return a numeric value or typed event only when the publication boundary passes.
They share datasets/canonical-fixture.json, including expected output and parameters. The code avoids provider SDKs and hidden network calls so the teaching arithmetic is fully inspectable.
Use the guided lab
Open visuals/animated/playground.html. Its objective is to step through an exact one-minute grid and compare a mirrored path with a genuine missing interval.
The initial screen is the completed canonical state. Back and Step reveal one observation at a time; Play uses the same transition function; Pause stops it; Reset restores the scenario and parameter. Comparison isolates a nearby outcome, while Failure / boundary demonstrates a reason code rather than a persuasive fake value. Reduced-motion Play advances one deterministic step without starting a timer.
The diagnostic panel and audit table should be read together. A smooth chart alone cannot prove denominator topology, chronological completeness, sampling continuity, or causal confirmation.
Operational interpretation
Use the sampling audit to prove that every interval exists before interpreting the session-running issue-snapshot balance.
Do not misuse it: Do not bridge a missing interval, merge sessions, or compare differently sampled cumulative paths as though they were the same series.
Passing the implementation checks proves definition fidelity. It does not prove reversal prediction, causal market explanation, trading profitability, transferability to another universe, or performance after costs.
Edge cases worth testing
- A timestamp gap that differs from interval_seconds invalidates the cumulative tail.
- A session change requires a new series and seed rather than an in-place continuation.
- Non-monotone timestamps and timezone-free strings are incomplete evidence.
- Changing the sampling interval changes the object even when the raw event stream is identical.
Provider corrections require recomputing the affected tail or event set. A corrected observation that becomes available later must not leak into an earlier point-in-time result.
Evidence and historical boundary
A named historical reconstruction remains deferred. Publication would require a licensed point-in-time universe, exact classification rules, synchronized observations, session and sampling policy, correction lineage, the selected calculation convention, a knowledge cutoff, and redistribution rights.
Using a famous chart without that bundle would make the story stronger and the evidence weaker. The labelled synthetic fixture is therefore the responsible public example.
Summary and handoff
You can now calculate TICK_k = U_k-D_k; CTICK_k = CTICK_{k-1}+TICK_k, interpret issue-snapshots, audit the method-specific boundary, and reproduce matching Python and TypeScript behavior. Review Net Advances for the immediate input concept. Continue with Breadth-Divergence Detector in the dependency path.
Rendered from the canonical Mermaid sources linked by this article.
Calculation Flow — Cumulative TICK
Purpose: The final cumulative value hides the sampling grid and any missing snapshot.
Takeaway: No complete grid, no complete cumulative path.
ReferencesPrimary sources and evidence notesExpand the source trail, evidence role, and limitations behind the engineering choices.
Expand the source trail, evidence role, and limitations behind the engineering choices.
Claim-to-source map
| Source ID | What it supports | Boundary |
|---|---|---|
STOCKCHARTS-TICK | TICK is the number of issues on upticks minus issues on downticks at a point in the session; unchanged last trades are neutral. | The source defines instantaneous TICK, not this package's one-minute cumulative sampling contract. |
NYSE-REALTIME | Real-time trades and last-sale data are licensed venue products with event and session semantics. | A feed subscription and constituent classification logic are required to reconstruct TICK; no observations are redistributed here. |
NYSE-TECHDOCS | Official trade, TAQ, volume, and reference feeds are versioned products with exchange, field, and delivery semantics. | The document index does not define a universal Cumulative TICK formula or provide public classified issue snapshots. |
The formula/concept source and the data-provenance source do different jobs. Exchange product documentation establishes venue fields, versioned feeds, and licensing boundaries; it does not silently define every derived indicator. Package-selected zero, seed, refresh, sampling, scale, and confirmation rules remain implementation choices.
STOCKCHARTS-TICK — Glossary: TICK
- Organization or authors: StockCharts ChartSchool
- Source type: Maintained provider glossary
- Publication or effective date: Current documentation
- Version or retrieval state: Exact page or PDF retrieved 2026-07-26
- URL: https://chartschool.stockcharts.com/table-of-contents/glossary/glossary-t
- Accessed: 2026-07-26
- Jurisdiction or applicability: NYSE and Nasdaq provider series
- Evidence role: sourced/provider convention
- Supports: TICK is the number of issues on upticks minus issues on downticks at a point in the session; unchanged last trades are neutral.
- Limitations: The source defines instantaneous TICK, not this package's one-minute cumulative sampling contract.
NYSE-REALTIME — NYSE Real-Time Data
- Organization or authors: New York Stock Exchange
- Source type: Official market-data product documentation
- Publication or effective date: Current product page
- Version or retrieval state: Exact page or PDF retrieved 2026-07-26
- URL: https://www.nyse.com/market-data/real-time
- Accessed: 2026-07-26
- Jurisdiction or applicability: NYSE Group markets
- Evidence role: sourced/provider convention
- Supports: Real-time trades and last-sale data are licensed venue products with event and session semantics.
- Limitations: A feed subscription and constituent classification logic are required to reconstruct TICK; no observations are redistributed here.
NYSE-TECHDOCS — NYSE Proprietary Data Products Technical Documents
- Organization or authors: New York Stock Exchange
- Source type: Official current specification index
- Publication or effective date: Current index accessed 2026-07-26
- Version or retrieval state: Exact page or PDF retrieved 2026-07-26
- URL: https://www.nyse.com/market-data/technical-documents
- Accessed: 2026-07-26
- Jurisdiction or applicability: NYSE Group market-data products
- Evidence role: sourced/provider convention
- Supports: Official trade, TAQ, volume, and reference feeds are versioned products with exchange, field, and delivery semantics.
- Limitations: The document index does not define a universal Cumulative TICK formula or provide public classified issue snapshots.
Historical-example decision
Deferred. A named reconstruction requires the exact point-in-time universe, classification method, timestamps, correction lineage, session rules, calculation convention, and redistribution rights. This public package publishes labelled synthetic inputs and author-derived arithmetic instead. It makes no historical-association, prediction, causation, or profitability claim.
Full dependency-light reference implementations in both supported languages.
export type Result = Record<string, any>;
const numberValue = (value: unknown, name: string): number => {
if (typeof value !== "number" || !Number.isFinite(value)) throw new Error(`${name} must be a finite number`);
return value;
};
export function calculate(rows:any[],seed=0,intervalSeconds=60):Result {
if(!rows.length)return{status:"incomplete",reason:"no observations",value:null,series:[]};
if(!Number.isInteger(intervalSeconds)||intervalSeconds<=0)throw new Error("intervalSeconds must be a positive integer");
let value=numberValue(seed,"seed"),previous:number|null=null,session:string|null=null;const series:any[]=[];
for(const row of rows){if(row.ready===false)return{status:"incomplete",reason:"unready snapshot",value:null,series};
if(session===null)session=row.session_id;if(row.session_id!==session)return{status:"incomplete",reason:"session changed",value:null,series};
if(typeof row.timestamp!=="string"||!/(Z|[+-]\d{2}:\d{2})$/.test(row.timestamp))return{status:"incomplete",reason:"timestamp_requires_timezone",value:null,series};
const observedAt=Date.parse(row.timestamp);if(Number.isNaN(observedAt))return{status:"incomplete",reason:"invalid_timestamp",value:null,series};
if(previous!==null){const elapsed=(observedAt-previous)/1000;if(elapsed<=0)return{status:"incomplete",reason:"timestamps_must_increase",value:null,series};if(elapsed!==intervalSeconds)return{status:"incomplete",reason:"sampling_gap",expected_seconds:intervalSeconds,observed_seconds:elapsed,value:null,series};}
const up=numberValue(row.uptick_issues,"uptick_issues"),down=numberValue(row.downtick_issues,"downtick_issues");
if(up<0||down<0)return{status:"incomplete",reason:"negative issue count",value:null,series};
const tick=up-down;value+=tick;series.push({timestamp:row.timestamp,tick,value});previous=observedAt;}
return{status:"resolved",value,interval_seconds:intervalSeconds,series};
}
The embedded lab now expands to its full document height, keeping the article as the only scroll surface.