technical-analysis 0.2.0 → 0.2.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (83) hide show
  1. checksums.yaml +4 -4
  2. data/lib/technical-analysis.rb +0 -0
  3. data/lib/technical_analysis.rb +1 -0
  4. data/lib/technical_analysis/helpers/array_helper.rb +0 -0
  5. data/lib/technical_analysis/helpers/stock_calculation.rb +0 -0
  6. data/lib/technical_analysis/helpers/validation.rb +0 -0
  7. data/lib/technical_analysis/indicators/adi.rb +0 -0
  8. data/lib/technical_analysis/indicators/adtv.rb +0 -0
  9. data/lib/technical_analysis/indicators/adx.rb +0 -0
  10. data/lib/technical_analysis/indicators/ao.rb +0 -0
  11. data/lib/technical_analysis/indicators/atr.rb +0 -0
  12. data/lib/technical_analysis/indicators/bb.rb +0 -0
  13. data/lib/technical_analysis/indicators/cci.rb +0 -0
  14. data/lib/technical_analysis/indicators/cmf.rb +0 -0
  15. data/lib/technical_analysis/indicators/cr.rb +0 -0
  16. data/lib/technical_analysis/indicators/dc.rb +0 -0
  17. data/lib/technical_analysis/indicators/dlr.rb +0 -0
  18. data/lib/technical_analysis/indicators/dpo.rb +0 -0
  19. data/lib/technical_analysis/indicators/dr.rb +0 -0
  20. data/lib/technical_analysis/indicators/ema.rb +101 -0
  21. data/lib/technical_analysis/indicators/eom.rb +0 -0
  22. data/lib/technical_analysis/indicators/fi.rb +0 -0
  23. data/lib/technical_analysis/indicators/ichimoku.rb +0 -0
  24. data/lib/technical_analysis/indicators/indicator.rb +0 -0
  25. data/lib/technical_analysis/indicators/kc.rb +0 -0
  26. data/lib/technical_analysis/indicators/kst.rb +0 -0
  27. data/lib/technical_analysis/indicators/macd.rb +0 -0
  28. data/lib/technical_analysis/indicators/mfi.rb +0 -0
  29. data/lib/technical_analysis/indicators/mi.rb +0 -0
  30. data/lib/technical_analysis/indicators/nvi.rb +0 -0
  31. data/lib/technical_analysis/indicators/obv.rb +0 -0
  32. data/lib/technical_analysis/indicators/obv_mean.rb +0 -0
  33. data/lib/technical_analysis/indicators/rsi.rb +0 -0
  34. data/lib/technical_analysis/indicators/sma.rb +0 -0
  35. data/lib/technical_analysis/indicators/sr.rb +0 -0
  36. data/lib/technical_analysis/indicators/trix.rb +0 -0
  37. data/lib/technical_analysis/indicators/tsi.rb +0 -0
  38. data/lib/technical_analysis/indicators/uo.rb +0 -0
  39. data/lib/technical_analysis/indicators/vi.rb +0 -0
  40. data/lib/technical_analysis/indicators/vpt.rb +0 -0
  41. data/lib/technical_analysis/indicators/vwap.rb +0 -0
  42. data/lib/technical_analysis/indicators/wr.rb +0 -0
  43. data/spec/helpers/array_helper_spec.rb +0 -0
  44. data/spec/helpers/validaton_spec.rb +0 -0
  45. data/spec/spec_helper.rb +0 -0
  46. data/spec/ta_test_data.csv +0 -0
  47. data/spec/technical_analysis/indicators/adi_spec.rb +0 -0
  48. data/spec/technical_analysis/indicators/adtv_spec.rb +0 -0
  49. data/spec/technical_analysis/indicators/adx_spec.rb +0 -0
  50. data/spec/technical_analysis/indicators/ao_spec.rb +0 -0
  51. data/spec/technical_analysis/indicators/atr_spec.rb +0 -0
  52. data/spec/technical_analysis/indicators/bb_spec.rb +0 -0
  53. data/spec/technical_analysis/indicators/cci_spec.rb +0 -0
  54. data/spec/technical_analysis/indicators/cmf_spec.rb +0 -0
  55. data/spec/technical_analysis/indicators/cr_spec.rb +0 -0
  56. data/spec/technical_analysis/indicators/dc_spec.rb +0 -0
  57. data/spec/technical_analysis/indicators/dlr_spec.rb +0 -0
  58. data/spec/technical_analysis/indicators/dpo_spec.rb +0 -0
  59. data/spec/technical_analysis/indicators/dr_spec.rb +0 -0
  60. data/spec/technical_analysis/indicators/ema_spec.rb +115 -0
  61. data/spec/technical_analysis/indicators/eom_spec.rb +0 -0
  62. data/spec/technical_analysis/indicators/fi_spec.rb +0 -0
  63. data/spec/technical_analysis/indicators/ichimoku_spec.rb +0 -0
  64. data/spec/technical_analysis/indicators/indicator_spec.rb +0 -0
  65. data/spec/technical_analysis/indicators/kc_spec.rb +0 -0
  66. data/spec/technical_analysis/indicators/kst_spec.rb +0 -0
  67. data/spec/technical_analysis/indicators/macd_spec.rb +0 -0
  68. data/spec/technical_analysis/indicators/mfi_spec.rb +0 -0
  69. data/spec/technical_analysis/indicators/mi_spec.rb +0 -0
  70. data/spec/technical_analysis/indicators/nvi_spec.rb +0 -0
  71. data/spec/technical_analysis/indicators/obv_mean_spec.rb +0 -0
  72. data/spec/technical_analysis/indicators/obv_spec.rb +0 -0
  73. data/spec/technical_analysis/indicators/rsi_spec.rb +0 -0
  74. data/spec/technical_analysis/indicators/sma_spec.rb +0 -0
  75. data/spec/technical_analysis/indicators/sr_spec.rb +0 -0
  76. data/spec/technical_analysis/indicators/trix_spec.rb +0 -0
  77. data/spec/technical_analysis/indicators/tsi_spec.rb +0 -0
  78. data/spec/technical_analysis/indicators/uo_spec.rb +0 -0
  79. data/spec/technical_analysis/indicators/vi_spec.rb +0 -0
  80. data/spec/technical_analysis/indicators/vpt_spec.rb +0 -0
  81. data/spec/technical_analysis/indicators/vwap_spec.rb +0 -0
  82. data/spec/technical_analysis/indicators/wr_spec.rb +0 -0
  83. metadata +6 -4
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 97d8d8c26202d454f1f8b2f9da59c312a8befe4d
4
- data.tar.gz: e64933ee1a04d1180ec5c9e45c32b2b5378da507
3
+ metadata.gz: 7d1fc18d8c1ee447d239eee8a10f502b1903a4e3
4
+ data.tar.gz: 6cd340eee546df96e2e90af61847f9c128be4285
5
5
  SHA512:
6
- metadata.gz: d9391b85785a8594b3c3cca136c3d96868efc7754557b504b045153a24f360586823fea2eed93f5039b79e2a942b61f7ab2c398637975032b89724ed523e41fa
7
- data.tar.gz: 1b7d990e4515a1d48186febb1dad7c29b933d2c6589a2b9192e7bd17c1078b6453e4feff679984c47d0d7af15ab1ce7149eef0a626db6e61f6c13ff899114f33
6
+ metadata.gz: 61b922d73c8946eed92c655f62a1edc3b87b3a1ea2eec23c44336b3663737571c04c10de07005b9006147612e3cd1ef00f7bebf2b00342845b099318adfe4bec
7
+ data.tar.gz: 6ebbb51e8fcc1ee5f7e80d1c0dda34ba0d2e499d92b17d47786e8d66b2e5404441f75dbc784ecfc7448cb688320618a8feba94c7ff9b16b09959d7fb4f6ba5e8
File without changes
@@ -19,6 +19,7 @@ require 'technical_analysis/indicators/dc'
19
19
  require 'technical_analysis/indicators/dlr'
20
20
  require 'technical_analysis/indicators/dpo'
21
21
  require 'technical_analysis/indicators/dr'
22
+ require 'technical_analysis/indicators/ema'
22
23
  require 'technical_analysis/indicators/eom'
23
24
  require 'technical_analysis/indicators/fi'
24
25
  require 'technical_analysis/indicators/ichimoku'
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,101 @@
1
+ module TechnicalAnalysis
2
+ # Exponential Moving Average
3
+ class Ema < Indicator
4
+
5
+ # Returns the symbol of the technical indicator
6
+ #
7
+ # @return [String] A string of the symbol of the technical indicator
8
+ def self.indicator_symbol
9
+ "ema"
10
+ end
11
+
12
+ # Returns the name of the technical indicator
13
+ #
14
+ # @return [String] A string of the name of the technical indicator
15
+ def self.indicator_name
16
+ "Exponential Moving Average"
17
+ end
18
+
19
+ # Returns an array of valid keys for options for this technical indicator
20
+ #
21
+ # @return [Array] An array of keys as symbols for valid options for this technical indicator
22
+ def self.valid_options
23
+ %i(period price_key)
24
+ end
25
+
26
+ # Validates the provided options for this technical indicator
27
+ #
28
+ # @param options [Hash] The options for the technical indicator to be validated
29
+ #
30
+ # @return [Boolean] Returns true if options are valid or raises a ValidationError if they're not
31
+ def self.validate_options(options)
32
+ Validation.validate_options(options, valid_options)
33
+ end
34
+
35
+ # Calculates the minimum number of observations needed to calculate the technical indicator
36
+ #
37
+ # @param options [Hash] The options for the technical indicator
38
+ #
39
+ # @return [Integer] Returns the minimum number of observations needed to calculate the technical
40
+ # indicator based on the options provided
41
+ def self.min_data_size(period: 30, **params)
42
+ period.to_i
43
+ end
44
+
45
+ # Calculates the exponential moving average (EMA) for the data over the given period
46
+ # https://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
47
+ #
48
+ # @param data [Array] Array of hashes with keys (:date_time, :value)
49
+ # @param period [Integer] The given period to calculate the EMA
50
+ # @param price_key [Symbol] The hash key for the price data. Default :value
51
+ #
52
+ # @return [Array<EmaValue>] An array of EmaValue instances
53
+ def self.calculate(data, period: 30, price_key: :value)
54
+ period = period.to_i
55
+ price_key = price_key.to_sym
56
+ Validation.validate_numeric_data(data, price_key)
57
+ Validation.validate_length(data, min_data_size(period: period))
58
+ Validation.validate_date_time_key(data)
59
+
60
+ data = data.sort_by { |row| row[:date_time] }
61
+
62
+ output = []
63
+ period_values = []
64
+ previous_ema = nil
65
+
66
+ data.each do |v|
67
+ period_values << v[price_key]
68
+ if period_values.size == period
69
+ ema = StockCalculation.ema(v[price_key], period_values, period, previous_ema)
70
+ previous_ema = ema
71
+
72
+ output << EmaValue.new(date_time: v[:date_time], ema: ema)
73
+ period_values.shift
74
+ end
75
+ end
76
+
77
+ output.sort_by(&:date_time).reverse
78
+ end
79
+
80
+ end
81
+
82
+ # The value class to be returned by calculations
83
+ class EmaValue
84
+
85
+ # @return [String] the date_time of the obversation as it was provided
86
+ attr_accessor :date_time
87
+
88
+ # @return [Float] the ema calculation value
89
+ attr_accessor :ema
90
+
91
+ def initialize(date_time: nil, ema: nil)
92
+ @date_time = date_time
93
+ @ema = ema
94
+ end
95
+
96
+ # @return [Hash] the attributes as a hash
97
+ def to_hash
98
+ { date_time: @date_time, ema: @ema }
99
+ end
100
+ end
101
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
data/spec/spec_helper.rb CHANGED
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
@@ -0,0 +1,115 @@
1
+ require 'technical-analysis'
2
+ require 'spec_helper'
3
+
4
+ describe 'Indicators' do
5
+ describe "EMA" do
6
+ input_data = SpecHelper.get_test_data(:close)
7
+ indicator = TechnicalAnalysis::Ema
8
+
9
+ describe 'Exponential Moving Average' do
10
+ it 'Calculates EMA (5 day)' do
11
+ output = indicator.calculate(input_data, period: 5, price_key: :close)
12
+ normalized_output = output.map(&:to_hash)
13
+
14
+ expected_output = [
15
+ {:date_time=>"2019-01-09T00:00:00.000Z", :ema=>151.1937160522574},
16
+ {:date_time=>"2019-01-08T00:00:00.000Z", :ema=>150.1355740783861},
17
+ {:date_time=>"2019-01-07T00:00:00.000Z", :ema=>149.82836111757913},
18
+ {:date_time=>"2019-01-04T00:00:00.000Z", :ema=>150.77754167636868},
19
+ {:date_time=>"2019-01-03T00:00:00.000Z", :ema=>152.03631251455303},
20
+ {:date_time=>"2019-01-02T00:00:00.000Z", :ema=>156.95946877182956},
21
+ {:date_time=>"2018-12-31T00:00:00.000Z", :ema=>156.47920315774434},
22
+ {:date_time=>"2018-12-28T00:00:00.000Z", :ema=>155.8488047366165},
23
+ {:date_time=>"2018-12-27T00:00:00.000Z", :ema=>155.65820710492477},
24
+ {:date_time=>"2018-12-26T00:00:00.000Z", :ema=>155.41231065738714},
25
+ {:date_time=>"2018-12-24T00:00:00.000Z", :ema=>154.53346598608073},
26
+ {:date_time=>"2018-12-21T00:00:00.000Z", :ema=>158.3851989791211},
27
+ {:date_time=>"2018-12-20T00:00:00.000Z", :ema=>162.21279846868165},
28
+ {:date_time=>"2018-12-19T00:00:00.000Z", :ema=>164.90419770302248},
29
+ {:date_time=>"2018-12-18T00:00:00.000Z", :ema=>166.91129655453372},
30
+ {:date_time=>"2018-12-17T00:00:00.000Z", :ema=>167.3319448318006},
31
+ {:date_time=>"2018-12-14T00:00:00.000Z", :ema=>169.02791724770088},
32
+ {:date_time=>"2018-12-13T00:00:00.000Z", :ema=>170.80187587155132},
33
+ {:date_time=>"2018-12-12T00:00:00.000Z", :ema=>170.72781380732698},
34
+ {:date_time=>"2018-12-11T00:00:00.000Z", :ema=>171.54172071099046},
35
+ {:date_time=>"2018-12-10T00:00:00.000Z", :ema=>172.99758106648568},
36
+ {:date_time=>"2018-12-07T00:00:00.000Z", :ema=>174.69637159972854},
37
+ {:date_time=>"2018-12-06T00:00:00.000Z", :ema=>177.7995573995928},
38
+ {:date_time=>"2018-12-04T00:00:00.000Z", :ema=>179.33933609938921},
39
+ {:date_time=>"2018-12-03T00:00:00.000Z", :ema=>180.6640041490838},
40
+ {:date_time=>"2018-11-30T00:00:00.000Z", :ema=>178.58600622362573},
41
+ {:date_time=>"2018-11-29T00:00:00.000Z", :ema=>178.5890093354386},
42
+ {:date_time=>"2018-11-28T00:00:00.000Z", :ema=>178.10851400315786},
43
+ {:date_time=>"2018-11-27T00:00:00.000Z", :ema=>176.69277100473678},
44
+ {:date_time=>"2018-11-26T00:00:00.000Z", :ema=>177.91915650710516},
45
+ {:date_time=>"2018-11-23T00:00:00.000Z", :ema=>179.56873476065772},
46
+ {:date_time=>"2018-11-21T00:00:00.000Z", :ema=>183.20810214098657},
47
+ {:date_time=>"2018-11-20T00:00:00.000Z", :ema=>186.42215321147984},
48
+ {:date_time=>"2018-11-19T00:00:00.000Z", :ema=>191.14322981721975},
49
+ {:date_time=>"2018-11-16T00:00:00.000Z", :ema=>193.7848447258296},
50
+ {:date_time=>"2018-11-15T00:00:00.000Z", :ema=>193.9122670887444},
51
+ {:date_time=>"2018-11-14T00:00:00.000Z", :ema=>195.1634006331166},
52
+ {:date_time=>"2018-11-13T00:00:00.000Z", :ema=>199.34510094967487},
53
+ {:date_time=>"2018-11-12T00:00:00.000Z", :ema=>202.90265142451233},
54
+ {:date_time=>"2018-11-09T00:00:00.000Z", :ema=>207.26897713676848},
55
+ {:date_time=>"2018-11-08T00:00:00.000Z", :ema=>208.66846570515273},
56
+ {:date_time=>"2018-11-07T00:00:00.000Z", :ema=>208.75769855772907},
57
+ {:date_time=>"2018-11-06T00:00:00.000Z", :ema=>208.16154783659363},
58
+ {:date_time=>"2018-11-05T00:00:00.000Z", :ema=>210.35732175489045},
59
+ {:date_time=>"2018-11-02T00:00:00.000Z", :ema=>214.7409826323357},
60
+ {:date_time=>"2018-11-01T00:00:00.000Z", :ema=>218.37147394850354},
61
+ {:date_time=>"2018-10-31T00:00:00.000Z", :ema=>216.44721092275532},
62
+ {:date_time=>"2018-10-30T00:00:00.000Z", :ema=>215.24081638413296},
63
+ {:date_time=>"2018-10-29T00:00:00.000Z", :ema=>216.21122457619944},
64
+ {:date_time=>"2018-10-26T00:00:00.000Z", :ema=>218.19683686429914},
65
+ {:date_time=>"2018-10-25T00:00:00.000Z", :ema=>219.1452552964487},
66
+ {:date_time=>"2018-10-24T00:00:00.000Z", :ema=>218.81788294467307},
67
+ {:date_time=>"2018-10-23T00:00:00.000Z", :ema=>220.6818244170096},
68
+ {:date_time=>"2018-10-22T00:00:00.000Z", :ema=>219.65773662551442},
69
+ {:date_time=>"2018-10-19T00:00:00.000Z", :ema=>219.1616049382716},
70
+ {:date_time=>"2018-10-18T00:00:00.000Z", :ema=>219.0874074074074},
71
+ {:date_time=>"2018-10-17T00:00:00.000Z", :ema=>220.6211111111111},
72
+ {:date_time=>"2018-10-16T00:00:00.000Z", :ema=>220.33666666666667},
73
+ {:date_time=>"2018-10-15T00:00:00.000Z", :ema=>219.43}
74
+ ]
75
+
76
+ expect(normalized_output).to eq(expected_output)
77
+ end
78
+
79
+ it "Throws exception if not enough data" do
80
+ expect {indicator.calculate(input_data, period: input_data.size+1, price_key: :close)}.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
81
+ end
82
+
83
+ it 'Returns the symbol' do
84
+ indicator_symbol = indicator.indicator_symbol
85
+ expect(indicator_symbol).to eq('ema')
86
+ end
87
+
88
+ it 'Returns the name' do
89
+ indicator_name = indicator.indicator_name
90
+ expect(indicator_name).to eq('Exponential Moving Average')
91
+ end
92
+
93
+ it 'Returns the valid options' do
94
+ valid_options = indicator.valid_options
95
+ expect(valid_options).to eq(%i(period price_key))
96
+ end
97
+
98
+ it 'Validates options' do
99
+ valid_options = { period: 22, price_key: :close }
100
+ options_validated = indicator.validate_options(valid_options)
101
+ expect(options_validated).to eq(true)
102
+ end
103
+
104
+ it 'Throws exception for invalid options' do
105
+ invalid_options = { test: 10 }
106
+ expect { indicator.validate_options(invalid_options) }.to raise_exception(TechnicalAnalysis::Validation::ValidationError)
107
+ end
108
+
109
+ it 'Calculates minimum data size' do
110
+ options = { period: 4 }
111
+ expect(indicator.min_data_size(options)).to eq(4)
112
+ end
113
+ end
114
+ end
115
+ end
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: technical-analysis
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.2.0
4
+ version: 0.2.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - Intrinio
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2019-03-19 00:00:00.000000000 Z
11
+ date: 2020-02-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler
@@ -58,14 +58,14 @@ dependencies:
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: 0.9.6
61
+ version: 0.9.20
62
62
  type: :development
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: 0.9.6
68
+ version: 0.9.20
69
69
  description: A Ruby library for performing technical analysis on stock prices and
70
70
  other data sets.
71
71
  email:
@@ -92,6 +92,7 @@ files:
92
92
  - lib/technical_analysis/indicators/dlr.rb
93
93
  - lib/technical_analysis/indicators/dpo.rb
94
94
  - lib/technical_analysis/indicators/dr.rb
95
+ - lib/technical_analysis/indicators/ema.rb
95
96
  - lib/technical_analysis/indicators/eom.rb
96
97
  - lib/technical_analysis/indicators/fi.rb
97
98
  - lib/technical_analysis/indicators/ichimoku.rb
@@ -131,6 +132,7 @@ files:
131
132
  - spec/technical_analysis/indicators/dlr_spec.rb
132
133
  - spec/technical_analysis/indicators/dpo_spec.rb
133
134
  - spec/technical_analysis/indicators/dr_spec.rb
135
+ - spec/technical_analysis/indicators/ema_spec.rb
134
136
  - spec/technical_analysis/indicators/eom_spec.rb
135
137
  - spec/technical_analysis/indicators/fi_spec.rb
136
138
  - spec/technical_analysis/indicators/ichimoku_spec.rb