MassIndex — Mass Index
תוכן זה אינו זמין עדיין בשפה שלך.
A bulge in the ratio of single- to double-smoothed range, summed over 25 bars. Dorsey’s “reversal bulge”: the index rising above 27 and then falling back below 26.5 marks range expansion that often precedes a turn — in either direction, since it is direction-blind.
Signature
MassIndex(ema_period, sum_period, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
ema_period |
int Param or literal | Yes | Smoothing for both EMAs. Default 9, bounds 1–100. |
sum_period |
int Param or literal | Yes | Summation window. Default 25, bounds 1–200. |
on= |
symbol | No | Source symbol. Defaults to the trade symbol. Reads high and low. |
Formula
$$ \text{MassIndex} = \sum_{i=1}^{m} \frac{\text{EMA}(H-L, n)}{\text{EMA}(\text{EMA}(H-L, n), n)} $$
Warmup
sum_period bars plus the EMA convergence. With the defaults the value sits near 25 (the sum
of 25 ratios all near 1).
Reading the value
mi.valuemi > 27Example
class ReversalBulge(Strategy): """Dorsey's bulge: exit when the mass index spikes and falls back.""" trade = Symbol() sizing = FixedCapital()
def execute(self): mi = MassIndex(9, 25, on=self.trade) sma = SMA(50, on=self.trade) if self.trade.close > sma.value and mi.value < 26 and self.trade.is_flat: self.buy(self.trade, reason="Trend, no bulge") if mi.value > 27 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason=f"Mass index {mi.value:.1f}")Notes
- Donald Dorsey, TASC (1992). The 27 / 26.5 thresholds are his and assume the 9/25 defaults — they do not transfer if you change the periods.
- Proven by an assert-via-trade run on SPY daily (stayed in its expected band on every bar of a 140-bar run; zero alarm trades).
- The recursion seeds from the first bar rather than from a warm-up window, so early values
are not comparable with pandas_ta’s
massi(9, 25), which seeds from an average of the firstn; measured on a 300-bar tape the two agree to 1e-6 from bar 80 onward.