Class: Quant::Indicators::DominantCycles::PhaseAccumulator

Inherits:
DominantCycle show all
Defined in:
lib/quant/indicators/dominant_cycles/phase_accumulator.rb

Overview

The phase accumulation method of computing the dominant cycle is perhaps the easiest to comprehend. In this technique, we measure the phase at each sample by taking the arctangent of the ratio of the quadrature component to the in-phase component. A delta phase is generated by taking the difference of the phase between successive samples. At each sample we can then look backwards, adding up the delta phases. When the sum of the delta phases reaches 360 degrees, we must have passed through one full cycle, on average. The process is repeated for each new sample.

The phase accumulation method of cycle measurement always uses one full cycle’s worth of historical data. This is both an advantage and a disadvantage. The advantage is the lag in obtaining the answer scales directly with the cycle period. That is, the measurement of a short cycle period has less lag than the measurement of a longer cycle period. However, the number of samples used in making the measurement means the averaging period is variable with cycle period. Longer averaging reduces the noise level compared to the signal. Therefore, shorter cycle periods necessarily have a higher output signal-to-noise ratio.

Constant Summary

Constants inherited from Indicator

Indicator::PRIORITIES

Constants included from Mixins::UniversalFilters

Mixins::UniversalFilters::K

Instance Attribute Summary

Attributes inherited from DominantCycle

#points

Attributes inherited from Indicator

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

Instance Method Summary collapse

Methods inherited from DominantCycle

#compute, #compute_input_data_points, #compute_mean_period, #compute_phase, #compute_quadrature_components, #compute_smooth_period, #constrain_period_bars, #constrain_period_magnitude_change, #dominant_cycle_indicator_class, #dominant_cycle_period, #points_class, #priority

Methods inherited from Indicator

#<<, #[], #adaptive_half_period, #adaptive_period, #compute, 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

#compute_periodObject



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/quant/indicators/dominant_cycles/phase_accumulator.rb', line 29

def compute_period
  p0.i1 = 0.15 * p0.i1 + 0.85 * p1.i1
  p0.q1 = 0.15 * p0.q1 + 0.85 * p1.q1

  p0.accumulator_phase = Math.atan(p0.q1 / p0.i1) unless p0.i1.zero?

  if p0.i1 < 0 && p0.q1 > 0
    p0.accumulator_phase = 180.0 - p0.accumulator_phase
  elsif p0.i1 < 0 && p0.q1 < 0
    p0.accumulator_phase = 180.0 + p0.accumulator_phase
  elsif p0.i1 > 0 && p0.q1 < 0
    p0.accumulator_phase = 360.0 - p0.accumulator_phase
  end

  p0.delta_phase = p1.accumulator_phase - p0.accumulator_phase
  if p1.accumulator_phase < 90.0 && p0.accumulator_phase > 270.0
    p0.delta_phase = 360.0 + p1.accumulator_phase - p0.accumulator_phase
  end

  p0.delta_phase = p0.delta_phase.clamp(min_period, max_period)

  p0.inst_period = p1.inst_period
  period_points(max_period).each_with_index do |prev, index|
    p0.phase_sum += prev.delta_phase
    if p0.phase_sum > 360.0
      p0.inst_period = index
      break
    end
  end
  p0.period = (0.25 * p0.inst_period + 0.75 * p1.inst_period).round(0)
end