Class: Quant::Indicators::Mama

Inherits:
Indicator show all
Defined in:
lib/quant/indicators/mama.rb

Overview

www.mesasoftware.com/papers/MAMA.pdf MESA Adaptive Moving Average (MAMA) adapts to price movement in an entirely new and unique way. The adapation is based on the rate change of phase as measured by the Hilbert Transform Discriminator.

This version of Ehler’s MAMA indicator duplicates the computations present in the homodyne version of the dominant cycle indicator. Use this version of the indicator when you’re using a different dominant cycle indicator other than the homodyne for the rest of your indicators.

Constant Summary collapse

FAMA =
0.500
GAMA =
0.950
DAMA =
0.125
LAMA =
0.100
FAGA =
0.050

Constants inherited from Indicator

Indicator::PRIORITIES

Constants included from Mixins::UniversalFilters

Mixins::UniversalFilters::K

Instance Attribute Summary

Attributes inherited from Indicator

#p0, #p1, #p2, #p3, #series, #source, #t0, #t1, #t2, #t3

Instance Method Summary collapse

Methods inherited from Indicator

#<<, #[], #adaptive_half_period, #adaptive_period, dependent_indicator_classes, depends_on, #dominant_cycle, #dominant_cycle_indicator_class, #dominant_cycle_kind, #each, #half_period, #indicator_name, #initialize, #input, #inspect, #max_period, #micro_period, #min_period, #p, #period_points, #pivot_kind, #points_class, #priority, register, #size, #t, #ticks, #values, #warmed_up?

Methods included from Mixins::FisherTransform

#fisher_transform, #inverse_fisher_transform, #relative_fisher_transform

Methods included from Mixins::Stochastic

#stochastic

Methods included from Mixins::SuperSmoother

#three_pole_super_smooth, #two_pole_super_smooth

Methods included from Mixins::HilbertTransform

#hilbert_transform

Methods included from Mixins::ExponentialMovingAverage

#exponential_moving_average

Methods included from Mixins::SimpleMovingAverage

#simple_moving_average

Methods included from Mixins::WeightedMovingAverage

#extended_weighted_moving_average, #weighted_moving_average

Methods included from Mixins::UniversalFilters

#universal_band_pass, #universal_ema, #universal_filter, #universal_one_pole_high_pass, #universal_one_pole_low_pass, #universal_two_pole_high_pass, #universal_two_pole_low_pass

Methods included from Mixins::ButterworthFilters

#three_pole_butterworth, #two_pole_butterworth

Methods included from Mixins::HighPassFilters

#high_pass_filter, #hpf2, #two_pole_high_pass_filter

Methods included from Mixins::Functions

#angle, #bars_to_alpha, #deg2rad, #period_to_alpha, #rad2deg

Constructor Details

This class inherits a constructor from Quant::Indicators::Indicator

Instance Method Details

#computeObject



137
138
139
140
141
142
# File 'lib/quant/indicators/mama.rb', line 137

def compute
  compute_dominant_cycle
  compute_dominant_cycle_phase
  compute_moving_averages
  compute_oscillator
end

#compute_dominant_cycleObject



82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
# File 'lib/quant/indicators/mama.rb', line 82

def compute_dominant_cycle
  p0.smooth = wma :input
  p0.detrend = hilbert_transform :smooth, period: p1.period

  # { Compute Inphase and Quadrature components }
  p0.q1 = hilbert_transform :detrend, period: p1.period
  p0.i1 = p3.detrend

  # { Advance the phase of I1 and Q1 by 90 degrees }
  p0.ji = hilbert_transform :i1, period: p1.period
  p0.jq = hilbert_transform :q1, period: p1.period

  # { Smooth the I and Q components before applying the discriminator }
  p0.i2 = (0.2 * (p0.i1 - p0.jq)) + 0.8 * (p1.i2 || (p0.i1 - p0.jq))
  p0.q2 = (0.2 * (p0.q1 + p0.ji)) + 0.8 * (p1.q2 || (p0.q1 + p0.ji))

  homodyne_discriminator
end

#compute_dominant_cycle_phaseObject



109
110
111
112
# File 'lib/quant/indicators/mama.rb', line 109

def compute_dominant_cycle_phase
  p0.delta_phase = p1.phase - p0.phase
  p0.delta_phase = 1.0 if p0.delta_phase < 1.0
end

#compute_moving_averagesObject



120
121
122
123
124
125
126
127
128
129
# File 'lib/quant/indicators/mama.rb', line 120

def compute_moving_averages
  alpha = [fast_limit / p0.delta_phase, slow_limit].max
  p0.mama = (alpha * p0.input) + ((1.0 - alpha) * p1.mama)

  p0.fama = (FAMA * alpha * p0.mama) + ((1.0 - (FAMA * alpha)) * p1.fama)
  p0.gama = (GAMA * alpha * p0.mama) + ((1.0 - (GAMA * alpha)) * p1.gama)
  p0.dama = (DAMA * alpha * p0.mama) + ((1.0 - (DAMA * alpha)) * p1.dama)
  p0.lama = (LAMA * alpha * p0.mama) + ((1.0 - (LAMA * alpha)) * p1.lama)
  p0.faga = (FAGA * alpha * p0.fama) + ((1.0 - (FAGA * alpha)) * p1.faga)
end

#compute_oscillatorObject



131
132
133
134
135
# File 'lib/quant/indicators/mama.rb', line 131

def compute_oscillator
  p0.osc = p0.mama - p0.fama
  p0.crossed = :up if p0.osc >= 0 && p1.osc < 0
  p0.crossed = :down if p0.osc <= 0 && p1.osc > 0
end

#compute_smooth_periodObject

amplitude correction using previous period value



63
64
65
66
# File 'lib/quant/indicators/mama.rb', line 63

def compute_smooth_period
  p0.period = ((0.2 * p0.period) + (0.8 * p1.period)).round
  p0.smooth_period = ((0.33333 * p0.period) + (0.666667 * p1.smooth_period)).round
end

#constrain_period_barsObject

constrain between 6 and 50 bars



52
53
54
# File 'lib/quant/indicators/mama.rb', line 52

def constrain_period_bars
  p0.period = p0.period.clamp(min_period, max_period)
end

#constrain_period_magnitude_changeObject

constrain magnitude of change in phase



57
58
59
60
# File 'lib/quant/indicators/mama.rb', line 57

def constrain_period_magnitude_change
  p0.period = [1.5 * p1.period, p0.period].min
  p0.period = [0.67 * p1.period, p0.period].max
end

#fast_limitObject



101
102
103
# File 'lib/quant/indicators/mama.rb', line 101

def fast_limit
  @fast_limit ||= bars_to_alpha(min_period / 2)
end

#homodyne_discriminatorObject



68
69
70
71
72
73
74
75
76
77
78
79
80
# File 'lib/quant/indicators/mama.rb', line 68

def homodyne_discriminator
  p0.re = (p0.i2 * p1.i2) + (p0.q2 * p1.q2)
  p0.im = (p0.i2 * p1.q2) - (p0.q2 * p1.i2)

  p0.re = (0.2 * p0.re) + (0.8 * p1.re)
  p0.im = (0.2 * p0.im) + (0.8 * p1.im)

  p0.period = 360.0 / rad2deg(Math.atan(p0.im / p0.re)) if (p0.im != 0) && (p0.re != 0)

  constrain_period_magnitude_change
  constrain_period_bars
  compute_smooth_period
end

#slow_limitObject



105
106
107
# File 'lib/quant/indicators/mama.rb', line 105

def slow_limit
  @slow_limit ||= bars_to_alpha(max_period)
end