quantitative 0.1.4 → 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 266a7aa51d29b809224fa76091d26c52d58f6e42959aeeb4ca5ffb6376828773
4
- data.tar.gz: 5b3ac92706338a77a098e5dee72f3ecf57f2c4032f946533225e6061d07082d5
3
+ metadata.gz: c9fa0c537499409fa9faa3fbca76beca44d37205c04c8de1c01b3e681985c2dc
4
+ data.tar.gz: 3916820207b47d2d19b79332e41329c35080ce1456c4a2ed751863ea220b5289
5
5
  SHA512:
6
- metadata.gz: 624d6945e690d51b5afef5ebc7939eb3f444fd7d4d79a31e73df5a42e0f6c351f8d4ac451a455a657c96a07448a0c724ba1481156d2e859ca720c8994328547a
7
- data.tar.gz: 51b9fd16424fe1fd1b48c72f350c89cfb9e26e0a082eb750ae864c436b51eeab2142c64744deee93b91aaafe119354f19a4159ecda84b066d75f1d242945a9a2
6
+ metadata.gz: e3bead0b7fc23208c62dd18bb8f701b684db20780ae793fab973ab07cea0740897026a66755a07b9857228e815bfc3679801171f2b5875f510a7c98781fd30cb
7
+ data.tar.gz: 8b07dbcbe1a86c507a31df950aef293ae018913964848a9298310fe71a7929924a5a7ced417cf5ef86e9282feb58bc9d16531bf6b77e0fa23cea28de7a761740
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- quantitative (0.1.4)
4
+ quantitative (0.1.5)
5
5
  oj (~> 3.10)
6
6
 
7
7
  GEM
@@ -0,0 +1,88 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative "asset_class"
4
+
5
+ module Quant
6
+ # A {Quant::Asset} is a representation of a financial instrument such as a stock, option, future, or currency.
7
+ # It is used to represent the instrument that is being traded, analyzed, or managed.
8
+ #
9
+ # Not all data sources have a rich set of attributes for their assets or securities. The {Quant::Asset} is designed
10
+ # to be flexible and to support a wide variety of data sources and use-cases. The most common use-cases are supported
11
+ # while allowing for additional attributes to be added via the +meta+ attribute, which is tyipically just a Hash,
12
+ # but can be any object that can hold useful information about the asset such as currency formatting, precision, etc.
13
+ # @example
14
+ # asset = Quant::Asset.new(symbol: "AAPL", name: "Apple Inc.", asset_class: :stock, exchange: "NASDAQ")
15
+ # asset.symbol # => "AAPL"
16
+ # asset.name # => "Apple Inc."
17
+ # asset.stock? # => true
18
+ # asset.option? # => false
19
+ # asset.future? # => false
20
+ # asset.currency? # => false
21
+ # asset.exchange # => "NASDAQ"
22
+ #
23
+ # # Can serialize two ways:
24
+ # asset.to_h # => { "s" => "AAPL" }
25
+ # asset.to_h(full: true) # => { "s" => "AAPL", "n" => "Apple Inc.", "sc" => "stock", "x" => "NASDAQ" }
26
+ class Asset
27
+ attr_reader :symbol, :name, :asset_class, :id, :exchange, :source, :meta, :created_at, :updated_at
28
+
29
+ def initialize(
30
+ symbol:,
31
+ name: nil,
32
+ id: nil,
33
+ active: true,
34
+ tradeable: true,
35
+ exchange: nil,
36
+ source: nil,
37
+ asset_class: nil,
38
+ created_at: Quant.current_time,
39
+ updated_at: Quant.current_time,
40
+ meta: {}
41
+ )
42
+ raise ArgumentError, "symbol is required" unless symbol
43
+
44
+ @symbol = symbol.to_s.upcase
45
+ @name = name
46
+ @id = id
47
+ @tradeable = tradeable
48
+ @active = active
49
+ @exchange = exchange
50
+ @source = source
51
+ @asset_class = AssetClass.new(asset_class)
52
+ @created_at = created_at
53
+ @updated_at = updated_at
54
+ @meta = meta
55
+ end
56
+
57
+ def active?
58
+ !!@active
59
+ end
60
+
61
+ def tradeable?
62
+ !!@tradeable
63
+ end
64
+
65
+ AssetClass::CLASSES.each do |class_name|
66
+ define_method("#{class_name}?") do
67
+ asset_class == class_name
68
+ end
69
+ end
70
+
71
+ def to_h(full: false)
72
+ return { "s" => symbol } unless full
73
+
74
+ { "s" => symbol,
75
+ "n" => name,
76
+ "id" => id,
77
+ "t" => tradeable?,
78
+ "a" => active?,
79
+ "x" => exchange,
80
+ "sc" => asset_class.to_s,
81
+ "src" => source.to_s }
82
+ end
83
+
84
+ def to_json(*args, full: false)
85
+ Oj.dump(to_h(full: full), *args)
86
+ end
87
+ end
88
+ end
@@ -24,7 +24,7 @@ module Quant
24
24
  # real estate. Investors can buy shares in a REIT, which provides them with a share of the
25
25
  # income produced by the real estate.
26
26
 
27
- # Cryptocurrencies: Digital or virtual currencies that use cryptography for security and operate on
27
+ # Cryptocurrencies: Digital or virtual currencies that use cryptography for asset and operate on
28
28
  # decentralized networks, typically based on blockchain technology. Examples include Bitcoin, Ethereum, and Ripple.
29
29
 
30
30
  # Preferred Stock: A type of stock that has priority over common stock in terms of dividend
@@ -40,7 +40,7 @@ module Quant
40
40
 
41
41
  # Foreign Exchange (Forex): The market where currencies are traded. Investors can buy and sell currencies to
42
42
  # profit from changes in exchange rates.
43
- class SecurityClass
43
+ class AssetClass
44
44
  CLASSES = %i(
45
45
  bond
46
46
  commodity
@@ -57,31 +57,31 @@ module Quant
57
57
  treasury_note
58
58
  ).freeze
59
59
 
60
- attr_reader :security_class
60
+ attr_reader :asset_class
61
61
 
62
62
  def initialize(name)
63
- return if @security_class = from_standard(name)
63
+ return if @asset_class = from_standard(name)
64
64
 
65
- @security_class = from_alternate(name.to_s.downcase.to_sym) unless name.nil?
66
- raise_unknown_security_class_error(name) unless security_class
65
+ @asset_class = from_alternate(name.to_s.downcase.to_sym) unless name.nil?
66
+ raise_unknown_asset_class_error(name) unless asset_class
67
67
  end
68
68
 
69
69
  CLASSES.each do |class_name|
70
70
  define_method("#{class_name}?") do
71
- security_class == class_name
71
+ asset_class == class_name
72
72
  end
73
73
  end
74
74
 
75
- def raise_unknown_security_class_error(name)
76
- raise SecurityClassError, "Unknown security class: #{name.inspect}"
75
+ def raise_unknown_asset_class_error(name)
76
+ raise Errors::AssetClassError, "Unknown asset class: #{name.inspect}"
77
77
  end
78
78
 
79
79
  def to_s
80
- security_class.to_s
80
+ asset_class.to_s
81
81
  end
82
82
 
83
83
  def to_h
84
- { "sc" => security_class }
84
+ { "sc" => asset_class }
85
85
  end
86
86
 
87
87
  def to_json(*args)
@@ -90,9 +90,9 @@ module Quant
90
90
 
91
91
  def ==(other)
92
92
  case other
93
- when String then from_alternate(other.to_sym) == security_class
94
- when Symbol then from_alternate(other) == security_class
95
- when SecurityClass then other.security_class == security_class
93
+ when String then from_alternate(other.to_sym) == asset_class
94
+ when Symbol then from_alternate(other) == asset_class
95
+ when AssetClass then other.asset_class == asset_class
96
96
  else
97
97
  false
98
98
  end
@@ -0,0 +1,134 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Quant
4
+ module Attributes
5
+ # Tracks all defined attributes, allowing child classes to inherit their parent's attributes.
6
+ # The registry key is the class registering an attrbritute and is itself a hash of the attribute name
7
+ # and the attribute's key and default value.
8
+ # Internal use only.
9
+ #
10
+ # @example
11
+ # { Quant::Indicators::IndicatorPoint => {
12
+ # tick: { key: nil, default: nil },
13
+ # source: { key: "src", default: nil },
14
+ # input: { key: "in", default: nil }
15
+ # },
16
+ # Quant::Indicators::PingPoint => {
17
+ # pong: { key: nil, default: nil },
18
+ # compute_count: { key: nil, default: 0 }
19
+ # }
20
+ # }
21
+ # @return [Hash] The registry of all defined attributes.
22
+ def self.registry
23
+ @registry ||= {}
24
+ end
25
+
26
+ # Removes the given class from the registry. Useful for testing.
27
+ def self.deregister(klass)
28
+ registry.delete(klass)
29
+ end
30
+
31
+ # Registers an attribute for a class in the registry.
32
+ # Internal use only.
33
+ #
34
+ # @param klass [Class] The class registering the attribute
35
+ # @param name [Symbol] The name of the attribute
36
+ # @param key [String] The key to use when serializing the attribute
37
+ # @param default [Object] The default value for the attribute
38
+ def self.register(klass, name, key, default)
39
+ # Disallow redefining or replacing a key as it is easy to miss the overwrite
40
+ # and leads to serialization surprises.
41
+ if key && registry.values.flat_map(&:values).map{ |entry| entry[:key] }.include?(key)
42
+ raise Errors::DuplicateAttributesKeyError, "Attribute Key #{key} already defined!"
43
+ end
44
+
45
+ registry[klass] ||= {}
46
+ registry[klass][name] = { key: key, default: default }
47
+ end
48
+
49
+ module InstanceMethods
50
+ def initialize(...)
51
+ initialize_attributes
52
+ super(...)
53
+ end
54
+
55
+ # Iterates over all defined attributes in a child => parent hierarchy,
56
+ # and yields the name and entry for each.
57
+ def each_attribute(&block)
58
+ klass = self.class
59
+ loop do
60
+ attributes = Attributes.registry[klass]
61
+ break if attributes.nil?
62
+
63
+ attributes.each{ |name, entry| block.call(name, entry) }
64
+ klass = klass.superclass
65
+ end
66
+ end
67
+
68
+ # Initializes the defined attributes with default values and
69
+ # defines accessor methods for each attribute.
70
+ # If a child class redefines a parent's attribute, the child's
71
+ # definition will be used.
72
+ def initialize_attributes
73
+ each_attribute do |name, entry|
74
+ # use the child's definition, skipping the parent's
75
+ next if respond_to?(name)
76
+
77
+ ivar_name = "@#{name}"
78
+ instance_variable_set(ivar_name, entry[:default])
79
+ define_singleton_method(name) { instance_variable_get(ivar_name) }
80
+ define_singleton_method("#{name}=") { |value| instance_variable_set(ivar_name, value) }
81
+ end
82
+ end
83
+
84
+ # Serializes keys that have been defined as serializeable attributes
85
+ # Key values that are nil are removed from the hash
86
+ # @return [Hash] The serialized attributes as a Ruby Hash.
87
+ def to_h
88
+ {}.tap do |key_values|
89
+ each_attribute do |name, entry|
90
+ next unless entry[:key]
91
+
92
+ ivar_name = "@#{name}"
93
+ value = instance_variable_get(ivar_name)
94
+
95
+ key_values[entry[:key]] = value if value
96
+ end
97
+ end
98
+ end
99
+
100
+ # Serializes keys that have been defined as serializeable attributes
101
+ # Key values that are nil are removed from the hash
102
+ # @return [String] The serialized attributes as a JSON string.
103
+ def to_json(*args)
104
+ Oj.dump(to_h, *args)
105
+ end
106
+ end
107
+
108
+ module ClassMethods
109
+ # Define an +attribute+ for the class that can optionally be serialized.
110
+ # Works much like an attr_accessor does, but also manages serialization for
111
+ # #to_h and #to_json methods.
112
+ #
113
+ # An +attribute+ will result in a same-named instance on the class when
114
+ # it is instantiated and it will set a default value if one is provided.
115
+ #
116
+ # @param name [Symbol] The name of the attribute and it's accessor methods
117
+ # @param key [String] The key to use when serializing the attribute
118
+ # @param default [Object] The default value for the attribute
119
+ #
120
+ # @examples
121
+ # attribute :tick # will not serialize to a key
122
+ # attribute :source, key: "src" # serializes to "src" key
123
+ # attribute :input, key: "in" # serializes to "in" key
124
+ def attribute(name, key: nil, default: nil)
125
+ Attributes.register(self, name, key, default)
126
+ end
127
+ end
128
+
129
+ def self.included(base) # :nodoc:
130
+ base.extend(ClassMethods)
131
+ base.prepend(InstanceMethods)
132
+ end
133
+ end
134
+ end
data/lib/quant/errors.rb CHANGED
@@ -1,9 +1,34 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quant
4
- class Error < StandardError; end
5
- class InvalidInterval < Error; end
6
- class InvalidResolution < Error; end
7
- class ArrayMaxSizeError < Error; end
8
- class SecurityClassError < Error; end
4
+ module Errors
5
+ # {Error} is the base class for all errors in the Quant gem.
6
+ # It is a subclass of the Ruby {StandardError}.
7
+ class Error < StandardError; end
8
+
9
+ # {InvalidInterval} is raised when attempting to instantiate an
10
+ # {Quant::Interval} with an invalid value.
11
+ class InvalidInterval < Error; end
12
+
13
+ # {InvalidResolution} is raised when attempting to instantiate
14
+ # an {Quant::Resolution} with a resolution value that has not been defined.
15
+ class InvalidResolution < Error; end
16
+
17
+ # {ArrayMaxSizeError} is raised when attempting to set the +max_size+ on
18
+ # the refined {Array} class to an invalid value or when attempting to
19
+ # redefine the +max_size+ on the refined {Array} class.
20
+ class ArrayMaxSizeError < Error; end
21
+
22
+ # {AssetClassError} is raised when attempting to instantiate a
23
+ # {Quant::Asset} with an attribute that is not a valid {Quant::Asset} attribute.
24
+ class AssetClassError < Error; end
25
+
26
+ # {DuplicateAttributesKeyError} is raised when attempting to define an
27
+ # attribute with a key that has already been defined.
28
+ class DuplicateAttributesKeyError < Error; end
29
+
30
+ # {DuplicateAttributesNameError} is raised when attempting to define an
31
+ # attribute with a name that has already been defined.
32
+ class DuplicateAttributesNameError < Error; end
33
+ end
9
34
  end
@@ -1,7 +1,7 @@
1
1
  module Quant
2
2
  class Indicators
3
3
  class Indicator
4
- # include Enumerable
4
+ include Enumerable
5
5
 
6
6
  # # include Mixins::TrendMethods
7
7
  # include Mixins::Trig
@@ -14,57 +14,103 @@ module Quant
14
14
  # include Mixins::Direction
15
15
  # include Mixins::Filters
16
16
 
17
- # def inspect
18
- # "#<#{self.class.name} #{symbol} #{interval} #{points.size} points>"
19
- # end
17
+ attr_reader :source, :series
20
18
 
21
- # def compute
22
- # raise NotImplementedError
23
- # end
19
+ def initialize(series:, source:)
20
+ @series = series
21
+ @source = source
22
+ @points = {}
23
+ series.each { |tick| self << tick }
24
+ end
24
25
 
25
- # def [](index)
26
- # points[index]
27
- # end
26
+ def ticks
27
+ @points.keys
28
+ end
28
29
 
29
- # def after_append
30
- # # NoOp
31
- # end
30
+ def values
31
+ @points.values
32
+ end
32
33
 
33
- # def points_class
34
- # "Quant::Indicators::#{indicator_name}Point".constantize
35
- # end
34
+ def size
35
+ @points.size
36
+ end
36
37
 
37
- # def indicator_name
38
- # self.class.name.demodulize
39
- # end
38
+ attr_reader :p0, :p1, :p2, :p3
39
+ attr_reader :t0, :t1, :t2, :t3
40
40
 
41
- # def warmed_up?
42
- # true
43
- # end
41
+ def <<(tick)
42
+ @t0 = tick
43
+ @p0 = points_class.new(tick: tick, source: source)
44
+ @points[tick] = @p0
44
45
 
45
- # def initial_max_size
46
- # value = [series.size, series.max_size].max
47
- # value.zero? ? settings.initial_max_size : value
48
- # end
46
+ @p1 = values[-2] || @p0
47
+ @p2 = values[-3] || @p1
48
+ @p3 = values[-4] || @p2
49
49
 
50
- attr_reader :series #, :settings, :max_size, :points, :dc_period
51
- # delegate :p0, :p1, :p2, :p3, :prev, :iteration, to: :points
52
- # delegate :each, :size, :[], :last, :first, to: :points
53
- # delegate :oc2, :high_price, :low_price, :open_price, :close_price, :volume, to: :p0
50
+ @t1 = ticks[-2] || @t0
51
+ @t2 = ticks[-3] || @t1
52
+ @t3 = ticks[-4] || @t2
54
53
 
55
- def initialize(series:) # settings: Settings::Indicators.defaults, cloning: false)
56
- @series = series
57
- # @settings = settings
58
- # @max_size = initial_max_size
59
- # @points = Points.new(indicator: self)
60
- # return if cloning
61
-
62
- # after_initialization
63
- # parent_series.each { |ohlc| append ohlc }
64
- # @points_for_cache = {}
65
- # @dc_period = nil
54
+ compute
55
+ end
56
+
57
+ def each(&block)
58
+ @points.each_value(&block)
59
+ end
60
+
61
+ def inspect
62
+ "#<#{self.class.name} symbol=#{series.symbol} source=#{source} #{points.size} ticks>"
63
+ end
64
+
65
+ def compute
66
+ raise NotImplementedError
66
67
  end
67
68
 
69
+ def indicator_name
70
+ self.class.name.split("::").last
71
+ end
72
+
73
+ def points_class
74
+ Object.const_get "Quant::Indicators::#{indicator_name}Point"
75
+ end
76
+
77
+ # p(0) => values[-1]
78
+ # p(1) => values[-2]
79
+ # p(2) => values[-3]
80
+ # p(3) => values[-4]
81
+ def p(offset)
82
+ raise ArgumentError, "offset must be a positive value" if offset < 0
83
+
84
+ index = offset + 1
85
+ values[[-index, -size].max]
86
+ end
87
+
88
+ # t(0) => ticks[-1]
89
+ # t(1) => ticks[-2]
90
+ # t(2) => ticks[-3]
91
+ # t(3) => ticks[-4]
92
+ def t(offset)
93
+ raise ArgumentError, "offset must be a positive value" if offset < 0
94
+
95
+ index = offset + 1
96
+ ticks[[-index, -size].max]
97
+ end
98
+
99
+ # The input is the value derived from the source for the indicator
100
+ # for the current tick.
101
+ # For example, if the source is :oc2, then the input is the
102
+ # value of the current tick's (open + close) / 2
103
+ # @return [Numeric]
104
+ def input
105
+ t0.send(source)
106
+ end
107
+
108
+ # def warmed_up?
109
+ # true
110
+ # end
111
+
112
+ # attr_reader :dc_period
113
+
68
114
  # def points_for(series:)
69
115
  # @points_for_cache[series] ||= self.class.new(series:, settings:, cloning: true).tap do |indicator|
70
116
  # series.ticks.each { |tick| indicator.points.push(tick.indicators[self]) }
@@ -77,10 +123,6 @@ module Quant
77
123
  # series.ticks.empty? ? series : series.ticks.first.series
78
124
  # end
79
125
 
80
- # def after_initialization
81
- # # NoOp
82
- # end
83
-
84
126
  # # Returns the last point of the current indicator rather than the entire series
85
127
  # # This is used for indicators that depend on dominant cycle or other indicators
86
128
  # # to compute their data points.
@@ -103,13 +145,6 @@ module Quant
103
145
  # raise 'Dominant Cycle Indicators cannot use the thing they compute!'
104
146
  # end
105
147
 
106
- # # Sets the dominant cycle period for the current indicator's point
107
- # # @dc_period gets set before each #compute call.
108
- # def update_dc_period
109
- # ensure_not_dominant_cycler_indicator
110
- # @dc_period = current_dominant_cycle.period
111
- # end
112
-
113
148
  # # Returns the dominant cycle point for the current indicator's point
114
149
  # def current_dominant_cycle
115
150
  # dominant_cycle_indicator[current_point]
@@ -3,33 +3,21 @@
3
3
  module Quant
4
4
  class Indicators
5
5
  class IndicatorPoint
6
- extend Forwardable
6
+ include Quant::Attributes
7
7
 
8
- attr_reader :tick, :source
8
+ attribute :tick
9
+ attribute :source, key: "src"
10
+ attribute :input, key: "in"
9
11
 
10
12
  def initialize(tick:, source:)
11
13
  @tick = tick
12
- @source = @tick.send(source)
14
+ @source = source
15
+ @input = @tick.send(source)
16
+ initialize_data_points
13
17
  end
14
18
 
15
- def volume
16
- @tick.base_volume
17
- end
18
-
19
- def timestamp
20
- @tick.close_timestamp
21
- end
22
-
23
- def initialize_data_points(indicator:)
24
- # NoOp
25
- end
26
-
27
- def to_h
28
- raise NotImplementedError
29
- end
30
-
31
- def to_json(*args)
32
- Oj.dump(to_h, *args)
19
+ def initialize_data_points
20
+ # No-Op - Override in subclass if needed.
33
21
  end
34
22
  end
35
23
  end
@@ -1,46 +1,38 @@
1
1
  module Quant
2
2
  class Indicators
3
3
  class MaPoint < IndicatorPoint
4
+ attribute :ss, key: "ss"
5
+ attribute :ema, key: "ema"
4
6
  attr_accessor :ss, :ema, :osc
5
7
 
6
- def to_h
7
- {
8
- "ss" => ss,
9
- "ema" => delta_phase,
10
- "osc" => osc
11
- }
12
- end
13
-
14
- def initialize_data_points(indicator:)
15
- @ss = oc2
16
- @ema = oc2
8
+ def initialize_data_points
9
+ @ss = input
10
+ @ema = input
17
11
  @osc = nil
18
12
  end
19
13
  end
20
14
 
21
15
  # Moving Averages
22
16
  class Ma < Indicator
23
- def self.indicator_key
24
- "ma"
25
- end
17
+ include Quant::Mixins::Filters
26
18
 
27
19
  def alpha(period)
28
20
  bars_to_alpha(period)
29
21
  end
30
22
 
31
23
  def min_period
32
- settings.min_period
24
+ 8 # Quant.config.indicators.min_period
33
25
  end
34
26
 
35
- def period
36
- settings.max_period
27
+ def max_period
28
+ 48 # Quant.config.indicators.max_period
37
29
  end
38
30
 
39
31
  def compute
40
- p0.ss = super_smoother p0.oc2, :ss, min_period
41
- p0.ema = alpha(period) * p0.oc2 + (1 - alpha(period)) * p1.ema
32
+ # p0.ss = super_smoother input, :ss, min_period
33
+ p0.ema = alpha(max_period) * input + (1 - alpha(max_period)) * p1.ema
42
34
  p0.osc = p0.ss - p0.ema
43
35
  end
44
36
  end
45
37
  end
46
- end
38
+ end
@@ -0,0 +1,16 @@
1
+ module Quant
2
+ class Indicators
3
+ class PingPoint < IndicatorPoint
4
+ attribute :pong
5
+ attribute :compute_count, default: 0
6
+ end
7
+
8
+ # A simple idicator used primarily to test the indicator system
9
+ class Ping < Indicator
10
+ def compute
11
+ p0.pong = input
12
+ p0.compute_count += 1
13
+ end
14
+ end
15
+ end
16
+ end
@@ -1,29 +1,7 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Quant
4
- # < IndicatorsAccessor
4
+ # TODO: build an Indicator registry so new indicators can be added and used outside those shipped with the library.
5
5
  class Indicators
6
- # def atr; indicator(Indicators::Atr) end
7
- # def adx; indicator(Indicators::Adx) end
8
- # def cci; indicator(Indicators::Cci) end
9
- # def cdi; indicator(Indicators::Cdi) end
10
- # def decycler; indicator(Indicators::Decycler) end
11
- # def frema; indicator(Indicators::Frema) end
12
- # def hilo; indicator(Indicators::HiLo) end
13
- # def ma; indicator(Indicators::Ma) end
14
- # def mama; indicator(Indicators::Mama) end
15
- # def frama; indicator(Indicators::Frama) end
16
- # def mesa; indicator(Indicators::Mesa) end
17
- # def roofing; indicator(Indicators::Roofing) end
18
- # def rsi; indicator(Indicators::Rsi) end
19
- # def rrr; indicator(Indicators::Rrr) end
20
- # def rrsi; indicator(Indicators::RocketRsi) end
21
- # def samo; indicator(Indicators::Samo) end
22
- # def snr; indicator(Indicators::Snr) end
23
- # def ssf; indicator(Indicators::Ssf) end
24
- # def volume; indicator(Indicators::VolumeSsf) end
25
- # def vol; indicator(Indicators::Vol) end
26
- # def vrsi; indicator(Indicators::VolumeRsi) end
27
- # def weibull; indicator(Indicators::Weibull) end
28
6
  end
29
7
  end