Class: Currency::Exchange::Rate
Overview
Represents a convertion rate between two currencies at a given period of time.
Defined Under Namespace
Modules: Source Classes: Deriver
Instance Attribute Summary collapse
-
#c1 ⇒ Object
readonly
The first Currency.
-
#c2 ⇒ Object
readonly
The second Currency.
-
#date ⇒ Object
readonly
The Time of the rate.
-
#date_0 ⇒ Object
readonly
The lowest date of sampled rates.
-
#date_1 ⇒ Object
readonly
The highest date of sampled rates.
-
#derived ⇒ Object
readonly
If the rate is derived from other rates, this describes from where it was derived.
-
#rate ⇒ Object
readonly
The rate between c1 and c2.
-
#rate_avg ⇒ Object
readonly
Average rate over rate samples in a time range.
-
#rate_date_0 ⇒ Object
readonly
The rate at date_0.
-
#rate_date_1 ⇒ Object
readonly
The rate at date_1.
-
#rate_hi ⇒ Object
readonly
The rate high between date_0 and date_1.
-
#rate_lo ⇒ Object
readonly
The rate low between date_0 and date_1.
-
#rate_samples ⇒ Object
readonly
Number of rate samples used to calcuate rate_avg.
-
#source ⇒ Object
readonly
The source of the rate.
Instance Method Summary collapse
-
#collect_rate(rate) ⇒ Object
Collect rates samples in to this Rate.
-
#collect_rates(rates) ⇒ Object
Collect rate samples into rate_avg, rate_hi, rate_lo, rate_date_0, rate_date_1, date_0, date_1.
-
#convert(m, c1) ⇒ Object
Converts from m in Currency c1 to the opposite currency.
-
#initialize(c1, c2, c1_to_c2_rate, source = "UNKNOWN", date = nil, derived = nil, reciprocal = nil, opts = nil) ⇒ Rate
constructor
A new instance of Rate.
- #inspect ⇒ Object
-
#reciprocal ⇒ Object
Returns a cached reciprocal Rate object from c2 to c1.
- #to_s(extended = false) ⇒ Object
Constructor Details
#initialize(c1, c2, c1_to_c2_rate, source = "UNKNOWN", date = nil, derived = nil, reciprocal = nil, opts = nil) ⇒ Rate
Returns a new instance of Rate.
54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/currency/exchange/rate.rb', line 54 def initialize(c1, c2, c1_to_c2_rate, source = "UNKNOWN", date = nil, derived = nil, reciprocal = nil, opts = nil) @c1 = c1 @c2 = c2 @rate = c1_to_c2_rate raise ::Currency::Exception::InvalidRate.new(@rate) unless @rate && @rate >= 0.0 @source = source @date = date @derived = derived @reciprocal = reciprocal # @rate_avg = @rate_samples = @rate_lo = @rate_hi = @rate_date_0 = @rate_date_1 = @date_0 = @date_1 = nil if opts opts.each_pair do | k, v | self.instance_variable_set("@#{k}", v) end end end |
Instance Attribute Details
#c1 ⇒ Object (readonly)
The first Currency.
7 8 9 |
# File 'lib/currency/exchange/rate.rb', line 7 def c1 @c1 end |
#c2 ⇒ Object (readonly)
The second Currency.
10 11 12 |
# File 'lib/currency/exchange/rate.rb', line 10 def c2 @c2 end |
#date ⇒ Object (readonly)
The Time of the rate.
23 24 25 |
# File 'lib/currency/exchange/rate.rb', line 23 def date @date end |
#date_0 ⇒ Object (readonly)
The lowest date of sampled rates.
47 48 49 |
# File 'lib/currency/exchange/rate.rb', line 47 def date_0 @date_0 end |
#date_1 ⇒ Object (readonly)
The highest date of sampled rates. This is non-inclusive during searches to allow seamless tileings of time with rate buckets.
52 53 54 |
# File 'lib/currency/exchange/rate.rb', line 52 def date_1 @date_1 end |
#derived ⇒ Object (readonly)
If the rate is derived from other rates, this describes from where it was derived.
26 27 28 |
# File 'lib/currency/exchange/rate.rb', line 26 def derived @derived end |
#rate ⇒ Object (readonly)
The rate between c1 and c2.
To convert between m1 in c1 and m2 in c2:
m2 = m1 * rate.
17 18 19 |
# File 'lib/currency/exchange/rate.rb', line 17 def rate @rate end |
#rate_avg ⇒ Object (readonly)
Average rate over rate samples in a time range.
29 30 31 |
# File 'lib/currency/exchange/rate.rb', line 29 def rate_avg @rate_avg end |
#rate_date_0 ⇒ Object (readonly)
The rate at date_0.
41 42 43 |
# File 'lib/currency/exchange/rate.rb', line 41 def rate_date_0 @rate_date_0 end |
#rate_date_1 ⇒ Object (readonly)
The rate at date_1.
44 45 46 |
# File 'lib/currency/exchange/rate.rb', line 44 def rate_date_1 @rate_date_1 end |
#rate_hi ⇒ Object (readonly)
The rate high between date_0 and date_1.
38 39 40 |
# File 'lib/currency/exchange/rate.rb', line 38 def rate_hi @rate_hi end |
#rate_lo ⇒ Object (readonly)
The rate low between date_0 and date_1.
35 36 37 |
# File 'lib/currency/exchange/rate.rb', line 35 def rate_lo @rate_lo end |
#rate_samples ⇒ Object (readonly)
Number of rate samples used to calcuate rate_avg.
32 33 34 |
# File 'lib/currency/exchange/rate.rb', line 32 def rate_samples @rate_samples end |
#source ⇒ Object (readonly)
The source of the rate.
20 21 22 |
# File 'lib/currency/exchange/rate.rb', line 20 def source @source end |
Instance Method Details
#collect_rate(rate) ⇒ Object
Collect rates samples in to this Rate.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 |
# File 'lib/currency/exchange/rate.rb', line 128 def collect_rate(rate) # Initial. @rate_samples ||= 0 @rate_sum ||= 0 @source ||= rate.source @c1 ||= rate.c1 @c2 ||= rate.c2 @date ||= rate.date # Reciprocal? if @c1 == rate.c2 && @c2 == rate.c1 collect_rate(rate.reciprocal) elsif ! (@c1 == rate.c1 && @c2 == rate.c2) raise("Cannot collect rates between different currency pairs") else # Multisource? @source = "<<multiple-sources>>" unless @source == rate.source # Calculate rate average. @rate_samples += 1 @rate_sum += rate.rate || (rate.rate_lo + rate.rate_hi) * 0.5 @rate_avg = @rate_sum / @rate_samples # Calculate rates ranges. r = rate.rate_lo || rate.rate unless @rate_lo && @rate_lo < r @rate_lo = r end r = rate.rate_hi || rate.rate unless @rate_hi && @rate_hi > r @rate_hi = r end # Calculate rates on date range boundaries r = rate.rate_date_0 || rate.rate d = rate.date_0 || rate.date unless @date_0 && @date_0 < d @date_0 = d @rate_date_0 = r end r = rate.rate_date_1 || rate.rate d = rate.date_1 || rate.date unless @date_1 && @date_1 > d @date_1 = d @rate_date_0 = r end @date ||= rate.date || rate.date0 || rate.date1 end self end |
#collect_rates(rates) ⇒ Object
Collect rate samples into rate_avg, rate_hi, rate_lo, rate_date_0, rate_date_1, date_0, date_1.
119 120 121 122 123 124 125 |
# File 'lib/currency/exchange/rate.rb', line 119 def collect_rates(rates) rates = [ rates ] unless rates.kind_of?(Enumerable) rates.each do | r | collect_rate(r) end self end |
#convert(m, c1) ⇒ Object
Converts from m in Currency c1 to the opposite currency.
106 107 108 109 110 111 112 113 114 115 |
# File 'lib/currency/exchange/rate.rb', line 106 def convert(m, c1) m = m.to_f if @c1 == c1 # $stderr.puts "Converting #{@c1} #{m} to #{@c2} #{m * @rate} using #{@rate}" m * @rate else # $stderr.puts "Converting #{@c2} #{m} to #{@c1} #{m / @rate} using #{1.0 / @rate}; recip" m / @rate end end |
#inspect ⇒ Object
188 |
# File 'lib/currency/exchange/rate.rb', line 188 def inspect; to_s; end |
#reciprocal ⇒ Object
Returns a cached reciprocal Rate object from c2 to c1.
84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 |
# File 'lib/currency/exchange/rate.rb', line 84 def reciprocal @reciprocal ||= @rate == 1.0 ? self : self.class.new(@c2, @c1, 1.0 / @rate, @source, @date, "reciprocal(#{derived || "#{c1.code}#{c2.code}"})", self, { :rate_avg => @rate_avg && 1.0 / @rate_avg, :rate_samples => @rate_samples, :rate_lo => @rate_lo && 1.0 / @rate_lo, :rate_hi => @rate_hi && 1.0 / @rate_hi, :rate_date_0 => @rate_date_0 && 1.0 / @rate_date_0, :rate_date_1 => @rate_date_1 && 1.0 / @rate_date_1, :date_0 => @date_0, :date_1 => @date_1, } ) end |
#to_s(extended = false) ⇒ Object
182 183 184 185 186 |
# File 'lib/currency/exchange/rate.rb', line 182 def to_s(extended = false) extended = "#{date_0} #{rate_date_0} |< #{rate_lo} #{rate} #{rate_hi} >| #{rate_date_1} #{date_1}" if extended extended ||= '' "#<#{self.class.name} #{c1.code} #{c2.code} #{rate} #{source.inspect} #{date ? date.strftime('%Y/%m/%d-%H:%M:%S') : 'nil'} #{derived && derived.inspect} #{extended}>" end |