Class: Currency::Exchange::Rate
Overview
Represents a convertion rate between two currencies at a given period of time.
Direct Known Subclasses
Defined Under Namespace
Modules: Source Classes: Deriver, Writable
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.
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 81 82 83 84 85 86 87 88 |
# File 'lib/currency/exchange/rate.rb', line 56 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, [ "rate is not positive", :rate, @rate, :c1, c1, :c2, c2, ] 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.
9 10 11 |
# File 'lib/currency/exchange/rate.rb', line 9 def c1 @c1 end |
#c2 ⇒ Object (readonly)
The second Currency.
12 13 14 |
# File 'lib/currency/exchange/rate.rb', line 12 def c2 @c2 end |
#date ⇒ Object (readonly)
The Time of the rate.
25 26 27 |
# File 'lib/currency/exchange/rate.rb', line 25 def date @date end |
#date_0 ⇒ Object (readonly)
The lowest date of sampled rates.
49 50 51 |
# File 'lib/currency/exchange/rate.rb', line 49 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.
54 55 56 |
# File 'lib/currency/exchange/rate.rb', line 54 def date_1 @date_1 end |
#derived ⇒ Object (readonly)
If the rate is derived from other rates, this describes from where it was derived.
28 29 30 |
# File 'lib/currency/exchange/rate.rb', line 28 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.
19 20 21 |
# File 'lib/currency/exchange/rate.rb', line 19 def rate @rate end |
#rate_avg ⇒ Object (readonly)
Average rate over rate samples in a time range.
31 32 33 |
# File 'lib/currency/exchange/rate.rb', line 31 def rate_avg @rate_avg end |
#rate_date_0 ⇒ Object (readonly)
The rate at date_0.
43 44 45 |
# File 'lib/currency/exchange/rate.rb', line 43 def rate_date_0 @rate_date_0 end |
#rate_date_1 ⇒ Object (readonly)
The rate at date_1.
46 47 48 |
# File 'lib/currency/exchange/rate.rb', line 46 def rate_date_1 @rate_date_1 end |
#rate_hi ⇒ Object (readonly)
The rate high between date_0 and date_1.
40 41 42 |
# File 'lib/currency/exchange/rate.rb', line 40 def rate_hi @rate_hi end |
#rate_lo ⇒ Object (readonly)
The rate low between date_0 and date_1.
37 38 39 |
# File 'lib/currency/exchange/rate.rb', line 37 def rate_lo @rate_lo end |
#rate_samples ⇒ Object (readonly)
Number of rate samples used to calcuate rate_avg.
34 35 36 |
# File 'lib/currency/exchange/rate.rb', line 34 def rate_samples @rate_samples end |
#source ⇒ Object (readonly)
The source of the rate.
22 23 24 |
# File 'lib/currency/exchange/rate.rb', line 22 def source @source end |
Instance Method Details
#collect_rate(rate) ⇒ Object
Collect rates samples in to this Rate.
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 180 181 182 183 184 185 186 187 188 189 190 191 |
# File 'lib/currency/exchange/rate.rb', line 136 def collect_rate(rate) # Initial. @rate_samples ||= 0 @rate_sum ||= 0 @source ||= rate.source @c1 ||= rate.c1 @c2 ||= rate.c2 # Reciprocal? if @c1 == rate.c2 && @c2 == rate.c1 collect_rate(rate.reciprocal) elsif ! (@c1 == rate.c1 && @c2 == rate.c2) raise ::Currency::Exception::InvalidRate, [ "Cannot collect rates between different currency pairs", :rate1, self, :rate2, rate, ] 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_1 = 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.
127 128 129 130 131 132 133 |
# File 'lib/currency/exchange/rate.rb', line 127 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.
114 115 116 117 118 119 120 121 122 123 |
# File 'lib/currency/exchange/rate.rb', line 114 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
200 |
# File 'lib/currency/exchange/rate.rb', line 200 def inspect; to_s; end |
#reciprocal ⇒ Object
Returns a cached reciprocal Rate object from c2 to c1.
92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 |
# File 'lib/currency/exchange/rate.rb', line 92 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
194 195 196 197 198 |
# File 'lib/currency/exchange/rate.rb', line 194 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 |