import "github.com/cinar/indicator/v2/volume"Package volume contains the volume indicator functions.
This package belongs to the Indicator project. Indicator is a Golang module that supplies a variety of technical indicators, strategies, and a backtesting framework for analysis.
Copyright (c) 2021-2026 The Indicator Authors.
The source code is provided under GNU AGPLv3 License.
https://github.com/cinar/indicator
The information provided on this project is strictly for informational purposes and is not to be construed as advice or solicitation to buy or sell any security.
- Constants
- type Ad
- type Cmf
- func NewCmf[T helper.Float]() *Cmf[T]
- func NewCmfWithPeriod[T helper.Float](period int) *Cmf[T]
- func (c *Cmf[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan T
- func (c *Cmf[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan T
- func (c *Cmf[T]) IdlePeriod() int
- func (c *Cmf[T]) String() string
- type Emv
- func NewEmv[T helper.Float]() *Emv[T]
- func NewEmvWithPeriod[T helper.Float](period int) *Emv[T]
- func (e *Emv[T]) Compute(highs, lows, volumes <-chan T) <-chan T
- func (e *Emv[T]) ComputeWithContext(ctx context.Context, highs, lows, volumes <-chan T) <-chan T
- func (e *Emv[T]) IdlePeriod() int
- func (e *Emv[T]) String() string
- type Fi
- func NewFi[T helper.Float]() *Fi[T]
- func NewFiWithPeriod[T helper.Float](period int) *Fi[T]
- func (f *Fi[T]) Compute(closings, volumes <-chan T) <-chan T
- func (f *Fi[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan T
- func (f *Fi[T]) IdlePeriod() int
- func (f *Fi[T]) String() string
- type Kvo
- type Mfi
- func NewMfi[T helper.Float]() *Mfi[T]
- func NewMfiWithPeriod[T helper.Float](period int) *Mfi[T]
- func (m *Mfi[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan T
- func (m *Mfi[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan T
- func (m *Mfi[T]) IdlePeriod() int
- func (m *Mfi[T]) String() string
- type Mfm
- type Mfv
- type Nvi
- type Obv
- type Vpt
- type Vwap
- func NewVwap[T helper.Float]() *Vwap[T]
- func NewVwapWithPeriod[T helper.Float](period int) *Vwap[T]
- func (v *Vwap[T]) Compute(closings, volumes <-chan T) <-chan T
- func (v *Vwap[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan T
- func (v *Vwap[T]) IdlePeriod() int
- func (v *Vwap[T]) String() string
const (
// DefaultKvoShortPeriod is the default short period for the Klinger Volume Oscillator.
DefaultKvoShortPeriod = 34
// DefaultKvoLongPeriod is the default long period for the Klinger Volume Oscillator.
DefaultKvoLongPeriod = 55
// DefaultKvoSignalPeriod is the default signal period for the Klinger Volume Oscillator.
DefaultKvoSignalPeriod = 13
)const (
// DefaultCmfPeriod is the default period of CMF.
DefaultCmfPeriod = 20
)const (
// DefaultEmvPeriod is the default period for the EMV.
DefaultEmvPeriod = 14
)const (
// DefaultFiPeriod is the default period for the FI.
DefaultFiPeriod = 13
)const (
// DefaultMfiPeriod is the default period of the MFI.
DefaultMfiPeriod = 14
)const (
// DefaultNviInitial is the default initial for the NVI.
DefaultNviInitial = 1000
)const (
// DefaultVwapPeriod is the default period for the VWAP.
DefaultVwapPeriod = 14
)type Ad
Ad holds configuration parameters for calculating Accumulation/Distribution (A/D). It is a cumulative indicator that uses volume and price to assess whether an asset is being accumulated or distributed.
MFM = ((Closing - Low) - (High - Closing)) / (High - Low)
MFV = MFM * Period Volume
AD = Previous AD + CMFV
Example:
ad := volume.NewAd[float64]()
result := ad.Compute(highs, lows, closings, volumes)
type Ad[T helper.Float] struct {
// Mfv is the MFV instance.
Mfv *Mfv[T]
}func NewAd
func NewAd[T helper.Float]() *Ad[T]NewAd function initializes a new A/D instance with the default parameters.
func (*Ad[T]) Compute
func (a *Ad[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Ad[T]) ComputeWithContext
func (a *Ad[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the A/D.
func (*Ad[T]) IdlePeriod
func (*Ad[T]) IdlePeriod() intIdlePeriod is the initial period that A/D won't yield any results.
func (*Ad[T]) String
func (*Ad[T]) String() stringString is the string representation of the A/D.
type Cmf
Cmf holds configuration parameters for calculating the Chaikin Money Flow (CMF). It measures the amount of money flow volume over a given period.
MFM = ((Closing - Low) - (High - Closing)) / (High - Low)
MFV = MFM * Volume
CMF = Sum(20, Money Flow Volume) / Sum(20, Volume)
When no trading occurred anywhere in the window, the volume sum is 0 and the money-flow-volume-weighted ratio is undefined (0/0). CMF returns 0, since a value near 0 conventionally reads as "no strong buying or selling pressure" - exactly what a window with no trading should report.
Example:
cmf := volume.NewCmf[float64]()
result := cmf.Compute(highs, lows, closings, volumes)
type Cmf[T helper.Float] struct {
// Mfv is the MFV instance.
Mfv *Mfv[T]
// Sum is the Moving Sum instance.
Sum *trend.MovingSum[T]
}func NewCmf
func NewCmf[T helper.Float]() *Cmf[T]NewCmf function initializes a new CMF instance with the default parameters.
func NewCmfWithPeriod
func NewCmfWithPeriod[T helper.Float](period int) *Cmf[T]NewCmfWithPeriod function initializes a new CMF instance with the given period.
func (*Cmf[T]) Compute
func (c *Cmf[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Cmf[T]) ComputeWithContext
func (c *Cmf[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the CMF.
func (*Cmf[T]) IdlePeriod
func (c *Cmf[T]) IdlePeriod() intIdlePeriod is the initial period that CMF won't yield any results.
func (*Cmf[T]) String
func (c *Cmf[T]) String() stringString is the string representation of the CMF.
type Emv
Emv holds configuration parameters for calculating the Ease of Movement (EMV). It is a volume based oscillator measuring the ease of price movement.
Distance Moved = ((High + Low) / 2) - ((Priod High + Prior Low) /2)
Box Ratio = ((Volume / 100000000) / (High - Low))
EMV(1) = Distance Moved / Box Ratio
EMV(14) = SMA(14, EMV(1))
Example:
emv := volume.NewEmv[float64]()
result := emv.Compute(highs, lows, volumes)
type Emv[T helper.Float] struct {
// Sma is the SMA instance.
Sma *trend.Sma[T]
}func NewEmv
func NewEmv[T helper.Float]() *Emv[T]NewEmv function initializes a new EMV instance with the default parameters.
func NewEmvWithPeriod
func NewEmvWithPeriod[T helper.Float](period int) *Emv[T]NewEmvWithPeriod function initializes a new EMV instance with the given period.
func (*Emv[T]) Compute
func (e *Emv[T]) Compute(highs, lows, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Emv[T]) ComputeWithContext
func (e *Emv[T]) ComputeWithContext(ctx context.Context, highs, lows, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the EMV.
func (*Emv[T]) IdlePeriod
func (e *Emv[T]) IdlePeriod() intIdlePeriod is the initial period that EMV won't yield any results.
func (*Emv[T]) String
func (e *Emv[T]) String() stringString is the string representation of the EMV.
type Fi
Fi holds configuration parameters for calculating the Force Index (FI). It uses the closing price and the volume to assess the power behind a move and identify turning points.
FI = EMA(period, (Current - Previous) * Volume)
Example:
fi := volume.NewFi[float64]()
result := fi.Compute(closings, volumes)
type Fi[T helper.Float] struct {
// Ema is the EMA instance.
Ema *trend.Ema[T]
}func NewFi
func NewFi[T helper.Float]() *Fi[T]NewFi function initializes a new FI instance with the default parameters.
func NewFiWithPeriod
func NewFiWithPeriod[T helper.Float](period int) *Fi[T]NewFiWithPeriod function initializes a new FI instance with the given period.
func (*Fi[T]) Compute
func (f *Fi[T]) Compute(closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Fi[T]) ComputeWithContext
func (f *Fi[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the FI.
func (*Fi[T]) IdlePeriod
func (f *Fi[T]) IdlePeriod() intIdlePeriod is the initial period that FI won't yield any results.
func (*Fi[T]) String
func (f *Fi[T]) String() stringString is the string representation of the FI.
type Kvo
Kvo represents the configuration parameters for calculating the Klinger Volume Oscillator (KVO). It is a volume-based oscillator that identifies long-term money flow trends using EMA differences.
Trend = +1 if High > High[1] and Low >= Low[1]
Trend = -1 if High <= High[1] and Low < Low[1]
Trend = 0 otherwise
VF = Volume * Trend
KVO = EMA(VF, shortPeriod) - EMA(VF, longPeriod)
Signal = EMA(KVO, signalPeriod)
Example:
kvo := volume.NewKvo[float64]()
kvoResult, signalResult := kvo.Compute(highs, lows, volumes)
type Kvo[T helper.Float] struct {
// ShortEma is the short EMA instance.
ShortEma *trend.Ema[T]
// LongEma is the long EMA instance.
LongEma *trend.Ema[T]
// SignalEma is the signal EMA instance.
SignalEma *trend.Ema[T]
}func NewKvo
func NewKvo[T helper.Float]() *Kvo[T]NewKvo function initializes a new KVO instance.
func (*Kvo[T]) Compute
func (k *Kvo[T]) Compute(highs, lows, volumes <-chan T) (<-chan T, <-chan T)Compute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Kvo[T]) ComputeWithContext
func (k *Kvo[T]) ComputeWithContext(ctx context.Context, highs, lows, volumes <-chan T) (<-chan T, <-chan T)ComputeWithContext function takes channels of numbers and computes the Klinger Volume Oscillator. Returns kvo and signal.
func (*Kvo[T]) IdlePeriod
func (k *Kvo[T]) IdlePeriod() intIdlePeriod is the initial period that KVO won't yield any results.
func (*Kvo[T]) String
func (k *Kvo[T]) String() stringString is the string representation of the KVO.
type Mfi
Mfi holds configuration parameters for calculating the Money Flow Index (MFI). It analyzes both the closing price and the volume to measure to identify overbought and oversold states. It is similar to the Relative Strength Index (RSI), but it also uses the volume.
Raw Money Flow = Typical Price * Volume
Money Ratio = Positive Money Flow / Negative Money Flow
Money Flow Index = 100 - (100 / (1 + Money Ratio))
Example:
mfi := volume.NewMfi[float64]()
result := mfi.Compute(highs, lows, closings, volumes)
type Mfi[T helper.Float] struct {
// TypicalPrice is the Typical Price instance.
TypicalPrice *trend.TypicalPrice[T]
// Sum is the Moving Sum instance.
Sum *trend.MovingSum[T]
}func NewMfi
func NewMfi[T helper.Float]() *Mfi[T]NewMfi function initializes a new MFI instance with the default parameters.
func NewMfiWithPeriod
func NewMfiWithPeriod[T helper.Float](period int) *Mfi[T]NewMfiWithPeriod function initializes a new MFI instance with the given period.
func (*Mfi[T]) Compute
func (m *Mfi[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Mfi[T]) ComputeWithContext
func (m *Mfi[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the MFI.
func (*Mfi[T]) IdlePeriod
func (m *Mfi[T]) IdlePeriod() intIdlePeriod is the initial period that MFI won't yield any results.
func (*Mfi[T]) String
func (m *Mfi[T]) String() stringString is the string representation of the MFI.
type Mfm
Mfm holds configuration parameters for calculating the Money Flow Multiplier (MFM), which adjusts volume based on the closing price's position within the high-low range:
MFM = ((Closing - Low) - (High - Closing)) / (High - Low)
- Positive MFM: Close in upper half of range, indicating buying pressure. - Negative MFM: Close in lower half of range, indicating selling pressure. - MFM of 1: Close equals high, strongest buying pressure. - MFM of -1: Close equals low, strongest selling pressure.
On a flat bar (High == Low), the close's position within the range is undefined (0/0). MFM returns 0, the neutral point of its [-1, 1] scale, matching the InternalBarStrength precedent for the identical High-Low denominator. Since MFM feeds Mfv, Ad, and Cmf, a neutral 0 flows through as "zero contribution" to all of them.
Example:
mfm := volume.NewMfm[float64]()
result := mfm.Compute(highs, lows, closings)
type Mfm[T helper.Float] struct{}func NewMfm
func NewMfm[T helper.Float]() *Mfm[T]NewMfm function initializes a new MFM instance with the default parameters.
func (*Mfm[T]) Compute
func (i *Mfm[T]) Compute(highs, lows, closings <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Mfm[T]) ComputeWithContext
func (i *Mfm[T]) ComputeWithContext(ctx context.Context, highs, lows, closings <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the MFM.
func (*Mfm[T]) IdlePeriod
func (*Mfm[T]) IdlePeriod() intIdlePeriod is the initial period that MFM won't yield any results.
func (*Mfm[T]) String
func (*Mfm[T]) String() stringString is the string representation of the MFM.
type Mfv
Mfv holds configuration parameters for calculating Money Flow Volume (MFV), a volume-based indicator that incorporates the Money Flow Multiplier (MFM) to gauge the intensity of buying and selling pressure. MFV reflects the cumulative volume adjusted by MFM, with higher values indicating stronger buying pressure and lower values suggesting selling dominance. MFV highlights periods of significant volume-driven price action, offering insights into potential trend strength and reversals.
MFV = MFM * Volume
Example:
mfv := volume.NewMfv[float64]()
result := mfv.Compute(highs, lows, closings, volumes)
type Mfv[T helper.Float] struct {
// Mfm is the MFM instance.
Mfm *Mfm[T]
}func NewMfv
func NewMfv[T helper.Float]() *Mfv[T]NewMfv function initializes a new MFV instance with the default parameters.
func (*Mfv[T]) Compute
func (m *Mfv[T]) Compute(highs, lows, closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Mfv[T]) ComputeWithContext
func (m *Mfv[T]) ComputeWithContext(ctx context.Context, highs, lows, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the MFV.
func (*Mfv[T]) IdlePeriod
func (*Mfv[T]) IdlePeriod() intIdlePeriod is the initial period that MFV won't yield any results.
func (*Mfv[T]) String
func (*Mfv[T]) String() stringString is the string representation of the MFV.
type Nvi
Nvi holds configuration parameters for calculating the Negative Volume Index (NVI). It is a cumulative indicator using the change in volume to decide when the smart money is active.
If Volume is greater than Previous Volume:
NVI = Previous NVI
Otherwise:
NVI = Previous NVI + (((Closing - Previous Closing) / Previous Closing) * Previous NVI)
Example:
nvi := volume.NewNvi[float64]()
result := nvi.Compute(closings, volumes)
type Nvi[T helper.Number] struct {
// Initial is the initial NVI value.
Initial T
}func NewNvi
func NewNvi[T helper.Number]() *Nvi[T]NewNvi function initializes a new NVI instance with the default parameters.
func (*Nvi[T]) Compute
func (n *Nvi[T]) Compute(closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Nvi[T]) ComputeWithContext
func (n *Nvi[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the NVI.
func (*Nvi[T]) IdlePeriod
func (*Nvi[T]) IdlePeriod() intIdlePeriod is the initial period that NVI won't yield any results.
func (*Nvi[T]) String
func (n *Nvi[T]) String() stringString is the string representation of the NVI.
type Obv
Obv holds configuration parameters for calculating the On-Balance Volume (OBV). It is a technical trading momentum indicator that uses volume flow to predict changes in asset price.
Foreach Closing:
If Closing[i] > Closing[i-1], OBV[i] = OBV[i-1] + Volume[i]
If Closing[i] = Closing[i-1], OBV[i] = OBV[i-1]
If Closing[i] < Closing[i-1], OBV[i] = OBV[i-1] - Volume[i]
Example:
obv := volume.NewObv[float64]()
result := obv.Compute(closings, volumes)
Note that the first emitted value, OBV[0], includes the full first-bar volume rather than starting at exactly 0. This is because there is no true "previous close" for the very first bar, so the zero-valued previousClosing causes the first comparison to read as an increase by default. This is inconsequential for typical OBV usage, such as slope or trend analysis, since it only introduces a constant offset to the series rather than changing its shape.
type Obv[T helper.Number] struct{}func NewObv
func NewObv[T helper.Number]() *Obv[T]NewObv function initializes a new OBV instance with the default parameters.
func (*Obv[T]) Compute
func (i *Obv[T]) Compute(closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Obv[T]) ComputeWithContext
func (i *Obv[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the OBV.
Note that the first result includes the full first-bar volume rather than 0, since previousClosing starts at its zero value and there is no real prior close to compare against for the first bar.
func (*Obv[T]) IdlePeriod
func (*Obv[T]) IdlePeriod() intIdlePeriod is the initial period that OBV won't yield any results.
func (*Obv[T]) String
func (*Obv[T]) String() stringString is the string representation of the OBV.
type Vpt
Vpt holds configuration parameters for calculating the Volume Price Trend (VPT). It provides a correlation between the volume and the price.
VPT = Previous VPT + (Volume * (Current Closing - Previous Closing) / Previous Closing)
Example:
vpt := volume.NewVpt[float64]()
result := vpt.Compute(closings, volumes)
type Vpt[T helper.Number] struct{}func NewVpt
func NewVpt[T helper.Number]() *Vpt[T]NewVpt function initializes a new VPT instance with the default parameters.
func (*Vpt[T]) Compute
func (i *Vpt[T]) Compute(closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Vpt[T]) ComputeWithContext
func (i *Vpt[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the VPT.
func (*Vpt[T]) IdlePeriod
func (*Vpt[T]) IdlePeriod() intIdlePeriod is the initial period that VPT won't yield any results.
func (*Vpt[T]) String
func (*Vpt[T]) String() stringString is the string representation of the VPT.
type Vwap
Vwap holds configuration parameters for calculating the Volume Weighted Average Price (VWAP). It provides the average price the asset has traded.
VWAP = Sum(Closing * Volume) / Sum(Volume)
When no trading occurred anywhere in the window, the volume sum is 0 and a volume-weighted price is undefined (0/0). Unlike MFM/CMF, 0 is not a safe stand-in here: a VWAP of 0 would read as a real, implausibly low price rather than "no data," which is actively misleading if plotted or compared against actual prices (see the example WeightedAveragePriceStrategy, which crosses closing price against VWAP - a fabricated 0 would falsely signal a crossover every time). Instead, VWAP carries forward the last period with actual volume, which is the conventional real-market handling for an illiquid bar. Before any window has had volume, there is no prior value to carry forward, so VWAP returns the zero value of T.
Example:
vwap := volume.NewVwap[float64]()
result := vwap.Compute(closings, volumes)
type Vwap[T helper.Float] struct {
// Sum is the Moving Sum instance.
Sum *trend.MovingSum[T]
}func NewVwap
func NewVwap[T helper.Float]() *Vwap[T]NewVwap function initializes a new VWAP instance with the default parameters.
func NewVwapWithPeriod
func NewVwapWithPeriod[T helper.Float](period int) *Vwap[T]NewVwapWithPeriod function initializes a new VWAP instance with the given period.
func (*Vwap[T]) Compute
func (v *Vwap[T]) Compute(closings, volumes <-chan T) <-chan TCompute wraps ComputeWithContext for backwards compatibility.
Deprecated: Use ComputeWithContext instead.
func (*Vwap[T]) ComputeWithContext
func (v *Vwap[T]) ComputeWithContext(ctx context.Context, closings, volumes <-chan T) <-chan TComputeWithContext function takes a channel of numbers and computes the VWAP.
func (*Vwap[T]) IdlePeriod
func (v *Vwap[T]) IdlePeriod() intIdlePeriod is the initial period that VWAP won't yield any results.
func (*Vwap[T]) String
func (v *Vwap[T]) String() stringString is the string representation of the VWAP.
Generated by gomarkdoc