technical-analysis 0.1.0
Sign up to get free protection for your applications and to get access to all the features.
- 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,120 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "Indicator" do
|
6
|
+
indicator = TechnicalAnalysis::Indicator
|
7
|
+
|
8
|
+
it 'Returns nil on a nonexistant indicator' do
|
9
|
+
nonexistant_indicator = indicator.find('test')
|
10
|
+
expect(nonexistant_indicator).to eq(nil)
|
11
|
+
end
|
12
|
+
|
13
|
+
it 'Finds an indicator' do
|
14
|
+
sma = indicator.find('sma')
|
15
|
+
expect(sma).to eq(TechnicalAnalysis::Sma)
|
16
|
+
end
|
17
|
+
|
18
|
+
describe 'Calculations' do
|
19
|
+
it 'Returns nil on a nonexistant calculation' do
|
20
|
+
calculation = indicator.calculate('sma', [], :test, { period: 20, price_key: :close })
|
21
|
+
expect(calculation).to eq(nil)
|
22
|
+
end
|
23
|
+
|
24
|
+
it 'Calculates indicator_name' do
|
25
|
+
indicator_name = indicator.calculate('sma', [], :indicator_name, { period: 20, price_key: :close })
|
26
|
+
expect(indicator_name).to eq('Simple Moving Average')
|
27
|
+
end
|
28
|
+
|
29
|
+
it 'Calculates indicator_symbol' do
|
30
|
+
indicator_name = indicator.calculate('sma', [], :indicator_symbol, { period: 20, price_key: :close })
|
31
|
+
expect(indicator_name).to eq('sma')
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'Calculates min_data_size' do
|
35
|
+
min_data_size = indicator.calculate('sma', [], :min_data_size, { period: 20, price_key: :close })
|
36
|
+
expect(min_data_size).to eq(20)
|
37
|
+
end
|
38
|
+
|
39
|
+
it 'Calculates valid_options' do
|
40
|
+
valid_options = indicator.calculate('sma', [], :valid_options, { period: 20, price_key: :close })
|
41
|
+
expect(valid_options).to eq(%i(period price_key))
|
42
|
+
end
|
43
|
+
|
44
|
+
it 'Calculates validate_options' do
|
45
|
+
options_validated = indicator.calculate('sma', [], :validate_options, { period: 20, price_key: :close })
|
46
|
+
expect(options_validated).to eq(true)
|
47
|
+
end
|
48
|
+
|
49
|
+
it 'Calculates technicals' do
|
50
|
+
input_data = SpecHelper.get_test_data(:close)
|
51
|
+
output = indicator.calculate('sma', input_data, :technicals, { period: 5, price_key: :close })
|
52
|
+
normalized_output = output.map(&:to_hash)
|
53
|
+
|
54
|
+
expected_output = [
|
55
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :sma=>148.488},
|
56
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :sma=>149.41},
|
57
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :sma=>150.808},
|
58
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :sma=>152.468},
|
59
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :sma=>154.046},
|
60
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :sma=>157.04199999999997},
|
61
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :sma=>154.824},
|
62
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :sma=>153.422},
|
63
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :sma=>153.54199999999997},
|
64
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :sma=>154.49},
|
65
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :sma=>156.27},
|
66
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :sma=>159.692},
|
67
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :sma=>162.642},
|
68
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :sma=>165.46599999999998},
|
69
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :sma=>167.108},
|
70
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :sma=>167.61999999999998},
|
71
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :sma=>168.752},
|
72
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :sma=>169.35399999999998},
|
73
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :sma=>170.108},
|
74
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :sma=>171.626},
|
75
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :sma=>174.864},
|
76
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :sma=>176.66},
|
77
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :sma=>178.872},
|
78
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :sma=>180.11600000000004},
|
79
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :sma=>179.62600000000003},
|
80
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :sma=>177.58599999999998},
|
81
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :sma=>176.32799999999997},
|
82
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :sma=>175.77400000000003},
|
83
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :sma=>174.982},
|
84
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :sma=>177.30599999999998},
|
85
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :sma=>181.088},
|
86
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :sma=>184.91199999999998},
|
87
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :sma=>186.916},
|
88
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :sma=>189.96599999999998},
|
89
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :sma=>191.628},
|
90
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :sma=>193.816},
|
91
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :sma=>197.23200000000003},
|
92
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :sma=>201.862},
|
93
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :sma=>204.17000000000002},
|
94
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :sma=>205.654},
|
95
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :sma=>206.256},
|
96
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :sma=>209.002},
|
97
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :sma=>210.78400000000002},
|
98
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :sma=>212.69},
|
99
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :sma=>214.82000000000002},
|
100
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :sma=>216.584},
|
101
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :sma=>216.1},
|
102
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :sma=>215.346},
|
103
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :sma=>217.23200000000003},
|
104
|
+
{:date_time=>"2018-10-26T00:00:00.000Z", :sma=>218.914},
|
105
|
+
{:date_time=>"2018-10-25T00:00:00.000Z", :sma=>219.51600000000002},
|
106
|
+
{:date_time=>"2018-10-24T00:00:00.000Z", :sma=>218.76},
|
107
|
+
{:date_time=>"2018-10-23T00:00:00.000Z", :sma=>219.97999999999996},
|
108
|
+
{:date_time=>"2018-10-22T00:00:00.000Z", :sma=>219.86400000000003},
|
109
|
+
{:date_time=>"2018-10-19T00:00:00.000Z", :sma=>219.206},
|
110
|
+
{:date_time=>"2018-10-18T00:00:00.000Z", :sma=>219.766},
|
111
|
+
{:date_time=>"2018-10-17T00:00:00.000Z", :sma=>219.452},
|
112
|
+
{:date_time=>"2018-10-16T00:00:00.000Z", :sma=>218.48600000000002},
|
113
|
+
{:date_time=>"2018-10-15T00:00:00.000Z", :sma=>219.43}
|
114
|
+
]
|
115
|
+
|
116
|
+
expect(normalized_output).to eq(expected_output)
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,110 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "KC" do
|
6
|
+
input_data = SpecHelper.get_test_data(:high, :low, :close)
|
7
|
+
indicator = TechnicalAnalysis::Kc
|
8
|
+
|
9
|
+
describe 'Keltner Channel' do
|
10
|
+
it 'Calculates KC (10 day)' do
|
11
|
+
output = indicator.calculate(input_data, period: 10)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :lower_band=>147.1630066666667, :middle_band=>151.9909966666667, :upper_band=>156.8189866666667},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :lower_band=>146.74034, :middle_band=>151.57433, :upper_band=>156.40832},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :lower_band=>146.46500666666665, :middle_band=>151.82199666666665, :upper_band=>157.17898666666665},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :lower_band=>147.12967333333333, :middle_band=>152.87466333333333, :upper_band=>158.61965333333333},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :lower_band=>148.32933333333335, :middle_band=>154.43533333333335, :upper_band=>160.54133333333334},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :lower_band=>150.65666666666667, :middle_band=>156.70466666666667, :upper_band=>162.75266666666667},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :lower_band=>151.35733333333334, :middle_band=>157.50533333333334, :upper_band=>163.65333333333334},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :lower_band=>152.14066666666668, :middle_band=>158.38066666666668, :upper_band=>164.6206666666667},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :lower_band=>153.69466666666665, :middle_band=>159.83966666666666, :upper_band=>165.98466666666667},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :lower_band=>155.643, :middle_band=>161.408, :upper_band=>167.17299999999997},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :lower_band=>157.75833333333333, :middle_band=>162.9513333333333, :upper_band=>168.1443333333333},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :lower_band=>159.51333333333332, :middle_band=>164.8863333333333, :upper_band=>170.2593333333333},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :lower_band=>161.50599999999997, :middle_band=>166.64499999999998, :upper_band=>171.784},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :lower_band=>163.27366666666666, :middle_band=>168.16766666666666, :upper_band=>173.06166666666667},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :lower_band=>165.09500666666668, :middle_band=>169.76499666666666, :upper_band=>174.43498666666665},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :lower_band=>166.80200666666667, :middle_band=>171.53099666666668, :upper_band=>176.2599866666667},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :lower_band=>168.39800666666667, :middle_band=>172.89499666666666, :upper_band=>177.39198666666664},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :lower_band=>169.60834, :middle_band=>174.23533, :upper_band=>178.86232},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :lower_band=>170.07734, :middle_band=>175.03833, :upper_band=>179.99932},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :lower_band=>170.30667333333332, :middle_band=>175.36666333333332, :upper_band=>180.42665333333332},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :lower_band=>170.73033999999998, :middle_band=>175.78033, :upper_band=>180.83032},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :lower_band=>171.55567333333335, :middle_band=>176.37916333333334, :upper_band=>181.20265333333333},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :lower_band=>172.54667333333333, :middle_band=>177.12316333333334, :upper_band=>181.69965333333334},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :lower_band=>172.85467333333332, :middle_band=>177.59116333333333, :upper_band=>182.32765333333333},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :lower_band=>173.76899999999998, :middle_band=>178.4645, :upper_band=>183.16},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :lower_band=>174.4907, :middle_band=>179.36415, :upper_band=>184.2376},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :lower_band=>175.45836666666665, :middle_band=>180.50881666666666, :upper_band=>185.55926666666667},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :lower_band=>176.01870000000002, :middle_band=>181.41415, :upper_band=>186.8096},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :lower_band=>177.53838, :middle_band=>182.87081999999998, :upper_band=>188.20325999999997},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :lower_band=>179.58538000000001, :middle_band=>185.13482000000002, :upper_band=>190.68426000000002},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :lower_band=>182.7750466666667, :middle_band=>188.23148666666668, :upper_band=>193.68792666666667},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :lower_band=>186.36671333333337, :middle_band=>191.71065333333337, :upper_band=>197.05459333333337},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :lower_band=>189.16371333333333, :middle_band=>194.72865333333334, :upper_band=>200.29359333333335},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :lower_band=>191.99738, :middle_band=>197.26932, :upper_band=>202.54126},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :lower_band=>193.36638000000002, :middle_band=>198.68932, :upper_band=>204.01226},
|
50
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :lower_band=>194.71534666666665, :middle_band=>200.30933666666664, :upper_band=>205.90332666666663},
|
51
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :lower_band=>197.70434666666668, :middle_band=>203.34633666666667, :upper_band=>208.98832666666667},
|
52
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :lower_band=>201.13368, :middle_band=>206.30367, :upper_band=>211.47366000000002},
|
53
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :lower_band=>203.012, :middle_band=>208.2, :upper_band=>213.38799999999998},
|
54
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :lower_band=>203.93166666666667, :middle_band=>209.87366666666668, :upper_band=>215.8156666666667},
|
55
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :lower_band=>204.77, :middle_band=>211.08800000000002, :upper_band=>217.40600000000003},
|
56
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :lower_band=>205.72966666666667, :middle_band=>212.17366666666666, :upper_band=>218.61766666666665},
|
57
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :lower_band=>206.34433333333334, :middle_band=>213.16433333333333, :upper_band=>219.98433333333332},
|
58
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :lower_band=>207.47566666666665, :middle_band=>214.84766666666664, :upper_band=>222.21966666666663},
|
59
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :lower_band=>209.61566666666667, :middle_band=>216.80766666666668, :upper_band=>223.99966666666668},
|
60
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :lower_band=>211.10266666666666, :middle_band=>217.85566666666668, :upper_band=>224.6086666666667},
|
61
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :lower_band=>210.5626666666667, :middle_band=>217.4346666666667, :upper_band=>224.30666666666667},
|
62
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :lower_band=>210.85700000000003, :middle_band=>217.67600000000002, :upper_band=>224.495},
|
63
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :lower_band=>211.63036000000005, :middle_band=>218.48109000000005, :upper_band=>225.33182000000005},
|
64
|
+
{:date_time=>"2018-10-26T00:00:00.000Z", :lower_band=>213.14902666666669, :middle_band=>219.0957566666667, :upper_band=>225.0424866666667},
|
65
|
+
{:date_time=>"2018-10-25T00:00:00.000Z", :lower_band=>213.71936000000002, :middle_band=>219.51809000000003, :upper_band=>225.31682000000004},
|
66
|
+
{:date_time=>"2018-10-24T00:00:00.000Z", :lower_band=>213.0756933333333, :middle_band=>219.1294233333333, :upper_band=>225.1831533333333},
|
67
|
+
{:date_time=>"2018-10-23T00:00:00.000Z", :lower_band=>213.17802666666663, :middle_band=>219.29275666666663, :upper_band=>225.40748666666664},
|
68
|
+
{:date_time=>"2018-10-22T00:00:00.000Z", :lower_band=>214.05418666666668, :middle_band=>219.8162966666667, :upper_band=>225.5784066666667}
|
69
|
+
]
|
70
|
+
|
71
|
+
expect(normalized_output).to eq(expected_output)
|
72
|
+
end
|
73
|
+
|
74
|
+
it "Throws exception if not enough data" do
|
75
|
+
expect {indicator.calculate(input_data, period: input_data.size+1)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Returns the symbol' do
|
79
|
+
indicator_symbol = indicator.indicator_symbol
|
80
|
+
expect(indicator_symbol).to eq('kc')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'Returns the name' do
|
84
|
+
indicator_name = indicator.indicator_name
|
85
|
+
expect(indicator_name).to eq('Keltner Channel')
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'Returns the valid options' do
|
89
|
+
valid_options = indicator.valid_options
|
90
|
+
expect(valid_options).to eq(%i(period))
|
91
|
+
end
|
92
|
+
|
93
|
+
it 'Validates options' do
|
94
|
+
valid_options = { period: 22 }
|
95
|
+
options_validated = indicator.validate_options(valid_options)
|
96
|
+
expect(options_validated).to eq(true)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'Throws exception for invalid options' do
|
100
|
+
invalid_options = { test: 10 }
|
101
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
102
|
+
end
|
103
|
+
|
104
|
+
it 'Calculates minimum data size' do
|
105
|
+
options = { period: 4 }
|
106
|
+
expect(indicator.min_data_size(options)).to eq(4)
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "KST" do
|
6
|
+
input_data = SpecHelper.get_test_data(:close)
|
7
|
+
indicator = TechnicalAnalysis::Kst
|
8
|
+
|
9
|
+
describe 'Know Sure Thing' do
|
10
|
+
it 'Calculates KST' do
|
11
|
+
output = indicator.calculate(input_data, roc1: 10, roc2: 15, roc3: 20, roc4: 30, sma1: 10, sma2: 10, sma3: 10, sma4: 15, price_key: :close)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :kst=>-140.9140022298261},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :kst=>-148.9261153101682},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :kst=>-155.71040741442587},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :kst=>-157.83675223915662},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :kst=>-157.0260814891967},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :kst=>-150.77021075475108},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :kst=>-152.43337072156913},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :kst=>-154.278039839607},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :kst=>-152.69243922992774},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :kst=>-151.25248412993977},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :kst=>-150.769274028613},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :kst=>-145.9029270207904},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :kst=>-143.4025404878081},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :kst=>-141.34365936138443},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :kst=>-141.36803679622636},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :kst=>-140.69442915235626},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :kst=>-141.6235541026754},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :kst=>-143.06704590371226},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :kst=>-146.67417088368043},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :kst=>-150.14198896419614}
|
35
|
+
]
|
36
|
+
|
37
|
+
expect(normalized_output).to eq(expected_output)
|
38
|
+
end
|
39
|
+
|
40
|
+
it "Throws exception if not enough data" do
|
41
|
+
roc4 = 60
|
42
|
+
sma4 = 30
|
43
|
+
expect {indicator.calculate(input_data, roc4: roc4, sma4: sma4, price_key: :close)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
44
|
+
end
|
45
|
+
|
46
|
+
it 'Returns the symbol' do
|
47
|
+
indicator_symbol = indicator.indicator_symbol
|
48
|
+
expect(indicator_symbol).to eq('kst')
|
49
|
+
end
|
50
|
+
|
51
|
+
it 'Returns the name' do
|
52
|
+
indicator_name = indicator.indicator_name
|
53
|
+
expect(indicator_name).to eq('Know Sure Thing')
|
54
|
+
end
|
55
|
+
|
56
|
+
it 'Returns the valid options' do
|
57
|
+
valid_options = indicator.valid_options
|
58
|
+
expect(valid_options).to eq(%i(period roc1 roc2 roc3 roc4 sma1 sma2 sma3 sma4 price_key))
|
59
|
+
end
|
60
|
+
|
61
|
+
it 'Validates options' do
|
62
|
+
valid_options = { roc1: 10, roc2: 15, roc3: 20, roc4: 30, sma1: 10, sma2: 10, sma3: 10, sma4: 15, price_key: :kst }
|
63
|
+
options_validated = indicator.validate_options(valid_options)
|
64
|
+
expect(options_validated).to eq(true)
|
65
|
+
end
|
66
|
+
|
67
|
+
it 'Throws exception for invalid options' do
|
68
|
+
invalid_options = { test: 10 }
|
69
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
70
|
+
end
|
71
|
+
|
72
|
+
it 'Calculates minimum data size' do
|
73
|
+
options = { roc4: 30, sma4: 15 }
|
74
|
+
expect(indicator.min_data_size(options)).to eq(44)
|
75
|
+
end
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,86 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "MACD" do
|
6
|
+
input_data = SpecHelper.get_test_data(:close)
|
7
|
+
indicator = TechnicalAnalysis::Macd
|
8
|
+
|
9
|
+
describe 'Moving Average Convergence Divergence' do
|
10
|
+
it 'Calculates MACD (12, 26, 9)' do
|
11
|
+
output = indicator.calculate(input_data, fast_period: 12, slow_period: 26, signal_period: 9, price_key: :close)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :macd_histogram=>0.8762597178840466, :macd_line=>-8.126908458242355, :signal_line=>-9.003168176126401},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :macd_histogram=>0.4770591535283888, :macd_line=>-8.745173952069024, :signal_line=>-9.222233105597413},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :macd_histogram=>0.19504942363819744, :macd_line=>-9.146448470341312, :signal_line=>-9.34149789397951},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :macd_histogram=>0.15180609943062073, :macd_line=>-9.238454150458438, :signal_line=>-9.390260249889058},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :macd_histogram=>0.17310243476363496, :macd_line=>-9.255109339983079, :signal_line=>-9.428211774746714},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :macd_histogram=>0.9477761010428516, :macd_line=>-8.523711282394771, :signal_line=>-9.471487383437623},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :macd_histogram=>0.6406312657329245, :macd_line=>-9.06780014296541, :signal_line=>-9.708431408698335},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :macd_histogram=>0.25655639311731626, :macd_line=>-9.61203283201425, :signal_line=>-9.868589225131567},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :macd_histogram=>-0.0803864814327433, :macd_line=>-10.013114804843639, :signal_line=>-9.932728323410895},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :macd_histogram=>-0.45861878631368036, :macd_line=>-10.371250489366389, :signal_line=>-9.912631703052709},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :macd_histogram=>-0.9833848403830618, :macd_line=>-10.78136184685735, :signal_line=>-9.797977006474289},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :macd_histogram=>-0.5430624653584708, :macd_line=>-10.095193261736995, :signal_line=>-9.552130796378524},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :macd_histogram=>-0.053279185610067614, :macd_line=>-9.469644365648975, :signal_line=>-9.416365180038907},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :macd_histogram=>0.24847825431282367, :macd_line=>-9.154567129323567, :signal_line=>-9.40304538363639},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :macd_histogram=>0.4325264668638127, :macd_line=>-9.032638480350784, :signal_line=>-9.465164947214596},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :macd_histogram=>0.30024902798283826, :macd_line=>-9.273047535947711, :signal_line=>-9.57329656393055},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :macd_histogram=>0.420215327266785, :macd_line=>-9.228143493659474, :signal_line=>-9.648358820926259},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :macd_histogram=>0.5600105875119272, :macd_line=>-9.193402065231027, :signal_line=>-9.753412652742954},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :macd_histogram=>0.3211326876237397, :macd_line=>-9.572282611997196, :signal_line=>-9.893415299620935},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :macd_histogram=>0.24542334510443808, :macd_line=>-9.728275126422432, :signal_line=>-9.97369847152687},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :macd_histogram=>0.29703273753484893, :macd_line=>-9.738021570268131, :signal_line=>-10.03505430780298},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :macd_histogram=>0.40173122915939885, :macd_line=>-9.707581263027294, :signal_line=>-10.109312492186692},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :macd_histogram=>0.7952363015170398, :macd_line=>-9.414508997959501, :signal_line=>-10.209745299476541},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :macd_histogram=>0.8707231988258766, :macd_line=>-9.537831176029925, :signal_line=>-10.408554374855802},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :macd_histogram=>0.8691503265374259, :macd_line=>-9.757084848024846, :signal_line=>-10.626235174562272},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :macd_histogram=>0.12072991006954936, :macd_line=>-10.722792846127078, :signal_line=>-10.843522756196627},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :macd_histogram=>-0.29036883404714864, :macd_line=>-11.164074067761163, :signal_line=>-10.873705233714015},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :macd_histogram=>-0.8625734517317483, :macd_line=>-11.663686476933975, :signal_line=>-10.801113025202227},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :macd_histogram=>-1.6877775772534704, :macd_line=>-12.27324723952276, :signal_line=>-10.58546966226929},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :macd_histogram=>-2.0270413850598707, :macd_line=>-12.190566653015793, :signal_line=>-10.163525267955922}
|
45
|
+
]
|
46
|
+
|
47
|
+
expect(normalized_output).to eq(expected_output)
|
48
|
+
end
|
49
|
+
|
50
|
+
it "Throws exception if not enough data" do
|
51
|
+
expect {indicator.calculate(input_data, slow_period: input_data.size+1, signal_period: input_data.size+1, price_key: :close)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
52
|
+
end
|
53
|
+
|
54
|
+
it 'Returns the symbol' do
|
55
|
+
indicator_symbol = indicator.indicator_symbol
|
56
|
+
expect(indicator_symbol).to eq('macd')
|
57
|
+
end
|
58
|
+
|
59
|
+
it 'Returns the name' do
|
60
|
+
indicator_name = indicator.indicator_name
|
61
|
+
expect(indicator_name).to eq('Moving Average Convergence Divergence')
|
62
|
+
end
|
63
|
+
|
64
|
+
it 'Returns the valid options' do
|
65
|
+
valid_options = indicator.valid_options
|
66
|
+
expect(valid_options).to eq(%i(fast_period slow_period signal_period price_key))
|
67
|
+
end
|
68
|
+
|
69
|
+
it 'Validates options' do
|
70
|
+
valid_options = { fast_period: 12, slow_period: 26, signal_period: 9, price_key: :close }
|
71
|
+
options_validated = indicator.validate_options(valid_options)
|
72
|
+
expect(options_validated).to eq(true)
|
73
|
+
end
|
74
|
+
|
75
|
+
it 'Throws exception for invalid options' do
|
76
|
+
invalid_options = { test: 10 }
|
77
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
78
|
+
end
|
79
|
+
|
80
|
+
it 'Calculates minimum data size' do
|
81
|
+
options = { fast_period: 12, slow_period: 24, signal_period: 10, price_key: :close }
|
82
|
+
expect(indicator.min_data_size(options)).to eq(33)
|
83
|
+
end
|
84
|
+
end
|
85
|
+
end
|
86
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "MFI" do
|
6
|
+
input_data = SpecHelper.get_test_data(:high, :low, :close, :volume)
|
7
|
+
indicator = TechnicalAnalysis::Mfi
|
8
|
+
|
9
|
+
describe 'Money Flow Index' do
|
10
|
+
it 'Calculates MFI (14 day)' do
|
11
|
+
output = indicator.calculate(input_data, period: 14)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :mfi=>50.72343663578981},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :mfi=>50.1757147722236},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :mfi=>44.40424662233335},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :mfi=>37.81171947764313},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :mfi=>36.12141791144509},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :mfi=>44.40322811326429},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :mfi=>50.84666407662511},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :mfi=>43.66248537462054},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :mfi=>37.56125308902594},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :mfi=>30.54886108664553},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :mfi=>22.795547568232564},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :mfi=>29.111701049682864},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :mfi=>31.23926122664477},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :mfi=>39.506183778454634},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :mfi=>47.447534147092476},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :mfi=>48.23034273673764},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :mfi=>47.94902504034211},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :mfi=>49.219385053554596},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :mfi=>43.77747404533765},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :mfi=>35.65846689890073},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :mfi=>28.368262151706787},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :mfi=>36.043235982173},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :mfi=>43.83608665179891},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :mfi=>42.20999531156955},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :mfi=>41.56028762200471},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :mfi=>34.05798943239071},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :mfi=>34.06816082393442},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :mfi=>32.76065853310956},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :mfi=>31.964707056845796},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :mfi=>31.547361595662196},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :mfi=>30.0162422598642},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :mfi=>26.562703378271138},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :mfi=>33.960148214906965},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :mfi=>41.216526023725},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :mfi=>41.22749344358184},
|
50
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :mfi=>35.21136683265594},
|
51
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :mfi=>28.384945303826555},
|
52
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :mfi=>34.34229761188338},
|
53
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :mfi=>34.42914208336833},
|
54
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :mfi=>34.82129345577579},
|
55
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :mfi=>39.93886476277229},
|
56
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :mfi=>40.83081970751587},
|
57
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :mfi=>35.50426811855657},
|
58
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :mfi=>34.78216906343063},
|
59
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :mfi=>41.95906812943111},
|
60
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :mfi=>46.69168911629936},
|
61
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :mfi=>45.214622261116865},
|
62
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :mfi=>36.38768375444253},
|
63
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :mfi=>35.973926377719295}
|
64
|
+
]
|
65
|
+
|
66
|
+
expect(normalized_output).to eq(expected_output)
|
67
|
+
end
|
68
|
+
|
69
|
+
it "Throws exception if not enough data" do
|
70
|
+
expect {indicator.calculate(input_data, period: input_data.size+2)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'Returns the symbol' do
|
74
|
+
indicator_symbol = indicator.indicator_symbol
|
75
|
+
expect(indicator_symbol).to eq('mfi')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Returns the name' do
|
79
|
+
indicator_name = indicator.indicator_name
|
80
|
+
expect(indicator_name).to eq('Money Flow Index')
|
81
|
+
end
|
82
|
+
|
83
|
+
it 'Returns the valid options' do
|
84
|
+
valid_options = indicator.valid_options
|
85
|
+
expect(valid_options).to eq(%i(period))
|
86
|
+
end
|
87
|
+
|
88
|
+
it 'Validates options' do
|
89
|
+
valid_options = { period: 22 }
|
90
|
+
options_validated = indicator.validate_options(valid_options)
|
91
|
+
expect(options_validated).to eq(true)
|
92
|
+
end
|
93
|
+
|
94
|
+
it 'Throws exception for invalid options' do
|
95
|
+
invalid_options = { test: 10 }
|
96
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
97
|
+
end
|
98
|
+
|
99
|
+
it 'Calculates minimum data size' do
|
100
|
+
options = { period: 4 }
|
101
|
+
expect(indicator.min_data_size(options)).to eq(5)
|
102
|
+
end
|
103
|
+
end
|
104
|
+
end
|
105
|
+
end
|