Skip to content

Commit

Permalink
Trend: Mass Index (MI) Fixes #50
Browse files Browse the repository at this point in the history
  • Loading branch information
cinar authored Jan 29, 2022
1 parent 63ebe2d commit b04a11c
Show file tree
Hide file tree
Showing 4 changed files with 55 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ The following list of indicators are currently supported by this package:
- [Community Channel Index (CMI)](trend_indicators.md#community-channel-index-cmi)
- [Double Exponential Moving Average (DEMA)](trend_indicators.md#double-exponential-moving-average-dema)
- [Exponential Moving Average (EMA)](trend_indicators.md#exponential-moving-average-ema)
- [Mass Index (MI)](trend_indicators.md#mass-index-mi)
- [Moving Average Convergence Divergence (MACD)](trend_indicators.md#moving-average-convergence-divergence-macd)
- [Moving Max](trend_indicators.md#moving-max)
- [Moving Min](trend_indicators.md#moving-min)
Expand Down
18 changes: 18 additions & 0 deletions trend_indicators.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,24 @@ func Macd(closing []float64) ([]float64, []float64) {
return macd, signal
}

// The Mass Index (MI) uses the high-low range to identify trend reversals
// based on range expansions.
//
// Singe EMA = EMA(9, Highs - Lows)
// Double EMA = EMA(9, Single EMA)
// Ratio = Single EMA / Double EMA
// MI = Sum(25, Ratio)
//
// Returns mi.
func MassIndex(high, low []float64) []float64 {
ema1 := Ema(9, substract(high, low))
ema2 := Ema(9, ema1)
ratio := divide(ema1, ema2)
mi := Sum(25, ratio)

return mi
}

// Moving Chande Forecast Oscillator calculates based on
// the given period.
//
Expand Down
16 changes: 16 additions & 0 deletions trend_indicators.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Trend indicators measure the direction and strength of a trend.
- [Community Channel Index (CMI)](#community-channel-index-cmi)
- [Double Exponential Moving Average (DEMA)](#double-exponential-moving-average-dema)
- [Exponential Moving Average (EMA)](#exponential-moving-average-ema)
- [Mass Index (MI)](#mass-index-mi)
- [Moving Average Convergence Divergence (MACD)](#moving-average-convergence-divergence-macd)
- [Moving Max](#moving-max)
- [Moving Min](#moving-min)
Expand Down Expand Up @@ -124,6 +125,21 @@ The [Ema](https://pkg.go.dev/github.com/cinar/indicator#Ema) function calculates
result := indicator.Ema(2, []float64{2, 4, 6, 8, 12, 14, 16, 18, 20})
```

#### Mass Index (MI)

The [MassIndex](https://pkg.go.dev/github.com/cinar/indicator#MassIndex) uses the high-low range to identify trend reversals based on range expansions.

```
Singe EMA = EMA(9, Highs - Lows)
Double EMA = EMA(9, Single EMA)
Ratio = Single EMA / Double EMA
MI = Sum(25, Ratio)
```

```Golang
result := indicator.MassIndex(high, low)
```

#### Moving Average Convergence Divergence (MACD)

The [Macd](https://pkg.go.dev/github.com/cinar/indicator#Macd) function calculates a trend-following momentum indicator that shows the relationship between two moving averages of price.
Expand Down
20 changes: 20 additions & 0 deletions trend_indicators_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,26 @@ func TestEma(t *testing.T) {
}
}

func TestMassIndex(t *testing.T) {
high := []float64{10, 9, 12, 14, 12}
low := []float64{6, 7, 9, 12, 10}
expected := []float64{1, 1.92, 2.83, 3.69, 4.52}

result := MassIndex(high, low)

if len(result) != len(expected) {
t.Fatal("result not same size")
}

for i := 0; i < len(result); i++ {
actual := math.Round(result[i]*100) / 100

if actual != expected[i] {
t.Fatalf("result %d actual %f expected %f", i, actual, expected[i])
}
}
}

func TestMax(t *testing.T) {
values := []float64{10, 9, 8, 7, 6, 5, 4, 3, 2, 1}
expected := []float64{10, 10, 10, 10, 9, 8, 7, 6, 5}
Expand Down

0 comments on commit b04a11c

Please sign in to comment.