moving_average 0.0.2 → 0.0.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -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