quantitative 0.3.1 → 0.3.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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