quantitative 0.3.1 → 0.3.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (44) hide show
  1. checksums.yaml +4 -4
  2. data/Gemfile.lock +1 -1
  3. data/lib/quant/dominant_cycles_source.rb +1 -32
  4. data/lib/quant/indicators/adx.rb +2 -5
  5. data/lib/quant/indicators/atr.rb +2 -0
  6. data/lib/quant/indicators/cci.rb +2 -0
  7. data/lib/quant/indicators/decycler.rb +2 -0
  8. data/lib/quant/indicators/dominant_cycles/acr.rb +2 -0
  9. data/lib/quant/indicators/dominant_cycles/band_pass.rb +2 -0
  10. data/lib/quant/indicators/dominant_cycles/differential.rb +2 -0
  11. data/lib/quant/indicators/dominant_cycles/half_period.rb +2 -0
  12. data/lib/quant/indicators/dominant_cycles/homodyne.rb +2 -0
  13. data/lib/quant/indicators/dominant_cycles/phase_accumulator.rb +2 -0
  14. data/lib/quant/indicators/ema.rb +67 -0
  15. data/lib/quant/indicators/frama.rb +1 -0
  16. data/lib/quant/indicators/indicator.rb +17 -57
  17. data/lib/quant/indicators/indicator_point.rb +11 -0
  18. data/lib/quant/indicators/mama.rb +2 -0
  19. data/lib/quant/indicators/mesa.rb +3 -4
  20. data/lib/quant/indicators/ping.rb +2 -0
  21. data/lib/quant/indicators/pivots/atr.rb +11 -16
  22. data/lib/quant/indicators/pivots/bollinger.rb +10 -25
  23. data/lib/quant/indicators/pivots/camarilla.rb +30 -31
  24. data/lib/quant/indicators/pivots/classic.rb +3 -1
  25. data/lib/quant/indicators/pivots/demark.rb +5 -3
  26. data/lib/quant/indicators/pivots/donchian.rb +20 -23
  27. data/lib/quant/indicators/pivots/fibbonacci.rb +12 -9
  28. data/lib/quant/indicators/pivots/guppy.rb +3 -1
  29. data/lib/quant/indicators/pivots/keltner.rb +11 -19
  30. data/lib/quant/indicators/pivots/murrey.rb +8 -13
  31. data/lib/quant/indicators/pivots/pivot.rb +109 -0
  32. data/lib/quant/indicators/pivots/traditional.rb +2 -0
  33. data/lib/quant/indicators/pivots/woodie.rb +2 -0
  34. data/lib/quant/indicators/rocket_rsi.rb +57 -0
  35. data/lib/quant/indicators/roofing.rb +59 -0
  36. data/lib/quant/indicators/rsi.rb +67 -0
  37. data/lib/quant/indicators/snr.rb +64 -0
  38. data/lib/quant/indicators_registry.rb +63 -0
  39. data/lib/quant/indicators_source.rb +14 -9
  40. data/lib/quant/pivots_source.rb +1 -13
  41. data/lib/quant/version.rb +1 -1
  42. data/lib/quantitative.rb +10 -3
  43. metadata +9 -3
  44. data/lib/quant/indicators/pivot.rb +0 -107
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 0cfda18120bf7e3432b359a53d19d633f70f66e3ea4468098673cfc89ac2f77e
4
- data.tar.gz: 598dc565f6da96ce9565afee249f38bc909234177d7b484ce82cba226e2e8d60
3
+ metadata.gz: 5980a746b36ba0ee44bbd6117df75040a94969c5f00e1129d0f74aa1772b5013
4
+ data.tar.gz: 88fff74e34d1c446d252f9750bb5363828a448b9b326904fefa41499318fdb20
5
5
  SHA512:
6
- metadata.gz: 5b2625954abe0e72a776de95da8d26af213440cb7e2d7beddd48529dfdb70d7247562066b09a3edd1dd3f171ad3ff8a32390ffe337729ca9712f65bdb147084e
7
- data.tar.gz: 780f81a808f14d2d63b53aa81f8f30920b252979f17409d1ba48105ed5eadc91dadc253ada0cd75c6c21b8e6a8450cf39c75ce542adb450759fb097679899cce
6
+ metadata.gz: 57dd5832cf3aceaac7fda15fe2cec89fb615387205fcbbfd2dcb20ed2241bde58648aaa5b87f6bf605e2f827086613e7309d4e71bffdf60d786e2d71038a146f
7
+ data.tar.gz: f80357622cd7cbcee2d13d5439b0423aa0aab9006d3a1aedfd215d8690cf5cc158a9c10990b5ecb933322d5784709c258daa26ccaa0c51ea4808e36ee35554a2
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- quantitative (0.3.1)
4
+ quantitative (0.3.3)
5
5
  oj (~> 3.10)
6
6
  zeitwerk (~> 2.6)
7
7
 
@@ -17,40 +17,9 @@ module Quant
17
17
  class DominantCyclesSource
18
18
  def initialize(indicator_source:)
19
19
  @indicator_source = indicator_source
20
+ indicator_source.define_indicator_accessors(indicator_source: self)
20
21
  end
21
22
 
22
- # Auto-Correlation Reversals is a method of computing the dominant cycle
23
- # by correlating the data stream with itself delayed by a lag.
24
- def acr; indicator(Indicators::DominantCycles::Acr) end
25
-
26
- # The band-pass dominant cycle passes signals within a certain frequency
27
- # range, and attenuates signals outside that range.
28
- # The trend component of the signal is removed, leaving only the cyclical
29
- # component. Then we count number of iterations between zero crossings
30
- # and this is the `period` of the dominant cycle.
31
- def band_pass; indicator(Indicators::DominantCycles::BandPass) end
32
-
33
- # The Dual Differentiator algorithm computes the phase angle from the
34
- # analytic signal as the arctangent of the ratio of the imaginary
35
- # component to the real component. Further, the angular frequency
36
- # is defined as the rate change of phase. We can use these facts to
37
- # derive the cycle period.
38
- def differential; indicator(Indicators::DominantCycles::Differential) end
39
-
40
- # Static, arbitrarily set period.
41
- def half_period; indicator(Indicators::DominantCycles::HalfPeriod) end
42
-
43
- # Homodyne means the signal is multiplied by itself. More precisely,
44
- # we want to multiply the signal of the current bar with the complex
45
- # value of the signal one bar ago
46
- def homodyne; indicator(Indicators::DominantCycles::Homodyne) end
47
-
48
- # The phase accumulation method of computing the dominant cycle measures
49
- # the phase at each sample by taking the arctangent of the ratio of the
50
- # quadrature component to the in-phase component. The phase is then
51
- # accumulated and the period is derived from the phase.
52
- def phase_accumulator; indicator(Indicators::DominantCycles::PhaseAccumulator) end
53
-
54
23
  private
55
24
 
56
25
  def indicator(indicator_class)
@@ -21,12 +21,9 @@ module Quant
21
21
  end
22
22
 
23
23
  class Adx < Indicator
24
+ register name: :adx
24
25
  depends_on Indicators::Atr
25
26
 
26
- def alpha
27
- bars_to_alpha(dc_period)
28
- end
29
-
30
27
  def scale
31
28
  1.0
32
29
  end
@@ -71,7 +68,7 @@ module Quant
71
68
  p0.di_ema = three_pole_super_smooth(:di, period:, previous: :di_ema).clamp(-10.0, 10.0)
72
69
 
73
70
  p0.value = p0.di_ema
74
- p0.inst_stoch = stochastic :di, period: dc_period
71
+ p0.inst_stoch = stochastic(:di, period:)
75
72
  p0.stoch = three_pole_super_smooth :inst_stoch, period:, previous: :stoch
76
73
  end
77
74
  end
@@ -25,6 +25,8 @@ module Quant
25
25
  end
26
26
 
27
27
  class Atr < Indicator
28
+ register name: :atr
29
+
28
30
  attr_reader :points
29
31
 
30
32
  def period
@@ -18,6 +18,8 @@ module Quant
18
18
  #
19
19
  # SOURCE: https://www.mesasoftware.com/papers/CORRELATION%20AS%20A%20CYCLE%20INDICATOR.pdf
20
20
  class Cci < Indicator
21
+ register name: :cci
22
+
21
23
  def max_period
22
24
  [min_period, dc_period].max
23
25
  end
@@ -24,6 +24,8 @@ module Quant
24
24
  end
25
25
 
26
26
  class Decycler < Indicator
27
+ register name: :decycler
28
+
27
29
  def max_period
28
30
  dc_period
29
31
  end
@@ -28,6 +28,8 @@ module Quant
28
28
  # The cyclic information is extracted using a discrete Fourier transform
29
29
  # (DFT) of the autocorrelation results.
30
30
  class Acr < DominantCycle
31
+ register name: :acr
32
+
31
33
  BANDWIDTH_DEGREES = 370
32
34
  BANDWIDTH_RADIANS = BANDWIDTH_DEGREES * Math::PI / 180.0
33
35
 
@@ -20,6 +20,8 @@ module Quant
20
20
  # component. Then we count number of iterations between zero crossings
21
21
  # and this is the `period` of the dominant cycle.
22
22
  class BandPass < DominantCycle
23
+ register name: :band_pass
24
+
23
25
  def bandwidth
24
26
  0.75
25
27
  end
@@ -9,6 +9,8 @@ module Quant
9
9
  # is defined as the rate change of phase. We can use these facts to
10
10
  # derive the cycle period.
11
11
  class Differential < DominantCycle
12
+ register name: :differential
13
+
12
14
  def compute_period
13
15
  p0.ddd = (p0.q2 * (p0.i2 - p1.i2)) - (p0.i2 * (p0.q2 - p1.q2))
14
16
  p0.inst_period = p0.ddd > 0.01 ? 6.2832 * (p0.i2**2 + p0.q2**2) / p0.ddd : 0.0
@@ -12,6 +12,8 @@ module Quant
12
12
  end
13
13
 
14
14
  class HalfPeriod < DominantCycle
15
+ register name: :half_period
16
+
15
17
  def compute
16
18
  # No-Op
17
19
  end
@@ -7,6 +7,8 @@ module Quant
7
7
  # we want to multiply the signal of the current bar with the complex
8
8
  # value of the signal one bar ago
9
9
  class Homodyne < DominantCycle
10
+ register name: :homodyne
11
+
10
12
  def compute_period
11
13
  p0.re = (p0.i2 * p1.i2) + (p0.q2 * p1.q2)
12
14
  p0.im = (p0.i2 * p1.q2) - (p0.q2 * p1.i2)
@@ -24,6 +24,8 @@ module Quant
24
24
  # Therefore, shorter cycle periods necessarily have a higher output
25
25
  # signal-to-noise ratio.
26
26
  class PhaseAccumulator < DominantCycle
27
+ register name: :phase_accumulator
28
+
27
29
  def compute_period
28
30
  p0.i1 = 0.15 * p0.i1 + 0.85 * p1.i1
29
31
  p0.q1 = 0.15 * p0.q1 + 0.85 * p1.q1
@@ -0,0 +1,67 @@
1
+ module Quant
2
+ module Indicators
3
+ class EmaPoint < IndicatorPoint
4
+ attribute :ss_dc_period, default: :input
5
+ attribute :ss_half_dc_period, default: :input
6
+ attribute :ss_micro_period, default: :input
7
+ attribute :ss_min_period, default: :input
8
+ attribute :ss_half_period, default: :input
9
+ attribute :ss_max_period, default: :input
10
+
11
+ attribute :ema_dc_period, default: :input
12
+ attribute :ema_half_dc_period, default: :input
13
+ attribute :ema_micro_period, default: :input
14
+ attribute :ema_min_period, default: :input
15
+ attribute :ema_half_period, default: :input
16
+ attribute :ema_max_period, default: :input
17
+
18
+ attribute :osc_dc_period, default: 0.0
19
+ attribute :osc_half_dc_period, default: 0.0
20
+ attribute :osc_micro_period, default: 0.0
21
+ attribute :osc_min_period, default: 0.0
22
+ attribute :osc_half_period, default: 0.0
23
+ attribute :osc_max_period, default: 0.0
24
+ end
25
+
26
+ class Ema < Indicator
27
+ register name: :ema
28
+
29
+ def half_dc_period
30
+ dc_period / 2
31
+ end
32
+
33
+ def compute_super_smoothers
34
+ p0.ss_dc_period = super_smoother :input, previous: :ss_dc_period, period: dc_period
35
+ p0.ss_half_dc_period = super_smoother :input, previous: :ss_half_dc_period, period: half_dc_period
36
+ p0.ss_micro_period = super_smoother :input, previous: :ss_micro_period, period: micro_period
37
+ p0.ss_min_period = super_smoother :input, previous: :ss_min_period, period: min_period
38
+ p0.ss_half_period = super_smoother :input, previous: :ss_half_period, period: half_period
39
+ p0.ss_max_period = super_smoother :input, previous: :ss_max_period, period: max_period
40
+ end
41
+
42
+ def compute_emas
43
+ p0.ema_dc_period = ema :input, previous: :ema_dc_period, period: dc_period
44
+ p0.ema_half_dc_period = ema :input, previous: :ema_half_dc_period, period: half_dc_period
45
+ p0.ema_micro_period = ema :input, previous: :ema_micro_period, period: micro_period
46
+ p0.ema_min_period = ema :input, previous: :ema_min_period, period: min_period
47
+ p0.ema_half_period = ema :input, previous: :ema_half_period, period: half_period
48
+ p0.ema_max_period = ema :input, previous: :ema_max_period, period: max_period
49
+ end
50
+
51
+ def compute_oscillators
52
+ p0.osc_dc_period = p0.ss_dc_period - p0.ema_dc_period
53
+ p0.osc_half_dc_period = p0.ss_half_dc_period - p0.ema_half_dc_period
54
+ p0.osc_micro_period = p0.ss_micro_period - p0.ema_micro_period
55
+ p0.osc_min_period = p0.ss_min_period - p0.ema_min_period
56
+ p0.osc_half_period = p0.ss_half_period - p0.ema_half_period
57
+ p0.osc_max_period = p0.ss_max_period - p0.ema_max_period
58
+ end
59
+
60
+ def compute
61
+ compute_super_smoothers
62
+ compute_emas
63
+ compute_oscillators
64
+ end
65
+ end
66
+ end
67
+ end
@@ -15,6 +15,7 @@ module Quant
15
15
  #
16
16
  # SOURCE: http://www.mesasoftware.com/papers/FRAMA.pdf
17
17
  class Frama < Indicator
18
+ register name: :frama
18
19
  using Quant
19
20
 
20
21
  # The max_period is divided into two smaller, equal periods, so must be even
@@ -15,6 +15,10 @@ module Quant
15
15
  include Mixins::FisherTransform
16
16
  # include Mixins::Direction
17
17
 
18
+ def self.register(name:)
19
+ Quant::IndicatorsSource.register(name:, indicator_class: self)
20
+ end
21
+
18
22
  # Provides a registry of dependent indicators for each indicator class.
19
23
  # NOTE: Internal use only.
20
24
  def self.dependent_indicator_classes
@@ -94,9 +98,18 @@ module Quant
94
98
  series.indicators[source][dominant_cycle_indicator_class]
95
99
  end
96
100
 
97
- def dc_period
101
+ # The adaptive period is the full dominant cycle period
102
+ def adaptive_period
98
103
  dominant_cycle.points[t0].period
99
104
  end
105
+ alias dc_period adaptive_period
106
+ alias dominant_cycle_period adaptive_period
107
+
108
+ def adaptive_half_period
109
+ adaptive_period / 2
110
+ end
111
+ alias dc_half_period adaptive_half_period
112
+ alias dominant_half_cycle_period adaptive_half_period
100
113
 
101
114
  def ticks
102
115
  @points.keys
@@ -189,67 +202,14 @@ module Quant
189
202
  t0.send(source)
190
203
  end
191
204
 
192
- # def warmed_up?
193
- # true
194
- # end
195
-
196
- # attr_reader :dc_period
197
-
198
- # def points_for(series:)
199
- # @points_for_cache[series] ||= self.class.new(series:, settings:, cloning: true).tap do |indicator|
200
- # series.ticks.each { |tick| indicator.points.push(tick.indicators[self]) }
201
- # end
202
- # end
203
-
204
- # # Ticks belong to the first series they're associated with always
205
- # # NOTE: No provisions for series merging their ticks to one series!
206
- # def parent_series
207
- # series.ticks.empty? ? series : series.ticks.first.series
208
- # end
209
-
210
- # # Returns the last point of the current indicator rather than the entire series
211
- # # This is used for indicators that depend on dominant cycle or other indicators
212
- # # to compute their data points.
213
- # def current_point
214
- # points.size - 1
215
- # end
216
-
217
- # def dominant_cycles
218
- # parent_series.indicators.dominant_cycles
219
- # end
220
-
221
- # # Override this method to change source of dominant cycle computation for an indicator
222
- # def dominant_cycle_indicator
223
- # @dominant_cycle_indicator ||= dominant_cycles.band_pass
224
- # end
225
-
226
- # def ensure_not_dominant_cycler_indicator
227
- # return unless is_a? Quant::Indicators::DominantCycles::DominantCycle
228
-
229
- # raise 'Dominant Cycle Indicators cannot use the thing they compute!'
230
- # end
231
-
232
- # # Returns the dominant cycle point for the current indicator's point
233
- # def current_dominant_cycle
234
- # dominant_cycle_indicator[current_point]
235
- # end
205
+ def warmed_up?
206
+ ticks.size > min_period
207
+ end
236
208
 
237
209
  # # Returns the atr point for the current indicator's point
238
210
  # def atr_point
239
211
  # parent_series.indicators.atr[current_point]
240
212
  # end
241
-
242
- # # def dc_period
243
- # # dominant_cycle.period.round(0).to_i
244
- # # end
245
-
246
- # def <<(ohlc)
247
- # points.append(ohlc)
248
- # end
249
-
250
- # def append(ohlc)
251
- # points.append(ohlc)
252
- # end
253
213
  end
254
214
  end
255
215
  end
@@ -27,6 +27,17 @@ module Quant
27
27
  def_delegator :indicator, :dominant_cycle_kind
28
28
  def_delegator :indicator, :pivot_kind
29
29
 
30
+ def_delegator :tick, :high_price
31
+ def_delegator :tick, :low_price
32
+ def_delegator :tick, :close_price
33
+ def_delegator :tick, :open_price
34
+ def_delegator :tick, :volume
35
+ def_delegator :tick, :trades
36
+
37
+ def oc2
38
+ tick.respond_to?(:oc2) ? tick.oc2 : tick.close_price
39
+ end
40
+
30
41
  def initialize_data_points
31
42
  # No-Op - Override in subclass if needed.
32
43
  end
@@ -46,6 +46,8 @@ module Quant
46
46
  # dominant cycle indicator other than the homodyne for the rest
47
47
  # of your indicators.
48
48
  class Mama < Indicator
49
+ register name: :mama
50
+
49
51
  # constrain between 6 and 50 bars
50
52
  def constrain_period_bars
51
53
  p0.period = p0.period.clamp(min_period, max_period)
@@ -33,12 +33,11 @@ module Quant
33
33
  # indicators for the dominant cycle, then this version is useful
34
34
  # as it avoids extra computational steps.
35
35
  class Mesa < Indicator
36
- def period
37
- dc_period
38
- end
36
+ register name: :mesa
37
+ depends_on DominantCycles::Homodyne
39
38
 
40
39
  def fast_limit
41
- @fast_limit ||= bars_to_alpha(min_period / 2)
40
+ @fast_limit ||= bars_to_alpha(micro_period)
42
41
  end
43
42
 
44
43
  def slow_limit
@@ -13,6 +13,8 @@ module Quant
13
13
 
14
14
  # A simple idicator used primarily to test the indicator system
15
15
  class Ping < Indicator
16
+ register name: :ping
17
+
16
18
  def compute
17
19
  p0.pong = input
18
20
  p0.compute_count += 1
@@ -2,6 +2,7 @@ module Quant
2
2
  module Indicators
3
3
  module Pivots
4
4
  class Atr < Pivot
5
+ register name: :atr
5
6
  depends_on Indicators::Atr
6
7
 
7
8
  def atr_point
@@ -9,31 +10,25 @@ module Quant
9
10
  end
10
11
 
11
12
  def scale
12
- 5.0
13
+ 3.0
13
14
  end
14
15
 
15
16
  def atr_value
16
- atr_point.slow * scale
17
+ atr_point.value * scale
17
18
  end
18
19
 
19
20
  def compute_midpoint
20
- p0.midpoint = two_pole_super_smooth :input, previous: :midpoint, period: averaging_period
21
+ p0.midpoint = smoothed_average_midpoint
21
22
  end
22
23
 
23
- def compute_bands
24
- p0.h6 = p0.midpoint + 1.000 * atr_value
25
- p0.h5 = p0.midpoint + 0.786 * atr_value
26
- p0.h4 = p0.midpoint + 0.618 * atr_value
27
- p0.h3 = p0.midpoint + 0.500 * atr_value
28
- p0.h2 = p0.midpoint + 0.382 * atr_value
29
- p0.h1 = p0.midpoint + 0.236 * atr_value
24
+ ATR_SERIES = [0.236, 0.382, 0.500, 0.618, 0.786, 1.0].freeze
30
25
 
31
- p0.l1 = p0.midpoint - 0.236 * atr_value
32
- p0.l2 = p0.midpoint - 0.382 * atr_value
33
- p0.l3 = p0.midpoint - 0.500 * atr_value
34
- p0.l4 = p0.midpoint - 0.618 * atr_value
35
- p0.l5 = p0.midpoint - 0.786 * atr_value
36
- p0.l6 = p0.midpoint - 1.000 * atr_value
26
+ def compute_bands
27
+ ATR_SERIES.each_with_index do |ratio, index|
28
+ offset = ratio * atr_value
29
+ p0[index + 1] = p0.midpoint + offset
30
+ p0[-index - 1] = p0.midpoint - offset
31
+ end
37
32
  end
38
33
  end
39
34
  end
@@ -4,40 +4,25 @@ module Quant
4
4
  module Indicators
5
5
  module Pivots
6
6
  class Bollinger < Pivot
7
+ register name: :bollinger
8
+
7
9
  using Quant
8
10
 
9
11
  def compute_midpoint
10
- values = period_points(half_period).map(&:input)
11
- alpha = bars_to_alpha(half_period)
12
+ values = period_points(adaptive_half_period).map(&:input)
13
+ alpha = bars_to_alpha(adaptive_half_period)
12
14
 
13
15
  p0.midpoint = alpha * values.mean + (1 - alpha) * p1.midpoint
14
16
  p0.std_dev = values.standard_deviation(p0.midpoint)
15
17
  end
16
18
 
17
- def compute_bands
18
- p0.h1 = p0.midpoint + p0.std_dev * 1.0
19
- p0.l1 = p0.midpoint - p0.std_dev * 1.0
20
-
21
- p0.h2 = p0.midpoint + p0.std_dev * 1.5
22
- p0.l2 = p0.midpoint - p0.std_dev * 1.5
23
-
24
- p0.h3 = p0.midpoint + p0.std_dev * 1.75
25
- p0.l3 = p0.midpoint - p0.std_dev * 1.75
26
-
27
- p0.h4 = p0.midpoint + p0.std_dev * 2.0
28
- p0.l4 = p0.midpoint - p0.std_dev * 2.0
19
+ BOLLINGER_SERIES = [1.0, 1.5, 1.75, 2.0, 2.25, 2.5, 2.75, 3.0].freeze
29
20
 
30
- p0.h5 = p0.midpoint + p0.std_dev * 2.25
31
- p0.l5 = p0.midpoint - p0.std_dev * 2.25
32
-
33
- p0.h6 = p0.midpoint + p0.std_dev * 2.5
34
- p0.l6 = p0.midpoint - p0.std_dev * 2.5
35
-
36
- p0.h7 = p0.midpoint + p0.std_dev * 2.75
37
- p0.l7 = p0.midpoint - p0.std_dev * 2.75
38
-
39
- p0.h8 = p0.midpoint + p0.std_dev * 3.0
40
- p0.l8 = p0.midpoint - p0.std_dev * 3.0
21
+ def compute_bands
22
+ BOLLINGER_SERIES.each_with_index do |ratio, index|
23
+ p0[index + 1] = p0.midpoint + ratio * p0.std_dev
24
+ p0[-index - 1] = p0.midpoint - ratio * p0.std_dev
25
+ end
41
26
  end
42
27
  end
43
28
  end
@@ -7,53 +7,52 @@ module Quant
7
7
  # input the previous day’s open, high, low and close. The formulas for each
8
8
  # resistance and support level are:
9
9
  #
10
- # R4 = Close + (High Low) * 1.1/2
11
- # R3 = Close + (High Low) * 1.1/4
12
- # R2 = Close + (High Low) * 1.1/6
13
- # R1 = Close + (High Low) * 1.1/12
14
- # S1 = Close – (High Low) * 1.1/12
15
- # S2 = Close – (High Low) * 1.1/6
16
- # S3 = Close – (High Low) * 1.1/4
17
- # S4 = Close – (High Low) * 1.1/2
10
+ # R4 = Closing + ((High -Low) x 1.5000)
11
+ # R3 = Closing + ((High -Low) x 1.2500)
12
+ # R2 = Closing + ((High -Low) x 1.1666)
13
+ # R1 = Closing + ((High -Low x 1.0833)
14
+ # PP = (High + Low + Closing) / 3
15
+ # S1 = Closing – ((High -Low) x 1.0833)
16
+ # S2 = Closing – ((High -Low) x 1.1666)
17
+ # S3 = Closing – ((High -Low) x 1.2500)
18
+ # S4 = Closing – ((High-Low) x 1.5000)
19
+ #
20
+ # R5 = R4 + 1.168 * (R4 – R3)
21
+ # R6 = (High/Low) * Close
22
+ # S5 = S4 – 1.168 * (S3 – S4)
23
+ # S6 = Close – (R6 – Close)
18
24
  #
19
25
  # The calculation for further resistance and support levels varies from this
20
26
  # norm. These levels can come into play during strong trend moves, so it’s
21
27
  # important to understand how to identify them. For example, R5, R6, S5 and S6
22
28
  # are calculated as follows:
23
29
  #
24
- # R5 = R4 + 1.168 * (R4 – R3)
25
- # R6 = (High/Low) * Close
26
- #
27
- # S5 = S4 – 1.168 * (S3 – S4)
28
- # S6 = Close – (R6 – Close)
30
+ # source: https://tradingstrategyguides.com/camarilla-pivot-trading-strategy/
29
31
  class Camarilla < Pivot
30
- def multiplier
31
- 1.1
32
- end
32
+ register name: :camarilla
33
33
 
34
34
  def compute_midpoint
35
- p0.midpoint = t0.close_price
35
+ p0.midpoint = t0.hlc3
36
36
  end
37
37
 
38
38
  def compute_bands
39
- mp_plus_range = p0.midpoint + p0.range
40
- mp_minus_range = p0.midpoint - p0.range
39
+ p0.h1 = t0.close_price + p0.range * 1.083
40
+ p0.l1 = t0.close_price - p0.range * 1.083
41
+
42
+ p0.h2 = t0.close_price + p0.range * 1.167
43
+ p0.l2 = t0.close_price - p0.range * 1.167
41
44
 
42
- p0.h4 = mp_plus_range * (1.1 / 2.0)
43
- p0.h3 = mp_plus_range * (1.1 / 4.0)
44
- p0.h2 = mp_plus_range * (1.1 / 6.0)
45
- p0.h1 = mp_plus_range * (1.1 / 12.0)
45
+ p0.h3 = t0.close_price + p0.range * 1.250
46
+ p0.l3 = t0.close_price - p0.range * 1.250
46
47
 
47
- p0.l1 = mp_minus_range * (1.1 / 12.0)
48
- p0.l2 = mp_minus_range * (1.1 / 6.0)
49
- p0.l3 = mp_minus_range * (1.1 / 4.0)
50
- p0.l4 = mp_minus_range * (1.1 / 2.0)
48
+ p0.h4 = t0.close_price + p0.range * 1.500
49
+ p0.l4 = t0.close_price - p0.range * 1.500
51
50
 
52
- p0.h5 = p0.h4 + 1.168 * (p0.h4 - p0.h3)
53
- p0.h6 = p0.midpoint * (p0.high_price / p0.low_price)
51
+ p0.h5 = p0.h4 + 1.68 * (p0.h4 - p0.h3)
52
+ p0.l5 = p0.l4 - 1.68 * (p0.l3 - p0.l4)
54
53
 
55
- p0.l5 = p0.l4 - 1.168 * (p0.l3 - p0.l4)
56
- p0.l6 = p0.midpoint - (p0.h6 - p0.midpoint)
54
+ p0.h6 = (t0.high_price / t0.low_price) * t0.close_price
55
+ p0.l6 = t0.close_price - (p0.h6 - t0.close_price)
57
56
  end
58
57
  end
59
58
  end
@@ -4,8 +4,10 @@ module Quant
4
4
  module Indicators
5
5
  module Pivots
6
6
  class Classic < Pivot
7
+ register name: :classic
8
+
7
9
  def compute_midpoint
8
- p0.midpoint = super_smoother :input, previous: :midpoint, period: averaging_period
10
+ p0.midpoint = smoothed_average_midpoint
9
11
  end
10
12
 
11
13
  def compute_bands
@@ -14,6 +14,8 @@ module Quant
14
14
  # PP = X / 4 (this is not an official DeMark number but merely a reference point based on the calculation of X)
15
15
  # S1 = X / 2 - H
16
16
  class Demark < Pivot
17
+ register name: :demark
18
+
17
19
  def averaging_period
18
20
  min_period / 2
19
21
  end
@@ -34,15 +36,15 @@ module Quant
34
36
 
35
37
  def compute_midpoint
36
38
  p0.midpoint = p0.input / 4.0
37
- p0.midpoint = super_smoother :midpoint, previous: :midpoint, period: averaging_period
39
+ p0.midpoint = three_pole_super_smooth :midpoint, previous: :midpoint, period: averaging_period
38
40
  end
39
41
 
40
42
  def compute_bands
41
43
  p0.h1 = (p0.input / 2.0) - p0.avg_high
42
- p0.h1 = super_smoother :h1, previous: :h1, period: averaging_period
44
+ p0.h1 = three_pole_super_smooth :h1, previous: :h1, period: averaging_period
43
45
 
44
46
  p0.l1 = (p0.input / 2.0) - p0.avg_low
45
- p0.l1 = super_smoother :l1, previous: :l1, period: averaging_period
47
+ p0.l1 = three_pole_super_smooth :l1, previous: :l1, period: averaging_period
46
48
  end
47
49
  end
48
50
  end