technical-analysis 0.1.0
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.
- checksums.yaml +7 -0
- data/lib/technical-analysis.rb +3 -0
- data/lib/technical_analysis.rb +41 -0
- data/lib/technical_analysis/helpers/array_helper.rb +27 -0
- data/lib/technical_analysis/helpers/stock_calculation.rb +25 -0
- data/lib/technical_analysis/helpers/validation.rb +33 -0
- data/lib/technical_analysis/indicators/adi.rb +101 -0
- data/lib/technical_analysis/indicators/adtv.rb +98 -0
- data/lib/technical_analysis/indicators/adx.rb +168 -0
- data/lib/technical_analysis/indicators/ao.rb +105 -0
- data/lib/technical_analysis/indicators/atr.rb +109 -0
- data/lib/technical_analysis/indicators/bb.rb +126 -0
- data/lib/technical_analysis/indicators/cci.rb +105 -0
- data/lib/technical_analysis/indicators/cmf.rb +105 -0
- data/lib/technical_analysis/indicators/cr.rb +95 -0
- data/lib/technical_analysis/indicators/dc.rb +108 -0
- data/lib/technical_analysis/indicators/dlr.rb +97 -0
- data/lib/technical_analysis/indicators/dpo.rb +106 -0
- data/lib/technical_analysis/indicators/dr.rb +96 -0
- data/lib/technical_analysis/indicators/eom.rb +104 -0
- data/lib/technical_analysis/indicators/fi.rb +95 -0
- data/lib/technical_analysis/indicators/ichimoku.rb +179 -0
- data/lib/technical_analysis/indicators/indicator.rb +138 -0
- data/lib/technical_analysis/indicators/kc.rb +124 -0
- data/lib/technical_analysis/indicators/kst.rb +132 -0
- data/lib/technical_analysis/indicators/macd.rb +144 -0
- data/lib/technical_analysis/indicators/mfi.rb +119 -0
- data/lib/technical_analysis/indicators/mi.rb +121 -0
- data/lib/technical_analysis/indicators/nvi.rb +102 -0
- data/lib/technical_analysis/indicators/obv.rb +104 -0
- data/lib/technical_analysis/indicators/obv_mean.rb +110 -0
- data/lib/technical_analysis/indicators/rsi.rb +133 -0
- data/lib/technical_analysis/indicators/sma.rb +98 -0
- data/lib/technical_analysis/indicators/sr.rb +122 -0
- data/lib/technical_analysis/indicators/trix.rb +127 -0
- data/lib/technical_analysis/indicators/tsi.rb +139 -0
- data/lib/technical_analysis/indicators/uo.rb +130 -0
- data/lib/technical_analysis/indicators/vi.rb +117 -0
- data/lib/technical_analysis/indicators/vpt.rb +95 -0
- data/lib/technical_analysis/indicators/wr.rb +103 -0
- data/spec/helpers/array_helper_spec.rb +31 -0
- data/spec/helpers/validaton_spec.rb +22 -0
- data/spec/spec_helper.rb +26 -0
- data/spec/ta_test_data.csv +64 -0
- data/spec/technical_analysis/indicators/adi_spec.rb +116 -0
- data/spec/technical_analysis/indicators/adtv_spec.rb +98 -0
- data/spec/technical_analysis/indicators/adx_spec.rb +92 -0
- data/spec/technical_analysis/indicators/ao_spec.rb +86 -0
- data/spec/technical_analysis/indicators/atr_spec.rb +105 -0
- data/spec/technical_analysis/indicators/bb_spec.rb +100 -0
- data/spec/technical_analysis/indicators/cci_spec.rb +100 -0
- data/spec/technical_analysis/indicators/cmf_spec.rb +100 -0
- data/spec/technical_analysis/indicators/cr_spec.rb +119 -0
- data/spec/technical_analysis/indicators/dc_spec.rb +100 -0
- data/spec/technical_analysis/indicators/dlr_spec.rb +119 -0
- data/spec/technical_analysis/indicators/dpo_spec.rb +90 -0
- data/spec/technical_analysis/indicators/dr_spec.rb +119 -0
- data/spec/technical_analysis/indicators/eom_spec.rb +105 -0
- data/spec/technical_analysis/indicators/fi_spec.rb +118 -0
- data/spec/technical_analysis/indicators/ichimoku_spec.rb +95 -0
- data/spec/technical_analysis/indicators/indicator_spec.rb +120 -0
- data/spec/technical_analysis/indicators/kc_spec.rb +110 -0
- data/spec/technical_analysis/indicators/kst_spec.rb +78 -0
- data/spec/technical_analysis/indicators/macd_spec.rb +86 -0
- data/spec/technical_analysis/indicators/mfi_spec.rb +105 -0
- data/spec/technical_analysis/indicators/mi_spec.rb +79 -0
- data/spec/technical_analysis/indicators/nvi_spec.rb +119 -0
- data/spec/technical_analysis/indicators/obv_mean_spec.rb +109 -0
- data/spec/technical_analysis/indicators/obv_spec.rb +119 -0
- data/spec/technical_analysis/indicators/rsi_spec.rb +105 -0
- data/spec/technical_analysis/indicators/sma_spec.rb +115 -0
- data/spec/technical_analysis/indicators/sr_spec.rb +104 -0
- data/spec/technical_analysis/indicators/trix_spec.rb +76 -0
- data/spec/technical_analysis/indicators/tsi_spec.rb +87 -0
- data/spec/technical_analysis/indicators/uo_spec.rb +91 -0
- data/spec/technical_analysis/indicators/vi_spec.rb +105 -0
- data/spec/technical_analysis/indicators/vpt_spec.rb +118 -0
- data/spec/technical_analysis/indicators/wr_spec.rb +106 -0
- metadata +177 -0
@@ -0,0 +1,96 @@
|
|
1
|
+
module TechnicalAnalysis
|
2
|
+
# Daily Return
|
3
|
+
class Dr < Indicator
|
4
|
+
|
5
|
+
# Returns the symbol of the technical indicator
|
6
|
+
#
|
7
|
+
# @return [String] A string of the symbol of the technical indicator
|
8
|
+
def self.indicator_symbol
|
9
|
+
"dr"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the technical indicator
|
13
|
+
#
|
14
|
+
# @return [String] A string of the name of the technical indicator
|
15
|
+
def self.indicator_name
|
16
|
+
"Daily Return"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of valid keys for options for this technical indicator
|
20
|
+
#
|
21
|
+
# @return [Array] An array of keys as symbols for valid options for this technical indicator
|
22
|
+
def self.valid_options
|
23
|
+
%i(price_key)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Validates the provided options for this technical indicator
|
27
|
+
#
|
28
|
+
# @param options [Hash] The options for the technical indicator to be validated
|
29
|
+
#
|
30
|
+
# @return [Boolean] Returns true if options are valid or raises a ValidationError if they're not
|
31
|
+
def self.validate_options(options)
|
32
|
+
Validation.validate_options(options, valid_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Calculates the minimum number of observations needed to calculate the technical indicator
|
36
|
+
#
|
37
|
+
# @param options [Hash] The options for the technical indicator
|
38
|
+
#
|
39
|
+
# @return [Integer] Returns the minimum number of observations needed to calculate the technical
|
40
|
+
# indicator based on the options provided
|
41
|
+
def self.min_data_size(**params)
|
42
|
+
1
|
43
|
+
end
|
44
|
+
|
45
|
+
# Calculates the daily return (percent expressed as a decimal) for the data over the given period
|
46
|
+
# https://en.wikipedia.org/wiki/Rate_of_return
|
47
|
+
#
|
48
|
+
# @param data [Array] Array of hashes with keys (:date_time, :value)
|
49
|
+
# @param price_key [Symbol] The hash key for the price data. Default :value
|
50
|
+
#
|
51
|
+
# @return [Array<DrValue>] An array of DrValue instances
|
52
|
+
def self.calculate(data, price_key: :value)
|
53
|
+
price_key = price_key.to_sym
|
54
|
+
Validation.validate_numeric_data(data, price_key)
|
55
|
+
Validation.validate_length(data, min_data_size({}))
|
56
|
+
Validation.validate_date_time_key(data)
|
57
|
+
|
58
|
+
data = data.sort_by { |row| row[:date_time] }
|
59
|
+
|
60
|
+
output = []
|
61
|
+
prev_price = data.first[price_key].to_f
|
62
|
+
|
63
|
+
data.each do |v|
|
64
|
+
current_price = v[:close].to_f
|
65
|
+
|
66
|
+
output << DrValue.new(date_time: v[:date_time], dr: ((current_price / prev_price) - 1))
|
67
|
+
|
68
|
+
prev_price = current_price
|
69
|
+
end
|
70
|
+
|
71
|
+
output.sort_by(&:date_time).reverse
|
72
|
+
end
|
73
|
+
|
74
|
+
end
|
75
|
+
|
76
|
+
# The value class to be returned by calculations
|
77
|
+
class DrValue
|
78
|
+
|
79
|
+
# @return [String] the date_time of the obversation as it was provided
|
80
|
+
attr_accessor :date_time
|
81
|
+
|
82
|
+
# @return [Float] the dr calculation value
|
83
|
+
attr_accessor :dr
|
84
|
+
|
85
|
+
def initialize(date_time: nil, dr: nil)
|
86
|
+
@date_time = date_time
|
87
|
+
@dr = dr
|
88
|
+
end
|
89
|
+
|
90
|
+
# @return [Hash] the attributes as a hash
|
91
|
+
def to_hash
|
92
|
+
{ date_time: @date_time, dr: @dr }
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
96
|
+
end
|
@@ -0,0 +1,104 @@
|
|
1
|
+
module TechnicalAnalysis
|
2
|
+
# Ease of Movement
|
3
|
+
class Eom < Indicator
|
4
|
+
|
5
|
+
# Returns the symbol of the technical indicator
|
6
|
+
#
|
7
|
+
# @return [String] A string of the symbol of the technical indicator
|
8
|
+
def self.indicator_symbol
|
9
|
+
"eom"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the technical indicator
|
13
|
+
#
|
14
|
+
# @return [String] A string of the name of the technical indicator
|
15
|
+
def self.indicator_name
|
16
|
+
"Ease of Movement"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of valid keys for options for this technical indicator
|
20
|
+
#
|
21
|
+
# @return [Array] An array of keys as symbols for valid options for this technical indicator
|
22
|
+
def self.valid_options
|
23
|
+
%i(period)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Validates the provided options for this technical indicator
|
27
|
+
#
|
28
|
+
# @param options [Hash] The options for the technical indicator to be validated
|
29
|
+
#
|
30
|
+
# @return [Boolean] Returns true if options are valid or raises a ValidationError if they're not
|
31
|
+
def self.validate_options(options)
|
32
|
+
Validation.validate_options(options, valid_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Calculates the minimum number of observations needed to calculate the technical indicator
|
36
|
+
#
|
37
|
+
# @param options [Hash] The options for the technical indicator
|
38
|
+
#
|
39
|
+
# @return [Integer] Returns the minimum number of observations needed to calculate the technical
|
40
|
+
# indicator based on the options provided
|
41
|
+
def self.min_data_size(period: 14)
|
42
|
+
period.to_i + 1
|
43
|
+
end
|
44
|
+
|
45
|
+
# Calculates the ease of movement (EoM) for the data over the given period
|
46
|
+
# https://en.wikipedia.org/wiki/Ease_of_movement
|
47
|
+
#
|
48
|
+
# @param data [Array] Array of hashes with keys (:date_time, :high, :low, :volume)
|
49
|
+
# @param period [Integer] The given period to calculate the EoM
|
50
|
+
#
|
51
|
+
# @return [Array<Hash>] An array of EomValue instances
|
52
|
+
def self.calculate(data, period: 14)
|
53
|
+
period = period.to_i
|
54
|
+
Validation.validate_numeric_data(data, :high, :low, :volume)
|
55
|
+
Validation.validate_length(data, min_data_size(period: period))
|
56
|
+
Validation.validate_date_time_key(data)
|
57
|
+
|
58
|
+
data = data.sort_by { |row| row[:date_time] }
|
59
|
+
|
60
|
+
output = []
|
61
|
+
period_values = []
|
62
|
+
prev_price = data.shift
|
63
|
+
|
64
|
+
data.each do |v|
|
65
|
+
distance_moved = ((v[:high] + v[:low]) / 2) - ((prev_price[:high] + prev_price[:low]) / 2)
|
66
|
+
box_ratio = (v[:volume] / 100_000_000.00) / (v[:high] - v[:low])
|
67
|
+
emv = distance_moved / box_ratio
|
68
|
+
|
69
|
+
period_values << emv
|
70
|
+
|
71
|
+
if period_values.size == period
|
72
|
+
output << EomValue.new(date_time: v[:date_time], eom: ArrayHelper.average(period_values))
|
73
|
+
period_values.shift
|
74
|
+
end
|
75
|
+
|
76
|
+
prev_price = v
|
77
|
+
end
|
78
|
+
|
79
|
+
output.sort_by(&:date_time).reverse
|
80
|
+
end
|
81
|
+
|
82
|
+
end
|
83
|
+
|
84
|
+
# The value class to be returned by calculations
|
85
|
+
class EomValue
|
86
|
+
|
87
|
+
# @return [String] the date_time of the obversation as it was provided
|
88
|
+
attr_accessor :date_time
|
89
|
+
|
90
|
+
# @return [Float] the eom calculation value
|
91
|
+
attr_accessor :eom
|
92
|
+
|
93
|
+
def initialize(date_time: nil, eom: nil)
|
94
|
+
@date_time = date_time
|
95
|
+
@eom = eom
|
96
|
+
end
|
97
|
+
|
98
|
+
# @return [Hash] the attributes as a hash
|
99
|
+
def to_hash
|
100
|
+
{ date_time: @date_time, eom: @eom }
|
101
|
+
end
|
102
|
+
|
103
|
+
end
|
104
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
module TechnicalAnalysis
|
2
|
+
# Force Index
|
3
|
+
class Fi < Indicator
|
4
|
+
|
5
|
+
# Returns the symbol of the technical indicator
|
6
|
+
#
|
7
|
+
# @return [String] A string of the symbol of the technical indicator
|
8
|
+
def self.indicator_symbol
|
9
|
+
"fi"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the technical indicator
|
13
|
+
#
|
14
|
+
# @return [String] A string of the name of the technical indicator
|
15
|
+
def self.indicator_name
|
16
|
+
"Force Index"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of valid keys for options for this technical indicator
|
20
|
+
#
|
21
|
+
# @return [Array] An array of keys as symbols for valid options for this technical indicator
|
22
|
+
def self.valid_options
|
23
|
+
[]
|
24
|
+
end
|
25
|
+
|
26
|
+
# Validates the provided options for this technical indicator
|
27
|
+
#
|
28
|
+
# @param options [Hash] The options for the technical indicator to be validated
|
29
|
+
#
|
30
|
+
# @return [Boolean] Returns true if options are valid or raises a ValidationError if they're not
|
31
|
+
def self.validate_options(options)
|
32
|
+
return true if options == {}
|
33
|
+
raise Validation::ValidationError.new "This indicator doesn't accept any options."
|
34
|
+
end
|
35
|
+
|
36
|
+
# Calculates the minimum number of observations needed to calculate the technical indicator
|
37
|
+
#
|
38
|
+
# @param options [Hash] The options for the technical indicator
|
39
|
+
#
|
40
|
+
# @return [Integer] Returns the minimum number of observations needed to calculate the technical
|
41
|
+
# indicator based on the options provided
|
42
|
+
def self.min_data_size(**params)
|
43
|
+
2
|
44
|
+
end
|
45
|
+
|
46
|
+
# Calculates the force index (FI) for the data
|
47
|
+
# https://en.wikipedia.org/wiki/Force_index
|
48
|
+
#
|
49
|
+
# @param data [Array] Array of hashes with keys (:date_time, :close, :volume)
|
50
|
+
#
|
51
|
+
# @return [Array<FiValue>] An array of FiValue instances
|
52
|
+
def self.calculate(data)
|
53
|
+
Validation.validate_numeric_data(data, :close, :volume)
|
54
|
+
Validation.validate_length(data, min_data_size({}))
|
55
|
+
Validation.validate_date_time_key(data)
|
56
|
+
|
57
|
+
data = data.sort_by { |row| row[:date_time] }
|
58
|
+
|
59
|
+
output = []
|
60
|
+
prev_price = data.shift
|
61
|
+
|
62
|
+
data.each do |v|
|
63
|
+
fi = ((v[:close] - prev_price[:close]) * v[:volume])
|
64
|
+
|
65
|
+
output << FiValue.new(date_time: v[:date_time], fi: fi)
|
66
|
+
|
67
|
+
prev_price = v
|
68
|
+
end
|
69
|
+
|
70
|
+
output.sort_by(&:date_time).reverse
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
# The value class to be returned by calculations
|
76
|
+
class FiValue
|
77
|
+
|
78
|
+
# @return [String] the date_time of the obversation as it was provided
|
79
|
+
attr_accessor :date_time
|
80
|
+
|
81
|
+
# @return [Float] the fi calculation value
|
82
|
+
attr_accessor :fi
|
83
|
+
|
84
|
+
def initialize(date_time: nil, fi: nil)
|
85
|
+
@date_time = date_time
|
86
|
+
@fi = fi
|
87
|
+
end
|
88
|
+
|
89
|
+
# @return [Hash] the attributes as a hash
|
90
|
+
def to_hash
|
91
|
+
{ date_time: @date_time, fi: @fi }
|
92
|
+
end
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
@@ -0,0 +1,179 @@
|
|
1
|
+
module TechnicalAnalysis
|
2
|
+
# Ichimoku Kinko Hyo
|
3
|
+
class Ichimoku < Indicator
|
4
|
+
|
5
|
+
# Returns the symbol of the technical indicator
|
6
|
+
#
|
7
|
+
# @return [String] A string of the symbol of the technical indicator
|
8
|
+
def self.indicator_symbol
|
9
|
+
"ichimoku"
|
10
|
+
end
|
11
|
+
|
12
|
+
# Returns the name of the technical indicator
|
13
|
+
#
|
14
|
+
# @return [String] A string of the name of the technical indicator
|
15
|
+
def self.indicator_name
|
16
|
+
"Ichimoku Kinko Hyo"
|
17
|
+
end
|
18
|
+
|
19
|
+
# Returns an array of valid keys for options for this technical indicator
|
20
|
+
#
|
21
|
+
# @return [Array] An array of keys as symbols for valid options for this technical indicator
|
22
|
+
def self.valid_options
|
23
|
+
%i(low_period medium_period high_period)
|
24
|
+
end
|
25
|
+
|
26
|
+
# Validates the provided options for this technical indicator
|
27
|
+
#
|
28
|
+
# @param options [Hash] The options for the technical indicator to be validated
|
29
|
+
#
|
30
|
+
# @return [Boolean] Returns true if options are valid or raises a ValidationError if they're not
|
31
|
+
def self.validate_options(options)
|
32
|
+
Validation.validate_options(options, valid_options)
|
33
|
+
end
|
34
|
+
|
35
|
+
# Calculates the minimum number of observations needed to calculate the technical indicator
|
36
|
+
#
|
37
|
+
# @param options [Hash] The options for the technical indicator
|
38
|
+
#
|
39
|
+
# @return [Integer] Returns the minimum number of observations needed to calculate the technical
|
40
|
+
# indicator based on the options provided
|
41
|
+
def self.min_data_size(medium_period: 26, high_period: 52, **params)
|
42
|
+
high_period.to_i + medium_period.to_i - 1
|
43
|
+
end
|
44
|
+
|
45
|
+
# Calculates the 5 points of Ichimoku Kinko Hyo (Ichimoku) for the data over the given period
|
46
|
+
# 1. tenkan_sen (Conversion Line)
|
47
|
+
# 2. kijun_sen (Base Line)
|
48
|
+
# 3. senkou_span_a (Leading Span A)
|
49
|
+
# 4. senkou_span_b (Leading Span B)
|
50
|
+
# 5. chickou_span (Lagging Span)
|
51
|
+
# https://en.wikipedia.org/wiki/Ichimoku_Kink%C5%8D_Hy%C5%8D
|
52
|
+
#
|
53
|
+
# @param data [Array] Array of hashes with keys (:date_time, :high, :low, :close)
|
54
|
+
# @param low_period [Integer] The given period to calculate tenkan_sen (Conversion Line)
|
55
|
+
# @param medium_period [Integer] The given period to calculate kijun_sen (Base Line), senkou_span_a (Leading Span A), and chikou_span (Lagging Span)
|
56
|
+
# @param high_period [Integer] The given period to calculate senkou_span_b (Leading Span B)
|
57
|
+
#
|
58
|
+
# @return [Array<IchimokuValue>] An array of IchimokuValue instances
|
59
|
+
def self.calculate(data, low_period: 9, medium_period: 26, high_period: 52)
|
60
|
+
low_period = low_period.to_i
|
61
|
+
medium_period = medium_period.to_i
|
62
|
+
high_period = high_period.to_i
|
63
|
+
Validation.validate_numeric_data(data, :high, :low, :close)
|
64
|
+
Validation.validate_length(data, min_data_size(high_period: high_period, medium_period: medium_period))
|
65
|
+
Validation.validate_date_time_key(data)
|
66
|
+
|
67
|
+
data = data.sort_by { |row| row[:date_time] }
|
68
|
+
|
69
|
+
index = high_period + medium_period - 2
|
70
|
+
output = []
|
71
|
+
|
72
|
+
while index < data.size
|
73
|
+
date_time = data[index][:date_time]
|
74
|
+
|
75
|
+
tenkan_sen = calculate_midpoint(index, low_period, data)
|
76
|
+
kinjun_sen = calculate_midpoint(index, medium_period, data)
|
77
|
+
senkou_span_a = calculate_senkou_span_a(index, low_period, medium_period, data)
|
78
|
+
senkou_span_b = calculate_senkou_span_b(index, medium_period, high_period, data)
|
79
|
+
chikou_span = calculate_chikou_span(index, medium_period, data)
|
80
|
+
|
81
|
+
output << IchimokuValue.new(
|
82
|
+
date_time: date_time,
|
83
|
+
tenkan_sen: tenkan_sen,
|
84
|
+
kijun_sen: kinjun_sen,
|
85
|
+
senkou_span_a: senkou_span_a,
|
86
|
+
senkou_span_b: senkou_span_b,
|
87
|
+
chikou_span: chikou_span
|
88
|
+
)
|
89
|
+
|
90
|
+
index += 1
|
91
|
+
end
|
92
|
+
|
93
|
+
output.sort_by(&:date_time).reverse
|
94
|
+
end
|
95
|
+
|
96
|
+
private_class_method def self.lowest_low(prices)
|
97
|
+
prices.map { |price| price[:low] }.min
|
98
|
+
end
|
99
|
+
|
100
|
+
private_class_method def self.highest_high(prices)
|
101
|
+
prices.map { |price| price[:high] }.max
|
102
|
+
end
|
103
|
+
|
104
|
+
private_class_method def self.calculate_midpoint(index, period, data)
|
105
|
+
period_range = ((index - (period - 1))..index)
|
106
|
+
period_data = data[period_range]
|
107
|
+
lowest_low = lowest_low(period_data)
|
108
|
+
highest_high = highest_high(period_data)
|
109
|
+
|
110
|
+
((highest_high + lowest_low) / 2.0)
|
111
|
+
end
|
112
|
+
|
113
|
+
private_class_method def self.calculate_senkou_span_a(index, low_period, medium_period, data)
|
114
|
+
mp_ago_index = (index - (medium_period - 1))
|
115
|
+
|
116
|
+
tenkan_sen_mp_ago = calculate_midpoint(mp_ago_index, low_period, data)
|
117
|
+
kinjun_sen_mp_ago = calculate_midpoint(mp_ago_index, medium_period, data)
|
118
|
+
|
119
|
+
((tenkan_sen_mp_ago + kinjun_sen_mp_ago) / 2.0)
|
120
|
+
end
|
121
|
+
|
122
|
+
private_class_method def self.calculate_senkou_span_b(index, medium_period, high_period, data)
|
123
|
+
mp_ago_index = (index - (medium_period - 1))
|
124
|
+
|
125
|
+
calculate_midpoint(mp_ago_index, high_period, data)
|
126
|
+
end
|
127
|
+
|
128
|
+
private_class_method def self.calculate_chikou_span(index, medium_period, data)
|
129
|
+
mp_ago_index = (index - (medium_period - 1))
|
130
|
+
|
131
|
+
data[mp_ago_index][:close]
|
132
|
+
end
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
# The value class to be returned by calculations
|
137
|
+
class IchimokuValue
|
138
|
+
|
139
|
+
# @return [String] the date_time of the obversation as it was provided
|
140
|
+
attr_accessor :date_time
|
141
|
+
|
142
|
+
# @return [Float] the tenkan_sen calculation value
|
143
|
+
attr_accessor :tenkan_sen
|
144
|
+
|
145
|
+
# @return [Float] the kijun_sen calculation value
|
146
|
+
attr_accessor :kijun_sen
|
147
|
+
|
148
|
+
# @return [Float] the senkou_span_a calculation value
|
149
|
+
attr_accessor :senkou_span_a
|
150
|
+
|
151
|
+
# @return [Float] the senkou_span_b calculation value
|
152
|
+
attr_accessor :senkou_span_b
|
153
|
+
|
154
|
+
# @return [Float] the chikou_span calculation value
|
155
|
+
attr_accessor :chikou_span
|
156
|
+
|
157
|
+
def initialize(date_time: nil, tenkan_sen: nil, kijun_sen: nil, senkou_span_a: nil, senkou_span_b: nil, chikou_span: nil)
|
158
|
+
@date_time = date_time
|
159
|
+
@tenkan_sen = tenkan_sen
|
160
|
+
@kijun_sen = kijun_sen
|
161
|
+
@senkou_span_a = senkou_span_a
|
162
|
+
@senkou_span_b = senkou_span_b
|
163
|
+
@chikou_span = chikou_span
|
164
|
+
end
|
165
|
+
|
166
|
+
# @return [Hash] the attributes as a hash
|
167
|
+
def to_hash
|
168
|
+
{
|
169
|
+
date_time: @date_time,
|
170
|
+
tenkan_sen: @tenkan_sen,
|
171
|
+
kijun_sen: @kijun_sen,
|
172
|
+
senkou_span_a: @senkou_span_a,
|
173
|
+
senkou_span_b: @senkou_span_b,
|
174
|
+
chikou_span: @chikou_span
|
175
|
+
}
|
176
|
+
end
|
177
|
+
|
178
|
+
end
|
179
|
+
end
|