Module: Quant::Mixins::Filters

Includes:
Trig
Included in:
Indicators::Ma
Defined in:
lib/quant/mixins/filters.rb

Overview

  1. All the common filters useful for traders have a transfer response that can be written as a ratio of two polynomials.

  2. Lag is very important to traders. More complex filters can be created using more input data, but more input data increases lag. Sophisticated filters are not very useful for trading because they incur too much lag.

  3. Filter transfer response can be viewed in the time domain and the frequency domain with equal validity.

  4. Nonrecursive filters can have zeros in the transfer response, enabling the complete cancellation of some selected frequency components.

  5. Nonrecursive filters having coefficients symmetrical about the center of the filter will have a delay of half the degree of the transfer response polynomial at all frequencies.

  6. Low-pass filters are smoothers because they attenuate the high-frequency components of the input data.

  7. High-pass filters are detrenders because they attenuate the low-frequency components of trends.

  8. Band-pass filters are both detrenders and smoothers because they attenuate all but the desired frequency components.

  9. Filters provide an output only through their transfer response. The transfer response is strictly a mathematical function, and interpretations such as overbought, oversold, convergence, divergence, and so on are not implied. The validity of such interpretations must be made on the basis of statistics apart from the filter.

  10. The critical period of a filter output is the frequency at which the output power of the filter is half the power of the input wave at that frequency.

  11. A WMA has little or no redeeming virtue.

  12. A median filter is best used when the data contain impulsive noise or when there are wild variations in the data. Smoothing volume data is one example of a good application for a median filter.

Filter Coefficients forVariousTypes of Filters Filter Type b0 b1 b2 a0 a1 a2 EMA α 0 0 1 −(1−α) 0 Two-pole low-pass α**2 0 0 1 −2*(1-α) (1-α)**2 High-pass (1-α/2) -(1-α/2) 0 1 −(1−α) 0 Two-pole high-pass (1-α/2)**2 -2*(1-α/2)**2 (1-α/2)**2 1 -2*(1-α) (1-α)**2 Band-pass (1-σ)/2 0 -(1-σ)/2 1 -λ*(1+σ) σ Band-stop (1+σ)/2 -2λ*(1+σ)/2 (1+σ)/2 1 -λ*(1+σ) σ

Instance Method Summary collapse

Methods included from Trig

#angle, #deg2rad, #rad2deg

Instance Method Details

#band_pass(source, prev_source, period, bandwidth) ⇒ Object



72
# File 'lib/quant/mixins/filters.rb', line 72

def band_pass(source, prev_source, period, bandwidth); end

#bars_to_alpha(bars) ⇒ Object

3 bars = 0.5 4 bars = 0.4 5 bars = 0.333 6 bars = 0.285 10 bars = 0.182 20 bars = 0.0952 40 bars = 0.0488 50 bars = 0.0392



61
62
63
# File 'lib/quant/mixins/filters.rb', line 61

def bars_to_alpha(bars)
  2.0 / (bars + 1)
end

#ema(source, prev_source, period) ⇒ Object



65
66
67
68
69
70
# File 'lib/quant/mixins/filters.rb', line 65

def ema(source, prev_source, period)
  alpha = bars_to_alpha(period)
  v0 = source.is_a?(Symbol) ? p0.send(source) : source
  v1 = p1.send(prev_source)
  (v0 * alpha) + (v1 * (1 - alpha))
end

#period_to_alpha(period, k: 1.0) ⇒ Object

α = Cos(K*360/Period)+Sin(K*360/Period)−1 / Cos(K*360/Period) k = 1.0 for single-pole filters k = 0.707 for two-pole high-pass filters k = 1.414 for two-pole low-pass filters



46
47
48
49
50
51
# File 'lib/quant/mixins/filters.rb', line 46

def period_to_alpha(period, k: 1.0)
  radians = deg2rad(k * 360 / period)
  cos = Math.cos(radians)
  sin = Math.sin(radians)
  (cos + sin - 1) / cos
end

#three_pole_butterworth(source, prev_source, period) ⇒ Object



92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/quant/mixins/filters.rb', line 92

def three_pole_butterworth(source, prev_source, period)
  v0 = source.is_a?(Symbol) ? p0.send(source) : source
  return v0 if p2 == p3

  v1 = p1.send(prev_source)
  v2 = p2.send(prev_source)
  v3 = p3.send(prev_source)

  radians = Math.sqrt(3) * Math::PI / period
  a = Math.exp(-radians)
  b = 2 * a * Math.cos(radians)
  c = a**2

  d4 = c**2
  d3 = -(c + (b * c))
  d2 = b + c
  d1 = 1.0 - d2 - d3 - d4

  (d1 * v0) + (d2 * v1) + (d3 * v2) + (d4 * v3)
end

#two_pole_butterworth(source, prev_source, period) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/quant/mixins/filters.rb', line 74

def two_pole_butterworth(source, prev_source, period)
  v0 = source.is_a?(Symbol) ? p0.send(source) : source

  v1 = 0.5 * (v0 + p1.send(source))
  v2 = p1.send(prev_source)
  v3 = p2.send(prev_source)

  radians = Math.sqrt(2) * Math::PI / period
  a = Math.exp(-radians)
  b = 2 * a * Math.cos(radians)

  c2 = b
  c3 = -a**2
  c1 = 1.0 - c2 - c3

  (c1 * v1) + (c2 * v2) + (c3 * v3)
end