RelativeVolume — Relative Volume
Volume as a multiple of its own N-bar average: 2.0 means twice the usual participation. The cleanest “is anyone here” test there is, and dimensionless, so the same thresholds work on any instrument.
Signature
RelativeVolume(period, on=<source>)| Argument | Type | Required | Notes |
|---|---|---|---|
period |
int Param or literal | Yes | Averaging window. Default 20, bounds 1–400. |
on= |
symbol | No | Source symbol. Defaults to the trade symbol. Reads volume. |
Formula
$$ \text{RelVol} = \frac{V_t}{\text{SMA}(V, n)} $$
Warmup
period bars; the average uses the bars available before that.
Reading the value
rv.valuerv > 1.5Example
class ParticipationGate(Strategy): """Require above-average participation for any entry.""" trade = Symbol() sizing = FixedCapital()
def execute(self): rv = RelativeVolume(20, on=self.trade) sma = SMA(50, on=self.trade) if rv.value > 1.5 and self.trade.close > sma.value and self.trade.is_flat: self.buy(self.trade, reason=f"RelVol {rv.value:.2f}") if rv.value < 0.7 and self.trade.is_long: self.sell(self.trade, self.trade.position, reason="Participation gone")Notes
- Note the window includes the current bar, so a single enormous bar raises its own denominator slightly — the reading is conservative by construction.