Class: Quant::Indicators::Mama
- 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
Constants included from Mixins::UniversalFilters
Instance Attribute Summary
Attributes inherited from Indicator
#p0, #p1, #p2, #p3, #series, #source, #t0, #t1, #t2, #t3
Instance Method Summary collapse
- #compute ⇒ Object
- #compute_dominant_cycle ⇒ Object
- #compute_dominant_cycle_phase ⇒ Object
- #compute_moving_averages ⇒ Object
- #compute_oscillator ⇒ Object
-
#compute_smooth_period ⇒ Object
amplitude correction using previous period value.
-
#constrain_period_bars ⇒ Object
constrain between 6 and 50 bars.
-
#constrain_period_magnitude_change ⇒ Object
constrain magnitude of change in phase.
- #fast_limit ⇒ Object
- #homodyne_discriminator ⇒ Object
- #slow_limit ⇒ Object
Methods inherited from Indicator
#<<, #[], #dc_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, #size, #t, #ticks, #values
Methods included from Mixins::FisherTransform
#fisher_transform, #inverse_fisher_transform, #relative_fisher_transform
Methods included from Mixins::Stochastic
Methods included from Mixins::SuperSmoother
#three_pole_super_smooth, #two_pole_super_smooth
Methods included from Mixins::HilbertTransform
Methods included from Mixins::ExponentialMovingAverage
Methods included from Mixins::SimpleMovingAverage
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
#compute ⇒ Object
135 136 137 138 139 140 |
# File 'lib/quant/indicators/mama.rb', line 135 def compute compute_dominant_cycle compute_dominant_cycle_phase compute_moving_averages compute_oscillator end |
#compute_dominant_cycle ⇒ Object
80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/quant/indicators/mama.rb', line 80 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_phase ⇒ Object
107 108 109 110 |
# File 'lib/quant/indicators/mama.rb', line 107 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_averages ⇒ Object
118 119 120 121 122 123 124 125 126 127 |
# File 'lib/quant/indicators/mama.rb', line 118 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_oscillator ⇒ Object
129 130 131 132 133 |
# File 'lib/quant/indicators/mama.rb', line 129 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_period ⇒ Object
amplitude correction using previous period value
61 62 63 64 |
# File 'lib/quant/indicators/mama.rb', line 61 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_bars ⇒ Object
constrain between 6 and 50 bars
50 51 52 |
# File 'lib/quant/indicators/mama.rb', line 50 def p0.period = p0.period.clamp(min_period, max_period) end |
#constrain_period_magnitude_change ⇒ Object
constrain magnitude of change in phase
55 56 57 58 |
# File 'lib/quant/indicators/mama.rb', line 55 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_limit ⇒ Object
99 100 101 |
# File 'lib/quant/indicators/mama.rb', line 99 def fast_limit @fast_limit ||= (min_period / 2) end |
#homodyne_discriminator ⇒ Object
66 67 68 69 70 71 72 73 74 75 76 77 78 |
# File 'lib/quant/indicators/mama.rb', line 66 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 compute_smooth_period end |
#slow_limit ⇒ Object
103 104 105 |
# File 'lib/quant/indicators/mama.rb', line 103 def slow_limit @slow_limit ||= (max_period) end |