A fast-minus-slow EMA of signed volume force — an indicator whose published formulas genuinely disagree across platforms.
The Klinger Volume Oscillator (KVO), attributed to Stephen Klinger, attempts to measure long-term volume-based money flow while staying responsive to shorter-term shifts. It does this by classifying each bar's volume as buying or selling pressure based on trend direction, then taking the difference between a 34-period and a 55-period EMA of that signed 'volume force', usually with a 13-period EMA signal line. An honest note before anything else: KVO is one of the most inconsistently implemented indicators in technical analysis. Klinger's original 'volume force' formula involves a trend-run accumulation term (cumulative and current daily ranges) and an absolute-value ratio, and published sources disagree on its exact form — as a result, MetaTrader, TradingView community scripts, and various books compute visibly different KVO values on identical data. The version documented here is the widely used simplified form (signed volume, where the sign comes from the direction of high+low+close), which is deterministic and reproducible; our Pine example implements exactly that, and we state so rather than pretending all versions match. As always: this is descriptive, educational material, not a prediction machine, and no indicator eliminates the risk of loss.
In the simplified form, each bar is first classified by trend: if today's high + low + close is greater than yesterday's, the bar is treated as accumulation and its volume takes a positive sign; otherwise it is distribution and volume takes a negative sign. This signed series is the volume force. The oscillator is then KVO = EMA(volume force, 34) − EMA(volume force, 55): when recent bars have been dominated by positively signed volume, the fast EMA sits above the slow one and KVO is positive; when negatively signed volume dominates, KVO is negative. A 13-period EMA of KVO serves as the signal line, and some platforms also plot the KVO-minus-signal difference as a histogram. Klinger's original formulation replaces the simple ±volume term with volume × |2 × (dm/cm) − 1| × trend × 100, where dm is the bar's high−low range and cm is a running accumulation of ranges that resets when the trend flips — this weights volume by range behaviour within a trend run. The two constructions can diverge meaningfully, which is exactly why you should verify which formula your platform uses before comparing readings across tools. Both versions are unbounded and centered on zero.
The near-universal defaults are 34 and 55 periods for the fast and slow EMAs of volume force, with a 13-period EMA signal line — Fibonacci-flavored numbers that are convention, not optimization. Some implementations expose the choice between the simplified signed-volume force and the original trend-run formula; most do not, which is the root of cross-platform mismatches. Shortening the EMAs makes the oscillator more reactive and noisier; the settings interact with timeframe, so any comparison should state timeframe, lengths, and which volume-force formula was used.
//@version=6
indicator("Klinger Volume Oscillator (simplified signed-volume form)", overlay = false)
fastLen = input.int(34, "Fast EMA Length", minval = 1)
slowLen = input.int(55, "Slow EMA Length", minval = 1)
sigLen = input.int(13, "Signal EMA Length", minval = 1)
// Trend classification: direction of high+low+close vs prior bar
hlcSum = high + low + close
trendDir = hlcSum > nz(hlcSum[1], hlcSum) ? 1.0 : -1.0
// Simplified volume force: signed volume (NOT Klinger's original trend-run formula)
volForce = trendDir * volume
kvo = ta.ema(volForce, fastLen) - ta.ema(volForce, slowLen)
sig = ta.ema(kvo, sigLen)
crossUp = ta.crossover(kvo, sig) and barstate.isconfirmed
plotshape(crossUp, "KVO Cross Up", style = shape.triangleup, location = location.bottom, color = color.teal, size = size.tiny)
plot(kvo, "KVO", color = color.blue)
plot(sig, "Signal", color = color.orange)
hline(0, "Zero", color = color.gray)Pro tip: Treat KVO as a case study in verification: before relying on it anywhere, plot your platform's built-in version against a formula you implemented yourself (like the simplified form above) and check whether they match. If they do not, you have learned which formula your platform uses — and that any KVO commentary you read online may be describing a different indicator entirely. That habit of validating the formula, not the name, transfers to every tool you use. Educational information only, not financial advice; no indicator predicts price, and trading involves risk of loss.
Educational only — not financial advice, not a recommendation to trade. No indicator is predictive; trading involves substantial risk of loss.