stockfolio 0.1.4 → 0.1.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.
@@ -3,4 +3,9 @@
3
3
  $LOAD_PATH << './lib'
4
4
 
5
5
  require 'stockfolio'
6
- StockFolio::Runner.start
6
+ begin
7
+ StockFolio::Runner.start
8
+ rescue Boson::OptionParser::Error => e
9
+ puts e.message
10
+ exit 1
11
+ end
@@ -0,0 +1,15 @@
1
+ require 'stockfolio/version'
2
+ require 'gems'
3
+
4
+ class StockFolio::Check
5
+
6
+ def self.has_newer
7
+ @info = Gems.info 'stockfolio'
8
+ Gem::Version.new(@info["version"]) > Gem::Version.new(StockFolio::VERSION)
9
+ end
10
+
11
+ def self.version_available
12
+ return @info["version"]
13
+ end
14
+
15
+ end
@@ -12,11 +12,46 @@ class StockFolio::Runner < Boson::Runner
12
12
  option :date, :type => :string, :desc => 'Transaction date'
13
13
  end
14
14
 
15
+ def version
16
+ require 'stockfolio/version'
17
+ require 'stockfolio/check'
18
+ puts StockFolio::VERSION
19
+ if StockFolio::Check.has_newer
20
+ puts "There is a more recent version #{StockFolio::Check.version_available}"
21
+ end
22
+ end
23
+
24
+ desc "Current quote for a stock"
15
25
  def quote(symbol)
16
26
  quote = StockFolio::Web.quote(symbol)
17
27
  print_quotes(quote)
18
28
  end
19
29
 
30
+ desc "Historical prices for a stock"
31
+ def historical(symbol,start_date,end_date)
32
+ history = StockFolio::Web.historical(symbol, DateTime.parse(start_date), DateTime.parse(end_date))
33
+ puts Hirb::Helpers::Table.render(history, :fields => [:date, :open, :close, :low, :high, :volume])
34
+ end
35
+
36
+ desc "Search symbol"
37
+ def search(term)
38
+ matches = StockFolio::Web.search(term)
39
+
40
+ lines = []
41
+ matches.each do |match|
42
+ if match['e'].length > 0 && match['t'].length > 0
43
+ line = {
44
+ :Symbol => "#{match['e']}:#{match['t']}",
45
+ :Name => match['n']
46
+ }
47
+ lines << line
48
+ end
49
+ end
50
+
51
+ puts Hirb::Helpers::Table.render(lines, :fields => [:Symbol, :Name])
52
+
53
+ end
54
+
20
55
  desc 'List porfolios'
21
56
  def portfolios
22
57
  q = Portfolio.all
@@ -122,6 +157,72 @@ class StockFolio::Runner < Boson::Runner
122
157
  puts "Created portfolio \"#{name}\""
123
158
  end
124
159
 
160
+ desc 'List transactions for a portfolio'
161
+ def transactions(name)
162
+ p = Portfolio.first(:name => name)
163
+ if p == nil
164
+ puts "Portfolio #{name} not found"
165
+ exit
166
+ end
167
+
168
+ transactions = []
169
+ p.transactions.each do |transaction|
170
+ transactions << {
171
+ :id => transaction.id,
172
+ :symbol => transaction.symbol,
173
+ :quantity => transaction.quantity,
174
+ :price => transaction.price,
175
+ :executed_at => transaction.executed_at,
176
+ :fee => transaction.fee,
177
+ :created_at => transaction.created_at
178
+ }
179
+ end
180
+ puts Hirb::Helpers::Table.render(transactions, fields: [:id, :symbol, :quantity, :price, :fee, :executed_at, :created_at])
181
+
182
+ end
183
+
184
+ def delete(type,alpha,beta = nil)
185
+ if type == "transaction"
186
+ name = alpha
187
+ id = beta
188
+ puts "Deleting transaction #{id} from #{name}"
189
+
190
+ portfolio = Portfolio.first(:name => name)
191
+ if portfolio == nil
192
+ puts "Portfolio #{name} not found"
193
+ exit
194
+ end
195
+
196
+ transaction = Transaction.get(id)
197
+
198
+ if transaction != nil && transaction.portfolio == portfolio
199
+ transaction.destroy!
200
+ else
201
+ puts "Could not find transaction #{id} in portfolio #{name}"
202
+ end
203
+
204
+ elsif type == "portfolio"
205
+ name = alpha
206
+ puts "Deleting portfolio #{name}"
207
+
208
+ portfolio = Portfolio.first(:name => name)
209
+ if portfolio == nil
210
+ puts "Portfolio #{name} not found"
211
+ exit
212
+ end
213
+
214
+ portfolio.transactions.each do |transaction|
215
+ transaction.destroy!
216
+ end
217
+ portfolio.destroy!
218
+
219
+ end
220
+ end
221
+
222
+ #
223
+ # WATCHLIST
224
+ #
225
+
125
226
  desc 'Add to watchlist'
126
227
  def watch(symbol)
127
228
  # Validate symbol
@@ -137,6 +238,15 @@ class StockFolio::Runner < Boson::Runner
137
238
  end
138
239
  end
139
240
 
241
+ desc 'Remove from watchlist'
242
+ def unwatch(symbol)
243
+ item = WatchList.first(:symbol => symbol)
244
+ if item != nil
245
+ item.destroy
246
+ puts "Removed #{symbol} from watchlist"
247
+ end
248
+ end
249
+
140
250
  desc 'Show Watchlist'
141
251
  def watchlist
142
252
  items = WatchList.all(:order => [:symbol.asc])
@@ -1,3 +1,3 @@
1
1
  module StockFolio
2
- VERSION = '0.1.4'
2
+ VERSION = '0.1.5'
3
3
  end
@@ -1,3 +1,4 @@
1
+ require 'uri'
1
2
  require 'json'
2
3
  require 'net/http'
3
4
 
@@ -13,4 +14,49 @@ class StockFolio::Web
13
14
  end
14
15
  JSON.parse(data.slice(3, data.length).strip)
15
16
  end
17
+
18
+ def self.historical(symbol, startDate, endDate)
19
+ s = startDate.strftime("%b+%d,+%Y")
20
+ e = endDate.strftime("%b+%d,+%Y")
21
+ url = "http://finance.google.com/finance/historical?q=#{symbol}&startdate=#{s}&enddate=#{e}&output=csv"
22
+
23
+ resp = Net::HTTP.get_response(URI.parse(url))
24
+ data = resp.body
25
+
26
+ if data.empty?
27
+ return nil
28
+ end
29
+
30
+ lines = data.split("\n")
31
+ lines.shift
32
+ items = []
33
+ lines.each do |line|
34
+ parts = line.split(",")
35
+ i = 0
36
+ item = {}
37
+ item[:date] = Date.parse(parts[0])
38
+ item[:open] = parts[1]
39
+ item[:high] = parts[2]
40
+ item[:low] = parts[3]
41
+ item[:close] = parts[4]
42
+ item[:volume] = parts[5]
43
+ items << item
44
+ end
45
+
46
+ items
47
+ end
48
+
49
+ def self.search(term)
50
+ q = URI.escape(term, Regexp.new("[^#{URI::PATTERN::UNRESERVED}]"))
51
+ url = "http://www.google.com/finance/match?matchtype=matchall&q=#{q}"
52
+ resp = Net::HTTP.get_response(URI.parse(url))
53
+ data = resp.body
54
+
55
+ if data.empty?
56
+ return nil
57
+ end
58
+ result = JSON.parse(data)
59
+ result["matches"]
60
+ end
61
+
16
62
  end
metadata CHANGED
@@ -1,89 +1,136 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: stockfolio
3
- version: !ruby/object:Gem::Version
4
- version: 0.1.4
5
- prerelease:
3
+ version: !ruby/object:Gem::Version
4
+ prerelease: false
5
+ segments:
6
+ - 0
7
+ - 1
8
+ - 5
9
+ version: 0.1.5
6
10
  platform: ruby
7
- authors:
11
+ authors:
8
12
  - Jerome Poichet
9
13
  autorequire:
10
14
  bindir: bin
11
15
  cert_chain: []
12
- date: 2012-03-22 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
16
+
17
+ date: 2012-03-22 00:00:00 -07:00
18
+ default_executable:
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
15
21
  name: boson
16
- requirement: &2169047320 !ruby/object:Gem::Requirement
22
+ prerelease: false
23
+ requirement: &id001 !ruby/object:Gem::Requirement
17
24
  none: false
18
- requirements:
19
- - - ! '>='
20
- - !ruby/object:Gem::Version
21
- version: '0'
25
+ requirements:
26
+ - - ">="
27
+ - !ruby/object:Gem::Version
28
+ segments:
29
+ - 0
30
+ version: "0"
22
31
  type: :runtime
23
- prerelease: false
24
- version_requirements: *2169047320
25
- - !ruby/object:Gem::Dependency
32
+ version_requirements: *id001
33
+ - !ruby/object:Gem::Dependency
26
34
  name: hirb
27
- requirement: &2169046660 !ruby/object:Gem::Requirement
35
+ prerelease: false
36
+ requirement: &id002 !ruby/object:Gem::Requirement
28
37
  none: false
29
- requirements:
30
- - - ! '>='
31
- - !ruby/object:Gem::Version
32
- version: '0'
38
+ requirements:
39
+ - - ">="
40
+ - !ruby/object:Gem::Version
41
+ segments:
42
+ - 0
43
+ version: "0"
33
44
  type: :runtime
34
- prerelease: false
35
- version_requirements: *2169046660
36
- - !ruby/object:Gem::Dependency
45
+ version_requirements: *id002
46
+ - !ruby/object:Gem::Dependency
37
47
  name: data_mapper
38
- requirement: &2169045840 !ruby/object:Gem::Requirement
48
+ prerelease: false
49
+ requirement: &id003 !ruby/object:Gem::Requirement
39
50
  none: false
40
- requirements:
41
- - - ! '>='
42
- - !ruby/object:Gem::Version
43
- version: '0'
51
+ requirements:
52
+ - - ">="
53
+ - !ruby/object:Gem::Version
54
+ segments:
55
+ - 0
56
+ version: "0"
44
57
  type: :runtime
45
- prerelease: false
46
- version_requirements: *2169045840
47
- - !ruby/object:Gem::Dependency
58
+ version_requirements: *id003
59
+ - !ruby/object:Gem::Dependency
48
60
  name: dm-migrations
49
- requirement: &2169045220 !ruby/object:Gem::Requirement
61
+ prerelease: false
62
+ requirement: &id004 !ruby/object:Gem::Requirement
50
63
  none: false
51
- requirements:
52
- - - ! '>='
53
- - !ruby/object:Gem::Version
54
- version: '0'
64
+ requirements:
65
+ - - ">="
66
+ - !ruby/object:Gem::Version
67
+ segments:
68
+ - 0
69
+ version: "0"
55
70
  type: :runtime
56
- prerelease: false
57
- version_requirements: *2169045220
58
- - !ruby/object:Gem::Dependency
71
+ version_requirements: *id004
72
+ - !ruby/object:Gem::Dependency
59
73
  name: dm-sqlite-adapter
60
- requirement: &2169044620 !ruby/object:Gem::Requirement
74
+ prerelease: false
75
+ requirement: &id005 !ruby/object:Gem::Requirement
61
76
  none: false
62
- requirements:
63
- - - ! '>='
64
- - !ruby/object:Gem::Version
65
- version: '0'
77
+ requirements:
78
+ - - ">="
79
+ - !ruby/object:Gem::Version
80
+ segments:
81
+ - 0
82
+ version: "0"
66
83
  type: :runtime
67
- prerelease: false
68
- version_requirements: *2169044620
69
- - !ruby/object:Gem::Dependency
84
+ version_requirements: *id005
85
+ - !ruby/object:Gem::Dependency
70
86
  name: json
71
- requirement: &2169043820 !ruby/object:Gem::Requirement
87
+ prerelease: false
88
+ requirement: &id006 !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ">="
92
+ - !ruby/object:Gem::Version
93
+ segments:
94
+ - 0
95
+ version: "0"
96
+ type: :runtime
97
+ version_requirements: *id006
98
+ - !ruby/object:Gem::Dependency
99
+ name: uri
100
+ prerelease: false
101
+ requirement: &id007 !ruby/object:Gem::Requirement
72
102
  none: false
73
- requirements:
74
- - - ! '>='
75
- - !ruby/object:Gem::Version
76
- version: '0'
103
+ requirements:
104
+ - - ">="
105
+ - !ruby/object:Gem::Version
106
+ segments:
107
+ - 0
108
+ version: "0"
77
109
  type: :runtime
110
+ version_requirements: *id007
111
+ - !ruby/object:Gem::Dependency
112
+ name: gems
78
113
  prerelease: false
79
- version_requirements: *2169043820
114
+ requirement: &id008 !ruby/object:Gem::Requirement
115
+ none: false
116
+ requirements:
117
+ - - ">="
118
+ - !ruby/object:Gem::Version
119
+ segments:
120
+ - 0
121
+ version: "0"
122
+ type: :runtime
123
+ version_requirements: *id008
80
124
  description:
81
125
  email: poitch@gmail.com
82
- executables:
126
+ executables:
83
127
  - stockfolio
84
128
  extensions: []
129
+
85
130
  extra_rdoc_files: []
86
- files:
131
+
132
+ files:
133
+ - lib/stockfolio/check.rb
87
134
  - lib/stockfolio/portfolio.rb
88
135
  - lib/stockfolio/runner.rb
89
136
  - lib/stockfolio/transaction.rb
@@ -92,29 +139,38 @@ files:
92
139
  - lib/stockfolio/web.rb
93
140
  - lib/stockfolio.rb
94
141
  - bin/stockfolio
142
+ has_rdoc: true
95
143
  homepage: http://github.com/poitch/stockfolio
96
144
  licenses: []
145
+
97
146
  post_install_message:
98
147
  rdoc_options: []
99
- require_paths:
148
+
149
+ require_paths:
100
150
  - lib
101
151
  - lib
102
- required_ruby_version: !ruby/object:Gem::Requirement
152
+ required_ruby_version: !ruby/object:Gem::Requirement
103
153
  none: false
104
- requirements:
105
- - - ! '>='
106
- - !ruby/object:Gem::Version
107
- version: '0'
108
- required_rubygems_version: !ruby/object:Gem::Requirement
154
+ requirements:
155
+ - - ">="
156
+ - !ruby/object:Gem::Version
157
+ segments:
158
+ - 0
159
+ version: "0"
160
+ required_rubygems_version: !ruby/object:Gem::Requirement
109
161
  none: false
110
- requirements:
111
- - - ! '>='
112
- - !ruby/object:Gem::Version
113
- version: '0'
162
+ requirements:
163
+ - - ">="
164
+ - !ruby/object:Gem::Version
165
+ segments:
166
+ - 0
167
+ version: "0"
114
168
  requirements: []
169
+
115
170
  rubyforge_project:
116
- rubygems_version: 1.8.10
171
+ rubygems_version: 1.3.7
117
172
  signing_key:
118
173
  specification_version: 3
119
174
  summary: Track stock portfolio from the command line
120
175
  test_files: []
176
+