rupee 0.2.4 → 0.2.5

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,7 +1,5 @@
1
1
  require "rupee/rupee" # keep this as the first require
2
2
  require "rupee/version"
3
- require "rupee/security"
4
- require "rupee/option.rb"
5
3
 
6
4
  # Rupee aims to provide user-friendly tools for use in financial applications.
7
5
  # The gem is in its development stages, but it currently offers:
@@ -18,7 +16,15 @@ require "rupee/option.rb"
18
16
 
19
17
  # This module contains all modules and classes associated with Rupee
20
18
  module Rupee
21
- # autoload :Option, "rupee/option.rb"
22
- autoload :Calendar, "rupee/calendar"
23
- autoload :Quote, "rupee/quote"
19
+ autoload :Security, "rupee/security"
20
+
21
+ autoload :Calendar, "rupee/calendar"
22
+ autoload :Custom, "rupee/custom"
23
+ autoload :Call, "rupee/option"
24
+ autoload :Currency, "rupee/currency"
25
+ autoload :DayCount, "rupee/day_count"
26
+ autoload :Option, "rupee/option"
27
+ autoload :Put, "rupee/option"
28
+ autoload :Quote, "rupee/quote"
29
+ autoload :YieldCurve, "rupee/yield_curve"
24
30
  end
@@ -0,0 +1,54 @@
1
+ # encoding: utf-8
2
+ module Rupee
3
+ # A holder for currencies
4
+ class Currency
5
+ # Default currencies, autoloaded as required
6
+ autoload :GBP, "rupee/currency/gbp"
7
+ autoload :POUND, "rupee/currency/gbp"
8
+ autoload :EUR, "rupee/currency/eur"
9
+ autoload :EURO, "rupee/currency/eur"
10
+ autoload :JPY, "rupee/currency/jpy"
11
+ autoload :YEN, "rupee/currency/jpy"
12
+ autoload :USD, "rupee/currency/usd"
13
+ autoload :DOLLAR, "rupee/currency/usd"
14
+
15
+ # A simple description of the currency
16
+ attr :description
17
+ # The currency symbol ($, ¥, £, etc.)
18
+ attr :symbol
19
+ # The default number of decimal places
20
+ attr :decimal_places
21
+ # The delimiter for thousands places
22
+ attr :delimiter
23
+ # The separator for ones and decimals
24
+ attr :separator
25
+
26
+ # Create a new currency
27
+ def initialize(description, opts = {})
28
+ opts = {
29
+ :symbol => "$",
30
+ :decimal_places => 2,
31
+ :delimiter => ",",
32
+ :separator => "."
33
+ }.merge opts
34
+
35
+ @description = description
36
+ @symbol = opts[:symbol]
37
+ @decimal_places = opts[:decimal_places]
38
+ @delimiter = opts[:delimiter]
39
+ @separator = opts[:separator]
40
+ end
41
+
42
+ # Returns a number using the currency's specified format
43
+ def format(number)
44
+ parts = number.round(@decimal_places).to_s.split(".")
45
+ parts[0].gsub! /(\d)(?=(\d\d\d)+(?!\d))/, "\\1#{@delimiter}"
46
+
47
+ if @decimal_places > 0
48
+ parts[1] = parts[1].ljust @decimal_places, "0"
49
+ end
50
+
51
+ "#{@symbol}#{parts.join @separator}"
52
+ end
53
+ end
54
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module Rupee
3
+ class Currency
4
+ # The euro
5
+ EUR = Currency.new "Euro", :symbol => "€"
6
+
7
+ # Alias for the euro
8
+ EURO = EUR
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module Rupee
3
+ class Currency
4
+ # The British pound sterling
5
+ GBP = Currency.new "British pound sterling", :symbol => "£"
6
+
7
+ # Alias for the British pound
8
+ POUND = GBP
9
+ end
10
+ end
@@ -0,0 +1,10 @@
1
+ # encoding: utf-8
2
+ module Rupee
3
+ class Currency
4
+ # The Japanese yen
5
+ JPY = Currency.new "Japanese yen", :symbol => "¥", :decimal_places => 0
6
+
7
+ # Alias for the Japanese yen
8
+ YEN = JPY
9
+ end
10
+ end
@@ -0,0 +1,9 @@
1
+ module Rupee
2
+ class Currency
3
+ # The US dollar
4
+ USD = Currency.new "US dollar"
5
+
6
+ # Alias for the US dollar
7
+ DOLLAR = USD
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ module Rupee
2
+ # Under construction
3
+ #
4
+ # A custom security that allows the user to specify cash flows, discount
5
+ # curves, payout curves, calendars, currencies, daycounts, roll day
6
+ # conventions, etc.
7
+ class Custom < Security
8
+ # The Calendar object
9
+ attr :calendar
10
+ # The security's Currency
11
+ attr :currency
12
+
13
+ # Build a custom security
14
+ def initialize(opts = {})
15
+ opts = {
16
+ :calendar => :us,
17
+ :currency => :usd
18
+ }.merge opts
19
+
20
+ self.calendar = opts[:calendar]
21
+ self.currency = opts[:currency]
22
+ end
23
+
24
+ def calendar=(x) # :nodoc:
25
+ @calendar = to_instance(x, Calendar)
26
+ end
27
+
28
+ def currency=(x) # :nodoc:
29
+ @currency = to_instance(x, Currency)
30
+ end
31
+
32
+ private
33
+
34
+ # Converts the supplied value to an instance of the specified class (if it
35
+ # isn't already one)
36
+ def to_instance(x, constant)
37
+ x = x.upcase
38
+
39
+ if x.instance_of?(constant)
40
+ x
41
+ else
42
+ constant.const_get(x)
43
+ end
44
+ end
45
+ end
46
+ end
@@ -0,0 +1,4 @@
1
+ module Rupee
2
+ class DayCount
3
+ end
4
+ end
@@ -69,16 +69,21 @@ module Rupee
69
69
  @next_pull = now + @frequency
70
70
  @results = {}
71
71
  url = URI.parse(@source.url % ticker)
72
- html = Net::HTTP.start(url.host, url.port) do |http|
72
+ res = Net::HTTP.start(url.host, url.port) do |http|
73
73
  http.get url.request_uri
74
- end.body
74
+ end
75
75
 
76
- @source.params.each do |param, regex|
77
- begin
78
- @results[param] = parse(regex.match(html)[1])
79
- rescue
80
- @results[param] = nil
76
+ case res
77
+ when Net::HTTPSuccess
78
+ @source.params.each do |param, regex|
79
+ begin
80
+ @results[param] = parse(regex.match(res.body)[1])
81
+ rescue
82
+ @results[param] = nil
83
+ end
81
84
  end
85
+ else
86
+ res.error!
82
87
  end
83
88
  end
84
89
 
@@ -1,4 +1,4 @@
1
1
  module Rupee
2
2
  # The current version
3
- VERSION = "0.2.4"
3
+ VERSION = "0.2.5"
4
4
  end
@@ -0,0 +1,12 @@
1
+ module Rupee
2
+ class YieldCurve
3
+ def initialize(description = "", opts = {})
4
+ opts = {
5
+ :currency => :usd,
6
+ :interpolation => :cubic_spline
7
+ }.merge opts
8
+
9
+ @description = description
10
+ end
11
+ end
12
+ end
@@ -0,0 +1,25 @@
1
+ # encoding: utf-8
2
+ require File.dirname(__FILE__) + "/../spec_helper"
3
+
4
+ describe Currency do
5
+ it "should at least have the dollar, euro, pound and yen" do
6
+ Currency::USD.should_not be_nil
7
+ Currency::EUR.should_not be_nil
8
+ Currency::GBP.should_not be_nil
9
+ Currency::JPY.should_not be_nil
10
+ end
11
+
12
+ it "should have more readable aliases for the dollar, euro, pound and yen" do
13
+ Currency::DOLLAR.should be Currency::USD
14
+ Currency::EURO.should be Currency::EUR
15
+ Currency::POUND.should be Currency::GBP
16
+ Currency::YEN.should be Currency::JPY
17
+ end
18
+
19
+ it "should apply the correct format for the dollar, euro, pound and yen" do
20
+ Currency::USD.format(1_234_567.89).should == "$1,234,567.89"
21
+ Currency::EUR.format(1_234_567.89).should == "€1,234,567.89"
22
+ Currency::GBP.format(1_234_567.89).should == "£1,234,567.89"
23
+ Currency::JPY.format(1_234_567.89).should == "¥1,234,568"
24
+ end
25
+ end
@@ -0,0 +1,19 @@
1
+ require File.dirname(__FILE__) + "/../spec_helper"
2
+
3
+ describe Rupee do
4
+ it "should produce no errors when loading all constants two levels deep" do
5
+ Rupee.constants.each do |c|
6
+ # Get classes and constants
7
+ const = Rupee.const_get(c)
8
+ const.should_not be_nil
9
+
10
+ # Get subconstants if original constant has a constants method (or, more
11
+ # generally, is a class)
12
+ if const.respond_to?(:constants)
13
+ const.constants.each do |sc|
14
+ const.const_get(sc).should_not be_nil
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -1,51 +1,76 @@
1
1
  require File.dirname(__FILE__) + "/../spec_helper"
2
2
 
3
3
  describe Quote do
4
+ # Attempts to run the block and submits a pending message if a socket error
5
+ # occurs, the most common cause of which is that the user isn't connected to
6
+ # the internet
7
+ def run_if_connected(&block)
8
+ begin
9
+ block.call
10
+ rescue SocketError
11
+ pending "Socket error: you're probably not connected to the internet"
12
+ end
13
+ end
14
+
4
15
  it "should automatically have a Bloomberg source" do
5
16
  Quote.sources.should include :bloomberg
6
17
  end
7
18
 
8
- describe "when pulling quotes" do
9
- describe "without any parameters specified" do
10
- before :each do
11
- @wfc = Quote.new(:wfc)
12
- end
19
+ describe "without any parameters specified" do
20
+ before :each do
21
+ @wfc = Quote.new(:wfc)
22
+ end
13
23
 
14
- it "should default to pulling the price" do
24
+ it "should default to pulling the price" do
25
+ run_if_connected do
15
26
  @wfc.get.should == @wfc.price
16
27
  end
28
+ end
17
29
 
18
- it "should return a price" do
30
+ it "should return a price" do
31
+ run_if_connected do
19
32
  @wfc.price.should be_a_kind_of Float
20
33
  end
34
+ end
21
35
 
22
- it "should reflect changes to frequency in next pull time" do
23
- freq_change = 5
24
- orig_freq = @wfc.frequency
25
- orig_pull = @wfc.next_pull
26
- @wfc.frequency -= freq_change
27
- @wfc.next_pull.should == orig_pull - freq_change
36
+ [:change, :pct_chg].each do |param|
37
+ it "should have a #{param}" do
38
+ run_if_connected do
39
+ @wfc.price.should be_a_kind_of Float
40
+ end
28
41
  end
29
42
  end
30
43
 
31
- describe "specifying Google Finance as the quote service" do
32
- before :each do
33
- @goog = Quote.new("GOOG", :source => :google)
34
- end
44
+ it "should reflect changes to frequency in next pull time" do
45
+ freq_change = 5
46
+ orig_freq = @wfc.frequency
47
+ orig_pull = @wfc.next_pull
48
+ @wfc.frequency -= freq_change
49
+ @wfc.next_pull.should == orig_pull - freq_change
50
+ end
51
+ end
52
+
53
+ describe "specifying Google Finance as the quote service" do
54
+ before :each do
55
+ @goog = Quote.new("GOOG", :source => :google)
56
+ end
35
57
 
36
- it "should have around the same price as Bloomberg" do
58
+ it "should have around the same price as Bloomberg" do
59
+ run_if_connected do
37
60
  bb_price = Quote.new("GOOG").price
38
61
  bb_price.should be_a_kind_of Float
39
62
  @goog.price.should be_within(0.05).of bb_price
40
63
  end
41
64
  end
65
+ end
42
66
 
43
- describe "specifying Yahoo! Finance as the quote service" do
44
- before :each do
45
- @yahoo = Quote.new("YHOO", :source => :yahoo)
46
- end
67
+ describe "specifying Yahoo! Finance as the quote service" do
68
+ before :each do
69
+ @yahoo = Quote.new("YHOO", :source => :yahoo)
70
+ end
47
71
 
48
- it "should have around the same price as Bloomberg" do
72
+ it "should have around the same price as Bloomberg" do
73
+ run_if_connected do
49
74
  bb_price = Quote.new("YHOO").price
50
75
  bb_price.should be_a_kind_of Float
51
76
  @yahoo.price.should be_within(0.05).of bb_price
metadata CHANGED
@@ -1,60 +1,58 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: rupee
3
- version: !ruby/object:Gem::Version
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.2.5
4
5
  prerelease:
5
- version: 0.2.4
6
6
  platform: ruby
7
- authors:
7
+ authors:
8
8
  - Bryan McKelvey
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
-
13
- date: 2011-10-01 00:00:00 Z
14
- dependencies:
15
- - !ruby/object:Gem::Dependency
12
+ date: 2011-10-01 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
16
15
  name: bundler
17
- prerelease: false
18
- requirement: &id001 !ruby/object:Gem::Requirement
16
+ requirement: &79191280 !ruby/object:Gem::Requirement
19
17
  none: false
20
- requirements:
18
+ requirements:
21
19
  - - ~>
22
- - !ruby/object:Gem::Version
23
- version: "1.0"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.0'
24
22
  type: :development
25
- version_requirements: *id001
26
- - !ruby/object:Gem::Dependency
27
- name: rspec
28
23
  prerelease: false
29
- requirement: &id002 !ruby/object:Gem::Requirement
24
+ version_requirements: *79191280
25
+ - !ruby/object:Gem::Dependency
26
+ name: rspec
27
+ requirement: &79191010 !ruby/object:Gem::Requirement
30
28
  none: false
31
- requirements:
29
+ requirements:
32
30
  - - ~>
33
- - !ruby/object:Gem::Version
34
- version: "2.0"
31
+ - !ruby/object:Gem::Version
32
+ version: '2.0'
35
33
  type: :development
36
- version_requirements: *id002
37
- - !ruby/object:Gem::Dependency
38
- name: sdoc
39
34
  prerelease: false
40
- requirement: &id003 !ruby/object:Gem::Requirement
35
+ version_requirements: *79191010
36
+ - !ruby/object:Gem::Dependency
37
+ name: sdoc
38
+ requirement: &79190780 !ruby/object:Gem::Requirement
41
39
  none: false
42
- requirements:
40
+ requirements:
43
41
  - - ~>
44
- - !ruby/object:Gem::Version
45
- version: "0.3"
42
+ - !ruby/object:Gem::Version
43
+ version: '0.3'
46
44
  type: :development
47
- version_requirements: *id003
48
- description: " rupee aims to provide user-friendly tools for use in\n financial gems and applications.\n"
49
- email:
45
+ prerelease: false
46
+ version_requirements: *79190780
47
+ description: ! " rupee aims to provide user-friendly tools for
48
+ use in\n financial gems and applications.\n"
49
+ email:
50
50
  - bryan.mckelvey@gmail.com
51
51
  executables: []
52
-
53
- extensions:
52
+ extensions:
54
53
  - ext/rupee/extconf.rb
55
54
  extra_rdoc_files: []
56
-
57
- files:
55
+ files:
58
56
  - .autotest
59
57
  - .gitignore
60
58
  - .rspec
@@ -74,54 +72,62 @@ files:
74
72
  - lib/rupee/calendar.rb
75
73
  - lib/rupee/calendar/japan.rb
76
74
  - lib/rupee/calendar/us.rb
77
- - lib/rupee/generators/install.rb
75
+ - lib/rupee/currency.rb
76
+ - lib/rupee/currency/eur.rb
77
+ - lib/rupee/currency/gbp.rb
78
+ - lib/rupee/currency/jpy.rb
79
+ - lib/rupee/currency/usd.rb
80
+ - lib/rupee/custom.rb
81
+ - lib/rupee/day_count.rb
78
82
  - lib/rupee/option.rb
79
83
  - lib/rupee/quote.rb
80
84
  - lib/rupee/quote/source.rb
81
85
  - lib/rupee/security.rb
82
86
  - lib/rupee/version.rb
87
+ - lib/rupee/yield_curve.rb
83
88
  - rupee.gemspec
84
89
  - spec/native/bond_spec.rb
85
90
  - spec/native/future_spec.rb
86
91
  - spec/native/option_spec.rb
87
92
  - spec/native/statistics_spec.rb
88
93
  - spec/ruby/calendar_spec.rb
94
+ - spec/ruby/currency_spec.rb
95
+ - spec/ruby/generic_spec.rb
89
96
  - spec/ruby/quote_spec.rb
90
97
  - spec/spec_helper.rb
91
98
  - tasks/benchmark.rake
92
99
  - test_rubies
93
100
  homepage: https://github.com/brymck/rupee
94
101
  licenses: []
95
-
96
102
  post_install_message:
97
103
  rdoc_options: []
98
-
99
- require_paths:
104
+ require_paths:
100
105
  - lib
101
106
  - ext
102
- required_ruby_version: !ruby/object:Gem::Requirement
107
+ required_ruby_version: !ruby/object:Gem::Requirement
103
108
  none: false
104
- requirements:
105
- - - ">="
106
- - !ruby/object:Gem::Version
107
- version: "0"
108
- required_rubygems_version: !ruby/object:Gem::Requirement
109
+ requirements:
110
+ - - ! '>='
111
+ - !ruby/object:Gem::Version
112
+ version: '0'
113
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
114
  none: false
110
- requirements:
111
- - - ">="
112
- - !ruby/object:Gem::Version
113
- version: "0"
115
+ requirements:
116
+ - - ! '>='
117
+ - !ruby/object:Gem::Version
118
+ version: '0'
114
119
  requirements: []
115
-
116
120
  rubyforge_project: rupee
117
121
  rubygems_version: 1.8.10
118
122
  signing_key:
119
123
  specification_version: 3
120
124
  summary: Financial tools for Ruby
121
- test_files:
125
+ test_files:
122
126
  - spec/native/bond_spec.rb
123
127
  - spec/native/future_spec.rb
124
128
  - spec/native/option_spec.rb
125
129
  - spec/native/statistics_spec.rb
126
130
  - spec/ruby/calendar_spec.rb
131
+ - spec/ruby/currency_spec.rb
132
+ - spec/ruby/generic_spec.rb
127
133
  - spec/ruby/quote_spec.rb
File without changes