Trade Volume Index — a cumulative volume level driven by the tick
direction, where an undecided bar keeps trading in the last decided
direction rather than counting for nothing:
Appends one column, defined from bar 0 — like obv there is no
period and no warm-up, because there is no window to size.
What it is for, and how it differs from OBV
obv reads the same tape and makes the opposite call on the bars
that did not move: it adds nothing for an unchanged close, which treats a
quiet bar as though no trading had a side. The Trade Volume Index is built
on the tick rule an exchange tape actually uses — a trade at the same
price as the last one is classified with the last directed trade — so a
run of unchanged bars accumulates in whichever direction the tape was last
going. On an instrument that trades in small ticks against a large price
that is most of the volume, which is the whole reason the study exists.
The second difference is the dead band. OBV compares closes exactly;
this compares them against minTick, so a one-tick wobble inside the
spread does not flip the direction. Set minTick to the instrument's own
tick and the study reads what the tape did; set it larger and it becomes a
noise filter.
minTick is REQUIRED, and that is the decision
It is a fact about the instrument — the exchange's minimum price
increment — not about the study, exactly as swingIndex's limit
is, and it is the third required option in the package after that and
benchmark. Every candidate default is wrong in a way that does not
announce itself:
0 collapses the dead band and makes the direction change on any
move at all, so the persistence rule — the only thing that distinguishes
this study from OBV with a carried sign — never fires on real (float)
prices.
A fixed 0.01 is right for a US equity, wrong by two orders of
magnitude for a JPY cross and by six for a crypto pair, and the reading
it produces is a number, not an error.
So the caller names it. A caller who wants no dead band at all passes a
value below the smallest move their data can make and gets exactly that.
The seed: 0, and no invented first direction
Bar 0 has no previous close, so it has no direction; the level starts at
0 and the first bar contributes nothing. Bars before the first
decisive move contribute nothing either — the direction is 0 until
one happens — rather than being scored as up-volume. Several vendor ports
seed the direction to +1 instead. That is a real fork, and it is pinned
by a unit test rather than by the oracle: the oracle input's bar 1
carries the largest close-to-close move in the whole series (1.412), so it
is decisive at any minTick worth testing and an up-seeded build would
agree with this one bar for bar there — the generator asserts that
agreement, so the day the input changes the omission surfaces. On closes
100, 100.2, 100.3, 101.5 at minTick 0.5 with volumes 10, 20, 30, 40,
this study reads 0, 0, 0, 40 and the up-seeded fork reads
0, 20, 50, 90.
The level is a total of volume, so 0 is a base and only differences
along the line are the reading — the same thing OBV's arbitrary seed
means. There is deliberately no start option: unlike
negativeVolumeIndex, which is multiplicative and where the base
scales the whole line, this one is additive, so a base is a constant
offset and adding a knob for it would be adding a knob for + k.
The gap rule: an interior gap ENDS the index
This is a K6 machine (foldRows), and the kernel's rule is that a
missing cell resets it. This machine resets its direction — it must; a
bar it did not see cannot tell it which way the tape went — but it does
not re-seed the level. It marks it NaN, so the index ends there.
That is obv's rule and cumulativeValues', and the reason is
what the level means: it is a total of volume, a quantity with units,
where the distance between two points on the line is the whole reading. A
hole makes every later level wrong by whatever the missing bar traded, and
a re-based line silently claims a distance that was never travelled.
Contrast negativeVolumeIndex, which re-seeds after a gap and is
right to: it accumulates returns from an arbitrary base, so re-basing
loses only the base. A leading run of gaps, by the same argument, only
shifts the start — the level begins at 0 on the first complete bar.
Edges
Equivariant in volume, invariant in a price shift, and invariant in a
price scale only if minTick scales too. The true statement has to
name the parameter, as swingIndex's does: doubling every volume
doubles the line (it is a sum of volumes); adding a constant to every
price leaves every difference alone and so changes nothing; multiplying
every price by k moves the differences against a fixed dead band
and can change the classification of a bar, so invariance needs
minTick · k. All three are pinned as property tests.
A zero volume bar moves nothing, whichever way it was ticking. There
is no division anywhere in the study, so there is no zero-denominator
case to guard.
A minTick of 0, negative, or non-finite is rejected, the same
validation swingIndex applies to limit.
Trade Volume Index — a cumulative volume level driven by the tick direction, where an undecided bar keeps trading in the last decided direction rather than counting for nothing:
Appends one column, defined from bar 0 — like obv there is no
periodand no warm-up, because there is no window to size.What it is for, and how it differs from OBV
obv reads the same tape and makes the opposite call on the bars that did not move: it adds nothing for an unchanged close, which treats a quiet bar as though no trading had a side. The Trade Volume Index is built on the tick rule an exchange tape actually uses — a trade at the same price as the last one is classified with the last directed trade — so a run of unchanged bars accumulates in whichever direction the tape was last going. On an instrument that trades in small ticks against a large price that is most of the volume, which is the whole reason the study exists.
The second difference is the dead band. OBV compares closes exactly; this compares them against
minTick, so a one-tick wobble inside the spread does not flip the direction. SetminTickto the instrument's own tick and the study reads what the tape did; set it larger and it becomes a noise filter.minTickis REQUIRED, and that is the decisionIt is a fact about the instrument — the exchange's minimum price increment — not about the study, exactly as swingIndex's
limitis, and it is the third required option in the package after that andbenchmark. Every candidate default is wrong in a way that does not announce itself:0collapses the dead band and makes the direction change on any move at all, so the persistence rule — the only thing that distinguishes this study from OBV with a carried sign — never fires on real (float) prices.0.01is right for a US equity, wrong by two orders of magnitude for a JPY cross and by six for a crypto pair, and the reading it produces is a number, not an error.So the caller names it. A caller who wants no dead band at all passes a value below the smallest move their data can make and gets exactly that.
The seed:
0, and no invented first directionBar 0 has no previous close, so it has no direction; the level starts at
0and the first bar contributes nothing. Bars before the first decisive move contribute nothing either — the direction is0until one happens — rather than being scored as up-volume. Several vendor ports seed the direction to+1instead. That is a real fork, and it is pinned by a unit test rather than by the oracle: the oracle input's bar 1 carries the largest close-to-close move in the whole series (1.412), so it is decisive at anyminTickworth testing and an up-seeded build would agree with this one bar for bar there — the generator asserts that agreement, so the day the input changes the omission surfaces. On closes100, 100.2, 100.3, 101.5atminTick 0.5with volumes10, 20, 30, 40, this study reads0, 0, 0, 40and the up-seeded fork reads0, 20, 50, 90.The level is a total of volume, so
0is a base and only differences along the line are the reading — the same thing OBV's arbitrary seed means. There is deliberately nostartoption: unlike negativeVolumeIndex, which is multiplicative and where the base scales the whole line, this one is additive, so a base is a constant offset and adding a knob for it would be adding a knob for+ k.The gap rule: an interior gap ENDS the index
This is a K6 machine (foldRows), and the kernel's rule is that a missing cell resets it. This machine resets its direction — it must; a bar it did not see cannot tell it which way the tape went — but it does not re-seed the level. It marks it
NaN, so the index ends there.That is obv's rule and cumulativeValues', and the reason is what the level means: it is a total of volume, a quantity with units, where the distance between two points on the line is the whole reading. A hole makes every later level wrong by whatever the missing bar traded, and a re-based line silently claims a distance that was never travelled. Contrast negativeVolumeIndex, which re-seeds after a gap and is right to: it accumulates returns from an arbitrary base, so re-basing loses only the base. A leading run of gaps, by the same argument, only shifts the start — the level begins at
0on the first complete bar.Edges
minTickscales too. The true statement has to name the parameter, asswingIndex's does: doubling every volume doubles the line (it is a sum of volumes); adding a constant to every price leaves every difference alone and so changes nothing; multiplying every price bykmoves the differences against a fixed dead band and can change the classification of a bar, so invariance needsminTick · k. All three are pinned as property tests.minTickof0, negative, or non-finite is rejected, the same validationswingIndexapplies tolimit.