quandl_operation 0.4.1 → 0.4.2.rc1

Sign up to get free protection for your applications and to get access to all the features.
@@ -2,4 +2,4 @@ require 'quandl/operation/core_ext/array'
2
2
  require 'quandl/operation/core_ext/date'
3
3
  require 'quandl/operation/core_ext/float'
4
4
  require 'quandl/operation/core_ext/string'
5
- require 'quandl/operation/core_ext/time'
5
+ require 'quandl/operation/core_ext/time'
@@ -1,22 +1,24 @@
1
1
  class Array
2
2
  def self.forwardable_methods
3
- [:reject, :keep_if, :to_a, :cycle, :drop, :map, :rotate, :each_slice, :pack, :select!,
4
- :combination, :repeated_combination, :shift, :select, :reverse!, :==, :clear, :rotate!, :inspect, :iter_for_each,
5
- :sort_by!, :compact!, :|, :copy_data_simple, :nitems, :zip, :take, :rassoc, :flatten!, :join, :compact, :[]=,
6
- :frozen?, :slice!, :drop_while, :reverse_each, :shuffle, :slice, :reverse, :insert, :uniq, :first, :count, :fetch,
7
- :hash, :to_ary, :find_index, :replace, :-, :product, :iter_for_reverse_each, :pop, :push, :sort, :fill, :uniq!,
8
- :length, :&, :flatten, :repeated_permutation, :[], :shuffle!, :sort!, :sample, :include?, :<<, :dimensions,
9
- :collect, :+, :rindex, :<=>, :eql?, :indices, :collect!, :iter_for_each_index, :iter_for_each_with_index, :index,
10
- :*, :indexes, :copy_data, :delete, :to_s, :assoc, :delete_at, :unshift, :delete_if, :empty?, :reject!, :last,
11
- :size, :concat, :map!, :at, :each_index, :transpose, :values_at, :each, :enum_cons, :group_by, :enum_with_index,
12
- :entries, :with_object, :chunk, :each_with_index, :min, :inject, :one?, :partition, :enum_slice, :none?, :max_by,
13
- :any?, :flat_map, :reduce, :each_entry, :find, :minmax_by, :collect_concat, :each_cons, :member?, :max, :sort_by,
14
- :detect, :all?, :minmax, :grep, :each_with_object, :find_all]
3
+ [:reject, :keep_if, :to_a, :cycle, :drop, :map, :rotate, :each_slice, :pack, :select!,
4
+ :combination, :repeated_combination, :shift, :select, :reverse!, :==, :clear, :rotate!, :inspect, :iter_for_each,
5
+ :sort_by!, :compact!, :|, :copy_data_simple, :nitems, :zip, :take, :rassoc, :flatten!, :join, :compact, :[]=,
6
+ :frozen?, :slice!, :drop_while, :reverse_each, :shuffle, :slice, :reverse, :insert, :uniq, :first, :count, :fetch,
7
+ :hash, :to_ary, :find_index, :replace, :-, :product, :iter_for_reverse_each, :pop, :push, :sort, :fill, :uniq!,
8
+ :length, :&, :flatten, :repeated_permutation, :[], :shuffle!, :sort!, :sample, :include?, :<<, :dimensions,
9
+ :collect, :+, :rindex, :<=>, :eql?, :indices, :collect!, :iter_for_each_index, :iter_for_each_with_index, :index,
10
+ :*, :indexes, :copy_data, :delete, :to_s, :assoc, :delete_at, :unshift, :delete_if, :empty?, :reject!, :last,
11
+ :size, :concat, :map!, :at, :each_index, :transpose, :values_at, :each, :enum_cons, :group_by, :enum_with_index,
12
+ :entries, :with_object, :chunk, :each_with_index, :min, :inject, :one?, :partition, :enum_slice, :none?, :max_by,
13
+ :any?, :flat_map, :reduce, :each_entry, :find, :minmax_by, :collect_concat, :each_cons, :member?, :max, :sort_by,
14
+ :detect, :all?, :minmax, :grep, :each_with_object, :find_all]
15
15
  end
16
+
16
17
  def average
17
- self.sum / self.count
18
+ sum / count
18
19
  end
20
+
19
21
  def extract_options
20
22
  last.is_a?(::Hash) ? last : {}
21
23
  end
22
- end
24
+ end
@@ -1,55 +1,53 @@
1
1
  class Date
2
-
3
2
  def start_of_frequency(freq)
4
3
  case freq.to_sym
5
4
  when :daily then self
6
- when :weekly then self.beginning_of_week
7
- when :monthly then self.beginning_of_month
8
- when :quarterly then self.beginning_of_quarter
9
- when :annual then self.beginning_of_year
10
- when :annually then self.beginning_of_year
5
+ when :weekly then beginning_of_week
6
+ when :monthly then beginning_of_month
7
+ when :quarterly then beginning_of_quarter
8
+ when :annual then beginning_of_year
9
+ when :annually then beginning_of_year
11
10
  else
12
11
  self
13
12
  end
14
13
  end
15
-
14
+
16
15
  def end_of_frequency(freq)
17
16
  case freq.to_sym
18
17
  when :daily then self
19
- when :weekly then self.end_of_week
20
- when :monthly then self.end_of_month
21
- when :quarterly then self.end_of_quarter
22
- when :annual then self.end_of_year
23
- when :annually then self.end_of_year
18
+ when :weekly then end_of_week
19
+ when :monthly then end_of_month
20
+ when :quarterly then end_of_quarter
21
+ when :annual then end_of_year
22
+ when :annually then end_of_year
24
23
  else
25
24
  self
26
25
  end
27
26
  end
28
-
29
- def ranging_until( date )
27
+
28
+ def ranging_until(date)
30
29
  self..date
31
30
  end
32
-
33
- def occurrences_of_frequency_ahead( occurrences, freq )
34
- occurrences_of_frequency_ago( occurrences.to_i * -1, freq )
31
+
32
+ def occurrences_of_frequency_ahead(occurrences, freq)
33
+ occurrences_of_frequency_ago(occurrences.to_i * -1, freq)
35
34
  end
36
35
 
37
- def occurrences_of_frequency_ago( occurrences, freq )
38
- occurrences_of_frequency( occurrences, freq )
36
+ def occurrences_of_frequency_ago(occurrences, freq)
37
+ occurrences_of_frequency(occurrences, freq)
39
38
  end
40
39
 
41
- def occurrences_of_frequency( occurrences, freq )
40
+ def occurrences_of_frequency(occurrences, freq)
42
41
  # ensure occurrences is an integer
43
42
  occurrences = occurrences.to_i
44
43
  case freq.try(:to_sym)
45
44
  when :weekly then self - occurrences.weeks
46
45
  when :monthly then self - occurrences.months
47
- when :quarterly then self - ( occurrences * 3 ).months
46
+ when :quarterly then self - (occurrences * 3).months
48
47
  when :annual then self - occurrences.years
49
48
  when :annually then self - occurrences.years
50
- else
49
+ else
51
50
  self - occurrences
52
51
  end
53
52
  end
54
-
55
- end
53
+ end
@@ -1,7 +1,5 @@
1
1
  class Float
2
-
3
2
  def microseconds
4
3
  (self * 1000.0).to_i
5
4
  end
6
-
7
- end
5
+ end
@@ -1,8 +1,10 @@
1
1
  class String
2
-
3
2
  def numeric?
4
3
  return true if self =~ /^\d+$/
5
- true if Float(self) rescue false
4
+ begin
5
+ true if Float(self)
6
+ rescue
7
+ false
8
+ end
6
9
  end
7
-
8
- end
10
+ end
@@ -1,8 +1,6 @@
1
1
  class Time
2
-
3
2
  class << self
4
-
5
- def log_elapsed(message=nil, &block)
3
+ def log_elapsed(message = nil, &block)
6
4
  timer = Time.now
7
5
  result = block.call
8
6
  message = "#{message} (#{timer.elapsed.microseconds}ms)"
@@ -10,56 +8,56 @@ class Time
10
8
  Quandl::Logger.info(message)
11
9
  result
12
10
  end
13
-
14
- def elapsed(message=nil, &block)
11
+
12
+ def elapsed(message = nil, &block)
15
13
  log_elapsed(message, &block)
16
14
  end
17
-
18
15
  end
19
-
16
+
20
17
  def week_from_beginning_to_end
21
- (self.beginning_of_week .. self.end_of_week)
18
+ (beginning_of_week..end_of_week)
22
19
  end
20
+
23
21
  def this_week?
24
- self.week_from_beginning_to_end.cover?(Time.now)
22
+ week_from_beginning_to_end.cover?(Time.now)
25
23
  end
26
24
 
27
25
  def month_from_beginning_to_end
28
- (self.beginning_of_month .. self.end_of_month)
26
+ (beginning_of_month..end_of_month)
29
27
  end
28
+
30
29
  def this_month?
31
- self.month_from_beginning_to_end.cover?(Time.now)
30
+ month_from_beginning_to_end.cover?(Time.now)
32
31
  end
33
32
 
34
33
  def round(seconds = 60)
35
- Time.at((self.to_f / seconds).round * seconds)
34
+ Time.at((to_f / seconds).round * seconds)
36
35
  end
37
36
 
38
37
  def floor(seconds = 60)
39
- Time.at((self.to_f / seconds).floor * seconds)
38
+ Time.at((to_f / seconds).floor * seconds)
40
39
  end
41
-
40
+
42
41
  def microseconds
43
- (self.to_f * 1000.0).to_i
42
+ (to_f * 1000.0).to_i
44
43
  end
45
-
46
- def self.elapsed(message=nil, &block)
44
+
45
+ def self.elapsed(message = nil, &block)
47
46
  timer = Time.now
48
47
  result = block.call
49
48
  puts "#{message} (#{timer.elapsed.microseconds}ms)"
50
49
  result
51
50
  end
52
-
51
+
53
52
  def elapsed
54
53
  elapsed_since(Time.now)
55
54
  end
56
-
55
+
57
56
  def elapsed_since(time)
58
57
  time - self
59
58
  end
60
-
59
+
61
60
  def elapsed_ms
62
61
  "#{elapsed.microseconds}ms"
63
62
  end
64
-
65
- end
63
+ end
@@ -1,22 +1,18 @@
1
1
  module Quandl
2
- module Operation
3
-
4
- class QDate
5
-
6
- class << self
7
- def parse(value)
8
- date = Date.jd(value.to_i) if value.kind_of?(String) && value.numeric?
9
- date = Date.jd(value) if value.is_a?(Integer)
10
- date = Date.parse(value) if value.is_a?(String) && value =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
11
- date = value if value.is_a?(Date)
12
- date = value.to_date if value.respond_to?(:to_date)
13
- date
14
- rescue
15
- nil
2
+ module Operation
3
+ class QDate
4
+ class << self
5
+ def parse(value)
6
+ date = Date.jd(value.to_i) if value.is_a?(String) && value.numeric?
7
+ date = Date.jd(value) if value.is_a?(Integer)
8
+ date = Date.parse(value) if value.is_a?(String) && value =~ /^[0-9]{4}\-[0-9]{2}\-[0-9]{2}$/
9
+ date = value if value.is_a?(Date)
10
+ date = value.to_date if value.respond_to?(:to_date)
11
+ date
12
+ rescue
13
+ nil
14
+ end
15
+ end
16
16
  end
17
17
  end
18
-
19
18
  end
20
-
21
- end
22
- end
@@ -1,33 +1,29 @@
1
1
  module Quandl
2
- module Operation
3
- class Sort
4
-
5
- class << self
6
-
7
- def order?(data)
8
- return :none if data.blank? || data[0].blank? || data[1].blank?
9
- data[0][0] > data[1][0] ? :desc : :asc
10
- end
11
-
12
- def order(data, order = :asc)
13
- # ascending
14
- case order
15
- when :asc then data = sort_asc(data)
16
- when :desc then data = sort_desc(data)
17
- end
18
- data
19
- end
2
+ module Operation
3
+ class Sort
4
+ class << self
5
+ def order?(data)
6
+ return :none if data.blank? || data[0].blank? || data[1].blank?
7
+ data[0][0] > data[1][0] ? :desc : :asc
8
+ end
20
9
 
21
- def asc(data)
22
- data.sort_by{|r| r[0] }
23
- end
24
-
25
- def desc(data)
26
- data.sort_by{|r| r[0] }.reverse
10
+ def order(data, order = :asc)
11
+ # ascending
12
+ case order
13
+ when :asc then data = sort_asc(data)
14
+ when :desc then data = sort_desc(data)
15
+ end
16
+ data
17
+ end
18
+
19
+ def asc(data)
20
+ data.sort_by { |r| r[0] }
21
+ end
22
+
23
+ def desc(data)
24
+ data.sort_by { |r| r[0] }.reverse
25
+ end
26
+ end
27
27
  end
28
-
29
28
  end
30
-
31
- end
32
29
  end
33
- end
@@ -1,170 +1,164 @@
1
1
  module Quandl
2
- module Operation
2
+ module Operation
3
+ class Transform
4
+ class << self
5
+ def perform(data, type)
6
+ assert_valid_arguments!(data, type)
7
+ # nothing to do with an empty array
8
+ return data unless data.compact.present?
9
+ # original order
10
+ order = Sort.order?(data)
11
+ # operations expect data in ascending order
12
+ data = Sort.asc(data)
13
+ # transform
14
+ data = transform(data, type)
15
+ # return to original order
16
+ data = Sort.desc(data) if order == :desc
17
+ # onwards
18
+ data = Value.precision(data, 14)
19
+ data
20
+ end
3
21
 
4
- class Transform
5
-
6
- class << self
7
-
8
- def perform( data, type )
9
- assert_valid_arguments!(data, type)
10
- # nothing to do with an empty array
11
- return data unless data.compact.present?
12
- # original order
13
- order = Sort.order?(data)
14
- # operations expect data in ascending order
15
- data = Sort.asc(data)
16
- # transform
17
- data = transform( data, type)
18
- # return to original order
19
- data = Sort.desc(data) if order == :desc
20
- # onwards
21
- data = Value.precision(data, 14)
22
- data
23
- end
24
-
25
- def assert_valid_arguments!(data, type)
26
- raise ArgumentError, "data must be an Array. Received: #{data.class}" unless data.is_a?(Array)
27
- raise ArgumentError, "frequency must be one of #{valid_transformations}. Received: #{type}" unless valid?(type)
28
- end
29
-
30
- def valid_transformation?(type)
31
- valid?(type)
32
- end
33
-
34
- def valid?(type)
35
- valid_transformations.include?( type.try(:to_sym) )
36
- end
37
-
38
- def valid_transformations
39
- [ :diff, :rdiff, :cumul, :normalize, :rdiff_from ]
40
- end
41
-
42
- def transform( data, type)
43
- return data if data.blank?
44
- #Transforms table from actual data points
45
- #to differences between points (:diff)
46
- #or a ratio between points(:rdiff)
47
- #or a ratio between the latest point and an earlier point (:rdiff_from)
48
- #If type is other than these two, nothing is done.
49
-
50
- # ensure that type is in the expected format
51
- type = type.try(:to_sym)
52
- # nothing to do unless valid transform
53
- return data unless valid_transformation?( type )
54
-
55
- temparr = Array.new
56
- #first make a keylist
57
- keylist = data.transpose.first
58
- # now sort the keylist from oldest to newest
59
- # unless there is only one point
60
- if keylist.count > 1
61
- keylist = keylist.reverse if keylist[0] > keylist[1] # better performance if we do this first
62
- keylist.sort!
63
- end
22
+ def assert_valid_arguments!(data, type)
23
+ fail ArgumentError, "data must be an Array. Received: #{data.class}" unless data.is_a?(Array)
24
+ fail ArgumentError, "frequency must be one of #{valid_transformations}. Received: #{type}" unless valid?(type)
25
+ end
64
26
 
65
- #find number of columns
66
- numcols = data.first.size - 1
67
- if type == :normalize
68
- divisor = Array.new(numcols,nil)
69
- 0.upto(keylist.length - 1) do |i|
70
- temparr[i] = []
71
- curr_row = data[i][1..-1]
72
- 0.upto(numcols-1) do |x|
73
- if curr_row[x].nil?
74
- temparr[i][x] = nil
75
- elsif divisor[x].nil?
76
- if curr_row[x].to_f != 0
77
- divisor[x] = curr_row[x].to_f
78
- temparr[i][x] = 100.0
79
- else
80
- temparr[i][x] = 0
81
- end
82
- else
83
- temparr[i][x] = curr_row[x] / divisor[x] * 100.0
84
- end
85
- end
27
+ def valid_transformation?(type)
28
+ valid?(type)
86
29
  end
87
- 0.upto(keylist.length-1) do |i|
88
- data[i] = [keylist[i], temparr[i]].flatten
30
+
31
+ def valid?(type)
32
+ valid_transformations.include?(type.try(:to_sym))
33
+ end
34
+
35
+ def valid_transformations
36
+ [:diff, :rdiff, :cumul, :normalize, :rdiff_from]
89
37
  end
90
- elsif [:diff, :rdiff].include? type
91
- #now build temparr
92
- 1.upto(keylist.length - 1) do |i|
93
- temparr[i] = []
94
- curr_row = data[i][1..-1]
95
- prev_row = data[i-1][1..-1]
96
- 0.upto(numcols-1) do |x|
97
- if type == :diff
98
- if !curr_row[x].nil? and !prev_row[x].nil?
99
- temparr[i][x] = Float(curr_row[x]) - Float(prev_row[x])
100
- else
101
- temparr[i][x] = nil
38
+
39
+ def transform(data, type)
40
+ return data if data.blank?
41
+ # Transforms table from actual data points
42
+ # to differences between points (:diff)
43
+ # or a ratio between points(:rdiff)
44
+ # or a ratio between the latest point and an earlier point (:rdiff_from)
45
+ # If type is other than these two, nothing is done.
46
+
47
+ # ensure that type is in the expected format
48
+ type = type.try(:to_sym)
49
+ # nothing to do unless valid transform
50
+ return data unless valid_transformation?(type)
51
+
52
+ temparr = []
53
+ # first make a keylist
54
+ keylist = data.transpose.first
55
+ # now sort the keylist from oldest to newest
56
+ # unless there is only one point
57
+ if keylist.count > 1
58
+ keylist = keylist.reverse if keylist[0] > keylist[1] # better performance if we do this first
59
+ keylist.sort!
60
+ end
61
+
62
+ # find number of columns
63
+ numcols = data.first.size - 1
64
+ if type == :normalize
65
+ divisor = Array.new(numcols, nil)
66
+ 0.upto(keylist.length - 1) do |i|
67
+ temparr[i] = []
68
+ curr_row = data[i][1..-1]
69
+ 0.upto(numcols - 1) do |x|
70
+ if curr_row[x].nil?
71
+ temparr[i][x] = nil
72
+ elsif divisor[x].nil?
73
+ if curr_row[x].to_f != 0
74
+ divisor[x] = curr_row[x].to_f
75
+ temparr[i][x] = 100.0
76
+ else
77
+ temparr[i][x] = 0
78
+ end
79
+ else
80
+ temparr[i][x] = curr_row[x] / divisor[x] * 100.0
81
+ end
102
82
  end
103
- else
104
- if !curr_row[x].nil? and !prev_row[x].nil? and prev_row[x] != 0
105
- temparr[i][x] = ( Float(curr_row[x]) - Float(prev_row[x]) ) / Float( prev_row[x] )
106
- else
107
- temparr[i][x] = nil
83
+ end
84
+ 0.upto(keylist.length - 1) do |i|
85
+ data[i] = [keylist[i], temparr[i]].flatten
86
+ end
87
+ elsif [:diff, :rdiff].include? type
88
+ # now build temparr
89
+ 1.upto(keylist.length - 1) do |i|
90
+ temparr[i] = []
91
+ curr_row = data[i][1..-1]
92
+ prev_row = data[i - 1][1..-1]
93
+ 0.upto(numcols - 1) do |x|
94
+ if type == :diff
95
+ if !curr_row[x].nil? && !prev_row[x].nil?
96
+ temparr[i][x] = Float(curr_row[x]) - Float(prev_row[x])
97
+ else
98
+ temparr[i][x] = nil
99
+ end
100
+ else
101
+ if !curr_row[x].nil? && !prev_row[x].nil? && prev_row[x] != 0
102
+ temparr[i][x] = (Float(curr_row[x]) - Float(prev_row[x])) / Float(prev_row[x])
103
+ else
104
+ temparr[i][x] = nil
105
+ end
106
+ end
108
107
  end
109
108
  end
110
- end
111
- end
112
109
 
113
- #now put temparr into datapac
114
- 1.upto(keylist.length-1) do |i|
115
- data[i] = [keylist[i], temparr[i]].flatten
116
- end
117
-
118
- #delete the first date in datapac (because there is no diff for that)
119
- data.delete_at(0)
120
- elsif type == :rdiff_from
121
- num_rows = keylist.length - 1
122
- initial = Array.new(numcols,nil)
123
- num_rows.downto(0) do |i|
124
- temparr[i] = []
125
- curr_row = data[i][1..-1]
126
- 0.upto(numcols-1) do |x|
127
- if curr_row[x].nil?
128
- temparr[i][x] = nil
129
- elsif initial[x].nil?
130
- initial[x] = curr_row[x]
131
- temparr[i][x] = 0.0
132
- elsif curr_row[x] == 0
133
- temparr[i][x] = nil
134
- else
135
- temparr[i][x] = ( Float(initial[x]) - Float(curr_row[x]) ) / Float(curr_row[x])
110
+ # now put temparr into datapac
111
+ 1.upto(keylist.length - 1) do |i|
112
+ data[i] = [keylist[i], temparr[i]].flatten
136
113
  end
137
- end
138
- end
139
114
 
115
+ # delete the first date in datapac (because there is no diff for that)
116
+ data.delete_at(0)
117
+ elsif type == :rdiff_from
118
+ num_rows = keylist.length - 1
119
+ initial = Array.new(numcols, nil)
120
+ num_rows.downto(0) do |i|
121
+ temparr[i] = []
122
+ curr_row = data[i][1..-1]
123
+ 0.upto(numcols - 1) do |x|
124
+ if curr_row[x].nil?
125
+ temparr[i][x] = nil
126
+ elsif initial[x].nil?
127
+ initial[x] = curr_row[x]
128
+ temparr[i][x] = 0.0
129
+ elsif curr_row[x] == 0
130
+ temparr[i][x] = nil
131
+ else
132
+ temparr[i][x] = (Float(initial[x]) - Float(curr_row[x])) / Float(curr_row[x])
133
+ end
134
+ end
135
+ end
140
136
 
141
- 0.upto(keylist.length-1) do |i|
142
- data[i] = [keylist[i], temparr[i]].flatten
143
- end
144
- else
145
- cumulsum = Array.new(numcols,0)
146
- sumstarted = Array.new(numcols,false)
147
- #now build temparr
148
- 0.upto(keylist.length - 1) do |i|
149
- temparr[i] = []
150
- curr_row = data[i][1..-1]
151
- 0.upto(numcols-1) do |x|
152
- if !curr_row[x].nil?
153
- cumulsum[x] = cumulsum[x] + curr_row[x]
154
- sumstarted[x] = true
137
+ 0.upto(keylist.length - 1) do |i|
138
+ data[i] = [keylist[i], temparr[i]].flatten
139
+ end
140
+ else
141
+ cumulsum = Array.new(numcols, 0)
142
+ sumstarted = Array.new(numcols, false)
143
+ # now build temparr
144
+ 0.upto(keylist.length - 1) do |i|
145
+ temparr[i] = []
146
+ curr_row = data[i][1..-1]
147
+ 0.upto(numcols - 1) do |x|
148
+ unless curr_row[x].nil?
149
+ cumulsum[x] = cumulsum[x] + curr_row[x]
150
+ sumstarted[x] = true
151
+ end
152
+ temparr[i][x] = cumulsum[x] if sumstarted[x]
153
+ end
154
+ end
155
+ 0.upto(keylist.length - 1) do |i|
156
+ data[i] = [keylist[i], temparr[i]].flatten
155
157
  end
156
- temparr[i][x] = cumulsum[x] if sumstarted[x]
157
158
  end
158
- end
159
- 0.upto(keylist.length-1) do |i|
160
- data[i] = [keylist[i],temparr[i]].flatten
159
+ data
161
160
  end
162
161
  end
163
- data
164
162
  end
165
-
166
163
  end
167
-
168
- end
169
164
  end
170
- end