technical-analysis 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (79) hide show
  1. checksums.yaml +7 -0
  2. data/lib/technical-analysis.rb +3 -0
  3. data/lib/technical_analysis.rb +41 -0
  4. data/lib/technical_analysis/helpers/array_helper.rb +27 -0
  5. data/lib/technical_analysis/helpers/stock_calculation.rb +25 -0
  6. data/lib/technical_analysis/helpers/validation.rb +33 -0
  7. data/lib/technical_analysis/indicators/adi.rb +101 -0
  8. data/lib/technical_analysis/indicators/adtv.rb +98 -0
  9. data/lib/technical_analysis/indicators/adx.rb +168 -0
  10. data/lib/technical_analysis/indicators/ao.rb +105 -0
  11. data/lib/technical_analysis/indicators/atr.rb +109 -0
  12. data/lib/technical_analysis/indicators/bb.rb +126 -0
  13. data/lib/technical_analysis/indicators/cci.rb +105 -0
  14. data/lib/technical_analysis/indicators/cmf.rb +105 -0
  15. data/lib/technical_analysis/indicators/cr.rb +95 -0
  16. data/lib/technical_analysis/indicators/dc.rb +108 -0
  17. data/lib/technical_analysis/indicators/dlr.rb +97 -0
  18. data/lib/technical_analysis/indicators/dpo.rb +106 -0
  19. data/lib/technical_analysis/indicators/dr.rb +96 -0
  20. data/lib/technical_analysis/indicators/eom.rb +104 -0
  21. data/lib/technical_analysis/indicators/fi.rb +95 -0
  22. data/lib/technical_analysis/indicators/ichimoku.rb +179 -0
  23. data/lib/technical_analysis/indicators/indicator.rb +138 -0
  24. data/lib/technical_analysis/indicators/kc.rb +124 -0
  25. data/lib/technical_analysis/indicators/kst.rb +132 -0
  26. data/lib/technical_analysis/indicators/macd.rb +144 -0
  27. data/lib/technical_analysis/indicators/mfi.rb +119 -0
  28. data/lib/technical_analysis/indicators/mi.rb +121 -0
  29. data/lib/technical_analysis/indicators/nvi.rb +102 -0
  30. data/lib/technical_analysis/indicators/obv.rb +104 -0
  31. data/lib/technical_analysis/indicators/obv_mean.rb +110 -0
  32. data/lib/technical_analysis/indicators/rsi.rb +133 -0
  33. data/lib/technical_analysis/indicators/sma.rb +98 -0
  34. data/lib/technical_analysis/indicators/sr.rb +122 -0
  35. data/lib/technical_analysis/indicators/trix.rb +127 -0
  36. data/lib/technical_analysis/indicators/tsi.rb +139 -0
  37. data/lib/technical_analysis/indicators/uo.rb +130 -0
  38. data/lib/technical_analysis/indicators/vi.rb +117 -0
  39. data/lib/technical_analysis/indicators/vpt.rb +95 -0
  40. data/lib/technical_analysis/indicators/wr.rb +103 -0
  41. data/spec/helpers/array_helper_spec.rb +31 -0
  42. data/spec/helpers/validaton_spec.rb +22 -0
  43. data/spec/spec_helper.rb +26 -0
  44. data/spec/ta_test_data.csv +64 -0
  45. data/spec/technical_analysis/indicators/adi_spec.rb +116 -0
  46. data/spec/technical_analysis/indicators/adtv_spec.rb +98 -0
  47. data/spec/technical_analysis/indicators/adx_spec.rb +92 -0
  48. data/spec/technical_analysis/indicators/ao_spec.rb +86 -0
  49. data/spec/technical_analysis/indicators/atr_spec.rb +105 -0
  50. data/spec/technical_analysis/indicators/bb_spec.rb +100 -0
  51. data/spec/technical_analysis/indicators/cci_spec.rb +100 -0
  52. data/spec/technical_analysis/indicators/cmf_spec.rb +100 -0
  53. data/spec/technical_analysis/indicators/cr_spec.rb +119 -0
  54. data/spec/technical_analysis/indicators/dc_spec.rb +100 -0
  55. data/spec/technical_analysis/indicators/dlr_spec.rb +119 -0
  56. data/spec/technical_analysis/indicators/dpo_spec.rb +90 -0
  57. data/spec/technical_analysis/indicators/dr_spec.rb +119 -0
  58. data/spec/technical_analysis/indicators/eom_spec.rb +105 -0
  59. data/spec/technical_analysis/indicators/fi_spec.rb +118 -0
  60. data/spec/technical_analysis/indicators/ichimoku_spec.rb +95 -0
  61. data/spec/technical_analysis/indicators/indicator_spec.rb +120 -0
  62. data/spec/technical_analysis/indicators/kc_spec.rb +110 -0
  63. data/spec/technical_analysis/indicators/kst_spec.rb +78 -0
  64. data/spec/technical_analysis/indicators/macd_spec.rb +86 -0
  65. data/spec/technical_analysis/indicators/mfi_spec.rb +105 -0
  66. data/spec/technical_analysis/indicators/mi_spec.rb +79 -0
  67. data/spec/technical_analysis/indicators/nvi_spec.rb +119 -0
  68. data/spec/technical_analysis/indicators/obv_mean_spec.rb +109 -0
  69. data/spec/technical_analysis/indicators/obv_spec.rb +119 -0
  70. data/spec/technical_analysis/indicators/rsi_spec.rb +105 -0
  71. data/spec/technical_analysis/indicators/sma_spec.rb +115 -0
  72. data/spec/technical_analysis/indicators/sr_spec.rb +104 -0
  73. data/spec/technical_analysis/indicators/trix_spec.rb +76 -0
  74. data/spec/technical_analysis/indicators/tsi_spec.rb +87 -0
  75. data/spec/technical_analysis/indicators/uo_spec.rb +91 -0
  76. data/spec/technical_analysis/indicators/vi_spec.rb +105 -0
  77. data/spec/technical_analysis/indicators/vpt_spec.rb +118 -0
  78. data/spec/technical_analysis/indicators/wr_spec.rb +106 -0
  79. metadata +177 -0
@@ -0,0 +1,105 @@
1
+ require 'technical-analysis'
2
+ require 'spec_helper'
3
+
4
+ describe 'Indicators' do
5
+ describe "VI" do
6
+ input_data = SpecHelper.get_test_data(:high, :low, :close)
7
+ indicator = TechnicalAnalysis::Vi
8
+
9
+ describe 'Vortex Indicator' do
10
+ it 'Calculates VI (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", :negative_vi=>0.9777149447928525, :positive_vi=>0.8609629970246735},
16
+ {:date_time=>"2019-01-08T00:00:00.000Z", :negative_vi=>1.0113586362578701, :positive_vi=>0.8600571901821686},
17
+ {:date_time=>"2019-01-07T00:00:00.000Z", :negative_vi=>1.0577860164333046, :positive_vi=>0.813115261460082},
18
+ {:date_time=>"2019-01-04T00:00:00.000Z", :negative_vi=>1.0760915145470467, :positive_vi=>0.7417758715458455},
19
+ {:date_time=>"2019-01-03T00:00:00.000Z", :negative_vi=>1.114675915889877, :positive_vi=>0.7324951224799482},
20
+ {:date_time=>"2019-01-02T00:00:00.000Z", :negative_vi=>1.1146552806731134, :positive_vi=>0.8035916112018086},
21
+ {:date_time=>"2018-12-31T00:00:00.000Z", :negative_vi=>1.08671679197995, :positive_vi=>0.8781954887218045},
22
+ {:date_time=>"2018-12-28T00:00:00.000Z", :negative_vi=>1.1487474529545731, :positive_vi=>0.8037876063766033},
23
+ {:date_time=>"2018-12-27T00:00:00.000Z", :negative_vi=>1.1655798789007923, :positive_vi=>0.729855612482534},
24
+ {:date_time=>"2018-12-26T00:00:00.000Z", :negative_vi=>1.2335085243974138, :positive_vi=>0.636331569664903},
25
+ {:date_time=>"2018-12-24T00:00:00.000Z", :negative_vi=>1.3088205560235893, :positive_vi=>0.5374882657359492},
26
+ {:date_time=>"2018-12-21T00:00:00.000Z", :negative_vi=>1.1606095395904847, :positive_vi=>0.5994780447390226},
27
+ {:date_time=>"2018-12-20T00:00:00.000Z", :negative_vi=>1.1525346959374216, :positive_vi=>0.6361329800656076},
28
+ {:date_time=>"2018-12-19T00:00:00.000Z", :negative_vi=>1.067568020631851, :positive_vi=>0.7127001934235981},
29
+ {:date_time=>"2018-12-18T00:00:00.000Z", :negative_vi=>0.9773071878279123, :positive_vi=>0.8213523084994758},
30
+ {:date_time=>"2018-12-17T00:00:00.000Z", :negative_vi=>0.974913770577476, :positive_vi=>0.814344133786256},
31
+ {:date_time=>"2018-12-14T00:00:00.000Z", :negative_vi=>0.9867067848168232, :positive_vi=>0.8214508662875287},
32
+ {:date_time=>"2018-12-13T00:00:00.000Z", :negative_vi=>1.011590726346824, :positive_vi=>0.8266537121415173},
33
+ {:date_time=>"2018-12-12T00:00:00.000Z", :negative_vi=>1.0422719380259118, :positive_vi=>0.8400547615867511},
34
+ {:date_time=>"2018-12-11T00:00:00.000Z", :negative_vi=>1.1040510191627, :positive_vi=>0.7505785426583675},
35
+ {:date_time=>"2018-12-10T00:00:00.000Z", :negative_vi=>1.136139122315593, :positive_vi=>0.6334605508870221},
36
+ {:date_time=>"2018-12-07T00:00:00.000Z", :negative_vi=>1.050514334444714, :positive_vi=>0.7172185077490695},
37
+ {:date_time=>"2018-12-06T00:00:00.000Z", :negative_vi=>1.0795256042654737, :positive_vi=>0.7516804020221332},
38
+ {:date_time=>"2018-12-04T00:00:00.000Z", :negative_vi=>1.0423007389465182, :positive_vi=>0.7496451535522679},
39
+ {:date_time=>"2018-12-03T00:00:00.000Z", :negative_vi=>1.0746012192731307, :positive_vi=>0.8019709726837323},
40
+ {:date_time=>"2018-11-30T00:00:00.000Z", :negative_vi=>1.1516224812958684, :positive_vi=>0.6987674707967169},
41
+ {:date_time=>"2018-11-29T00:00:00.000Z", :negative_vi=>1.1373201600900555, :positive_vi=>0.6548920237509929},
42
+ {:date_time=>"2018-11-28T00:00:00.000Z", :negative_vi=>1.1564601777941095, :positive_vi=>0.6464192792510783},
43
+ {:date_time=>"2018-11-27T00:00:00.000Z", :negative_vi=>1.1714346511931206, :positive_vi=>0.6287012609627801},
44
+ {:date_time=>"2018-11-26T00:00:00.000Z", :negative_vi=>1.1658984366885399, :positive_vi=>0.65775873808705},
45
+ {:date_time=>"2018-11-23T00:00:00.000Z", :negative_vi=>1.2070792620527797, :positive_vi=>0.6046320015251558},
46
+ {:date_time=>"2018-11-21T00:00:00.000Z", :negative_vi=>1.1504168141815485, :positive_vi=>0.5639363354788292},
47
+ {:date_time=>"2018-11-20T00:00:00.000Z", :negative_vi=>1.1182403853648055, :positive_vi=>0.5634420498548615},
48
+ {:date_time=>"2018-11-19T00:00:00.000Z", :negative_vi=>1.018527704309603, :positive_vi=>0.6562081533662589},
49
+ {:date_time=>"2018-11-16T00:00:00.000Z", :negative_vi=>1.0499147710692558, :positive_vi=>0.7525644147579889},
50
+ {:date_time=>"2018-11-15T00:00:00.000Z", :negative_vi=>1.0787197159390678, :positive_vi=>0.6861446786495575},
51
+ {:date_time=>"2018-11-14T00:00:00.000Z", :negative_vi=>1.0659261208578774, :positive_vi=>0.6477869675714517},
52
+ {:date_time=>"2018-11-13T00:00:00.000Z", :negative_vi=>1.053272641569953, :positive_vi=>0.6968210271671884},
53
+ {:date_time=>"2018-11-12T00:00:00.000Z", :negative_vi=>1.0186513629842182, :positive_vi=>0.7271341463414641},
54
+ {:date_time=>"2018-11-09T00:00:00.000Z", :negative_vi=>1.0059420422342082, :positive_vi=>0.7587530852911607},
55
+ {:date_time=>"2018-11-08T00:00:00.000Z", :negative_vi=>0.9713674816398625, :positive_vi=>0.8198382448638102},
56
+ {:date_time=>"2018-11-07T00:00:00.000Z", :negative_vi=>0.9456323099415208, :positive_vi=>0.8265716374269011},
57
+ {:date_time=>"2018-11-06T00:00:00.000Z", :negative_vi=>1.0107777977366625, :positive_vi=>0.7408837794144069},
58
+ {:date_time=>"2018-11-05T00:00:00.000Z", :negative_vi=>1.017756255044391, :positive_vi=>0.73372163931486},
59
+ {:date_time=>"2018-11-02T00:00:00.000Z", :negative_vi=>0.9506581829483907, :positive_vi=>0.7977446639361122},
60
+ {:date_time=>"2018-11-01T00:00:00.000Z", :negative_vi=>0.9510765744895432, :positive_vi=>0.9155241699342749},
61
+ {:date_time=>"2018-10-31T00:00:00.000Z", :negative_vi=>0.9136449963918103, :positive_vi=>0.9374983015842824},
62
+ {:date_time=>"2018-10-30T00:00:00.000Z", :negative_vi=>1.0400453579079016, :positive_vi=>0.8594387814137219},
63
+ {:date_time=>"2018-10-29T00:00:00.000Z", :negative_vi=>0.9987535631315481, :positive_vi=>0.7711714493088508}
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+1)}.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('vi')
76
+ end
77
+
78
+ it 'Returns the name' do
79
+ indicator_name = indicator.indicator_name
80
+ expect(indicator_name).to eq('Vortex Indicator')
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 "VPT" do
6
+ input_data = SpecHelper.get_test_data(:close, :volume)
7
+ indicator = TechnicalAnalysis::Vpt
8
+
9
+ describe 'Volume-Price Trend' do
10
+ it 'Calculates VPT' 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", :vpt=>-27383899.78109331},
16
+ {:date_time=>"2019-01-08T00:00:00.000Z", :vpt=>-28148662.548589166},
17
+ {:date_time=>"2019-01-07T00:00:00.000Z", :vpt=>-28923059.940598898},
18
+ {:date_time=>"2019-01-04T00:00:00.000Z", :vpt=>-28801593.76496151},
19
+ {:date_time=>"2019-01-03T00:00:00.000Z", :vpt=>-31252972.592586517},
20
+ {:date_time=>"2019-01-02T00:00:00.000Z", :vpt=>-22178057.48873647},
21
+ {:date_time=>"2018-12-31T00:00:00.000Z", :vpt=>-22218723.601326805},
22
+ {:date_time=>"2018-12-28T00:00:00.000Z", :vpt=>-22552168.387219403},
23
+ {:date_time=>"2018-12-27T00:00:00.000Z", :vpt=>-22573553.26073845},
24
+ {:date_time=>"2018-12-26T00:00:00.000Z", :vpt=>-22238622.758734256},
25
+ {:date_time=>"2018-12-24T00:00:00.000Z", :vpt=>-26332500.093066465},
26
+ {:date_time=>"2018-12-21T00:00:00.000Z", :vpt=>-25370780.481841102},
27
+ {:date_time=>"2018-12-20T00:00:00.000Z", :vpt=>-21656330.504158247},
28
+ {:date_time=>"2018-12-19T00:00:00.000Z", :vpt=>-20031264.8456338},
29
+ {:date_time=>"2018-12-18T00:00:00.000Z", :vpt=>-18546614.21276814},
30
+ {:date_time=>"2018-12-17T00:00:00.000Z", :vpt=>-18985158.397835847},
31
+ {:date_time=>"2018-12-14T00:00:00.000Z", :vpt=>-18582658.71932485},
32
+ {:date_time=>"2018-12-13T00:00:00.000Z", :vpt=>-17282902.245502096},
33
+ {:date_time=>"2018-12-12T00:00:00.000Z", :vpt=>-17630301.940948576},
34
+ {:date_time=>"2018-12-11T00:00:00.000Z", :vpt=>-17729175.804436687},
35
+ {:date_time=>"2018-12-10T00:00:00.000Z", :vpt=>-17466268.97188952},
36
+ {:date_time=>"2018-12-07T00:00:00.000Z", :vpt=>-17873132.82137613},
37
+ {:date_time=>"2018-12-06T00:00:00.000Z", :vpt=>-16386993.991247926},
38
+ {:date_time=>"2018-12-04T00:00:00.000Z", :vpt=>-15910856.843135413},
39
+ {:date_time=>"2018-12-03T00:00:00.000Z", :vpt=>-14101104.854714246},
40
+ {:date_time=>"2018-11-30T00:00:00.000Z", :vpt=>-15517586.252407152},
41
+ {:date_time=>"2018-11-29T00:00:00.000Z", :vpt=>-15304600.832189944},
42
+ {:date_time=>"2018-11-28T00:00:00.000Z", :vpt=>-14985612.348714761},
43
+ {:date_time=>"2018-11-27T00:00:00.000Z", :vpt=>-16752197.088154612},
44
+ {:date_time=>"2018-11-26T00:00:00.000Z", :vpt=>-16662634.99217477},
45
+ {:date_time=>"2018-11-23T00:00:00.000Z", :vpt=>-17266635.256844807},
46
+ {:date_time=>"2018-11-21T00:00:00.000Z", :vpt=>-16666614.749434467},
47
+ {:date_time=>"2018-11-20T00:00:00.000Z", :vpt=>-16631473.78435367},
48
+ {:date_time=>"2018-11-19T00:00:00.000Z", :vpt=>-13397928.75906581},
49
+ {:date_time=>"2018-11-16T00:00:00.000Z", :vpt=>-11748170.533467716},
50
+ {:date_time=>"2018-11-15T00:00:00.000Z", :vpt=>-12149014.896876106},
51
+ {:date_time=>"2018-11-14T00:00:00.000Z", :vpt=>-13290943.979317216},
52
+ {:date_time=>"2018-11-13T00:00:00.000Z", :vpt=>-11580638.32359231},
53
+ {:date_time=>"2018-11-12T00:00:00.000Z", :vpt=>-11113790.317206156},
54
+ {:date_time=>"2018-11-09T00:00:00.000Z", :vpt=>-8545161.134440955},
55
+ {:date_time=>"2018-11-08T00:00:00.000Z", :vpt=>-7883463.234301859},
56
+ {:date_time=>"2018-11-07T00:00:00.000Z", :vpt=>-7707600.723227796},
57
+ {:date_time=>"2018-11-06T00:00:00.000Z", :vpt=>-8717279.945880784},
58
+ {:date_time=>"2018-11-05T00:00:00.000Z", :vpt=>-9060892.67270255},
59
+ {:date_time=>"2018-11-02T00:00:00.000Z", :vpt=>-7185217.517024899},
60
+ {:date_time=>"2018-11-01T00:00:00.000Z", :vpt=>-1146038.8004377298},
61
+ {:date_time=>"2018-10-31T00:00:00.000Z", :vpt=>-1959004.510023763},
62
+ {:date_time=>"2018-10-30T00:00:00.000Z", :vpt=>-2949972.4593908517},
63
+ {:date_time=>"2018-10-29T00:00:00.000Z", :vpt=>-3132205.8074873467},
64
+ {:date_time=>"2018-10-26T00:00:00.000Z", :vpt=>-2274149.490335243},
65
+ {:date_time=>"2018-10-25T00:00:00.000Z", :vpt=>-1522689.2992524402},
66
+ {:date_time=>"2018-10-24T00:00:00.000Z", :vpt=>-2158324.481734193},
67
+ {:date_time=>"2018-10-23T00:00:00.000Z", :vpt=>-786529.9466468699},
68
+ {:date_time=>"2018-10-22T00:00:00.000Z", :vpt=>-1151165.4943468445},
69
+ {:date_time=>"2018-10-19T00:00:00.000Z", :vpt=>-1326839.4882367724},
70
+ {:date_time=>"2018-10-18T00:00:00.000Z", :vpt=>-1827517.8777377433},
71
+ {:date_time=>"2018-10-17T00:00:00.000Z", :vpt=>-1070464.7668376141},
72
+ {:date_time=>"2018-10-16T00:00:00.000Z", :vpt=>-972399.6540759658},
73
+ {:date_time=>"2018-10-15T00:00:00.000Z", :vpt=>-1607126.441433344},
74
+ {:date_time=>"2018-10-12T00:00:00.000Z", :vpt=>-959554.7990039173},
75
+ {:date_time=>"2018-10-11T00:00:00.000Z", :vpt=>-2370279.621573285},
76
+ {:date_time=>"2018-10-10T00:00:00.000Z", :vpt=>-1903264.3174505206}
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('vpt')
89
+ end
90
+
91
+ it 'Returns the name' do
92
+ indicator_name = indicator.indicator_name
93
+ expect(indicator_name).to eq('Volume-price Trend')
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,106 @@
1
+ require 'technical-analysis'
2
+ require 'spec_helper'
3
+
4
+ describe 'Indicators' do
5
+ describe "WR" do
6
+ input_data = SpecHelper.get_test_data(:high, :low, :close)
7
+ indicator = TechnicalAnalysis::Wr
8
+
9
+ describe 'Williams %R' do
10
+ it 'Calculates Williams %R' 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", :wr=>-55.55992141453828},
16
+ {:date_time=>"2019-01-08T00:00:00.000Z", :wr=>-65.72659616137877},
17
+ {:date_time=>"2019-01-07T00:00:00.000Z", :wr=>-77.4952561669829},
18
+ {:date_time=>"2019-01-04T00:00:00.000Z", :wr=>-76.88330871491881},
19
+ {:date_time=>"2019-01-03T00:00:00.000Z", :wr=>-99.37847562970234},
20
+ {:date_time=>"2019-01-02T00:00:00.000Z", :wr=>-56.38953040800621},
21
+ {:date_time=>"2018-12-31T00:00:00.000Z", :wr=>-57.082371054657386},
22
+ {:date_time=>"2018-12-28T00:00:00.000Z", :wr=>-62.8945342571209},
23
+ {:date_time=>"2018-12-27T00:00:00.000Z", :wr=>-65.7347670250896},
24
+ {:date_time=>"2018-12-26T00:00:00.000Z", :wr=>-62.468960624334926},
25
+ {:date_time=>"2018-12-24T00:00:00.000Z", :wr=>-99.32960706594149},
26
+ {:date_time=>"2018-12-21T00:00:00.000Z", :wr=>-96.88473520249222},
27
+ {:date_time=>"2018-12-20T00:00:00.000Z", :wr=>-94.83805668016194},
28
+ {:date_time=>"2018-12-19T00:00:00.000Z", :wr=>-93.03675048355906},
29
+ {:date_time=>"2018-12-18T00:00:00.000Z", :wr=>-84.961728950923},
30
+ {:date_time=>"2018-12-17T00:00:00.000Z", :wr=>-94.55200360198106},
31
+ {:date_time=>"2018-12-14T00:00:00.000Z", :wr=>-90.0509023600186},
32
+ {:date_time=>"2018-12-13T00:00:00.000Z", :wr=>-64.73854696899592},
33
+ {:date_time=>"2018-12-12T00:00:00.000Z", :wr=>-73.29939842665439},
34
+ {:date_time=>"2018-12-11T00:00:00.000Z", :wr=>-75.47431744562708},
35
+ {:date_time=>"2018-12-10T00:00:00.000Z", :wr=>-77.09170624771653},
36
+ {:date_time=>"2018-12-07T00:00:00.000Z", :wr=>-99.28757569508241},
37
+ {:date_time=>"2018-12-06T00:00:00.000Z", :wr=>-81.95026204496244},
38
+ {:date_time=>"2018-12-04T00:00:00.000Z", :wr=>-73.97761994374633},
39
+ {:date_time=>"2018-12-03T00:00:00.000Z", :wr=>-45.9138187221397},
40
+ {:date_time=>"2018-11-30T00:00:00.000Z", :wr=>-71.8823927002365},
41
+ {:date_time=>"2018-11-29T00:00:00.000Z", :wr=>-74.01398601398596},
42
+ {:date_time=>"2018-11-28T00:00:00.000Z", :wr=>-73.20622177621675},
43
+ {:date_time=>"2018-11-27T00:00:00.000Z", :wr=>-90.01505268439534},
44
+ {:date_time=>"2018-11-26T00:00:00.000Z", :wr=>-89.06171600602104},
45
+ {:date_time=>"2018-11-23T00:00:00.000Z", :wr=>-99.50026301946345},
46
+ {:date_time=>"2018-11-21T00:00:00.000Z", :wr=>-96.67016255899316},
47
+ {:date_time=>"2018-11-20T00:00:00.000Z", :wr=>-96.8623265741729},
48
+ {:date_time=>"2018-11-19T00:00:00.000Z", :wr=>-97.67192935509766},
49
+ {:date_time=>"2018-11-16T00:00:00.000Z", :wr=>-79.13807301674446},
50
+ {:date_time=>"2018-11-15T00:00:00.000Z", :wr=>-84.95745264891575},
51
+ {:date_time=>"2018-11-14T00:00:00.000Z", :wr=>-97.61185835849572},
52
+ {:date_time=>"2018-11-13T00:00:00.000Z", :wr=>-97.47686016454276},
53
+ {:date_time=>"2018-11-12T00:00:00.000Z", :wr=>-98.75164257555849},
54
+ {:date_time=>"2018-11-09T00:00:00.000Z", :wr=>-75.82501918649267},
55
+ {:date_time=>"2018-11-08T00:00:00.000Z", :wr=>-60.39907904834988},
56
+ {:date_time=>"2018-11-07T00:00:00.000Z", :wr=>-54.79662317728319},
57
+ {:date_time=>"2018-11-06T00:00:00.000Z", :wr=>-78.51112816577121},
58
+ {:date_time=>"2018-11-05T00:00:00.000Z", :wr=>-86.87643898695312},
59
+ {:date_time=>"2018-11-02T00:00:00.000Z", :wr=>-89.09574468085114},
60
+ {:date_time=>"2018-11-01T00:00:00.000Z", :wr=>-11.080485115766221},
61
+ {:date_time=>"2018-10-31T00:00:00.000Z", :wr=>-29.60308710033065},
62
+ {:date_time=>"2018-10-30T00:00:00.000Z", :wr=>-60.253583241455274},
63
+ {:date_time=>"2018-10-29T00:00:00.000Z", :wr=>-69.64461994076994},
64
+ {:date_time=>"2018-10-26T00:00:00.000Z", :wr=>-73.3779264214046}
65
+ ]
66
+
67
+ expect(normalized_output).to eq(expected_output)
68
+ end
69
+
70
+ it "Throws exception if not enough data" do
71
+ expect {indicator.calculate(input_data, period: input_data.size+1)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
72
+ end
73
+
74
+ it 'Returns the symbol' do
75
+ indicator_symbol = indicator.indicator_symbol
76
+ expect(indicator_symbol).to eq('wr')
77
+ end
78
+
79
+ it 'Returns the name' do
80
+ indicator_name = indicator.indicator_name
81
+ expect(indicator_name).to eq('Williams %R')
82
+ end
83
+
84
+ it 'Returns the valid options' do
85
+ valid_options = indicator.valid_options
86
+ expect(valid_options).to eq(%i(period))
87
+ end
88
+
89
+ it 'Validates options' do
90
+ valid_options = { period: 22 }
91
+ options_validated = indicator.validate_options(valid_options)
92
+ expect(options_validated).to eq(true)
93
+ end
94
+
95
+ it 'Throws exception for invalid options' do
96
+ invalid_options = { test: 10 }
97
+ expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
98
+ end
99
+
100
+ it 'Calculates minimum data size' do
101
+ options = { period: 4 }
102
+ expect(indicator.min_data_size(options)).to eq(4)
103
+ end
104
+ end
105
+ end
106
+ end
metadata ADDED
@@ -0,0 +1,177 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: technical-analysis
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Intrinio
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2019-03-06 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: bundler
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - "~>"
18
+ - !ruby/object:Gem::Version
19
+ version: '1.16'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - "~>"
25
+ - !ruby/object:Gem::Version
26
+ version: '1.16'
27
+ - !ruby/object:Gem::Dependency
28
+ name: rake
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - "~>"
32
+ - !ruby/object:Gem::Version
33
+ version: '10.0'
34
+ type: :development
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - "~>"
39
+ - !ruby/object:Gem::Version
40
+ version: '10.0'
41
+ - !ruby/object:Gem::Dependency
42
+ name: rspec
43
+ requirement: !ruby/object:Gem::Requirement
44
+ requirements:
45
+ - - "~>"
46
+ - !ruby/object:Gem::Version
47
+ version: '3.0'
48
+ type: :development
49
+ prerelease: false
50
+ version_requirements: !ruby/object:Gem::Requirement
51
+ requirements:
52
+ - - "~>"
53
+ - !ruby/object:Gem::Version
54
+ version: '3.0'
55
+ - !ruby/object:Gem::Dependency
56
+ name: yard
57
+ requirement: !ruby/object:Gem::Requirement
58
+ requirements:
59
+ - - "~>"
60
+ - !ruby/object:Gem::Version
61
+ version: 0.9.6
62
+ type: :development
63
+ prerelease: false
64
+ version_requirements: !ruby/object:Gem::Requirement
65
+ requirements:
66
+ - - "~>"
67
+ - !ruby/object:Gem::Version
68
+ version: 0.9.6
69
+ description: Intrinio Technical Analysis
70
+ email:
71
+ - admin@intrinio.com
72
+ executables: []
73
+ extensions: []
74
+ extra_rdoc_files: []
75
+ files:
76
+ - lib/technical-analysis.rb
77
+ - lib/technical_analysis.rb
78
+ - lib/technical_analysis/helpers/array_helper.rb
79
+ - lib/technical_analysis/helpers/stock_calculation.rb
80
+ - lib/technical_analysis/helpers/validation.rb
81
+ - lib/technical_analysis/indicators/adi.rb
82
+ - lib/technical_analysis/indicators/adtv.rb
83
+ - lib/technical_analysis/indicators/adx.rb
84
+ - lib/technical_analysis/indicators/ao.rb
85
+ - lib/technical_analysis/indicators/atr.rb
86
+ - lib/technical_analysis/indicators/bb.rb
87
+ - lib/technical_analysis/indicators/cci.rb
88
+ - lib/technical_analysis/indicators/cmf.rb
89
+ - lib/technical_analysis/indicators/cr.rb
90
+ - lib/technical_analysis/indicators/dc.rb
91
+ - lib/technical_analysis/indicators/dlr.rb
92
+ - lib/technical_analysis/indicators/dpo.rb
93
+ - lib/technical_analysis/indicators/dr.rb
94
+ - lib/technical_analysis/indicators/eom.rb
95
+ - lib/technical_analysis/indicators/fi.rb
96
+ - lib/technical_analysis/indicators/ichimoku.rb
97
+ - lib/technical_analysis/indicators/indicator.rb
98
+ - lib/technical_analysis/indicators/kc.rb
99
+ - lib/technical_analysis/indicators/kst.rb
100
+ - lib/technical_analysis/indicators/macd.rb
101
+ - lib/technical_analysis/indicators/mfi.rb
102
+ - lib/technical_analysis/indicators/mi.rb
103
+ - lib/technical_analysis/indicators/nvi.rb
104
+ - lib/technical_analysis/indicators/obv.rb
105
+ - lib/technical_analysis/indicators/obv_mean.rb
106
+ - lib/technical_analysis/indicators/rsi.rb
107
+ - lib/technical_analysis/indicators/sma.rb
108
+ - lib/technical_analysis/indicators/sr.rb
109
+ - lib/technical_analysis/indicators/trix.rb
110
+ - lib/technical_analysis/indicators/tsi.rb
111
+ - lib/technical_analysis/indicators/uo.rb
112
+ - lib/technical_analysis/indicators/vi.rb
113
+ - lib/technical_analysis/indicators/vpt.rb
114
+ - lib/technical_analysis/indicators/wr.rb
115
+ - spec/helpers/array_helper_spec.rb
116
+ - spec/helpers/validaton_spec.rb
117
+ - spec/spec_helper.rb
118
+ - spec/ta_test_data.csv
119
+ - spec/technical_analysis/indicators/adi_spec.rb
120
+ - spec/technical_analysis/indicators/adtv_spec.rb
121
+ - spec/technical_analysis/indicators/adx_spec.rb
122
+ - spec/technical_analysis/indicators/ao_spec.rb
123
+ - spec/technical_analysis/indicators/atr_spec.rb
124
+ - spec/technical_analysis/indicators/bb_spec.rb
125
+ - spec/technical_analysis/indicators/cci_spec.rb
126
+ - spec/technical_analysis/indicators/cmf_spec.rb
127
+ - spec/technical_analysis/indicators/cr_spec.rb
128
+ - spec/technical_analysis/indicators/dc_spec.rb
129
+ - spec/technical_analysis/indicators/dlr_spec.rb
130
+ - spec/technical_analysis/indicators/dpo_spec.rb
131
+ - spec/technical_analysis/indicators/dr_spec.rb
132
+ - spec/technical_analysis/indicators/eom_spec.rb
133
+ - spec/technical_analysis/indicators/fi_spec.rb
134
+ - spec/technical_analysis/indicators/ichimoku_spec.rb
135
+ - spec/technical_analysis/indicators/indicator_spec.rb
136
+ - spec/technical_analysis/indicators/kc_spec.rb
137
+ - spec/technical_analysis/indicators/kst_spec.rb
138
+ - spec/technical_analysis/indicators/macd_spec.rb
139
+ - spec/technical_analysis/indicators/mfi_spec.rb
140
+ - spec/technical_analysis/indicators/mi_spec.rb
141
+ - spec/technical_analysis/indicators/nvi_spec.rb
142
+ - spec/technical_analysis/indicators/obv_mean_spec.rb
143
+ - spec/technical_analysis/indicators/obv_spec.rb
144
+ - spec/technical_analysis/indicators/rsi_spec.rb
145
+ - spec/technical_analysis/indicators/sma_spec.rb
146
+ - spec/technical_analysis/indicators/sr_spec.rb
147
+ - spec/technical_analysis/indicators/trix_spec.rb
148
+ - spec/technical_analysis/indicators/tsi_spec.rb
149
+ - spec/technical_analysis/indicators/uo_spec.rb
150
+ - spec/technical_analysis/indicators/vi_spec.rb
151
+ - spec/technical_analysis/indicators/vpt_spec.rb
152
+ - spec/technical_analysis/indicators/wr_spec.rb
153
+ homepage: https://github.com/intrinio/technical-analysis
154
+ licenses: []
155
+ metadata:
156
+ allowed_push_host: https://rubygems.org
157
+ post_install_message:
158
+ rdoc_options: []
159
+ require_paths:
160
+ - lib
161
+ required_ruby_version: !ruby/object:Gem::Requirement
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ version: '0'
166
+ required_rubygems_version: !ruby/object:Gem::Requirement
167
+ requirements:
168
+ - - ">="
169
+ - !ruby/object:Gem::Version
170
+ version: '0'
171
+ requirements: []
172
+ rubyforge_project:
173
+ rubygems_version: 2.5.2.2
174
+ signing_key:
175
+ specification_version: 4
176
+ summary: Intrinio Technical Analysis
177
+ test_files: []