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
#<<, #[], #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
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
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_cycle ⇒ Object
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_phase ⇒ Object
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_averages ⇒ Object
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_oscillator ⇒ Object
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_period ⇒ Object
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_bars ⇒ Object
constrain between 6 and 50 bars
52 53 54 |
# File 'lib/quant/indicators/mama.rb', line 52 def p0.period = p0.period.clamp(min_period, max_period) end |
#constrain_period_magnitude_change ⇒ Object
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_limit ⇒ Object
101 102 103 |
# File 'lib/quant/indicators/mama.rb', line 101 def fast_limit @fast_limit ||= (min_period / 2) end |
#homodyne_discriminator ⇒ Object
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 compute_smooth_period end |
#slow_limit ⇒ Object
105 106 107 |
# File 'lib/quant/indicators/mama.rb', line 105 def slow_limit @slow_limit ||= (max_period) end |