@pond-ts/financial API Reference
    Preparing search index...

    Function easeOfMovement

    • Ease of Movement (Richard Arms) — how far the bar's midpoint travelled per unit of volume it took to get there:

      distance  = (high + low)/2 − (prevHigh + prevLow)/2
      boxRatio = (volume / scale) / (high − low)
      eom₁ = distance / boxRatio the 1-bar value
      eom = MA(eom₁, period) Arms' 14-bar SMA

      Arms' idea from his Equivolume charts: a bar that moves the midpoint a long way on little volume in a narrow range moved easily, and that is bullish; the same move on heavy volume was hard-won. Large positive readings mean price is rising easily, large negative that it is falling easily, and a value near zero that price is not moving despite the volume. Appends one column.

      The midpoint is medianPriceValues — the same kernel awesomeOscillator reads — and the smoothing is the K2 engine (movingAverageValues), so maType is the whole shared menu rather than a private smoother. 'sma' is the default because Arms' definition and every publication of it name a simple average.

      100_000_000 is StockCharts' and ChartIQ's published constant, and it is what ships. It exists only to bring the reading onto a legible axis: the whole expression is distance · (high − low) · scale / volume, so scale is a pure linear multiplier — it cannot change a sign, a crossing, or the shape of the line, and a property test pins that.

      It is exposed anyway because the right constant depends on the instrument's units, not on taste: 100 million is calibrated to US equity share counts, and a crypto pair quoting fractional volume or a futures contract quoting lots reads as a wall of zeros (or of millions) at that setting. The alternative considered was to fix it and tell callers to multiply the output column themselves — rejected because a caller who needs a different constant would then be silently incomparable with the chart package they are reading beside, for the sake of removing an option that has no other effect.

      TA-Lib has no Ease of Movement, so the oracle is a pandas replication at {14, sma} and {5, ema}, with the analytic first valid bar (period — see below) asserted and the result separated from a version that drops the (high − low) factor, so the box ratio is pinned rather than assumed.

      • Warm-up is period rows. The 1-bar value needs a previous midpoint, so bar 0 has none and the K2 array door waits for period finite values. Length-preserving.
      • A flat bar (high === low) has no value. The box ratio divides by the range, so a bar with no range has no box — x / 0. Reported as undefined rather than as the 0 the algebraically-simplified form would produce, which would claim the price did not move when it may well have. (The simplified form is what the code computes, for one pass and no cancellation; the guard is what keeps it honest.)
      • A bar with zero volume has no value either — the box ratio is 0 and the division by it is ±Infinity, which is not a reading. Both guards report undefined, the package's answer for a zero denominator everywhere. The zero-volume guard looks redundant on the window MA types, which mask a non-finite cell anyway — but it is load-bearing on the carrying ones: smma is Wilder's recursion and passes what it is given straight through, so an unguarded ±Infinity would arrive at withColumn, which rejects an infinity loudly rather than mapping it to a gap. (Found by the mutation matrix: removing the guard killed no test until one ran maType: 'smma' over a zero-volume bar.)
      • A gap in any input costs two bars (its own and the next, whose distance reads the missing midpoint) plus whatever the chosen maType costs — window types recover once it leaves the window, the ema family skips the bar, smma and kama propagate to the end. Stated per type on movingAverageValues.
      • Scale behaviour, and it is the odd one here: EOM is quadratic in price — the distance and the range both scale, so scaling every price by k scales the reading by inversely proportional to volume, and linear in scale. All three are pinned by property tests, because "linear in price like every other absolute study" is the plausible wrong assumption here.

      Type Parameters

      • S extends SeriesSchema
      • const Output extends string = "eom"

      Parameters

      Returns TimeSeries<
          readonly [S[0], ValueColumnsForSchema<S>, OptionalNumberColumn<Output>],
      >