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,90 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "DPO" do
|
6
|
+
input_data = SpecHelper.get_test_data(:close)
|
7
|
+
indicator = TechnicalAnalysis::Dpo
|
8
|
+
|
9
|
+
describe 'Detrended Price Oscillator' do
|
10
|
+
it 'Calculates DPO (20 day)' do
|
11
|
+
output = indicator.calculate(input_data, period: 20, price_key: :close)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :dpo=>-15.774999999999977},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :dpo=>-19.607999999999976},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :dpo=>-23.730500000000006},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :dpo=>-24.407999999999987},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :dpo=>-31.726499999999987},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :dpo=>-17.36949999999996},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :dpo=>-18.922999999999973},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :dpo=>-21.498999999999995},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :dpo=>-22.642999999999972},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :dpo=>-22.876499999999993},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :dpo=>-35.0085},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :dpo=>-33.053},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :dpo=>-29.025999999999982},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :dpo=>-26.41850000000005},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :dpo=>-22.48350000000005},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :dpo=>-25.746500000000054},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :dpo=>-26.388500000000022},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :dpo=>-22.884000000000043},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :dpo=>-26.35200000000006},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :dpo=>-28.722000000000037},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :dpo=>-29.836000000000013},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :dpo=>-33.321500000000015},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :dpo=>-29.007000000000033},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :dpo=>-29.3245},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :dpo=>-22.93399999999997},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :dpo=>-30.462999999999965},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :dpo=>-30.723499999999945},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :dpo=>-31.052999999999997},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :dpo=>-39.24899999999997},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :dpo=>-40.02850000000001},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :dpo=>-43.2405},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :dpo=>-39.04850000000002},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :dpo=>-39.16900000000004},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :dpo=>-31.444000000000017}
|
49
|
+
]
|
50
|
+
|
51
|
+
expect(normalized_output).to eq(expected_output)
|
52
|
+
end
|
53
|
+
|
54
|
+
it "Throws exception if not enough data" do
|
55
|
+
expect {indicator.calculate(input_data, period: input_data.size+1, price_key: :close)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
56
|
+
end
|
57
|
+
|
58
|
+
it 'Returns the symbol' do
|
59
|
+
indicator_symbol = indicator.indicator_symbol
|
60
|
+
expect(indicator_symbol).to eq('dpo')
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'Returns the name' do
|
64
|
+
indicator_name = indicator.indicator_name
|
65
|
+
expect(indicator_name).to eq('Detrended Price Oscillator')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'Returns the valid options' do
|
69
|
+
valid_options = indicator.valid_options
|
70
|
+
expect(valid_options).to eq(%i(period price_key))
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'Validates options' do
|
74
|
+
valid_options = { period: 22, price_key: :close }
|
75
|
+
options_validated = indicator.validate_options(valid_options)
|
76
|
+
expect(options_validated).to eq(true)
|
77
|
+
end
|
78
|
+
|
79
|
+
it 'Throws exception for invalid options' do
|
80
|
+
invalid_options = { test: 10 }
|
81
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'Calculates minimum data size' do
|
85
|
+
options = { period: 4 }
|
86
|
+
expect(indicator.min_data_size(options)).to eq(6)
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,119 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "DR" do
|
6
|
+
input_data = SpecHelper.get_test_data(:close)
|
7
|
+
indicator = TechnicalAnalysis::Dr
|
8
|
+
|
9
|
+
describe 'Daily Return' do
|
10
|
+
it 'Calculates Daily Return' do
|
11
|
+
output = indicator.calculate(input_data, price_key: :close)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :dr=>0.01698175787728018},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :dr=>0.019063070371121427},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :dr=>-0.0022258195062726527},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :dr=>0.042689359307968244},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :dr=>-0.09960739614994929},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :dr=>0.0011411182959297772},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :dr=>0.009665237150355388},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :dr=>0.00051232788984934},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :dr=>-0.006489788127505114},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :dr=>0.07042157597221266},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :dr=>-0.02587407947986453},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :dr=>-0.038895619460562525},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :dr=>-0.025234632357511222},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :dr=>-0.031191666164870235},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :dr=>0.01299255825301926},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :dr=>-0.009306260575296044},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :dr=>-0.031997660134542305},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :dr=>0.010940272028385545},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :dr=>0.0027871671707289103},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :dr=>-0.005719339622641484},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :dr=>0.006587928066947413},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :dr=>-0.03565705128205121},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :dr=>-0.011149470824608043},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :dr=>-0.043988745806730845},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :dr=>0.03494232276850706},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :dr=>-0.005402394876079075},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :dr=>-0.0076821045650491415},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :dr=>0.038452708907254385},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :dr=>-0.0021761539342571856},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :dr=>0.013523710023797264},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :dr=>-0.025398800769317886},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :dr=>-0.0011300711944851605},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :dr=>-0.047777897342085596},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :dr=>-0.03963209838267967},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :dr=>0.011075701374013924},
|
50
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :dr=>0.02467880085653107},
|
51
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :dr=>-0.02824741195442948},
|
52
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :dr=>-0.009991244785497289},
|
53
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :dr=>-0.05037413801535684},
|
54
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :dr=>-0.019281500311765565},
|
55
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :dr=>-0.006954036675398845},
|
56
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :dr=>0.030328311331403013},
|
57
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :dr=>0.010814028473634663},
|
58
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :dr=>-0.028388278388278287},
|
59
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :dr=>-0.06633066330663306},
|
60
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :dr=>0.015352279996344587},
|
61
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :dr=>0.026066572902015972},
|
62
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :dr=>0.004994346023369678},
|
63
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :dr=>-0.018770226537216828},
|
64
|
+
{:date_time=>"2018-10-26T00:00:00.000Z", :dr=>-0.015923566878980888},
|
65
|
+
{:date_time=>"2018-10-25T00:00:00.000Z", :dr=>0.021897810218978186},
|
66
|
+
{:date_time=>"2018-10-24T00:00:00.000Z", :dr=>-0.034301620796480026},
|
67
|
+
{:date_time=>"2018-10-23T00:00:00.000Z", :dr=>0.009426693859052815},
|
68
|
+
{:date_time=>"2018-10-22T00:00:00.000Z", :dr=>0.006110072500113972},
|
69
|
+
{:date_time=>"2018-10-19T00:00:00.000Z", :dr=>0.015230071289695335},
|
70
|
+
{:date_time=>"2018-10-18T00:00:00.000Z", :dr=>-0.023373570233735652},
|
71
|
+
{:date_time=>"2018-10-17T00:00:00.000Z", :dr=>-0.004321404456448352},
|
72
|
+
{:date_time=>"2018-10-16T00:00:00.000Z", :dr=>0.022037173352962736},
|
73
|
+
{:date_time=>"2018-10-15T00:00:00.000Z", :dr=>-0.021385799828913643},
|
74
|
+
{:date_time=>"2018-10-12T00:00:00.000Z", :dr=>0.035719281883889176},
|
75
|
+
{:date_time=>"2018-10-11T00:00:00.000Z", :dr=>-0.00882787946015906},
|
76
|
+
{:date_time=>"2018-10-10T00:00:00.000Z", :dr=>-0.046326089831180806},
|
77
|
+
{:date_time=>"2018-10-09T00:00:00.000Z", :dr=>0.0}
|
78
|
+
]
|
79
|
+
|
80
|
+
expect(normalized_output).to eq(expected_output)
|
81
|
+
end
|
82
|
+
|
83
|
+
it "Throws exception if not enough data" do
|
84
|
+
expect {indicator.calculate([], price_key: :close)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
85
|
+
end
|
86
|
+
|
87
|
+
it 'Returns the symbol' do
|
88
|
+
indicator_symbol = indicator.indicator_symbol
|
89
|
+
expect(indicator_symbol).to eq('dr')
|
90
|
+
end
|
91
|
+
|
92
|
+
it 'Returns the name' do
|
93
|
+
indicator_name = indicator.indicator_name
|
94
|
+
expect(indicator_name).to eq('Daily Return')
|
95
|
+
end
|
96
|
+
|
97
|
+
it 'Returns the valid options' do
|
98
|
+
valid_options = indicator.valid_options
|
99
|
+
expect(valid_options).to eq(%i(price_key))
|
100
|
+
end
|
101
|
+
|
102
|
+
it 'Validates options' do
|
103
|
+
valid_options = { price_key: :close }
|
104
|
+
options_validated = indicator.validate_options(valid_options)
|
105
|
+
expect(options_validated).to eq(true)
|
106
|
+
end
|
107
|
+
|
108
|
+
it 'Throws exception for invalid options' do
|
109
|
+
invalid_options = { test: 10 }
|
110
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
111
|
+
end
|
112
|
+
|
113
|
+
it 'Calculates minimum data size' do
|
114
|
+
options = {}
|
115
|
+
expect(indicator.min_data_size(options)).to eq(1)
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
end
|
@@ -0,0 +1,105 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "EoM" do
|
6
|
+
input_data = SpecHelper.get_test_data(:high, :low, :volume)
|
7
|
+
indicator = TechnicalAnalysis::Eom
|
8
|
+
|
9
|
+
describe 'Ease of Movement' do
|
10
|
+
it 'Calculates EoM (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", :eom=>-6.497226050937367},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :eom=>-7.7025655861800235},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :eom=>-10.852331038262774},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :eom=>-13.901372232239117},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :eom=>-14.868322149693872},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :eom=>-10.542472341445862},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :eom=>-7.266128029998595},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :eom=>-11.754905920393293},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :eom=>-15.149439471732872},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :eom=>-21.397258702024285},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :eom=>-29.127850557035778},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :eom=>-21.640253827328284},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :eom=>-19.510117531121228},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :eom=>-14.184550665717635},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :eom=>-5.583810139052782},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :eom=>-5.714363954096145},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :eom=>-5.49920090817078},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :eom=>-8.427863395925653},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :eom=>-8.897024349696329},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :eom=>-15.409243349973261},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :eom=>-21.68916026908629},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :eom=>-15.003602992747133},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :eom=>-14.327931101318542},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :eom=>-13.565693513893978},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :eom=>-11.780616477806618},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :eom=>-20.874548142667777},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :eom=>-23.304959556064855},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :eom=>-23.906907831421474},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :eom=>-24.18360420308819},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :eom=>-23.02094878061384},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :eom=>-27.26817615617346},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :eom=>-28.2247053700715},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :eom=>-27.37028760395389},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :eom=>-16.94506299946587},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :eom=>-13.43297156412281},
|
50
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :eom=>-23.978202090280167},
|
51
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :eom=>-26.374761082588922},
|
52
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :eom=>-22.593717509723117},
|
53
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :eom=>-19.69000228424736},
|
54
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :eom=>-16.918604972309158},
|
55
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :eom=>-11.567473480653877},
|
56
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :eom=>-10.367227984759097},
|
57
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :eom=>-22.183583990006944},
|
58
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :eom=>-22.338003197707696},
|
59
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :eom=>-16.2797807192085},
|
60
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :eom=>-10.135395436615527},
|
61
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :eom=>-6.606596973217312},
|
62
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :eom=>-16.275660385464448},
|
63
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :eom=>-21.877975231994814}
|
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('eom')
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Returns the name' do
|
79
|
+
indicator_name = indicator.indicator_name
|
80
|
+
expect(indicator_name).to eq('Ease of Movement')
|
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
|
@@ -0,0 +1,118 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "FI" do
|
6
|
+
input_data = SpecHelper.get_test_data(:close, :volume)
|
7
|
+
indicator = TechnicalAnalysis::Fi
|
8
|
+
|
9
|
+
describe 'Forced Index' do
|
10
|
+
it 'Calculates FI' do
|
11
|
+
output = indicator.calculate(input_data)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :fi=>115287987.2000001},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :fi=>114556606.19999972},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :fi=>-18008575.19999913},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :fi=>348561555.4999996},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :fi=>-1433110593.199999},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :fi=>6414672.59999923},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :fi=>52094078.90000067},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :fi=>3339247.9999993355},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :fi=>-52641026.99999906},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :fi=>601104008.9999986},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :fi=>-144959996.99999917},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :fi=>-582537190.0000021},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :fi=>-261456813.7999983},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :fi=>-246555930.60000032},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :fi=>71894933.69999984},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :fi=>-66605646.799999654},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :fi=>-222193369.19999996},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :fi=>58745288.49999982},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :fi=>16673099.59999996},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :fi=>-44588998.799999945},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :fi=>68552489.99999909},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :fi=>-259658176.39999956},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :fi=>-84128672.69999996},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :fi=>-334478362.4999998},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :fi=>252955247.99999923},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :fi=>-38241532.19999996},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :fi=>-57717776.19999944},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :fi=>307809724.99999946},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :fi=>-15639333.199999813},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :fi=>104063205.60000056},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :fi=>-106071625.30000022},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :fi=>-6219247.999999646},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :fi=>-600986678.4000016},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :fi=>-319277709.3999995},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :fi=>76725619.60000016},
|
50
|
+
{:date_time=>"2018-11-15T00:00:00.000Z", :fi=>213312352.5999993},
|
51
|
+
{:date_time=>"2018-11-14T00:00:00.000Z", :fi=>-328772056.1999987},
|
52
|
+
{:date_time=>"2018-11-13T00:00:00.000Z", :fi=>-90647877.39999989},
|
53
|
+
{:date_time=>"2018-11-12T00:00:00.000Z", :fi=>-525207609.0000006},
|
54
|
+
{:date_time=>"2018-11-09T00:00:00.000Z", :fi=>-137957395.20000035},
|
55
|
+
{:date_time=>"2018-11-08T00:00:00.000Z", :fi=>-36922334.19999948},
|
56
|
+
{:date_time=>"2018-11-07T00:00:00.000Z", :fi=>205742335.19999927},
|
57
|
+
{:date_time=>"2018-11-06T00:00:00.000Z", :fi=>69268889.60000022},
|
58
|
+
{:date_time=>"2018-11-05T00:00:00.000Z", :fi=>-389165081.2999991},
|
59
|
+
{:date_time=>"2018-11-02T00:00:00.000Z", :fi=>-1342026294.4000008},
|
60
|
+
{:date_time=>"2018-11-01T00:00:00.000Z", :fi=>177925675.1999992},
|
61
|
+
{:date_time=>"2018-10-31T00:00:00.000Z", :fi=>211373463.60000008},
|
62
|
+
{:date_time=>"2018-10-30T00:00:00.000Z", :fi=>38677205.80000009},
|
63
|
+
{:date_time=>"2018-10-29T00:00:00.000Z", :fi=>-185597581.4000001},
|
64
|
+
{:date_time=>"2018-10-26T00:00:00.000Z", :fi=>-165170950.0},
|
65
|
+
{:date_time=>"2018-10-25T00:00:00.000Z", :fi=>136718771.40000024},
|
66
|
+
{:date_time=>"2018-10-24T00:00:00.000Z", :fi=>-305539796.7999995},
|
67
|
+
{:date_time=>"2018-10-23T00:00:00.000Z", :fi=>80456833.59999938},
|
68
|
+
{:date_time=>"2018-10-22T00:00:00.000Z", :fi=>38527063.6000001},
|
69
|
+
{:date_time=>"2018-10-19T00:00:00.000Z", :fi=>108156545.69999973},
|
70
|
+
{:date_time=>"2018-10-18T00:00:00.000Z", :fi=>-167452577.5999996},
|
71
|
+
{:date_time=>"2018-10-17T00:00:00.000Z", :fi=>-21785164.80000018},
|
72
|
+
{:date_time=>"2018-10-16T00:00:00.000Z", :fi=>137964214.49999976},
|
73
|
+
{:date_time=>"2018-10-15T00:00:00.000Z", :fi=>-143832137.5},
|
74
|
+
{:date_time=>"2018-10-12T00:00:00.000Z", :fi=>302529938.200001},
|
75
|
+
{:date_time=>"2018-10-11T00:00:00.000Z", :fi=>-101043431.20000133},
|
76
|
+
{:date_time=>"2018-10-10T00:00:00.000Z", :fi=>-431793575.69999963}
|
77
|
+
]
|
78
|
+
|
79
|
+
expect(normalized_output).to eq(expected_output)
|
80
|
+
end
|
81
|
+
|
82
|
+
it "Throws exception if not enough data" do
|
83
|
+
expect {indicator.calculate([])}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
84
|
+
end
|
85
|
+
|
86
|
+
it 'Returns the symbol' do
|
87
|
+
indicator_symbol = indicator.indicator_symbol
|
88
|
+
expect(indicator_symbol).to eq('fi')
|
89
|
+
end
|
90
|
+
|
91
|
+
it 'Returns the name' do
|
92
|
+
indicator_name = indicator.indicator_name
|
93
|
+
expect(indicator_name).to eq('Force Index')
|
94
|
+
end
|
95
|
+
|
96
|
+
it 'Returns the valid options' do
|
97
|
+
valid_options = indicator.valid_options
|
98
|
+
expect(valid_options).to eq([])
|
99
|
+
end
|
100
|
+
|
101
|
+
it 'Validates options' do
|
102
|
+
valid_options = {}
|
103
|
+
options_validated = indicator.validate_options(valid_options)
|
104
|
+
expect(options_validated).to eq(true)
|
105
|
+
end
|
106
|
+
|
107
|
+
it 'Throws exception for invalid options' do
|
108
|
+
invalid_options = { test: 10 }
|
109
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
110
|
+
end
|
111
|
+
|
112
|
+
it 'Calculates minimum data size' do
|
113
|
+
options = {}
|
114
|
+
expect(indicator.min_data_size(options)).to eq(2)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
require 'technical-analysis'
|
2
|
+
require 'spec_helper'
|
3
|
+
|
4
|
+
describe 'Indicators' do
|
5
|
+
describe "Ichimoku" do
|
6
|
+
input_data = SpecHelper.get_test_data(:high, :low, :close)
|
7
|
+
indicator = TechnicalAnalysis::Ichimoku
|
8
|
+
|
9
|
+
describe 'Ichimoku' do
|
10
|
+
it 'Calculates Ichimoku' do
|
11
|
+
output = indicator.calculate(input_data, low_period: 3, medium_period: 10, high_period: 20)
|
12
|
+
normalized_output = output.map(&:to_hash)
|
13
|
+
|
14
|
+
expected_output = [
|
15
|
+
{:date_time=>"2019-01-09T00:00:00.000Z", :chikou_span=>157.17, :kijun_sen=>150.68, :senkou_span_a=>155.9775, :senkou_span_b=>165.765, :tenkan_sen=>150.215},
|
16
|
+
{:date_time=>"2019-01-08T00:00:00.000Z", :chikou_span=>146.83, :kijun_sen=>150.68, :senkou_span_a=>156.965, :senkou_span_b=>165.765, :tenkan_sen=>147.81},
|
17
|
+
{:date_time=>"2019-01-07T00:00:00.000Z", :chikou_span=>150.73, :kijun_sen=>150.68, :senkou_span_a=>159.82, :senkou_span_b=>167.285, :tenkan_sen=>145.41500000000002},
|
18
|
+
{:date_time=>"2019-01-04T00:00:00.000Z", :chikou_span=>156.83, :kijun_sen=>152.055, :senkou_span_a=>163.15500000000003, :senkou_span_b=>170.12, :tenkan_sen=>150.425},
|
19
|
+
{:date_time=>"2019-01-03T00:00:00.000Z", :chikou_span=>160.89, :kijun_sen=>154.725, :senkou_span_a=>165.3275, :senkou_span_b=>172.015, :tenkan_sen=>150.68},
|
20
|
+
{:date_time=>"2019-01-02T00:00:00.000Z", :chikou_span=>166.07, :kijun_sen=>157.06, :senkou_span_a=>169.23247500000002, :senkou_span_b=>176.71499999999997, :tenkan_sen=>156.79500000000002},
|
21
|
+
{:date_time=>"2018-12-31T00:00:00.000Z", :chikou_span=>163.94, :kijun_sen=>157.47, :senkou_span_a=>170.74249999999998, :senkou_span_b=>178.84975, :tenkan_sen=>154.715},
|
22
|
+
{:date_time=>"2018-12-28T00:00:00.000Z", :chikou_span=>165.48, :kijun_sen=>157.835, :senkou_span_a=>171.53, :senkou_span_b=>179.14975, :tenkan_sen=>152.62},
|
23
|
+
{:date_time=>"2018-12-27T00:00:00.000Z", :chikou_span=>170.95, :kijun_sen=>159.57999999999998, :senkou_span_a=>171.95999999999998, :senkou_span_b=>179.14975, :tenkan_sen=>151.91},
|
24
|
+
{:date_time=>"2018-12-26T00:00:00.000Z", :chikou_span=>169.1, :kijun_sen=>159.57999999999998, :senkou_span_a=>170.88, :senkou_span_b=>180.255, :tenkan_sen=>152.375},
|
25
|
+
{:date_time=>"2018-12-24T00:00:00.000Z", :chikou_span=>168.63, :kijun_sen=>159.57999999999998, :senkou_span_a=>171.5225, :senkou_span_b=>181.59, :tenkan_sen=>154.35000000000002},
|
26
|
+
{:date_time=>"2018-12-21T00:00:00.000Z", :chikou_span=>169.6, :kijun_sen=>161.1, :senkou_span_a=>171.595, :senkou_span_b=>184.67000000000002, :tenkan_sen=>158.54},
|
27
|
+
{:date_time=>"2018-12-20T00:00:00.000Z", :chikou_span=>168.49, :kijun_sen=>164.895, :senkou_span_a=>175.98247500000002, :senkou_span_b=>189.21, :tenkan_sen=>161.41500000000002},
|
28
|
+
{:date_time=>"2018-12-19T00:00:00.000Z", :chikou_span=>174.72, :kijun_sen=>166.935, :senkou_span_a=>177.64, :senkou_span_b=>190.19, :tenkan_sen=>163.72},
|
29
|
+
{:date_time=>"2018-12-18T00:00:00.000Z", :chikou_span=>176.69, :kijun_sen=>172.55995000000001, :senkou_span_a=>179.10250000000002, :senkou_span_b=>190.19, :tenkan_sen=>165.905},
|
30
|
+
{:date_time=>"2018-12-17T00:00:00.000Z", :chikou_span=>184.82, :kijun_sen=>173.83499999999998, :senkou_span_a=>180.73250000000002, :senkou_span_b=>190.19, :tenkan_sen=>167.64999999999998},
|
31
|
+
{:date_time=>"2018-12-14T00:00:00.000Z", :chikou_span=>178.58, :kijun_sen=>174.135, :senkou_span_a=>180.739875, :senkou_span_b=>191.95499999999998, :tenkan_sen=>168.925},
|
32
|
+
{:date_time=>"2018-12-13T00:00:00.000Z", :chikou_span=>179.55, :kijun_sen=>174.135, :senkou_span_a=>179.727375, :senkou_span_b=>196.31, :tenkan_sen=>169.785},
|
33
|
+
{:date_time=>"2018-12-12T00:00:00.000Z", :chikou_span=>180.94, :kijun_sen=>174.135, :senkou_span_a=>179.194875, :senkou_span_b=>196.31, :tenkan_sen=>167.625},
|
34
|
+
{:date_time=>"2018-12-11T00:00:00.000Z", :chikou_span=>174.24, :kijun_sen=>174.135, :senkou_span_a=>178.57375000000002, :senkou_span_b=>196.31, :tenkan_sen=>168.91000000000003},
|
35
|
+
{:date_time=>"2018-12-10T00:00:00.000Z", :chikou_span=>174.62, :kijun_sen=>174.135, :senkou_span_a=>180.16, :senkou_span_b=>196.31, :tenkan_sen=>169.055},
|
36
|
+
{:date_time=>"2018-12-07T00:00:00.000Z", :chikou_span=>172.29, :kijun_sen=>176.62, :senkou_span_a=>182.92000000000002, :senkou_span_b=>197.23000000000002, :tenkan_sen=>175.34495},
|
37
|
+
{:date_time=>"2018-12-06T00:00:00.000Z", :chikou_span=>176.78, :kijun_sen=>177.6, :senkou_span_a=>187.95999999999998, :senkou_span_b=>198.935, :tenkan_sen=>177.68},
|
38
|
+
{:date_time=>"2018-12-04T00:00:00.000Z", :chikou_span=>176.98, :kijun_sen=>177.6, :senkou_span_a=>189.027375, :senkou_span_b=>199.87, :tenkan_sen=>180.60500000000002},
|
39
|
+
{:date_time=>"2018-12-03T00:00:00.000Z", :chikou_span=>185.86, :kijun_sen=>180.48, :senkou_span_a=>193.76737500000002, :senkou_span_b=>204.61, :tenkan_sen=>180.985},
|
40
|
+
{:date_time=>"2018-11-30T00:00:00.000Z", :chikou_span=>193.53, :kijun_sen=>182.61475000000002, :senkou_span_a=>194.237375, :senkou_span_b=>205.07999999999998, :tenkan_sen=>178.865},
|
41
|
+
{:date_time=>"2018-11-29T00:00:00.000Z", :chikou_span=>191.41, :kijun_sen=>182.61475000000002, :senkou_span_a=>195.6725, :senkou_span_b=>205.07999999999998, :tenkan_sen=>176.84},
|
42
|
+
{:date_time=>"2018-11-28T00:00:00.000Z", :chikou_span=>186.8, :kijun_sen=>182.61475000000002, :senkou_span_a=>198.51749999999998, :senkou_span_b=>205.07999999999998, :tenkan_sen=>175.77499999999998},
|
43
|
+
{:date_time=>"2018-11-27T00:00:00.000Z", :chikou_span=>192.23, :kijun_sen=>183.72, :senkou_span_a=>202.81755, :senkou_span_b=>207.84005, :tenkan_sen=>173.4275},
|
44
|
+
{:date_time=>"2018-11-26T00:00:00.000Z", :chikou_span=>194.17, :kijun_sen=>185.055, :senkou_span_a=>205.015, :senkou_span_b=>209.01, :tenkan_sen=>175.265},
|
45
|
+
{:date_time=>"2018-11-23T00:00:00.000Z", :chikou_span=>204.47, :kijun_sen=>189.055, :senkou_span_a=>208.225, :senkou_span_b=>211.2, :tenkan_sen=>176.785},
|
46
|
+
{:date_time=>"2018-11-21T00:00:00.000Z", :chikou_span=>208.49, :kijun_sen=>192.815, :senkou_span_a=>208.08499999999998, :senkou_span_b=>211.2, :tenkan_sen=>183.105},
|
47
|
+
{:date_time=>"2018-11-20T00:00:00.000Z", :chikou_span=>209.95, :kijun_sen=>192.815, :senkou_span_a=>207.19, :senkou_span_b=>211.2, :tenkan_sen=>185.23975000000002},
|
48
|
+
{:date_time=>"2018-11-19T00:00:00.000Z", :chikou_span=>203.77, :kijun_sen=>197.555, :senkou_span_a=>208.555, :senkou_span_b=>212.26, :tenkan_sen=>189.97975000000002},
|
49
|
+
{:date_time=>"2018-11-16T00:00:00.000Z", :chikou_span=>201.59, :kijun_sen=>198.025, :senkou_span_a=>210.7325, :senkou_span_b=>212.72, :tenkan_sen=>190.44975}
|
50
|
+
]
|
51
|
+
|
52
|
+
expect(normalized_output).to eq(expected_output)
|
53
|
+
end
|
54
|
+
|
55
|
+
it "Throws exception if not enough data" do
|
56
|
+
medium_period = 20
|
57
|
+
high_period = 40
|
58
|
+
size_limit = (medium_period + high_period + 1)
|
59
|
+
|
60
|
+
expect {indicator.calculate(input_data, high_period: size_limit)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
61
|
+
end
|
62
|
+
|
63
|
+
it 'Returns the symbol' do
|
64
|
+
indicator_symbol = indicator.indicator_symbol
|
65
|
+
expect(indicator_symbol).to eq('ichimoku')
|
66
|
+
end
|
67
|
+
|
68
|
+
it 'Returns the name' do
|
69
|
+
indicator_name = indicator.indicator_name
|
70
|
+
expect(indicator_name).to eq('Ichimoku Kinko Hyo')
|
71
|
+
end
|
72
|
+
|
73
|
+
it 'Returns the valid options' do
|
74
|
+
valid_options = indicator.valid_options
|
75
|
+
expect(valid_options).to eq(%i(low_period medium_period high_period))
|
76
|
+
end
|
77
|
+
|
78
|
+
it 'Validates options' do
|
79
|
+
valid_options = { low_period: 9, medium_period: 26, high_period: 52 }
|
80
|
+
options_validated = indicator.validate_options(valid_options)
|
81
|
+
expect(options_validated).to eq(true)
|
82
|
+
end
|
83
|
+
|
84
|
+
it 'Throws exception for invalid options' do
|
85
|
+
invalid_options = { test: 10 }
|
86
|
+
expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
|
87
|
+
end
|
88
|
+
|
89
|
+
it 'Calculates minimum data size' do
|
90
|
+
options = { medium_period: 4, high_period: 10 }
|
91
|
+
expect(indicator.min_data_size(options)).to eq(13)
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
end
|