finance-ytd 0.1.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 78d9d25898942f0f0b2bd1febdc70a8db42e7c7e
4
+ data.tar.gz: 7128b8e8142482ce5dfb3ea855014840c0821c75
5
+ SHA512:
6
+ metadata.gz: 068c790a6d71e8be634529551e31db8bc85884a082dd292f50d9a51182ed7889fed29e0d55f7c3dfaacea701b58ffe21494186fdbe5f078c81ab4cb99889e2b2
7
+ data.tar.gz: 02dd7d5ecbabd5e1063df169c6583f730ab338bc0b519b646d6426f9f6edcd35bacf0a8de0f1f163f67aaea8d1df902b5a1d7209cbf39c82e1ccb4fccee2f4dd
@@ -0,0 +1,89 @@
1
+ require 'rubygems'
2
+ require 'nokogiri'
3
+ require 'open-uri'
4
+
5
+ class String
6
+ def bg_red; "\033[41m#{self}\033[0m" end
7
+ def bg_green; "\033[42m#{self}\033[0m" end
8
+ end
9
+
10
+ class FinanceYtd
11
+ attr_accessor :css, :url, :symbol, :friendly_name, :css_text, :ytd_return
12
+
13
+ def initialize(options)
14
+ @symbol = options[:symbol]
15
+ @friendly_name = options[:friendly_name]
16
+ @decimal_places = options[:decimal_places]
17
+ @price_last_year = options[:price_last_year]
18
+ end
19
+
20
+ def match
21
+ page = Nokogiri::HTML(open(@url))
22
+ @css_text = page.css(@css).text
23
+ end
24
+
25
+ def calculate
26
+ @ytd_return = @css_text.tr('+%', '').to_f / 100.0
27
+ end
28
+
29
+ def to_s
30
+ ytd_return_rounded = (@ytd_return * 100.0).round(@decimal_places)
31
+ s = @friendly_name + ' (' + @symbol + ') ' + ytd_return_rounded.to_s + '%'
32
+
33
+ if ytd_return_rounded >= 0.0
34
+ s.bg_green
35
+ else
36
+ s.bg_red
37
+ end
38
+ end
39
+ end
40
+
41
+ class CnnEtfFinanceYtd < FinanceYtd
42
+ def initialize(options)
43
+ super(options)
44
+ @css = 'td.wsod_ytd > span'
45
+ @url = 'http://money.cnn.com/quote/etf/etf.html?exHours=off&symb=' + @symbol
46
+ match()
47
+ calculate()
48
+ end
49
+ end
50
+
51
+ class ApmexGoldFinanceYtd < FinanceYtd
52
+ def initialize(options)
53
+ super(options)
54
+ @css = 'table.table-spot-prices > tbody > tr:nth-child(1) > td:nth-child(2) > span'
55
+ @url = 'http://www.apmex.com'
56
+ match()
57
+ calculate()
58
+ end
59
+
60
+ def match
61
+ super
62
+ css_text_match = /(\d*,*\d+\.\d+)/.match(@css_text)
63
+ @price_this_year = css_text_match[1].gsub(',', '').to_f
64
+ end
65
+
66
+ def calculate
67
+ @ytd_return = @price_this_year / @price_last_year - 1.0
68
+ end
69
+ end
70
+
71
+ class ApmexSilverFinanceYtd < FinanceYtd
72
+ def initialize(options)
73
+ super(options)
74
+ @css = 'table.table-spot-prices > tbody > tr:nth-child(2) > td:nth-child(2) > span'
75
+ @url = 'http://www.apmex.com'
76
+ match()
77
+ calculate()
78
+ end
79
+
80
+ def match
81
+ super
82
+ css_text_match = /(\d*,*\d+\.\d+)/.match(@css_text)
83
+ @price_this_year = css_text_match[1].gsub(',', '').to_f
84
+ end
85
+
86
+ def calculate
87
+ @ytd_return = @price_this_year / @price_last_year - 1.0
88
+ end
89
+ end
@@ -0,0 +1,31 @@
1
+ require 'minitest/autorun'
2
+ require 'finance-ytd'
3
+
4
+ class FinanceYtdTest < Minitest::Unit::TestCase
5
+ def test
6
+ cnn_etf_tests = []
7
+ cnn_etf_tests.push({ :symbol => 'VT', :friendly_name => 'World Stocks', :decimal_places => 0 })
8
+ cnn_etf_tests.push({ :symbol => 'VTI', :friendly_name => 'U.S Stocks', :decimal_places => 0 })
9
+ cnn_etf_tests.push({ :symbol => 'VXUS', :friendly_name => 'Foreign Stocks', :decimal_places => 0 })
10
+ cnn_etf_tests.push({ :symbol => 'GDX', :friendly_name => 'Gold Miners', :decimal_places => 0 })
11
+ cnn_etf_tests.push({ :symbol => 'BND', :friendly_name => 'U.S. Bonds', :decimal_places => 0 })
12
+ cnn_etf_tests.push({ :symbol => 'IEF', :friendly_name => '10 Year Treasury', :decimal_places => 0 })
13
+ cnn_etf_tests.push({ :symbol => 'BNDX', :friendly_name => 'Foreign Bonds', :decimal_places => 0 })
14
+ cnn_etf_tests.push({ :symbol => 'BWZ', :friendly_name => 'Foreign Cash', :decimal_places => 0 })
15
+ cnn_etf_tests.push({ :symbol => 'XBT', :friendly_name => 'Bitcoin', :decimal_places => 0 })
16
+
17
+ cnn_etf_tests.each do |c|
18
+ f = CnnEtfFinanceYtd.new(c)
19
+ puts f
20
+ assert f.ytd_return.is_a? Float
21
+ end
22
+
23
+ f = ApmexGoldFinanceYtd.new({ :symbol => 'Gold Spot', :friendly_name => 'Gold', :decimal_places => 0, :price_last_year => 1183.90 })
24
+ puts f
25
+ assert f.ytd_return.is_a? Float
26
+
27
+ f = ApmexSilverFinanceYtd.new({ :symbol => 'Silver Spot', :friendly_name => 'Silver', :decimal_places => 0, :price_last_year => 15.56 })
28
+ puts f
29
+ assert f.ytd_return.is_a? Float
30
+ end
31
+ end
metadata ADDED
@@ -0,0 +1,49 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: finance-ytd
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.1
5
+ platform: ruby
6
+ authors:
7
+ - cscribn
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2015-06-30 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: Most financial websites show the daily change of assets. The purpose
14
+ of this gem is to provide year-to-date change. ETS, mutual funds, and Bitcoin are
15
+ supported via money.cnn. Precious metals are supported using apmex.com, but require
16
+ users to pass in last year's ending price.
17
+ email:
18
+ executables: []
19
+ extensions: []
20
+ extra_rdoc_files: []
21
+ files:
22
+ - lib/finance-ytd.rb
23
+ - test/test-finance-ytd.rb
24
+ homepage: http://rubygems.org/gems/finance-ytd
25
+ licenses:
26
+ - MIT
27
+ metadata: {}
28
+ post_install_message:
29
+ rdoc_options: []
30
+ require_paths:
31
+ - lib
32
+ required_ruby_version: !ruby/object:Gem::Requirement
33
+ requirements:
34
+ - - '>='
35
+ - !ruby/object:Gem::Version
36
+ version: '0'
37
+ required_rubygems_version: !ruby/object:Gem::Requirement
38
+ requirements:
39
+ - - '>='
40
+ - !ruby/object:Gem::Version
41
+ version: '0'
42
+ requirements: []
43
+ rubyforge_project:
44
+ rubygems_version: 2.0.15
45
+ signing_key:
46
+ specification_version: 4
47
+ summary: Get the year-to-date change for assets in your portfolio, instead of the
48
+ daily change.
49
+ test_files: []