moving_average 0.0.2 → 0.0.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,15 @@
1
1
  class Array
2
2
 
3
+ def idx_and_tail_or_defaults(idx, tail)
4
+ if tail.nil?
5
+ tail = self.size
6
+ if idx.nil?
7
+ idx = self.size - 1
8
+ end
9
+ end
10
+ [idx, tail]
11
+ end; private :idx_and_tail_or_defaults
12
+
3
13
  def valid_for_ma(idx, tail)
4
14
  unless idx >= 0 && idx < self.size
5
15
  raise MovingAverage::Errors::InvalidIndexError
@@ -13,7 +23,8 @@ class Array
13
23
  true
14
24
  end; private :valid_for_ma
15
25
 
16
- def exponential_moving_average(idx, tail)
26
+ def exponential_moving_average(idx=nil, tail=nil)
27
+ idx, tail = idx_and_tail_or_defaults(idx, tail)
17
28
  valid_for_ma(idx, tail)
18
29
  # Taken from
19
30
  # http://en.wikipedia.org/wiki/Moving_average#Exponential_moving_average
@@ -27,13 +38,15 @@ class Array
27
38
  end
28
39
  alias_method :ema, :exponential_moving_average
29
40
 
30
- def simple_moving_average(idx, tail)
41
+ def simple_moving_average(idx=nil, tail=nil)
42
+ idx, tail = idx_and_tail_or_defaults(idx, tail)
31
43
  valid_for_ma(idx, tail)
32
44
  self[idx-tail+1..idx].sum.to_f / tail
33
45
  end
34
46
  alias_method :sma, :simple_moving_average
35
47
 
36
- def weighted_moving_average(idx, tail)
48
+ def weighted_moving_average(idx=nil, tail=nil)
49
+ idx, tail = idx_and_tail_or_defaults(idx, tail)
37
50
  valid_for_ma(idx, tail)
38
51
  # Taken from
39
52
  # http://en.wikipedia.org/wiki/Moving_average#Weighted_moving_average
@@ -1,3 +1,3 @@
1
1
  module MovingAverage
2
- VERSION = '0.0.2'
2
+ VERSION = '0.0.3'
3
3
  end
@@ -2,46 +2,84 @@ require 'moving_average'
2
2
 
3
3
  describe MovingAverage do
4
4
 
5
- it "exponential moving average should work for valid arguments" do
5
+ describe "exponential moving average" do
6
+
6
7
  # Example taken from
7
8
  # http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
8
- a = [22.27, 22.19, 22.08, 22.17, 22.18, 22.13, 22.23, 22.43, 22.24, 22.29]
9
- a.exponential_moving_average(9, 10).round(3).should eql(22.247)
10
- a.ema(9, 10).round(3).should eql(22.247)
11
- end
9
+ EMA_DATA = [22.27, 22.19, 22.08, 22.17, 22.18, 22.13, 22.23, 22.43, 22.24, 22.29].freeze
10
+ EMA = 22.247
12
11
 
13
- it "exponential moving average should raise NotEnoughDataError for invalid arguments" do
14
- expect { [1, 2, 3].exponential_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
15
- expect { [1, 2, 3].exponential_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
16
- expect { [1, 2, 3].exponential_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
17
- expect { [1, 2, 3].exponential_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
18
- end
12
+ it "should work for missing arguments" do
13
+ EMA_DATA.exponential_moving_average.round(3).should eql(EMA)
14
+ EMA_DATA.ema.round(3).should eql(EMA)
15
+ EMA_DATA.exponential_moving_average(9).round(3).should eql(EMA)
16
+ EMA_DATA.ema(9).round(3).should eql(EMA)
17
+ end
18
+
19
+ it "should work for valid arguments" do
20
+ # Example taken from
21
+ # http://stockcharts.com/school/doku.php?id=chart_school:technical_indicators:moving_averages
22
+ EMA_DATA.exponential_moving_average(9, 10).round(3).should eql(EMA)
23
+ EMA_DATA.ema(9, 10).round(3).should eql(EMA)
24
+ end
25
+
26
+ it "should raise proper errors for invalid arguments" do
27
+ expect { [1, 2, 3].exponential_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
28
+ expect { [1, 2, 3].exponential_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
29
+ expect { [1, 2, 3].exponential_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
30
+ expect { [1, 2, 3].exponential_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
31
+ end
19
32
 
20
- it "simple moving average should work" do
21
- (1..5).to_a.simple_moving_average(4, 5).should ==(3)
22
- (1..5).to_a.sma(4, 5).should ==(3)
23
33
  end
24
34
 
25
- it "simple moving average should raise proper errors for invalid arguments" do
26
- expect { [1, 2, 3].simple_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
27
- expect { [1, 2, 3].simple_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
28
- expect { [1, 2, 3].simple_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
29
- expect { [1, 2, 3].simple_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
35
+ describe "simple moving average" do
36
+
37
+ it "should work for missing arguments" do
38
+ (1..5).to_a.simple_moving_average.should ==(3)
39
+ (1..5).to_a.sma.should ==(3)
40
+ (1..5).to_a.simple_moving_average(4).should ==(3)
41
+ (1..5).to_a.sma(4).should ==(3)
42
+ end
43
+
44
+ it "should work for valid arguments" do
45
+ (1..5).to_a.simple_moving_average(4, 5).should ==(3)
46
+ (1..5).to_a.sma(4, 5).should ==(3)
47
+ end
48
+
49
+ it "should raise proper errors for invalid arguments" do
50
+ expect { [1, 2, 3].simple_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
51
+ expect { [1, 2, 3].simple_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
52
+ expect { [1, 2, 3].simple_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
53
+ expect { [1, 2, 3].simple_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
54
+ end
30
55
  end
31
56
 
32
- it "weighted moving average should work" do
57
+ describe "weighted moving average" do
58
+
33
59
  # Example taken from
34
60
  # http://daytrading.about.com/od/indicators/a/MovingAverages.htm
35
- vals = [1.2900, 1.2900, 1.2903, 1.2904]
36
- vals.weighted_moving_average(3, 4).should eql(1.29025)
37
- vals.wma(3, 4).should eql(1.29025)
38
- end
61
+ WMA_DATA = [1.2900, 1.2900, 1.2903, 1.2904].freeze
62
+ WMA = 1.29025
63
+
64
+ it "should work for missing arguments" do
65
+ WMA_DATA.weighted_moving_average.should eql(WMA)
66
+ WMA_DATA.wma.should eql(WMA)
67
+ WMA_DATA.weighted_moving_average(3).should eql(WMA)
68
+ WMA_DATA.wma(3).should eql(WMA)
69
+ end
70
+
71
+ it "should work for valid arguments" do
72
+ WMA_DATA.weighted_moving_average(3, 4).should eql(WMA)
73
+ WMA_DATA.wma(3, 4).should eql(WMA)
74
+ end
75
+
76
+ it "should raise proper errors for invalid arguments" do
77
+ expect { [1, 2, 3].weighted_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
78
+ expect { [1, 2, 3].weighted_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
79
+ expect { [1, 2, 3].weighted_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
80
+ expect { [1, 2, 3].weighted_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
81
+ end
39
82
 
40
- it "weighted moving average should raise proper errors for invalid arguments" do
41
- expect { [1, 2, 3].weighted_moving_average(-1, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
42
- expect { [1, 2, 3].weighted_moving_average(3, 3) }.to raise_exception(MovingAverage::Errors::InvalidIndexError, "Given idx is outside the Array.")
43
- expect { [1, 2, 3].weighted_moving_average(1, -1) }.to raise_exception(MovingAverage::Errors::InvalidTailError, "Given tail is <= 0.")
44
- expect { [1, 2, 3].weighted_moving_average(1, 3) }.to raise_exception(MovingAverage::Errors::NotEnoughDataError, "Given tail is too large for idx.")
45
83
  end
46
84
 
47
85
  end
metadata CHANGED
@@ -1,48 +1,40 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: moving_average
3
- version: !ruby/object:Gem::Version
4
- hash: 27
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.3
5
5
  prerelease:
6
- segments:
7
- - 0
8
- - 0
9
- - 2
10
- version: 0.0.2
11
6
  platform: ruby
12
- authors:
7
+ authors:
13
8
  - Brad Cater
14
9
  autorequire:
15
10
  bindir: bin
16
11
  cert_chain: []
17
-
18
- date: 2013-03-16 00:00:00 -04:00
19
- default_executable:
20
- dependencies:
21
- - !ruby/object:Gem::Dependency
12
+ date: 2013-03-17 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
22
15
  name: rspec
23
- prerelease: false
24
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: !ruby/object:Gem::Requirement
25
17
  none: false
26
- requirements:
18
+ requirements:
27
19
  - - ~>
28
- - !ruby/object:Gem::Version
29
- hash: 25
30
- segments:
31
- - 2
32
- - 13
33
- version: "2.13"
20
+ - !ruby/object:Gem::Version
21
+ version: '2.13'
34
22
  type: :development
35
- version_requirements: *id001
36
- description: This gem adds methods to the Array class to compute different types of moving averages.
37
- email:
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: '2.13'
30
+ description: This gem adds methods to the Array class to compute different types of
31
+ moving averages.
32
+ email:
38
33
  - bradcater@gmail.com
39
34
  executables: []
40
-
41
35
  extensions: []
42
-
43
36
  extra_rdoc_files: []
44
-
45
- files:
37
+ files:
46
38
  - .gitignore
47
39
  - Gemfile
48
40
  - LICENSE
@@ -54,39 +46,30 @@ files:
54
46
  - lib/moving_average/version.rb
55
47
  - moving_average.gemspec
56
48
  - spec/moving_average_spec.rb
57
- has_rdoc: true
58
- homepage: ""
49
+ homepage: ''
59
50
  licenses: []
60
-
61
51
  post_install_message:
62
52
  rdoc_options: []
63
-
64
- require_paths:
53
+ require_paths:
65
54
  - lib
66
- required_ruby_version: !ruby/object:Gem::Requirement
55
+ required_ruby_version: !ruby/object:Gem::Requirement
67
56
  none: false
68
- requirements:
69
- - - ">="
70
- - !ruby/object:Gem::Version
71
- hash: 3
72
- segments:
73
- - 0
74
- version: "0"
75
- required_rubygems_version: !ruby/object:Gem::Requirement
57
+ requirements:
58
+ - - ! '>='
59
+ - !ruby/object:Gem::Version
60
+ version: '0'
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
76
62
  none: false
77
- requirements:
78
- - - ">="
79
- - !ruby/object:Gem::Version
80
- hash: 3
81
- segments:
82
- - 0
83
- version: "0"
63
+ requirements:
64
+ - - ! '>='
65
+ - !ruby/object:Gem::Version
66
+ version: '0'
84
67
  requirements: []
85
-
86
68
  rubyforge_project:
87
- rubygems_version: 1.6.2
69
+ rubygems_version: 1.8.23
88
70
  signing_key:
89
71
  specification_version: 3
90
- summary: This gem adds methods to the Array class to compute different types of moving averages.
91
- test_files:
72
+ summary: This gem adds methods to the Array class to compute different types of moving
73
+ averages.
74
+ test_files:
92
75
  - spec/moving_average_spec.rb